memory/cpu: Have safe_write128 use write128 and mmap_write128

According to Fabian: safe_write128 is called suprisingly often as it is used by
Linux to fill the frame buffer. We can do two optimisations here: Add write128
to avoid one in_mapped_range check. Add mmap_write128 (taking 4 32-bit integers)
to avoid several switches from wasm to js and lookups of
memory_map_write32[aligned_addr]
(we can assume that writes don't cross a 16-byte boundary)
This commit is contained in:
Amaan Cheval 2018-03-27 11:31:36 +05:30 committed by Fabian
parent 96e99c2076
commit d79f084f1d
6 changed files with 29 additions and 2 deletions

View file

@ -184,6 +184,7 @@ function V86Starter(options)
"_mmap_write8": function(addr, value) { return cpu.mmap_write8(addr, value); },
"_mmap_write16": function(addr, value) { return cpu.mmap_write16(addr, value); },
"_mmap_write32": function(addr, value) { return cpu.mmap_write32(addr, value); },
"_mmap_write128": function(addr, value0, value1, value2, value3) { return cpu.mmap_write128(addr, value0, value1, value2, value3); },
"_int_log2": function(val) { return v86util.int_log2(val); },

View file

@ -40,6 +40,14 @@ CPU.prototype.mmap_write32 = function(addr, value)
this.memory_map_write32[aligned_addr](addr, value);
};
CPU.prototype.mmap_write128 = function(addr, value0, value1, value2, value3)
{
this.mmap_write32(addr, value0);
this.mmap_write32(addr + 4, value1);
this.mmap_write32(addr + 8, value2);
this.mmap_write32(addr + 12, value3);
};
/**
* @param {Array.<number>|Uint8Array} blob
* @param {number} offset

View file

@ -1349,8 +1349,7 @@ void safe_write128(int32_t addr, union reg128 value)
else
{
int32_t phys = translate_address_write(addr);
write64(phys, value.u64[0]);
write64(phys + 8, value.u64[1]);
write128(phys, value);
}
}

View file

@ -37,6 +37,7 @@ extern void iret16(void);
extern void iret32(void);
extern void load_ldt(int32_t);
extern void load_tr(int32_t);
extern void mmap_write128(uint32_t, int32_t, int32_t, int32_t, int32_t);
extern void mmap_write16(uint32_t, int32_t);
extern void mmap_write32(uint32_t, int32_t);
extern void mmap_write8(uint32_t, int32_t);

View file

@ -264,3 +264,20 @@ void write64(uint32_t addr, int64_t value)
*(int64_t*)(mem8 + addr) = value;
}
}
void write128(uint32_t addr, union reg128 value)
{
if(USE_A20 && !*a20_enabled) addr &= A20_MASK;
jit_dirty_cache_small(addr, addr + 16);
if(in_mapped_range(addr))
{
mmap_write128(addr, value.i32[0], value.i32[1], value.i32[2], value.i32[3]);
}
else
{
*(int64_t*)(mem8 + addr) = value.i64[0];
*(int64_t*)(mem8 + addr + 8) = value.i64[1];
}
}

View file

@ -22,3 +22,4 @@ void write_aligned16(uint32_t addr, uint32_t value);
void write32(uint32_t addr, int32_t value);
void write_aligned32(uint32_t addr, int32_t value);
void write64(uint32_t addr, int64_t value);
void write128(uint32_t addr, union reg128 value);