add static Memory r/w functions that can easily be called when emitting

This commit is contained in:
Anthony Pesch 2015-08-10 18:54:19 -07:00
parent e26ceb9b04
commit 4ec98dfa42
3 changed files with 49 additions and 50 deletions

View File

@ -340,14 +340,14 @@ CALLBACK(LOAD_I64) {
}
CALLBACK(LOAD_F32) {
uint32_t addr = (uint32_t)LOAD_ARG0();
R v = memory->RF32(addr);
STORE_RESULT(v);
uint32_t v = memory->R32(addr);
STORE_RESULT(*reinterpret_cast<float *>(&v));
return NEXT_INSTR;
}
CALLBACK(LOAD_F64) {
uint32_t addr = (uint32_t)LOAD_ARG0();
R v = memory->RF64(addr);
STORE_RESULT(v);
uint64_t v = memory->R64(addr);
STORE_RESULT(*reinterpret_cast<double *>(&v));
return NEXT_INSTR;
}
REGISTER_CALLBACK(LOAD, LOAD_I8, I8, I32, V);
@ -384,13 +384,13 @@ CALLBACK(STORE_I64) {
CALLBACK(STORE_F32) {
uint32_t addr = (uint32_t)LOAD_ARG0();
A1 v = LOAD_ARG1();
memory->WF32(addr, v);
memory->W32(addr, *reinterpret_cast<uint32_t *>(&v));
return NEXT_INSTR;
}
CALLBACK(STORE_F64) {
uint32_t addr = (uint32_t)LOAD_ARG0();
A1 v = LOAD_ARG1();
memory->WF64(addr, v);
memory->W64(addr, *reinterpret_cast<uint64_t *>(&v));
return NEXT_INSTR;
}
REGISTER_CALLBACK(STORE, STORE_I8, V, I32, I8);

View File

@ -520,26 +520,26 @@ EMITTER(STORE_CONTEXT) {
}
}
uint8_t R8(Memory *memory, uint32_t addr) { return memory->R8(addr); }
uint16_t R16(Memory *memory, uint32_t addr) { return memory->R16(addr); }
uint32_t R32(Memory *memory, uint32_t addr) { return memory->R32(addr); }
uint64_t R64(Memory *memory, uint32_t addr) { return memory->R64(addr); }
EMITTER(LOAD) {
const Xbyak::Operand &result = e.GetOperand(instr->result());
void *fn = nullptr;
switch (instr->result()->type()) {
case VALUE_I8:
fn = reinterpret_cast<void *>(&R8);
fn = reinterpret_cast<void *>(
static_cast<uint8_t (*)(Memory *, uint32_t)>(&Memory::R8));
break;
case VALUE_I16:
fn = reinterpret_cast<void *>(&R16);
fn = reinterpret_cast<void *>(
static_cast<uint16_t (*)(Memory *, uint32_t)>(&Memory::R16));
break;
case VALUE_I32:
fn = reinterpret_cast<void *>(&R32);
fn = reinterpret_cast<void *>(
static_cast<uint32_t (*)(Memory *, uint32_t)>(&Memory::R32));
break;
case VALUE_I64:
fn = reinterpret_cast<void *>(&R64);
fn = reinterpret_cast<void *>(
static_cast<uint64_t (*)(Memory *, uint32_t)>(&Memory::R64));
break;
default:
CHECK(false);
@ -560,24 +560,24 @@ EMITTER(LOAD) {
e.RestoreParameters();
}
void W8(Memory *memory, uint32_t addr, uint8_t v) { memory->W8(addr, v); }
void W16(Memory *memory, uint32_t addr, uint16_t v) { memory->W16(addr, v); }
void W32(Memory *memory, uint32_t addr, uint32_t v) { memory->W32(addr, v); }
void W64(Memory *memory, uint32_t addr, uint64_t v) { memory->W64(addr, v); }
EMITTER(STORE) {
void *fn = nullptr;
switch (instr->arg1()->type()) {
case VALUE_I8:
fn = reinterpret_cast<void *>(&W8);
fn = reinterpret_cast<void *>(
static_cast<void (*)(Memory *, uint32_t, uint8_t)>(&Memory::W8));
break;
case VALUE_I16:
fn = reinterpret_cast<void *>(&W16);
fn = reinterpret_cast<void *>(
static_cast<void (*)(Memory *, uint32_t, uint16_t)>(&Memory::W16));
break;
case VALUE_I32:
fn = reinterpret_cast<void *>(&W32);
fn = reinterpret_cast<void *>(
static_cast<void (*)(Memory *, uint32_t, uint32_t)>(&Memory::W32));
break;
case VALUE_I64:
fn = reinterpret_cast<void *>(&W64);
fn = reinterpret_cast<void *>(
static_cast<void (*)(Memory *, uint32_t, uint64_t)>(&Memory::W64));
break;
default:
CHECK(false);

View File

@ -167,7 +167,7 @@ class Memory {
: num_banks_(1) // 0 is UNMAPPED
{}
virtual ~Memory() {
~Memory() {
for (auto block : blocks_) {
free(block);
}
@ -257,58 +257,57 @@ class Memory {
}
}
// static versions of the functions for ease of calling from assembly
static uint8_t R8(Memory *memory, uint32_t addr) {
return memory->ReadBytes<uint8_t, &MemoryBank::r8>(addr);
}
static uint16_t R16(Memory *memory, uint32_t addr) {
return memory->ReadBytes<uint16_t, &MemoryBank::r16>(addr);
}
static uint32_t R32(Memory *memory, uint32_t addr) {
return memory->ReadBytes<uint32_t, &MemoryBank::r32>(addr);
}
static uint64_t R64(Memory *memory, uint32_t addr) {
return memory->ReadBytes<uint64_t, &MemoryBank::r64>(addr);
}
static void W8(Memory *memory, uint32_t addr, uint8_t value) {
memory->WriteBytes<uint8_t, &MemoryBank::w8>(addr, value);
}
static void W16(Memory *memory, uint32_t addr, uint16_t value) {
memory->WriteBytes<uint16_t, &MemoryBank::w16>(addr, value);
}
static void W32(Memory *memory, uint32_t addr, uint32_t value) {
memory->WriteBytes<uint32_t, &MemoryBank::w32>(addr, value);
}
static void W64(Memory *memory, uint32_t addr, uint64_t value) {
memory->WriteBytes<uint64_t, &MemoryBank::w64>(addr, value);
}
uint8_t R8(uint32_t addr) {
return ReadBytes<uint8_t, &MemoryBank::r8>(addr);
}
uint16_t R16(uint32_t addr) {
return ReadBytes<uint16_t, &MemoryBank::r16>(addr);
}
uint32_t R32(uint32_t addr) {
return ReadBytes<uint32_t, &MemoryBank::r32>(addr);
}
uint64_t R64(uint32_t addr) {
return ReadBytes<uint64_t, &MemoryBank::r64>(addr);
}
float RF32(uint32_t addr) {
uint32_t v = R32(addr);
return *(float *)&v;
}
double RF64(uint32_t addr) {
uint64_t v = R64(addr);
return *(double *)&v;
}
void W8(uint32_t addr, uint8_t value) {
WriteBytes<uint8_t, &MemoryBank::w8>(addr, value);
}
void W16(uint32_t addr, uint16_t value) {
WriteBytes<uint16_t, &MemoryBank::w16>(addr, value);
}
void W32(uint32_t addr, uint32_t value) {
WriteBytes<uint32_t, &MemoryBank::w32>(addr, value);
}
void W64(uint32_t addr, uint64_t value) {
WriteBytes<uint64_t, &MemoryBank::w64>(addr, value);
}
void WF32(uint32_t addr, float value) {
uint32_t v = *(uint32_t *)&value;
W32(addr, v);
}
void WF64(uint32_t addr, double value) {
uint64_t v = *(uint64_t *)&value;
W64(addr, v);
}
private:
PageTable table_;
int num_banks_;