mirror of https://github.com/inolen/redream.git
added OP_LOAD_HOST and OP_STORE_HOST for directly accessing host memory
added lookup table for fsca removed sin, cos ir ops
This commit is contained in:
parent
a039b60d52
commit
f457e8e9d8
|
@ -21,7 +21,7 @@ bool Holly::Init() {
|
||||||
maple_ = dc_->maple;
|
maple_ = dc_->maple;
|
||||||
sh4_ = dc_->sh4;
|
sh4_ = dc_->sh4;
|
||||||
|
|
||||||
// initialize registers
|
// initialize registers
|
||||||
#define HOLLY_REG(addr, name, flags, default, type) \
|
#define HOLLY_REG(addr, name, flags, default, type) \
|
||||||
holly_regs_[name##_OFFSET] = {flags, default};
|
holly_regs_[name##_OFFSET] = {flags, default};
|
||||||
#include "hw/holly/holly_regs.inc"
|
#include "hw/holly/holly_regs.inc"
|
||||||
|
|
|
@ -20,7 +20,7 @@ bool PVR2::Init() {
|
||||||
palette_ram_ = dc_->palette_ram;
|
palette_ram_ = dc_->palette_ram;
|
||||||
video_ram_ = dc_->video_ram;
|
video_ram_ = dc_->video_ram;
|
||||||
|
|
||||||
// initialize registers
|
// initialize registers
|
||||||
#define PVR_REG(addr, name, flags, default, type) \
|
#define PVR_REG(addr, name, flags, default, type) \
|
||||||
pvr_regs_[name##_OFFSET] = {flags, default};
|
pvr_regs_[name##_OFFSET] = {flags, default};
|
||||||
#include "hw/holly/pvr2_regs.inc"
|
#include "hw/holly/pvr2_regs.inc"
|
||||||
|
|
|
@ -86,7 +86,7 @@ void InterpreterEmitter::TranslateInstr(Instr &ir_i, IntInstr *instr) {
|
||||||
// HACK instead of writing out ctx and an array of IntValues, it'd be nice
|
// HACK instead of writing out ctx and an array of IntValues, it'd be nice
|
||||||
// to encode exactly what's needed for each instruction into the codegen
|
// to encode exactly what's needed for each instruction into the codegen
|
||||||
// buffer
|
// buffer
|
||||||
if (ir_i.op() == OP_LOAD || ir_i.op() == OP_STORE) {
|
if (ir_i.op() == OP_LOAD_GUEST || ir_i.op() == OP_STORE_GUEST) {
|
||||||
instr->ctx = &memory_;
|
instr->ctx = &memory_;
|
||||||
} else if (ir_i.op() == OP_LOAD_CONTEXT || ir_i.op() == OP_STORE_CONTEXT ||
|
} else if (ir_i.op() == OP_LOAD_CONTEXT || ir_i.op() == OP_STORE_CONTEXT ||
|
||||||
ir_i.op() == OP_CALL_EXTERNAL) {
|
ir_i.op() == OP_CALL_EXTERNAL) {
|
||||||
|
@ -341,6 +341,154 @@ struct helper<T, ARG, ACC_IMM> {
|
||||||
//
|
//
|
||||||
// interpreter callbacks
|
// interpreter callbacks
|
||||||
//
|
//
|
||||||
|
INT_CALLBACK(LOAD_HOST_I8) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
R v = dvm::load<int8_t>(reinterpret_cast<void *>(addr));
|
||||||
|
STORE_RESULT(v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_HOST_I16) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
R v = dvm::load<int16_t>(reinterpret_cast<void *>(addr));
|
||||||
|
STORE_RESULT(v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_HOST_I32) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
R v = dvm::load<int32_t>(reinterpret_cast<void *>(addr));
|
||||||
|
STORE_RESULT(v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_HOST_I64) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
R v = dvm::load<int64_t>(reinterpret_cast<void *>(addr));
|
||||||
|
STORE_RESULT(v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_HOST_F32) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
int32_t v = dvm::load<int32_t>(reinterpret_cast<void *>(addr));
|
||||||
|
STORE_RESULT(dvm::load<float>(&v));
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_HOST_F64) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
int64_t v = dvm::load<int64_t>(reinterpret_cast<void *>(addr));
|
||||||
|
STORE_RESULT(dvm::load<double>(&v));
|
||||||
|
}
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_HOST, LOAD_HOST_I8, I8, I64, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_HOST, LOAD_HOST_I16, I16, I64, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_HOST, LOAD_HOST_I32, I32, I64, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_HOST, LOAD_HOST_I64, I64, I64, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_HOST, LOAD_HOST_F32, F32, I64, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_HOST, LOAD_HOST_F64, F64, I64, V);
|
||||||
|
|
||||||
|
INT_CALLBACK(STORE_HOST_I8) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
dvm::store(reinterpret_cast<void *>(addr), v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_HOST_I16) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
dvm::store(reinterpret_cast<void *>(addr), v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_HOST_I32) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
dvm::store(reinterpret_cast<void *>(addr), v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_HOST_I64) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
dvm::store(reinterpret_cast<void *>(addr), v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_HOST_F32) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
dvm::store(reinterpret_cast<void *>(addr), dvm::load<uint32_t>(&v));
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_HOST_F64) {
|
||||||
|
uint64_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
dvm::store(reinterpret_cast<void *>(addr), dvm::load<uint64_t>(&v));
|
||||||
|
}
|
||||||
|
REGISTER_INT_CALLBACK(STORE_HOST, STORE_HOST_I8, V, I64, I8);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_HOST, STORE_HOST_I16, V, I64, I16);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_HOST, STORE_HOST_I32, V, I64, I32);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_HOST, STORE_HOST_I64, V, I64, I64);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_HOST, STORE_HOST_F32, V, I64, F32);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_HOST, STORE_HOST_F64, V, I64, F64);
|
||||||
|
|
||||||
|
INT_CALLBACK(LOAD_GUEST_I8) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
R v = reinterpret_cast<Memory *>(i->ctx)->R8(addr);
|
||||||
|
STORE_RESULT(v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_GUEST_I16) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
R v = reinterpret_cast<Memory *>(i->ctx)->R16(addr);
|
||||||
|
STORE_RESULT(v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_GUEST_I32) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
R v = reinterpret_cast<Memory *>(i->ctx)->R32(addr);
|
||||||
|
STORE_RESULT(v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_GUEST_I64) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
R v = reinterpret_cast<Memory *>(i->ctx)->R64(addr);
|
||||||
|
STORE_RESULT(v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_GUEST_F32) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
uint32_t v = reinterpret_cast<Memory *>(i->ctx)->R32(addr);
|
||||||
|
STORE_RESULT(dvm::load<float>(&v));
|
||||||
|
}
|
||||||
|
INT_CALLBACK(LOAD_GUEST_F64) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
uint64_t v = reinterpret_cast<Memory *>(i->ctx)->R64(addr);
|
||||||
|
STORE_RESULT(dvm::load<double>(&v));
|
||||||
|
}
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_GUEST, LOAD_GUEST_I8, I8, I32, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_GUEST, LOAD_GUEST_I16, I16, I32, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_GUEST, LOAD_GUEST_I32, I32, I32, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_GUEST, LOAD_GUEST_I64, I64, I32, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_GUEST, LOAD_GUEST_F32, F32, I32, V);
|
||||||
|
REGISTER_INT_CALLBACK(LOAD_GUEST, LOAD_GUEST_F64, F64, I32, V);
|
||||||
|
|
||||||
|
INT_CALLBACK(STORE_GUEST_I8) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
reinterpret_cast<Memory *>(i->ctx)->W8(addr, v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_GUEST_I16) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
reinterpret_cast<Memory *>(i->ctx)->W16(addr, v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_GUEST_I32) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
reinterpret_cast<Memory *>(i->ctx)->W32(addr, v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_GUEST_I64) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
reinterpret_cast<Memory *>(i->ctx)->W64(addr, v);
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_GUEST_F32) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
reinterpret_cast<Memory *>(i->ctx)->W32(addr, dvm::load<uint32_t>(&v));
|
||||||
|
}
|
||||||
|
INT_CALLBACK(STORE_GUEST_F64) {
|
||||||
|
uint32_t addr = LOAD_ARG0();
|
||||||
|
A1 v = LOAD_ARG1();
|
||||||
|
reinterpret_cast<Memory *>(i->ctx)->W64(addr, dvm::load<uint64_t>(&v));
|
||||||
|
}
|
||||||
|
REGISTER_INT_CALLBACK(STORE_GUEST, STORE_GUEST_I8, V, I32, I8);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_GUEST, STORE_GUEST_I16, V, I32, I16);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_GUEST, STORE_GUEST_I32, V, I32, I32);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_GUEST, STORE_GUEST_I64, V, I32, I64);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_GUEST, STORE_GUEST_F32, V, I32, F32);
|
||||||
|
REGISTER_INT_CALLBACK(STORE_GUEST, STORE_GUEST_F64, V, I32, F64);
|
||||||
|
|
||||||
INT_CALLBACK(LOAD_CONTEXT) {
|
INT_CALLBACK(LOAD_CONTEXT) {
|
||||||
A0 offset = LOAD_ARG0();
|
A0 offset = LOAD_ARG0();
|
||||||
R v = dvm::load<R>(reinterpret_cast<uint8_t *>(i->ctx) + offset);
|
R v = dvm::load<R>(reinterpret_cast<uint8_t *>(i->ctx) + offset);
|
||||||
|
@ -389,80 +537,6 @@ REGISTER_INT_CALLBACK(STORE_LOCAL, STORE_LOCAL, V, I32, I64);
|
||||||
REGISTER_INT_CALLBACK(STORE_LOCAL, STORE_LOCAL, V, I32, F32);
|
REGISTER_INT_CALLBACK(STORE_LOCAL, STORE_LOCAL, V, I32, F32);
|
||||||
REGISTER_INT_CALLBACK(STORE_LOCAL, STORE_LOCAL, V, I32, F64);
|
REGISTER_INT_CALLBACK(STORE_LOCAL, STORE_LOCAL, V, I32, F64);
|
||||||
|
|
||||||
INT_CALLBACK(LOAD_I8) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
R v = reinterpret_cast<Memory *>(i->ctx)->R8(addr);
|
|
||||||
STORE_RESULT(v);
|
|
||||||
}
|
|
||||||
INT_CALLBACK(LOAD_I16) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
R v = reinterpret_cast<Memory *>(i->ctx)->R16(addr);
|
|
||||||
STORE_RESULT(v);
|
|
||||||
}
|
|
||||||
INT_CALLBACK(LOAD_I32) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
R v = reinterpret_cast<Memory *>(i->ctx)->R32(addr);
|
|
||||||
STORE_RESULT(v);
|
|
||||||
}
|
|
||||||
INT_CALLBACK(LOAD_I64) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
R v = reinterpret_cast<Memory *>(i->ctx)->R64(addr);
|
|
||||||
STORE_RESULT(v);
|
|
||||||
}
|
|
||||||
INT_CALLBACK(LOAD_F32) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
uint32_t v = reinterpret_cast<Memory *>(i->ctx)->R32(addr);
|
|
||||||
STORE_RESULT(dvm::load<float>(&v));
|
|
||||||
}
|
|
||||||
INT_CALLBACK(LOAD_F64) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
uint64_t v = reinterpret_cast<Memory *>(i->ctx)->R64(addr);
|
|
||||||
STORE_RESULT(dvm::load<double>(&v));
|
|
||||||
}
|
|
||||||
REGISTER_INT_CALLBACK(LOAD, LOAD_I8, I8, I32, V);
|
|
||||||
REGISTER_INT_CALLBACK(LOAD, LOAD_I16, I16, I32, V);
|
|
||||||
REGISTER_INT_CALLBACK(LOAD, LOAD_I32, I32, I32, V);
|
|
||||||
REGISTER_INT_CALLBACK(LOAD, LOAD_I64, I64, I32, V);
|
|
||||||
REGISTER_INT_CALLBACK(LOAD, LOAD_F32, F32, I32, V);
|
|
||||||
REGISTER_INT_CALLBACK(LOAD, LOAD_F64, F64, I32, V);
|
|
||||||
|
|
||||||
INT_CALLBACK(STORE_I8) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
A1 v = LOAD_ARG1();
|
|
||||||
reinterpret_cast<Memory *>(i->ctx)->W8(addr, v);
|
|
||||||
}
|
|
||||||
INT_CALLBACK(STORE_I16) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
A1 v = LOAD_ARG1();
|
|
||||||
reinterpret_cast<Memory *>(i->ctx)->W16(addr, v);
|
|
||||||
}
|
|
||||||
INT_CALLBACK(STORE_I32) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
A1 v = LOAD_ARG1();
|
|
||||||
reinterpret_cast<Memory *>(i->ctx)->W32(addr, v);
|
|
||||||
}
|
|
||||||
INT_CALLBACK(STORE_I64) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
A1 v = LOAD_ARG1();
|
|
||||||
reinterpret_cast<Memory *>(i->ctx)->W64(addr, v);
|
|
||||||
}
|
|
||||||
INT_CALLBACK(STORE_F32) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
A1 v = LOAD_ARG1();
|
|
||||||
reinterpret_cast<Memory *>(i->ctx)->W32(addr, dvm::load<uint32_t>(&v));
|
|
||||||
}
|
|
||||||
INT_CALLBACK(STORE_F64) {
|
|
||||||
uint32_t addr = static_cast<uint32_t>(LOAD_ARG0());
|
|
||||||
A1 v = LOAD_ARG1();
|
|
||||||
reinterpret_cast<Memory *>(i->ctx)->W64(addr, dvm::load<uint64_t>(&v));
|
|
||||||
}
|
|
||||||
REGISTER_INT_CALLBACK(STORE, STORE_I8, V, I32, I8);
|
|
||||||
REGISTER_INT_CALLBACK(STORE, STORE_I16, V, I32, I16);
|
|
||||||
REGISTER_INT_CALLBACK(STORE, STORE_I32, V, I32, I32);
|
|
||||||
REGISTER_INT_CALLBACK(STORE, STORE_I64, V, I32, I64);
|
|
||||||
REGISTER_INT_CALLBACK(STORE, STORE_F32, V, I32, F32);
|
|
||||||
REGISTER_INT_CALLBACK(STORE, STORE_F64, V, I32, F64);
|
|
||||||
|
|
||||||
INT_CALLBACK(CAST) {
|
INT_CALLBACK(CAST) {
|
||||||
A0 v = LOAD_ARG0();
|
A0 v = LOAD_ARG0();
|
||||||
STORE_RESULT(static_cast<R>(v));
|
STORE_RESULT(static_cast<R>(v));
|
||||||
|
@ -728,28 +802,6 @@ INT_CALLBACK(ABSF) {
|
||||||
REGISTER_INT_CALLBACK(ABS, ABSF, F32, F32, V);
|
REGISTER_INT_CALLBACK(ABS, ABSF, F32, F32, V);
|
||||||
REGISTER_INT_CALLBACK(ABS, ABSF, F64, F64, V);
|
REGISTER_INT_CALLBACK(ABS, ABSF, F64, F64, V);
|
||||||
|
|
||||||
INT_CALLBACK(SINF) {
|
|
||||||
A0 v = LOAD_ARG0();
|
|
||||||
STORE_RESULT(sinf(v));
|
|
||||||
}
|
|
||||||
INT_CALLBACK(SIN) {
|
|
||||||
A0 v = LOAD_ARG0();
|
|
||||||
STORE_RESULT(sin(v));
|
|
||||||
}
|
|
||||||
REGISTER_INT_CALLBACK(SIN, SINF, F32, F32, V);
|
|
||||||
REGISTER_INT_CALLBACK(SIN, SIN, F64, F64, V);
|
|
||||||
|
|
||||||
INT_CALLBACK(COSF) {
|
|
||||||
A0 v = LOAD_ARG0();
|
|
||||||
STORE_RESULT(cosf(v));
|
|
||||||
}
|
|
||||||
INT_CALLBACK(COS) {
|
|
||||||
A0 v = LOAD_ARG0();
|
|
||||||
STORE_RESULT(cos(v));
|
|
||||||
}
|
|
||||||
REGISTER_INT_CALLBACK(COS, COSF, F32, F32, V);
|
|
||||||
REGISTER_INT_CALLBACK(COS, COS, F64, F64, V);
|
|
||||||
|
|
||||||
INT_CALLBACK(AND) {
|
INT_CALLBACK(AND) {
|
||||||
A0 lhs = LOAD_ARG0();
|
A0 lhs = LOAD_ARG0();
|
||||||
A1 rhs = LOAD_ARG1();
|
A1 rhs = LOAD_ARG1();
|
||||||
|
|
|
@ -440,6 +440,275 @@ void X64Emitter::RestoreArgs() {
|
||||||
mov(int_arg1, reinterpret_cast<uintptr_t>(memory_->protected_base()));
|
mov(int_arg1, reinterpret_cast<uintptr_t>(memory_->protected_base()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMITTER(LOAD_HOST) {
|
||||||
|
const Xbyak::Reg &a = e.GetRegister(instr->arg0());
|
||||||
|
|
||||||
|
if (IsFloatType(instr->result()->type())) {
|
||||||
|
const Xbyak::Xmm &result = e.GetXMMRegister(instr->result());
|
||||||
|
|
||||||
|
switch (instr->result()->type()) {
|
||||||
|
case VALUE_F32:
|
||||||
|
e.vmovss(result, e.dword[a]);
|
||||||
|
break;
|
||||||
|
case VALUE_F64:
|
||||||
|
e.vmovsd(result, e.qword[a]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected result type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const Xbyak::Reg &result = e.GetRegister(instr->result());
|
||||||
|
|
||||||
|
switch (instr->result()->type()) {
|
||||||
|
case VALUE_I8:
|
||||||
|
e.mov(result, e.byte[a]);
|
||||||
|
break;
|
||||||
|
case VALUE_I16:
|
||||||
|
e.mov(result, e.word[a]);
|
||||||
|
break;
|
||||||
|
case VALUE_I32:
|
||||||
|
e.mov(result, e.dword[a]);
|
||||||
|
break;
|
||||||
|
case VALUE_I64:
|
||||||
|
e.mov(result, e.qword[a]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected load result type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EMITTER(STORE_HOST) {
|
||||||
|
const Xbyak::Reg &a = e.GetRegister(instr->arg0());
|
||||||
|
|
||||||
|
if (IsFloatType(instr->arg1()->type())) {
|
||||||
|
const Xbyak::Xmm &b = e.GetXMMRegister(instr->arg1());
|
||||||
|
|
||||||
|
switch (instr->arg1()->type()) {
|
||||||
|
case VALUE_F32:
|
||||||
|
e.movss(e.dword[a], b);
|
||||||
|
break;
|
||||||
|
case VALUE_F64:
|
||||||
|
e.movsd(e.qword[a], b);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected value type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const Xbyak::Reg &b = e.GetRegister(instr->arg1());
|
||||||
|
|
||||||
|
switch (instr->arg1()->type()) {
|
||||||
|
case VALUE_I8:
|
||||||
|
e.mov(e.byte[a], b);
|
||||||
|
break;
|
||||||
|
case VALUE_I16:
|
||||||
|
e.mov(e.word[a], b);
|
||||||
|
break;
|
||||||
|
case VALUE_I32:
|
||||||
|
e.mov(e.dword[a], b);
|
||||||
|
break;
|
||||||
|
case VALUE_I64:
|
||||||
|
e.mov(e.qword[a], b);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected store value type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EMITTER(LOAD_GUEST) {
|
||||||
|
const Xbyak::Reg &result = e.GetRegister(instr->result());
|
||||||
|
|
||||||
|
if (instr->arg0()->constant()) {
|
||||||
|
// try to resolve the address to a physical page
|
||||||
|
uint32_t addr = static_cast<uint32_t>(instr->arg0()->value<int32_t>());
|
||||||
|
uint8_t *host_addr = nullptr;
|
||||||
|
MemoryRegion *region = nullptr;
|
||||||
|
uint32_t offset = 0;
|
||||||
|
|
||||||
|
e.memory().Lookup(addr, &host_addr, ®ion, &offset);
|
||||||
|
|
||||||
|
// if the address maps to a physical page, not a dynamic handler, make it
|
||||||
|
// fast
|
||||||
|
if (host_addr) {
|
||||||
|
// FIXME it'd be nice if xbyak had a mov operation which would convert
|
||||||
|
// the displacement to a RIP-relative address when finalizing code so
|
||||||
|
// we didn't have to store the absolute address in the scratch register
|
||||||
|
e.mov(e.rax, reinterpret_cast<uintptr_t>(host_addr));
|
||||||
|
|
||||||
|
switch (instr->result()->type()) {
|
||||||
|
case VALUE_I8:
|
||||||
|
e.mov(result, e.byte[e.rax]);
|
||||||
|
break;
|
||||||
|
case VALUE_I16:
|
||||||
|
e.mov(result, e.word[e.rax]);
|
||||||
|
break;
|
||||||
|
case VALUE_I32:
|
||||||
|
e.mov(result, e.dword[e.rax]);
|
||||||
|
break;
|
||||||
|
case VALUE_I64:
|
||||||
|
e.mov(result, e.qword[e.rax]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected load result type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Xbyak::Reg &a = e.GetRegister(instr->arg0());
|
||||||
|
|
||||||
|
if (e.block_flags() & BF_SLOWMEM) {
|
||||||
|
void *fn = nullptr;
|
||||||
|
switch (instr->result()->type()) {
|
||||||
|
case VALUE_I8:
|
||||||
|
fn = reinterpret_cast<void *>(
|
||||||
|
static_cast<uint8_t (*)(Memory *, uint32_t)>(&Memory::R8));
|
||||||
|
break;
|
||||||
|
case VALUE_I16:
|
||||||
|
fn = reinterpret_cast<void *>(
|
||||||
|
static_cast<uint16_t (*)(Memory *, uint32_t)>(&Memory::R16));
|
||||||
|
break;
|
||||||
|
case VALUE_I32:
|
||||||
|
fn = reinterpret_cast<void *>(
|
||||||
|
static_cast<uint32_t (*)(Memory *, uint32_t)>(&Memory::R32));
|
||||||
|
break;
|
||||||
|
case VALUE_I64:
|
||||||
|
fn = reinterpret_cast<void *>(
|
||||||
|
static_cast<uint64_t (*)(Memory *, uint32_t)>(&Memory::R64));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected load result type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.mov(int_arg0, reinterpret_cast<uintptr_t>(&e.memory()));
|
||||||
|
e.mov(int_arg1, a);
|
||||||
|
e.mov(e.rax, reinterpret_cast<uintptr_t>(fn));
|
||||||
|
e.call(e.rax);
|
||||||
|
e.mov(result, e.rax);
|
||||||
|
e.RestoreArgs();
|
||||||
|
} else {
|
||||||
|
switch (instr->result()->type()) {
|
||||||
|
case VALUE_I8:
|
||||||
|
e.mov(result, e.byte[a.cvt64() + int_arg1]);
|
||||||
|
break;
|
||||||
|
case VALUE_I16:
|
||||||
|
e.mov(result, e.word[a.cvt64() + int_arg1]);
|
||||||
|
break;
|
||||||
|
case VALUE_I32:
|
||||||
|
e.mov(result, e.dword[a.cvt64() + int_arg1]);
|
||||||
|
break;
|
||||||
|
case VALUE_I64:
|
||||||
|
e.mov(result, e.qword[a.cvt64() + int_arg1]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected load result type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EMITTER(STORE_GUEST) {
|
||||||
|
if (instr->arg0()->constant()) {
|
||||||
|
// try to resolve the address to a physical page
|
||||||
|
uint32_t addr = static_cast<uint32_t>(instr->arg0()->value<int32_t>());
|
||||||
|
uint8_t *host_addr = nullptr;
|
||||||
|
MemoryRegion *bank = nullptr;
|
||||||
|
uint32_t offset = 0;
|
||||||
|
|
||||||
|
e.memory().Lookup(addr, &host_addr, &bank, &offset);
|
||||||
|
|
||||||
|
if (host_addr) {
|
||||||
|
const Xbyak::Reg &b = e.GetRegister(instr->arg1());
|
||||||
|
|
||||||
|
// FIXME it'd be nice if xbyak had a mov operation which would convert
|
||||||
|
// the displacement to a RIP-relative address when finalizing code so
|
||||||
|
// we didn't have to store the absolute address in the scratch register
|
||||||
|
e.mov(e.rax, reinterpret_cast<uintptr_t>(host_addr));
|
||||||
|
|
||||||
|
switch (instr->arg1()->type()) {
|
||||||
|
case VALUE_I8:
|
||||||
|
e.mov(e.byte[e.rax], b);
|
||||||
|
break;
|
||||||
|
case VALUE_I16:
|
||||||
|
e.mov(e.word[e.rax], b);
|
||||||
|
break;
|
||||||
|
case VALUE_I32:
|
||||||
|
e.mov(e.dword[e.rax], b);
|
||||||
|
break;
|
||||||
|
case VALUE_I64:
|
||||||
|
e.mov(e.qword[e.rax], b);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected store value type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Xbyak::Reg &a = e.GetRegister(instr->arg0());
|
||||||
|
const Xbyak::Reg &b = e.GetRegister(instr->arg1());
|
||||||
|
|
||||||
|
if (e.block_flags() & BF_SLOWMEM) {
|
||||||
|
void *fn = nullptr;
|
||||||
|
switch (instr->arg1()->type()) {
|
||||||
|
case VALUE_I8:
|
||||||
|
fn = reinterpret_cast<void *>(
|
||||||
|
static_cast<void (*)(Memory *, uint32_t, uint8_t)>(&Memory::W8));
|
||||||
|
break;
|
||||||
|
case VALUE_I16:
|
||||||
|
fn = reinterpret_cast<void *>(
|
||||||
|
static_cast<void (*)(Memory *, uint32_t, uint16_t)>(&Memory::W16));
|
||||||
|
break;
|
||||||
|
case VALUE_I32:
|
||||||
|
fn = reinterpret_cast<void *>(
|
||||||
|
static_cast<void (*)(Memory *, uint32_t, uint32_t)>(&Memory::W32));
|
||||||
|
break;
|
||||||
|
case VALUE_I64:
|
||||||
|
fn = reinterpret_cast<void *>(
|
||||||
|
static_cast<void (*)(Memory *, uint32_t, uint64_t)>(&Memory::W64));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected store value type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.mov(int_arg0, reinterpret_cast<uintptr_t>(&e.memory()));
|
||||||
|
e.mov(int_arg1, a);
|
||||||
|
e.mov(int_arg2, b);
|
||||||
|
e.mov(e.rax, reinterpret_cast<uintptr_t>(fn));
|
||||||
|
e.call(e.rax);
|
||||||
|
e.RestoreArgs();
|
||||||
|
} else {
|
||||||
|
switch (instr->arg1()->type()) {
|
||||||
|
case VALUE_I8:
|
||||||
|
e.mov(e.byte[a.cvt64() + int_arg1], b);
|
||||||
|
break;
|
||||||
|
case VALUE_I16:
|
||||||
|
e.mov(e.word[a.cvt64() + int_arg1], b);
|
||||||
|
break;
|
||||||
|
case VALUE_I32:
|
||||||
|
e.mov(e.dword[a.cvt64() + int_arg1], b);
|
||||||
|
break;
|
||||||
|
case VALUE_I64:
|
||||||
|
e.mov(e.qword[a.cvt64() + int_arg1], b);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unexpected store value type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EMITTER(LOAD_CONTEXT) {
|
EMITTER(LOAD_CONTEXT) {
|
||||||
int offset = instr->arg0()->value<int32_t>();
|
int offset = instr->arg0()->value<int32_t>();
|
||||||
|
|
||||||
|
@ -624,195 +893,6 @@ EMITTER(STORE_LOCAL) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EMITTER(LOAD) {
|
|
||||||
const Xbyak::Reg &result = e.GetRegister(instr->result());
|
|
||||||
|
|
||||||
if (instr->arg0()->constant()) {
|
|
||||||
// try to resolve the address to a physical page
|
|
||||||
uint32_t addr = static_cast<uint32_t>(instr->arg0()->value<int32_t>());
|
|
||||||
uint8_t *host_addr = nullptr;
|
|
||||||
MemoryRegion *region = nullptr;
|
|
||||||
uint32_t offset = 0;
|
|
||||||
|
|
||||||
e.memory().Lookup(addr, &host_addr, ®ion, &offset);
|
|
||||||
|
|
||||||
// if the address maps to a physical page, not a dynamic handler, make it
|
|
||||||
// fast
|
|
||||||
if (host_addr) {
|
|
||||||
// FIXME it'd be nice if xbyak had a mov operation which would convert
|
|
||||||
// the displacement to a RIP-relative address when finalizing code so
|
|
||||||
// we didn't have to store the absolute address in the scratch register
|
|
||||||
e.mov(e.rax, reinterpret_cast<uintptr_t>(host_addr));
|
|
||||||
|
|
||||||
switch (instr->result()->type()) {
|
|
||||||
case VALUE_I8:
|
|
||||||
e.mov(result, e.byte[e.rax]);
|
|
||||||
break;
|
|
||||||
case VALUE_I16:
|
|
||||||
e.mov(result, e.word[e.rax]);
|
|
||||||
break;
|
|
||||||
case VALUE_I32:
|
|
||||||
e.mov(result, e.dword[e.rax]);
|
|
||||||
break;
|
|
||||||
case VALUE_I64:
|
|
||||||
e.mov(result, e.qword[e.rax]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_FATAL("Unexpected load result type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Xbyak::Reg &a = e.GetRegister(instr->arg0());
|
|
||||||
|
|
||||||
if (e.block_flags() & BF_SLOWMEM) {
|
|
||||||
void *fn = nullptr;
|
|
||||||
switch (instr->result()->type()) {
|
|
||||||
case VALUE_I8:
|
|
||||||
fn = reinterpret_cast<void *>(
|
|
||||||
static_cast<uint8_t (*)(Memory *, uint32_t)>(&Memory::R8));
|
|
||||||
break;
|
|
||||||
case VALUE_I16:
|
|
||||||
fn = reinterpret_cast<void *>(
|
|
||||||
static_cast<uint16_t (*)(Memory *, uint32_t)>(&Memory::R16));
|
|
||||||
break;
|
|
||||||
case VALUE_I32:
|
|
||||||
fn = reinterpret_cast<void *>(
|
|
||||||
static_cast<uint32_t (*)(Memory *, uint32_t)>(&Memory::R32));
|
|
||||||
break;
|
|
||||||
case VALUE_I64:
|
|
||||||
fn = reinterpret_cast<void *>(
|
|
||||||
static_cast<uint64_t (*)(Memory *, uint32_t)>(&Memory::R64));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_FATAL("Unexpected load result type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.mov(int_arg0, reinterpret_cast<uintptr_t>(&e.memory()));
|
|
||||||
e.mov(int_arg1, a);
|
|
||||||
e.mov(e.rax, reinterpret_cast<uintptr_t>(fn));
|
|
||||||
e.call(e.rax);
|
|
||||||
e.mov(result, e.rax);
|
|
||||||
e.RestoreArgs();
|
|
||||||
} else {
|
|
||||||
switch (instr->result()->type()) {
|
|
||||||
case VALUE_I8:
|
|
||||||
e.mov(result, e.byte[a.cvt64() + int_arg1]);
|
|
||||||
break;
|
|
||||||
case VALUE_I16:
|
|
||||||
e.mov(result, e.word[a.cvt64() + int_arg1]);
|
|
||||||
break;
|
|
||||||
case VALUE_I32:
|
|
||||||
e.mov(result, e.dword[a.cvt64() + int_arg1]);
|
|
||||||
break;
|
|
||||||
case VALUE_I64:
|
|
||||||
e.mov(result, e.qword[a.cvt64() + int_arg1]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_FATAL("Unexpected load result type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EMITTER(STORE) {
|
|
||||||
if (instr->arg0()->constant()) {
|
|
||||||
// try to resolve the address to a physical page
|
|
||||||
uint32_t addr = static_cast<uint32_t>(instr->arg0()->value<int32_t>());
|
|
||||||
uint8_t *host_addr = nullptr;
|
|
||||||
MemoryRegion *bank = nullptr;
|
|
||||||
uint32_t offset = 0;
|
|
||||||
|
|
||||||
e.memory().Lookup(addr, &host_addr, &bank, &offset);
|
|
||||||
|
|
||||||
if (host_addr) {
|
|
||||||
const Xbyak::Reg &b = e.GetRegister(instr->arg1());
|
|
||||||
|
|
||||||
// FIXME it'd be nice if xbyak had a mov operation which would convert
|
|
||||||
// the displacement to a RIP-relative address when finalizing code so
|
|
||||||
// we didn't have to store the absolute address in the scratch register
|
|
||||||
e.mov(e.rax, reinterpret_cast<uintptr_t>(host_addr));
|
|
||||||
|
|
||||||
switch (instr->arg1()->type()) {
|
|
||||||
case VALUE_I8:
|
|
||||||
e.mov(e.byte[e.rax], b);
|
|
||||||
break;
|
|
||||||
case VALUE_I16:
|
|
||||||
e.mov(e.word[e.rax], b);
|
|
||||||
break;
|
|
||||||
case VALUE_I32:
|
|
||||||
e.mov(e.dword[e.rax], b);
|
|
||||||
break;
|
|
||||||
case VALUE_I64:
|
|
||||||
e.mov(e.qword[e.rax], b);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_FATAL("Unexpected store value type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Xbyak::Reg &a = e.GetRegister(instr->arg0());
|
|
||||||
const Xbyak::Reg &b = e.GetRegister(instr->arg1());
|
|
||||||
|
|
||||||
if (e.block_flags() & BF_SLOWMEM) {
|
|
||||||
void *fn = nullptr;
|
|
||||||
switch (instr->arg1()->type()) {
|
|
||||||
case VALUE_I8:
|
|
||||||
fn = reinterpret_cast<void *>(
|
|
||||||
static_cast<void (*)(Memory *, uint32_t, uint8_t)>(&Memory::W8));
|
|
||||||
break;
|
|
||||||
case VALUE_I16:
|
|
||||||
fn = reinterpret_cast<void *>(
|
|
||||||
static_cast<void (*)(Memory *, uint32_t, uint16_t)>(&Memory::W16));
|
|
||||||
break;
|
|
||||||
case VALUE_I32:
|
|
||||||
fn = reinterpret_cast<void *>(
|
|
||||||
static_cast<void (*)(Memory *, uint32_t, uint32_t)>(&Memory::W32));
|
|
||||||
break;
|
|
||||||
case VALUE_I64:
|
|
||||||
fn = reinterpret_cast<void *>(
|
|
||||||
static_cast<void (*)(Memory *, uint32_t, uint64_t)>(&Memory::W64));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_FATAL("Unexpected store value type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.mov(int_arg0, reinterpret_cast<uintptr_t>(&e.memory()));
|
|
||||||
e.mov(int_arg1, a);
|
|
||||||
e.mov(int_arg2, b);
|
|
||||||
e.mov(e.rax, reinterpret_cast<uintptr_t>(fn));
|
|
||||||
e.call(e.rax);
|
|
||||||
e.RestoreArgs();
|
|
||||||
} else {
|
|
||||||
switch (instr->arg1()->type()) {
|
|
||||||
case VALUE_I8:
|
|
||||||
e.mov(e.byte[a.cvt64() + int_arg1], b);
|
|
||||||
break;
|
|
||||||
case VALUE_I16:
|
|
||||||
e.mov(e.word[a.cvt64() + int_arg1], b);
|
|
||||||
break;
|
|
||||||
case VALUE_I32:
|
|
||||||
e.mov(e.dword[a.cvt64() + int_arg1], b);
|
|
||||||
break;
|
|
||||||
case VALUE_I64:
|
|
||||||
e.mov(e.qword[a.cvt64() + int_arg1], b);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_FATAL("Unexpected store value type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EMITTER(CAST) {
|
EMITTER(CAST) {
|
||||||
if (IsFloatType(instr->result()->type())) {
|
if (IsFloatType(instr->result()->type())) {
|
||||||
const Xbyak::Xmm &result = e.GetXMMRegister(instr->result());
|
const Xbyak::Xmm &result = e.GetXMMRegister(instr->result());
|
||||||
|
@ -876,7 +956,7 @@ EMITTER(ZEXT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.isBit(64)) {
|
if (result.isBit(64) && a.isBit(32)) {
|
||||||
// mov will automatically zero fill the upper 32-bits
|
// mov will automatically zero fill the upper 32-bits
|
||||||
e.mov(result.cvt32(), a);
|
e.mov(result.cvt32(), a);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1354,52 +1434,6 @@ EMITTER(ABS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EMITTER(SIN) {
|
|
||||||
CHECK(IsFloatType(instr->result()->type()));
|
|
||||||
|
|
||||||
const Xbyak::Xmm &result = e.GetXMMRegister(instr->result());
|
|
||||||
const Xbyak::Xmm &a = e.GetXMMRegister(instr->arg0());
|
|
||||||
|
|
||||||
// FIXME xmm registers aren't callee saved, this would probably break if we
|
|
||||||
// used the lower indexed xmm registers
|
|
||||||
if (instr->result()->type() == VALUE_F32) {
|
|
||||||
e.movss(e.xmm0, a);
|
|
||||||
e.mov(e.rax, (uint64_t) reinterpret_cast<float (*)(float)>(&sinf));
|
|
||||||
e.call(e.rax);
|
|
||||||
e.movss(result, e.xmm0);
|
|
||||||
} else {
|
|
||||||
e.movsd(e.xmm0, a);
|
|
||||||
e.mov(e.rax, (uint64_t) reinterpret_cast<double (*)(double)>(&sin));
|
|
||||||
e.call(e.rax);
|
|
||||||
e.movsd(result, e.xmm0);
|
|
||||||
}
|
|
||||||
|
|
||||||
e.RestoreArgs();
|
|
||||||
}
|
|
||||||
|
|
||||||
EMITTER(COS) {
|
|
||||||
CHECK(IsFloatType(instr->result()->type()));
|
|
||||||
|
|
||||||
const Xbyak::Xmm &result = e.GetXMMRegister(instr->result());
|
|
||||||
const Xbyak::Xmm &a = e.GetXMMRegister(instr->arg0());
|
|
||||||
|
|
||||||
// FIXME xmm registers aren't callee saved, this would probably break if we
|
|
||||||
// used the lower indexed xmm registers
|
|
||||||
if (instr->result()->type() == VALUE_F32) {
|
|
||||||
e.movss(e.xmm0, a);
|
|
||||||
e.mov(e.rax, (uint64_t) reinterpret_cast<float (*)(float)>(&cosf));
|
|
||||||
e.call(e.rax);
|
|
||||||
e.movss(result, e.xmm0);
|
|
||||||
} else {
|
|
||||||
e.movsd(e.xmm0, a);
|
|
||||||
e.mov(e.rax, (uint64_t) reinterpret_cast<double (*)(double)>(&cos));
|
|
||||||
e.call(e.rax);
|
|
||||||
e.movsd(result, e.xmm0);
|
|
||||||
}
|
|
||||||
|
|
||||||
e.RestoreArgs();
|
|
||||||
}
|
|
||||||
|
|
||||||
EMITTER(AND) {
|
EMITTER(AND) {
|
||||||
CHECK(IsIntType(instr->result()->type()));
|
CHECK(IsIntType(instr->result()->type()));
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,10 @@ using namespace dvm::jit::frontend;
|
||||||
using namespace dvm::jit::frontend::sh4;
|
using namespace dvm::jit::frontend::sh4;
|
||||||
using namespace dvm::jit::ir;
|
using namespace dvm::jit::ir;
|
||||||
|
|
||||||
|
static uint32_t s_fsca_table[0x20000] = {
|
||||||
|
#include "jit/frontend/sh4/sh4_fsca.inc"
|
||||||
|
};
|
||||||
|
|
||||||
typedef void (*EmitCallback)(SH4Builder &b, const FPUState &,
|
typedef void (*EmitCallback)(SH4Builder &b, const FPUState &,
|
||||||
const sh4::Instr &i);
|
const sh4::Instr &i);
|
||||||
|
|
||||||
|
@ -191,14 +195,14 @@ EMITTER(MOVI) {
|
||||||
// MOV.W @(disp,PC),Rn
|
// MOV.W @(disp,PC),Rn
|
||||||
EMITTER(MOVWLPC) {
|
EMITTER(MOVWLPC) {
|
||||||
uint32_t addr = (i.disp * 2) + i.addr + 4;
|
uint32_t addr = (i.disp * 2) + i.addr + 4;
|
||||||
Value *v = b.SExt(b.Load(b.AllocConstant(addr), VALUE_I16), VALUE_I32);
|
Value *v = b.SExt(b.LoadGuest(b.AllocConstant(addr), VALUE_I16), VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.L @(disp,PC),Rn
|
// MOV.L @(disp,PC),Rn
|
||||||
EMITTER(MOVLLPC) {
|
EMITTER(MOVLLPC) {
|
||||||
uint32_t addr = (i.disp * 4) + (i.addr & ~3) + 4;
|
uint32_t addr = (i.disp * 4) + (i.addr & ~3) + 4;
|
||||||
Value *v = b.Load(b.AllocConstant(addr), VALUE_I32);
|
Value *v = b.LoadGuest(b.AllocConstant(addr), VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,40 +216,40 @@ EMITTER(MOV) {
|
||||||
EMITTER(MOVBS) {
|
EMITTER(MOVBS) {
|
||||||
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I8);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I8);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.W Rm,@Rn
|
// MOV.W Rm,@Rn
|
||||||
EMITTER(MOVWS) {
|
EMITTER(MOVWS) {
|
||||||
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I16);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I16);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.L Rm,@Rn
|
// MOV.L Rm,@Rn
|
||||||
EMITTER(MOVLS) {
|
EMITTER(MOVLS) {
|
||||||
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.B @Rm,Rn
|
// MOV.B @Rm,Rn
|
||||||
EMITTER(MOVBL) {
|
EMITTER(MOVBL) {
|
||||||
Value *v =
|
Value *v =
|
||||||
b.SExt(b.Load(b.LoadRegister(i.Rm, VALUE_I32), VALUE_I8), VALUE_I32);
|
b.SExt(b.LoadGuest(b.LoadRegister(i.Rm, VALUE_I32), VALUE_I8), VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.W @Rm,Rn
|
// MOV.W @Rm,Rn
|
||||||
EMITTER(MOVWL) {
|
EMITTER(MOVWL) {
|
||||||
Value *v =
|
Value *v = b.SExt(b.LoadGuest(b.LoadRegister(i.Rm, VALUE_I32), VALUE_I16),
|
||||||
b.SExt(b.Load(b.LoadRegister(i.Rm, VALUE_I32), VALUE_I16), VALUE_I32);
|
VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.L @Rm,Rn
|
// MOV.L @Rm,Rn
|
||||||
EMITTER(MOVLL) {
|
EMITTER(MOVLL) {
|
||||||
Value *v = b.Load(b.LoadRegister(i.Rm, VALUE_I32), VALUE_I32);
|
Value *v = b.LoadGuest(b.LoadRegister(i.Rm, VALUE_I32), VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +262,7 @@ EMITTER(MOVBM) {
|
||||||
|
|
||||||
// store Rm at (Rn)
|
// store Rm at (Rn)
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I8);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I8);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.W Rm,@-Rn
|
// MOV.W Rm,@-Rn
|
||||||
|
@ -270,7 +274,7 @@ EMITTER(MOVWM) {
|
||||||
|
|
||||||
// store Rm at (Rn)
|
// store Rm at (Rn)
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I16);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I16);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.L Rm,@-Rn
|
// MOV.L Rm,@-Rn
|
||||||
|
@ -282,14 +286,14 @@ EMITTER(MOVLM) {
|
||||||
|
|
||||||
// store Rm at (Rn)
|
// store Rm at (Rn)
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.B @Rm+,Rn
|
// MOV.B @Rm+,Rn
|
||||||
EMITTER(MOVBP) {
|
EMITTER(MOVBP) {
|
||||||
// store (Rm) at Rn
|
// store (Rm) at Rn
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.SExt(b.Load(addr, VALUE_I8), VALUE_I32);
|
Value *v = b.SExt(b.LoadGuest(addr, VALUE_I8), VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
|
|
||||||
// increase Rm by 1
|
// increase Rm by 1
|
||||||
|
@ -302,7 +306,7 @@ EMITTER(MOVBP) {
|
||||||
EMITTER(MOVWP) {
|
EMITTER(MOVWP) {
|
||||||
// store (Rm) at Rn
|
// store (Rm) at Rn
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.SExt(b.Load(addr, VALUE_I16), VALUE_I32);
|
Value *v = b.SExt(b.LoadGuest(addr, VALUE_I16), VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
|
|
||||||
// increase Rm by 2
|
// increase Rm by 2
|
||||||
|
@ -315,7 +319,7 @@ EMITTER(MOVWP) {
|
||||||
EMITTER(MOVLP) {
|
EMITTER(MOVLP) {
|
||||||
// store (Rm) at Rn
|
// store (Rm) at Rn
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
|
|
||||||
// increase Rm by 2
|
// increase Rm by 2
|
||||||
|
@ -329,7 +333,7 @@ EMITTER(MOVBS0D) {
|
||||||
Value *addr =
|
Value *addr =
|
||||||
b.Add(b.AllocConstant((uint32_t)i.disp), b.LoadRegister(i.Rn, VALUE_I32));
|
b.Add(b.AllocConstant((uint32_t)i.disp), b.LoadRegister(i.Rn, VALUE_I32));
|
||||||
Value *v = b.LoadRegister(0, VALUE_I8);
|
Value *v = b.LoadRegister(0, VALUE_I8);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.W R0,@(disp,Rn)
|
// MOV.W R0,@(disp,Rn)
|
||||||
|
@ -337,7 +341,7 @@ EMITTER(MOVWS0D) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 2),
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 2),
|
||||||
b.LoadRegister(i.Rn, VALUE_I32));
|
b.LoadRegister(i.Rn, VALUE_I32));
|
||||||
Value *v = b.LoadRegister(0, VALUE_I16);
|
Value *v = b.LoadRegister(0, VALUE_I16);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.L Rm,@(disp,Rn)
|
// MOV.L Rm,@(disp,Rn)
|
||||||
|
@ -345,14 +349,14 @@ EMITTER(MOVLSMD) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 4),
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 4),
|
||||||
b.LoadRegister(i.Rn, VALUE_I32));
|
b.LoadRegister(i.Rn, VALUE_I32));
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.B @(disp,Rm),R0
|
// MOV.B @(disp,Rm),R0
|
||||||
EMITTER(MOVBLD0) {
|
EMITTER(MOVBLD0) {
|
||||||
Value *addr =
|
Value *addr =
|
||||||
b.Add(b.AllocConstant((uint32_t)i.disp), b.LoadRegister(i.Rm, VALUE_I32));
|
b.Add(b.AllocConstant((uint32_t)i.disp), b.LoadRegister(i.Rm, VALUE_I32));
|
||||||
Value *v = b.SExt(b.Load(addr, VALUE_I8), VALUE_I32);
|
Value *v = b.SExt(b.LoadGuest(addr, VALUE_I8), VALUE_I32);
|
||||||
b.StoreRegister(0, v);
|
b.StoreRegister(0, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +364,7 @@ EMITTER(MOVBLD0) {
|
||||||
EMITTER(MOVWLD0) {
|
EMITTER(MOVWLD0) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 2),
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 2),
|
||||||
b.LoadRegister(i.Rm, VALUE_I32));
|
b.LoadRegister(i.Rm, VALUE_I32));
|
||||||
Value *v = b.SExt(b.Load(addr, VALUE_I16), VALUE_I32);
|
Value *v = b.SExt(b.LoadGuest(addr, VALUE_I16), VALUE_I32);
|
||||||
b.StoreRegister(0, v);
|
b.StoreRegister(0, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +372,7 @@ EMITTER(MOVWLD0) {
|
||||||
EMITTER(MOVLLDN) {
|
EMITTER(MOVLLDN) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 4),
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 4),
|
||||||
b.LoadRegister(i.Rm, VALUE_I32));
|
b.LoadRegister(i.Rm, VALUE_I32));
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +381,7 @@ EMITTER(MOVBS0) {
|
||||||
Value *addr =
|
Value *addr =
|
||||||
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rn, VALUE_I32));
|
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rn, VALUE_I32));
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I8);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I8);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.W Rm,@(R0,Rn)
|
// MOV.W Rm,@(R0,Rn)
|
||||||
|
@ -385,7 +389,7 @@ EMITTER(MOVWS0) {
|
||||||
Value *addr =
|
Value *addr =
|
||||||
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rn, VALUE_I32));
|
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rn, VALUE_I32));
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I16);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I16);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.L Rm,@(R0,Rn)
|
// MOV.L Rm,@(R0,Rn)
|
||||||
|
@ -393,14 +397,14 @@ EMITTER(MOVLS0) {
|
||||||
Value *addr =
|
Value *addr =
|
||||||
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rn, VALUE_I32));
|
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rn, VALUE_I32));
|
||||||
Value *v = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *v = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.B @(R0,Rm),Rn
|
// MOV.B @(R0,Rm),Rn
|
||||||
EMITTER(MOVBL0) {
|
EMITTER(MOVBL0) {
|
||||||
Value *addr =
|
Value *addr =
|
||||||
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rm, VALUE_I32));
|
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rm, VALUE_I32));
|
||||||
Value *v = b.SExt(b.Load(addr, VALUE_I8), VALUE_I32);
|
Value *v = b.SExt(b.LoadGuest(addr, VALUE_I8), VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +412,7 @@ EMITTER(MOVBL0) {
|
||||||
EMITTER(MOVWL0) {
|
EMITTER(MOVWL0) {
|
||||||
Value *addr =
|
Value *addr =
|
||||||
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rm, VALUE_I32));
|
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rm, VALUE_I32));
|
||||||
Value *v = b.SExt(b.Load(addr, VALUE_I16), VALUE_I32);
|
Value *v = b.SExt(b.LoadGuest(addr, VALUE_I16), VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +420,7 @@ EMITTER(MOVWL0) {
|
||||||
EMITTER(MOVLL0) {
|
EMITTER(MOVLL0) {
|
||||||
Value *addr =
|
Value *addr =
|
||||||
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rm, VALUE_I32));
|
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rm, VALUE_I32));
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreRegister(i.Rn, v);
|
b.StoreRegister(i.Rn, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,41 +428,41 @@ EMITTER(MOVLL0) {
|
||||||
EMITTER(MOVBS0G) {
|
EMITTER(MOVBS0G) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp), b.LoadGBR());
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp), b.LoadGBR());
|
||||||
Value *v = b.LoadRegister(0, VALUE_I8);
|
Value *v = b.LoadRegister(0, VALUE_I8);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.W R0,@(disp,GBR)
|
// MOV.W R0,@(disp,GBR)
|
||||||
EMITTER(MOVWS0G) {
|
EMITTER(MOVWS0G) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 2), b.LoadGBR());
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 2), b.LoadGBR());
|
||||||
Value *v = b.LoadRegister(0, VALUE_I16);
|
Value *v = b.LoadRegister(0, VALUE_I16);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.L R0,@(disp,GBR)
|
// MOV.L R0,@(disp,GBR)
|
||||||
EMITTER(MOVLS0G) {
|
EMITTER(MOVLS0G) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 4), b.LoadGBR());
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 4), b.LoadGBR());
|
||||||
Value *v = b.LoadRegister(0, VALUE_I32);
|
Value *v = b.LoadRegister(0, VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.B @(disp,GBR),R0
|
// MOV.B @(disp,GBR),R0
|
||||||
EMITTER(MOVBLG0) {
|
EMITTER(MOVBLG0) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp), b.LoadGBR());
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp), b.LoadGBR());
|
||||||
Value *v = b.SExt(b.Load(addr, VALUE_I8), VALUE_I32);
|
Value *v = b.SExt(b.LoadGuest(addr, VALUE_I8), VALUE_I32);
|
||||||
b.StoreRegister(0, v);
|
b.StoreRegister(0, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.W @(disp,GBR),R0
|
// MOV.W @(disp,GBR),R0
|
||||||
EMITTER(MOVWLG0) {
|
EMITTER(MOVWLG0) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 2), b.LoadGBR());
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 2), b.LoadGBR());
|
||||||
Value *v = b.SExt(b.Load(addr, VALUE_I16), VALUE_I32);
|
Value *v = b.SExt(b.LoadGuest(addr, VALUE_I16), VALUE_I32);
|
||||||
b.StoreRegister(0, v);
|
b.StoreRegister(0, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOV.L @(disp,GBR),R0
|
// MOV.L @(disp,GBR),R0
|
||||||
EMITTER(MOVLLG0) {
|
EMITTER(MOVLLG0) {
|
||||||
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 4), b.LoadGBR());
|
Value *addr = b.Add(b.AllocConstant((uint32_t)i.disp * 4), b.LoadGBR());
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreRegister(0, v);
|
b.StoreRegister(0, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,8 +846,8 @@ EMITTER(ANDI) {
|
||||||
// AND.B #imm,@(R0,GBR)
|
// AND.B #imm,@(R0,GBR)
|
||||||
EMITTER(ANDB) {
|
EMITTER(ANDB) {
|
||||||
Value *addr = b.Add(b.LoadRegister(0, VALUE_I32), b.LoadGBR());
|
Value *addr = b.Add(b.LoadRegister(0, VALUE_I32), b.LoadGBR());
|
||||||
Value *v = b.Load(addr, VALUE_I8);
|
Value *v = b.LoadGuest(addr, VALUE_I8);
|
||||||
b.Store(addr, b.And(v, b.AllocConstant((uint8_t)i.imm)));
|
b.StoreGuest(addr, b.And(v, b.AllocConstant((uint8_t)i.imm)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOT Rm,Rn
|
// NOT Rm,Rn
|
||||||
|
@ -869,15 +873,15 @@ EMITTER(ORI) {
|
||||||
// OR.B #imm,@(R0,GBR)
|
// OR.B #imm,@(R0,GBR)
|
||||||
EMITTER(ORB) {
|
EMITTER(ORB) {
|
||||||
Value *addr = b.Add(b.LoadRegister(0, VALUE_I32), b.LoadGBR());
|
Value *addr = b.Add(b.LoadRegister(0, VALUE_I32), b.LoadGBR());
|
||||||
Value *v = b.Load(addr, VALUE_I8);
|
Value *v = b.LoadGuest(addr, VALUE_I8);
|
||||||
b.Store(addr, b.Or(v, b.AllocConstant((uint8_t)i.imm)));
|
b.StoreGuest(addr, b.Or(v, b.AllocConstant((uint8_t)i.imm)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TAS.B @Rn
|
// TAS.B @Rn
|
||||||
EMITTER(TAS) {
|
EMITTER(TAS) {
|
||||||
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I8);
|
Value *v = b.LoadGuest(addr, VALUE_I8);
|
||||||
b.Store(addr, b.Or(v, b.AllocConstant((uint8_t)0x80)));
|
b.StoreGuest(addr, b.Or(v, b.AllocConstant((uint8_t)0x80)));
|
||||||
b.StoreT(b.EQ(v, b.AllocConstant((uint8_t)0)));
|
b.StoreT(b.EQ(v, b.AllocConstant((uint8_t)0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -898,7 +902,7 @@ EMITTER(TSTI) {
|
||||||
// TST.B #imm,@(R0,GBR)
|
// TST.B #imm,@(R0,GBR)
|
||||||
EMITTER(TSTB) {
|
EMITTER(TSTB) {
|
||||||
Value *addr = b.Add(b.LoadRegister(0, VALUE_I32), b.LoadGBR());
|
Value *addr = b.Add(b.LoadRegister(0, VALUE_I32), b.LoadGBR());
|
||||||
Value *v = b.Load(addr, VALUE_I8);
|
Value *v = b.LoadGuest(addr, VALUE_I8);
|
||||||
Value *imm = b.AllocConstant((uint8_t)i.imm);
|
Value *imm = b.AllocConstant((uint8_t)i.imm);
|
||||||
b.StoreT(b.EQ(b.And(v, imm), b.AllocConstant((uint8_t)0)));
|
b.StoreT(b.EQ(b.And(v, imm), b.AllocConstant((uint8_t)0)));
|
||||||
}
|
}
|
||||||
|
@ -920,7 +924,8 @@ EMITTER(XORI) {
|
||||||
// XOR.B #imm,@(R0,GBR)
|
// XOR.B #imm,@(R0,GBR)
|
||||||
EMITTER(XORB) {
|
EMITTER(XORB) {
|
||||||
Value *addr = b.Add(b.LoadRegister(0, VALUE_I32), b.LoadGBR());
|
Value *addr = b.Add(b.LoadRegister(0, VALUE_I32), b.LoadGBR());
|
||||||
b.Store(addr, b.Xor(b.Load(addr, VALUE_I8), b.AllocConstant((uint8_t)i.imm)));
|
b.StoreGuest(addr, b.Xor(b.LoadGuest(addr, VALUE_I8),
|
||||||
|
b.AllocConstant((uint8_t)i.imm)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ROTL Rn
|
// ROTL Rn
|
||||||
|
@ -1212,7 +1217,7 @@ EMITTER(LDCRBANK) {
|
||||||
// LDC.L @Rm+,SR
|
// LDC.L @Rm+,SR
|
||||||
EMITTER(LDCMSR) {
|
EMITTER(LDCMSR) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreSR(v);
|
b.StoreSR(v);
|
||||||
// reload Rm, sr store could have swapped banks
|
// reload Rm, sr store could have swapped banks
|
||||||
addr = b.LoadRegister(i.Rm, VALUE_I32);
|
addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
|
@ -1222,7 +1227,7 @@ EMITTER(LDCMSR) {
|
||||||
// LDC.L @Rm+,GBR
|
// LDC.L @Rm+,GBR
|
||||||
EMITTER(LDCMGBR) {
|
EMITTER(LDCMGBR) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreGBR(v);
|
b.StoreGBR(v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1230,7 +1235,7 @@ EMITTER(LDCMGBR) {
|
||||||
// LDC.L @Rm+,VBR
|
// LDC.L @Rm+,VBR
|
||||||
EMITTER(LDCMVBR) {
|
EMITTER(LDCMVBR) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreContext(offsetof(SH4Context, vbr), v);
|
b.StoreContext(offsetof(SH4Context, vbr), v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1238,7 +1243,7 @@ EMITTER(LDCMVBR) {
|
||||||
// LDC.L @Rm+,SSR
|
// LDC.L @Rm+,SSR
|
||||||
EMITTER(LDCMSSR) {
|
EMITTER(LDCMSSR) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreContext(offsetof(SH4Context, ssr), v);
|
b.StoreContext(offsetof(SH4Context, ssr), v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1246,7 +1251,7 @@ EMITTER(LDCMSSR) {
|
||||||
// LDC.L @Rm+,SPC
|
// LDC.L @Rm+,SPC
|
||||||
EMITTER(LDCMSPC) {
|
EMITTER(LDCMSPC) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreContext(offsetof(SH4Context, spc), v);
|
b.StoreContext(offsetof(SH4Context, spc), v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1254,7 +1259,7 @@ EMITTER(LDCMSPC) {
|
||||||
// LDC.L @Rm+,DBR
|
// LDC.L @Rm+,DBR
|
||||||
EMITTER(LDCMDBR) {
|
EMITTER(LDCMDBR) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreContext(offsetof(SH4Context, dbr), v);
|
b.StoreContext(offsetof(SH4Context, dbr), v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1264,7 +1269,7 @@ EMITTER(LDCMRBANK) {
|
||||||
int reg = i.Rn & 0x7;
|
int reg = i.Rn & 0x7;
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreContext(offsetof(SH4Context, ralt) + reg * 4, v);
|
b.StoreContext(offsetof(SH4Context, ralt) + reg * 4, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,7 +1294,7 @@ EMITTER(LDSPR) {
|
||||||
// LDS.L @Rm+,MACH
|
// LDS.L @Rm+,MACH
|
||||||
EMITTER(LDSMMACH) {
|
EMITTER(LDSMMACH) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreContext(offsetof(SH4Context, mach), v);
|
b.StoreContext(offsetof(SH4Context, mach), v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1297,7 +1302,7 @@ EMITTER(LDSMMACH) {
|
||||||
// LDS.L @Rm+,MACL
|
// LDS.L @Rm+,MACL
|
||||||
EMITTER(LDSMMACL) {
|
EMITTER(LDSMMACL) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreContext(offsetof(SH4Context, macl), v);
|
b.StoreContext(offsetof(SH4Context, macl), v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1305,7 +1310,7 @@ EMITTER(LDSMMACL) {
|
||||||
// LDS.L @Rm+,PR
|
// LDS.L @Rm+,PR
|
||||||
EMITTER(LDSMPR) {
|
EMITTER(LDSMPR) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StorePR(v);
|
b.StorePR(v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1403,7 +1408,7 @@ EMITTER(STCMSR) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
Value *v = b.LoadSR();
|
Value *v = b.LoadSR();
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STC.L GBR,@-Rn
|
// STC.L GBR,@-Rn
|
||||||
|
@ -1411,7 +1416,7 @@ EMITTER(STCMGBR) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
Value *v = b.LoadGBR();
|
Value *v = b.LoadGBR();
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STC.L VBR,@-Rn
|
// STC.L VBR,@-Rn
|
||||||
|
@ -1419,7 +1424,7 @@ EMITTER(STCMVBR) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
Value *v = b.LoadContext(offsetof(SH4Context, vbr), VALUE_I32);
|
Value *v = b.LoadContext(offsetof(SH4Context, vbr), VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STC.L SSR,@-Rn
|
// STC.L SSR,@-Rn
|
||||||
|
@ -1427,7 +1432,7 @@ EMITTER(STCMSSR) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
Value *v = b.LoadContext(offsetof(SH4Context, ssr), VALUE_I32);
|
Value *v = b.LoadContext(offsetof(SH4Context, ssr), VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STC.L SPC,@-Rn
|
// STC.L SPC,@-Rn
|
||||||
|
@ -1435,7 +1440,7 @@ EMITTER(STCMSPC) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
Value *v = b.LoadContext(offsetof(SH4Context, spc), VALUE_I32);
|
Value *v = b.LoadContext(offsetof(SH4Context, spc), VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STC.L SGR,@-Rn
|
// STC.L SGR,@-Rn
|
||||||
|
@ -1443,7 +1448,7 @@ EMITTER(STCMSGR) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
Value *v = b.LoadContext(offsetof(SH4Context, sgr), VALUE_I32);
|
Value *v = b.LoadContext(offsetof(SH4Context, sgr), VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STC.L DBR,@-Rn
|
// STC.L DBR,@-Rn
|
||||||
|
@ -1451,7 +1456,7 @@ EMITTER(STCMDBR) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
Value *v = b.LoadContext(offsetof(SH4Context, dbr), VALUE_I32);
|
Value *v = b.LoadContext(offsetof(SH4Context, dbr), VALUE_I32);
|
||||||
b.Store(addr, v);
|
b.StoreGuest(addr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STC.L Rm_BANK,@-Rn
|
// STC.L Rm_BANK,@-Rn
|
||||||
|
@ -1459,7 +1464,8 @@ EMITTER(STCMRBANK) {
|
||||||
int reg = i.Rm & 0x7;
|
int reg = i.Rm & 0x7;
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
b.Store(addr, b.LoadContext(offsetof(SH4Context, ralt) + reg * 4, VALUE_I32));
|
b.StoreGuest(addr,
|
||||||
|
b.LoadContext(offsetof(SH4Context, ralt) + reg * 4, VALUE_I32));
|
||||||
}
|
}
|
||||||
|
|
||||||
// STS MACH,Rn
|
// STS MACH,Rn
|
||||||
|
@ -1486,7 +1492,7 @@ EMITTER(STSMMACH) {
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
|
|
||||||
Value *mach = b.LoadContext(offsetof(SH4Context, mach), VALUE_I32);
|
Value *mach = b.LoadContext(offsetof(SH4Context, mach), VALUE_I32);
|
||||||
b.Store(addr, mach);
|
b.StoreGuest(addr, mach);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STS.L MACL,@-Rn
|
// STS.L MACL,@-Rn
|
||||||
|
@ -1495,7 +1501,7 @@ EMITTER(STSMMACL) {
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
|
|
||||||
Value *macl = b.LoadContext(offsetof(SH4Context, macl), VALUE_I32);
|
Value *macl = b.LoadContext(offsetof(SH4Context, macl), VALUE_I32);
|
||||||
b.Store(addr, macl);
|
b.StoreGuest(addr, macl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STS.L PR,@-Rn
|
// STS.L PR,@-Rn
|
||||||
|
@ -1504,7 +1510,7 @@ EMITTER(STSMPR) {
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
|
|
||||||
Value *pr = b.LoadPR();
|
Value *pr = b.LoadPR();
|
||||||
b.Store(addr, pr);
|
b.StoreGuest(addr, pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRAPA #imm
|
// TRAPA #imm
|
||||||
|
@ -1555,26 +1561,26 @@ EMITTER(FMOV1) {
|
||||||
|
|
||||||
if (fpu.double_precision) {
|
if (fpu.double_precision) {
|
||||||
if (i.Rn & 1) {
|
if (i.Rn & 1) {
|
||||||
b.StoreRegisterXF(i.Rn | 0x1, b.Load(addr, VALUE_I32));
|
b.StoreRegisterXF(i.Rn | 0x1, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterXF(i.Rn & 0xe,
|
b.StoreRegisterXF(
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
i.Rn & 0xe, b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
} else {
|
} else {
|
||||||
b.StoreRegisterF(i.Rn | 0x1, b.Load(addr, VALUE_I32));
|
b.StoreRegisterF(i.Rn | 0x1, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterF(i.Rn & 0xe,
|
b.StoreRegisterF(i.Rn & 0xe,
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
}
|
}
|
||||||
} else if (fpu.single_precision_pair) {
|
} else if (fpu.single_precision_pair) {
|
||||||
if (i.Rn & 1) {
|
if (i.Rn & 1) {
|
||||||
b.StoreRegisterXF(i.Rn & 0xe, b.Load(addr, VALUE_I32));
|
b.StoreRegisterXF(i.Rn & 0xe, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterXF(i.Rn | 0x1,
|
b.StoreRegisterXF(
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
i.Rn | 0x1, b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
} else {
|
} else {
|
||||||
b.StoreRegisterF(i.Rn & 0xe, b.Load(addr, VALUE_I32));
|
b.StoreRegisterF(i.Rn & 0xe, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterF(i.Rn | 0x1,
|
b.StoreRegisterF(i.Rn | 0x1,
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
b.StoreRegisterF(i.Rn, b.Load(addr, VALUE_I32));
|
b.StoreRegisterF(i.Rn, b.LoadGuest(addr, VALUE_I32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1588,21 +1594,21 @@ EMITTER(FMOV2) {
|
||||||
|
|
||||||
// FMOV with PR=1 assumes the values are word-swapped in memory
|
// FMOV with PR=1 assumes the values are word-swapped in memory
|
||||||
if (fpu.double_precision) {
|
if (fpu.double_precision) {
|
||||||
b.StoreRegisterXF(i.Rn | 0x1, b.Load(addr, VALUE_I32));
|
b.StoreRegisterXF(i.Rn | 0x1, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterXF(i.Rn & 0xe,
|
b.StoreRegisterXF(i.Rn & 0xe,
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
} else if (fpu.single_precision_pair) {
|
} else if (fpu.single_precision_pair) {
|
||||||
if (i.Rn & 1) {
|
if (i.Rn & 1) {
|
||||||
b.StoreRegisterXF(i.Rn & 0xe, b.Load(addr, VALUE_I32));
|
b.StoreRegisterXF(i.Rn & 0xe, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterXF(i.Rn | 0x1,
|
b.StoreRegisterXF(
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
i.Rn | 0x1, b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
} else {
|
} else {
|
||||||
b.StoreRegisterF(i.Rn & 0xe, b.Load(addr, VALUE_I32));
|
b.StoreRegisterF(i.Rn & 0xe, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterF(i.Rn | 0x1,
|
b.StoreRegisterF(i.Rn | 0x1,
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
b.StoreRegisterF(i.Rn, b.Load(addr, VALUE_I32));
|
b.StoreRegisterF(i.Rn, b.LoadGuest(addr, VALUE_I32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1615,23 +1621,23 @@ EMITTER(FMOV3) {
|
||||||
|
|
||||||
// FMOV with PR=1 assumes the values are word-swapped in memory
|
// FMOV with PR=1 assumes the values are word-swapped in memory
|
||||||
if (fpu.double_precision) {
|
if (fpu.double_precision) {
|
||||||
b.StoreRegisterXF(i.Rn | 0x1, b.Load(addr, VALUE_I32));
|
b.StoreRegisterXF(i.Rn | 0x1, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterXF(i.Rn & 0xe,
|
b.StoreRegisterXF(i.Rn & 0xe,
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(8)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(8)));
|
||||||
} else if (fpu.single_precision_pair) {
|
} else if (fpu.single_precision_pair) {
|
||||||
if (i.Rn & 1) {
|
if (i.Rn & 1) {
|
||||||
b.StoreRegisterXF(i.Rn & 0xe, b.Load(addr, VALUE_I32));
|
b.StoreRegisterXF(i.Rn & 0xe, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterXF(i.Rn | 0x1,
|
b.StoreRegisterXF(
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
i.Rn | 0x1, b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
} else {
|
} else {
|
||||||
b.StoreRegisterF(i.Rn & 0xe, b.Load(addr, VALUE_I32));
|
b.StoreRegisterF(i.Rn & 0xe, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegisterF(i.Rn | 0x1,
|
b.StoreRegisterF(i.Rn | 0x1,
|
||||||
b.Load(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
b.LoadGuest(b.Add(addr, b.AllocConstant(4)), VALUE_I32));
|
||||||
}
|
}
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(8)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(8)));
|
||||||
} else {
|
} else {
|
||||||
b.StoreRegisterF(i.Rn, b.Load(addr, VALUE_I32));
|
b.StoreRegisterF(i.Rn, b.LoadGuest(addr, VALUE_I32));
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1644,21 +1650,21 @@ EMITTER(FMOV4) {
|
||||||
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rn, VALUE_I32);
|
||||||
|
|
||||||
if (fpu.double_precision) {
|
if (fpu.double_precision) {
|
||||||
b.Store(addr, b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
||||||
b.Store(b.Add(addr, b.AllocConstant(4)),
|
b.StoreGuest(b.Add(addr, b.AllocConstant(4)),
|
||||||
b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
||||||
} else if (fpu.single_precision_pair) {
|
} else if (fpu.single_precision_pair) {
|
||||||
if (i.Rm & 1) {
|
if (i.Rm & 1) {
|
||||||
b.Store(addr, b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
||||||
b.Store(b.Add(addr, b.AllocConstant(4)),
|
b.StoreGuest(b.Add(addr, b.AllocConstant(4)),
|
||||||
b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
||||||
} else {
|
} else {
|
||||||
b.Store(addr, b.LoadRegisterF(i.Rm & 0xe, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterF(i.Rm & 0xe, VALUE_I32));
|
||||||
b.Store(b.Add(addr, b.AllocConstant(4)),
|
b.StoreGuest(b.Add(addr, b.AllocConstant(4)),
|
||||||
b.LoadRegisterF(i.Rm | 0x1, VALUE_I32));
|
b.LoadRegisterF(i.Rm | 0x1, VALUE_I32));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
b.Store(addr, b.LoadRegisterF(i.Rm, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterF(i.Rm, VALUE_I32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1670,25 +1676,25 @@ EMITTER(FMOV5) {
|
||||||
if (fpu.double_precision) {
|
if (fpu.double_precision) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(8));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(8));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
b.Store(addr, b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
||||||
b.Store(b.Add(addr, b.AllocConstant(4)),
|
b.StoreGuest(b.Add(addr, b.AllocConstant(4)),
|
||||||
b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
||||||
} else if (fpu.single_precision_pair) {
|
} else if (fpu.single_precision_pair) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(8));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(8));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
if (i.Rm & 1) {
|
if (i.Rm & 1) {
|
||||||
b.Store(addr, b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
||||||
b.Store(b.Add(addr, b.AllocConstant(4)),
|
b.StoreGuest(b.Add(addr, b.AllocConstant(4)),
|
||||||
b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
||||||
} else {
|
} else {
|
||||||
b.Store(addr, b.LoadRegisterF(i.Rm & 0xe, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterF(i.Rm & 0xe, VALUE_I32));
|
||||||
b.Store(b.Add(addr, b.AllocConstant(4)),
|
b.StoreGuest(b.Add(addr, b.AllocConstant(4)),
|
||||||
b.LoadRegisterF(i.Rm | 0x1, VALUE_I32));
|
b.LoadRegisterF(i.Rm | 0x1, VALUE_I32));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
b.Store(addr, b.LoadRegisterF(i.Rm, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterF(i.Rm, VALUE_I32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1701,21 +1707,21 @@ EMITTER(FMOV6) {
|
||||||
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rn, VALUE_I32));
|
b.Add(b.LoadRegister(0, VALUE_I32), b.LoadRegister(i.Rn, VALUE_I32));
|
||||||
|
|
||||||
if (fpu.double_precision) {
|
if (fpu.double_precision) {
|
||||||
b.Store(addr, b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
||||||
b.Store(b.Add(addr, b.AllocConstant(4)),
|
b.StoreGuest(b.Add(addr, b.AllocConstant(4)),
|
||||||
b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
||||||
} else if (fpu.single_precision_pair) {
|
} else if (fpu.single_precision_pair) {
|
||||||
if (i.Rm & 1) {
|
if (i.Rm & 1) {
|
||||||
b.Store(addr, b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterXF(i.Rm & 0xe, VALUE_I32));
|
||||||
b.Store(b.Add(addr, b.AllocConstant(4)),
|
b.StoreGuest(b.Add(addr, b.AllocConstant(4)),
|
||||||
b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
b.LoadRegisterXF(i.Rm | 0x1, VALUE_I32));
|
||||||
} else {
|
} else {
|
||||||
b.Store(addr, b.LoadRegisterF(i.Rm & 0xe, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterF(i.Rm & 0xe, VALUE_I32));
|
||||||
b.Store(b.Add(addr, b.AllocConstant(4)),
|
b.StoreGuest(b.Add(addr, b.AllocConstant(4)),
|
||||||
b.LoadRegisterF(i.Rm | 0x1, VALUE_I32));
|
b.LoadRegisterF(i.Rm | 0x1, VALUE_I32));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
b.Store(addr, b.LoadRegisterF(i.Rm, VALUE_I32));
|
b.StoreGuest(addr, b.LoadRegisterF(i.Rm, VALUE_I32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1904,7 +1910,7 @@ EMITTER(LDSFPUL) {
|
||||||
// LDS.L @Rm+,FPSCR
|
// LDS.L @Rm+,FPSCR
|
||||||
EMITTER(LDSMFPSCR) {
|
EMITTER(LDSMFPSCR) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreFPSCR(v);
|
b.StoreFPSCR(v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1912,7 +1918,7 @@ EMITTER(LDSMFPSCR) {
|
||||||
// LDS.L @Rm+,FPUL
|
// LDS.L @Rm+,FPUL
|
||||||
EMITTER(LDSMFPUL) {
|
EMITTER(LDSMFPUL) {
|
||||||
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
Value *addr = b.LoadRegister(i.Rm, VALUE_I32);
|
||||||
Value *v = b.Load(addr, VALUE_I32);
|
Value *v = b.LoadGuest(addr, VALUE_I32);
|
||||||
b.StoreContext(offsetof(SH4Context, fpul), v);
|
b.StoreContext(offsetof(SH4Context, fpul), v);
|
||||||
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
b.StoreRegister(i.Rm, b.Add(addr, b.AllocConstant(4)));
|
||||||
}
|
}
|
||||||
|
@ -1930,7 +1936,7 @@ EMITTER(STSFPUL) {
|
||||||
EMITTER(STSMFPSCR) {
|
EMITTER(STSMFPSCR) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
b.Store(addr, b.LoadFPSCR());
|
b.StoreGuest(addr, b.LoadFPSCR());
|
||||||
}
|
}
|
||||||
|
|
||||||
// STS.L FPUL,@-Rn
|
// STS.L FPUL,@-Rn
|
||||||
|
@ -1938,7 +1944,7 @@ EMITTER(STSMFPUL) {
|
||||||
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
Value *addr = b.Sub(b.LoadRegister(i.Rn, VALUE_I32), b.AllocConstant(4));
|
||||||
b.StoreRegister(i.Rn, addr);
|
b.StoreRegister(i.Rn, addr);
|
||||||
Value *fpul = b.LoadContext(offsetof(SH4Context, fpul), VALUE_I32);
|
Value *fpul = b.LoadContext(offsetof(SH4Context, fpul), VALUE_I32);
|
||||||
b.Store(addr, fpul);
|
b.StoreGuest(addr, fpul);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIPR FVm,FVn PR=0 1111nnmm11101101
|
// FIPR FVm,FVn PR=0 1111nnmm11101101
|
||||||
|
@ -1959,16 +1965,16 @@ EMITTER(FIPR) {
|
||||||
EMITTER(FSCA) {
|
EMITTER(FSCA) {
|
||||||
int n = i.Rn << 1;
|
int n = i.Rn << 1;
|
||||||
|
|
||||||
Value *angle = b.SMul(
|
Value *fpul = b.LoadContext(offsetof(SH4Context, fpul), VALUE_I16);
|
||||||
b.SMul(b.Div(b.Cast(b.ZExt(b.LoadContext(offsetof(SH4Context, fpul),
|
fpul = b.ZExt(fpul, VALUE_I64);
|
||||||
VALUE_I16),
|
|
||||||
VALUE_I32),
|
Value *fsca_table = b.AllocConstant(reinterpret_cast<uint64_t>(s_fsca_table));
|
||||||
VALUE_F32),
|
Value *fsca_offset = b.Shl(fpul, 3);
|
||||||
b.AllocConstant(65536.0f)),
|
Value *addr = b.Add(fsca_table, fsca_offset);
|
||||||
b.AllocConstant(2.0f)),
|
|
||||||
b.AllocConstant((float)M_PI));
|
b.StoreRegisterF(n, b.LoadHost(addr, VALUE_F32));
|
||||||
b.StoreRegisterF(n, b.Sin(angle));
|
b.StoreRegisterF(n + 1,
|
||||||
b.StoreRegisterF(n + 1, b.Cos(angle));
|
b.LoadHost(b.Add(addr, b.AllocConstant(4ll)), VALUE_F32));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FTRV XMTRX,FVn PR=0 1111nn0111111101
|
// FTRV XMTRX,FVn PR=0 1111nn0111111101
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -239,6 +239,42 @@ void IRBuilder::RemoveBlock(Block *block) {
|
||||||
block->~Block();
|
block->~Block();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value *IRBuilder::LoadHost(Value *addr, ValueTy type) {
|
||||||
|
CHECK_EQ(VALUE_I64, addr->type());
|
||||||
|
|
||||||
|
Instr *instr = AppendInstr(OP_LOAD_HOST);
|
||||||
|
Value *result = AllocDynamic(type);
|
||||||
|
instr->set_arg0(addr);
|
||||||
|
instr->set_result(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::StoreHost(Value *addr, Value *v) {
|
||||||
|
CHECK_EQ(VALUE_I64, addr->type());
|
||||||
|
|
||||||
|
Instr *instr = AppendInstr(OP_STORE_HOST);
|
||||||
|
instr->set_arg0(addr);
|
||||||
|
instr->set_arg1(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *IRBuilder::LoadGuest(Value *addr, ValueTy type) {
|
||||||
|
CHECK_EQ(VALUE_I32, addr->type());
|
||||||
|
|
||||||
|
Instr *instr = AppendInstr(OP_LOAD_GUEST);
|
||||||
|
Value *result = AllocDynamic(type);
|
||||||
|
instr->set_arg0(addr);
|
||||||
|
instr->set_result(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::StoreGuest(Value *addr, Value *v) {
|
||||||
|
CHECK_EQ(VALUE_I32, addr->type());
|
||||||
|
|
||||||
|
Instr *instr = AppendInstr(OP_STORE_GUEST);
|
||||||
|
instr->set_arg0(addr);
|
||||||
|
instr->set_arg1(v);
|
||||||
|
}
|
||||||
|
|
||||||
Value *IRBuilder::LoadContext(size_t offset, ValueTy type) {
|
Value *IRBuilder::LoadContext(size_t offset, ValueTy type) {
|
||||||
Instr *instr = AppendInstr(OP_LOAD_CONTEXT);
|
Instr *instr = AppendInstr(OP_LOAD_CONTEXT);
|
||||||
Value *result = AllocDynamic(type);
|
Value *result = AllocDynamic(type);
|
||||||
|
@ -267,24 +303,6 @@ void IRBuilder::StoreLocal(Local *local, Value *v) {
|
||||||
instr->set_arg1(v);
|
instr->set_arg1(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *IRBuilder::Load(Value *addr, ValueTy type) {
|
|
||||||
CHECK_EQ(VALUE_I32, addr->type());
|
|
||||||
|
|
||||||
Instr *instr = AppendInstr(OP_LOAD);
|
|
||||||
Value *result = AllocDynamic(type);
|
|
||||||
instr->set_arg0(addr);
|
|
||||||
instr->set_result(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IRBuilder::Store(Value *addr, Value *v) {
|
|
||||||
CHECK_EQ(VALUE_I32, addr->type());
|
|
||||||
|
|
||||||
Instr *instr = AppendInstr(OP_STORE);
|
|
||||||
instr->set_arg0(addr);
|
|
||||||
instr->set_arg1(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *IRBuilder::Cast(Value *v, ValueTy dest_type) {
|
Value *IRBuilder::Cast(Value *v, ValueTy dest_type) {
|
||||||
CHECK((IsIntType(v->type()) && IsFloatType(dest_type)) ||
|
CHECK((IsIntType(v->type()) && IsFloatType(dest_type)) ||
|
||||||
(IsFloatType(v->type()) && IsIntType(dest_type)));
|
(IsFloatType(v->type()) && IsIntType(dest_type)));
|
||||||
|
@ -536,22 +554,6 @@ Value *IRBuilder::Abs(Value *a) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *IRBuilder::Sin(Value *a) {
|
|
||||||
Instr *instr = AppendInstr(OP_SIN);
|
|
||||||
Value *result = AllocDynamic(a->type());
|
|
||||||
instr->set_arg0(a);
|
|
||||||
instr->set_result(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *IRBuilder::Cos(Value *a) {
|
|
||||||
Instr *instr = AppendInstr(OP_COS);
|
|
||||||
Value *result = AllocDynamic(a->type());
|
|
||||||
instr->set_arg0(a);
|
|
||||||
instr->set_result(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *IRBuilder::And(Value *a, Value *b) {
|
Value *IRBuilder::And(Value *a, Value *b) {
|
||||||
CHECK_EQ(a->type(), b->type());
|
CHECK_EQ(a->type(), b->type());
|
||||||
|
|
||||||
|
|
|
@ -378,6 +378,14 @@ class IRBuilder {
|
||||||
Block *AppendBlock();
|
Block *AppendBlock();
|
||||||
void RemoveBlock(Block *block);
|
void RemoveBlock(Block *block);
|
||||||
|
|
||||||
|
// direct access to host memory
|
||||||
|
Value *LoadHost(Value *addr, ValueTy type);
|
||||||
|
void StoreHost(Value *addr, Value *v);
|
||||||
|
|
||||||
|
// guest memory operations
|
||||||
|
Value *LoadGuest(Value *addr, ValueTy type);
|
||||||
|
void StoreGuest(Value *addr, Value *v);
|
||||||
|
|
||||||
// context operations
|
// context operations
|
||||||
Value *LoadContext(size_t offset, ValueTy type);
|
Value *LoadContext(size_t offset, ValueTy type);
|
||||||
void StoreContext(size_t offset, Value *v, InstrFlag flags = IF_NONE);
|
void StoreContext(size_t offset, Value *v, InstrFlag flags = IF_NONE);
|
||||||
|
@ -386,10 +394,6 @@ class IRBuilder {
|
||||||
Value *LoadLocal(Local *local);
|
Value *LoadLocal(Local *local);
|
||||||
void StoreLocal(Local *local, Value *v);
|
void StoreLocal(Local *local, Value *v);
|
||||||
|
|
||||||
// memory operations
|
|
||||||
Value *Load(Value *addr, ValueTy type);
|
|
||||||
void Store(Value *addr, Value *v);
|
|
||||||
|
|
||||||
// cast / conversion operations
|
// cast / conversion operations
|
||||||
Value *Cast(Value *v, ValueTy dest_type);
|
Value *Cast(Value *v, ValueTy dest_type);
|
||||||
Value *SExt(Value *v, ValueTy dest_type);
|
Value *SExt(Value *v, ValueTy dest_type);
|
||||||
|
@ -418,8 +422,6 @@ class IRBuilder {
|
||||||
Value *Neg(Value *a);
|
Value *Neg(Value *a);
|
||||||
Value *Sqrt(Value *a);
|
Value *Sqrt(Value *a);
|
||||||
Value *Abs(Value *a);
|
Value *Abs(Value *a);
|
||||||
Value *Sin(Value *a);
|
|
||||||
Value *Cos(Value *a);
|
|
||||||
|
|
||||||
// bitwise operations
|
// bitwise operations
|
||||||
Value *And(Value *a, Value *b);
|
Value *And(Value *a, Value *b);
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
IR_OP(LOAD_HOST)
|
||||||
|
IR_OP(STORE_HOST)
|
||||||
|
IR_OP(LOAD_GUEST)
|
||||||
|
IR_OP(STORE_GUEST)
|
||||||
IR_OP(LOAD_CONTEXT)
|
IR_OP(LOAD_CONTEXT)
|
||||||
IR_OP(STORE_CONTEXT)
|
IR_OP(STORE_CONTEXT)
|
||||||
IR_OP(LOAD_LOCAL)
|
IR_OP(LOAD_LOCAL)
|
||||||
IR_OP(STORE_LOCAL)
|
IR_OP(STORE_LOCAL)
|
||||||
IR_OP(LOAD)
|
|
||||||
IR_OP(STORE)
|
|
||||||
IR_OP(CAST)
|
IR_OP(CAST)
|
||||||
IR_OP(SEXT)
|
IR_OP(SEXT)
|
||||||
IR_OP(ZEXT)
|
IR_OP(ZEXT)
|
||||||
|
@ -27,8 +29,6 @@ IR_OP(DIV)
|
||||||
IR_OP(NEG)
|
IR_OP(NEG)
|
||||||
IR_OP(SQRT)
|
IR_OP(SQRT)
|
||||||
IR_OP(ABS)
|
IR_OP(ABS)
|
||||||
IR_OP(SIN)
|
|
||||||
IR_OP(COS)
|
|
||||||
IR_OP(AND)
|
IR_OP(AND)
|
||||||
IR_OP(OR)
|
IR_OP(OR)
|
||||||
IR_OP(XOR)
|
IR_OP(XOR)
|
||||||
|
|
|
@ -5,4 +5,4 @@ test_fsca:
|
||||||
rts
|
rts
|
||||||
nop
|
nop
|
||||||
# REGISTER_OUT fr2 0x3f800000
|
# REGISTER_OUT fr2 0x3f800000
|
||||||
# REGISTER_OUT fr3 0xb33bbd2e
|
# REGISTER_OUT fr3 0x80000000
|
||||||
|
|
|
@ -74,7 +74,7 @@ TEST_SH4(test_fmuld,(uint8_t *)"\x02\xf2\x0b\x00\x09\x00\x02\xf1\x0b\x00\x09\x00
|
||||||
TEST_SH4(test_fnegf,(uint8_t *)"\x4d\xf0\x0b\x00\x09\x00\x4d\xf0\x0b\x00\x09\x00",12,0x6,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x40800000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xc0800000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
TEST_SH4(test_fnegf,(uint8_t *)"\x4d\xf0\x0b\x00\x09\x00\x4d\xf0\x0b\x00\x09\x00",12,0x6,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x40800000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xc0800000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
||||||
TEST_SH4(test_fnegd,(uint8_t *)"\x4d\xf0\x0b\x00\x09\x00\x4d\xf0\x0b\x00\x09\x00",12,0x0,0xc0001,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x0,0x40140000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x0L,0xc0140000L,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
TEST_SH4(test_fnegd,(uint8_t *)"\x4d\xf0\x0b\x00\x09\x00\x4d\xf0\x0b\x00\x09\x00",12,0x0,0xc0001,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x0,0x40140000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x0L,0xc0140000L,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
||||||
TEST_SH4(test_frchg,(uint8_t *)"\x6a\x01\xfd\xfb\x6a\x02\x0a\xd0\x0a\xf0\x02\x63\xfd\xfb\x0a\xf0\x02\x64\x0b\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x00\x00\x00\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x20\x00\x01\x8c\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00",64,0x0,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x41500000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x40001,0x240001,0x0,0x41500000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
TEST_SH4(test_frchg,(uint8_t *)"\x6a\x01\xfd\xfb\x6a\x02\x0a\xd0\x0a\xf0\x02\x63\xfd\xfb\x0a\xf0\x02\x64\x0b\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x00\x00\x00\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x20\x00\x01\x8c\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00\x09\x00",64,0x0,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x41500000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x40001,0x240001,0x0,0x41500000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
||||||
TEST_SH4(test_fsca,(uint8_t *)"\x5a\x40\xfd\xf2\x0b\x00\x09\x00",8,0x0,0xbaadf00d,0x4000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x3f800000,0xb33bbd2e,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
TEST_SH4(test_fsca,(uint8_t *)"\x5a\x40\xfd\xf2\x0b\x00\x09\x00",8,0x0,0xbaadf00d,0x4000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x3f800000,0x80000000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
||||||
TEST_SH4(test_fschg,(uint8_t *)"\x6a\x00\xfd\xf3\x6a\x01\x0b\x00\x09\x00",10,0x0,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x40001,0x140001,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
TEST_SH4(test_fschg,(uint8_t *)"\x6a\x00\xfd\xf3\x6a\x01\x0b\x00\x09\x00",10,0x0,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x40001,0x140001,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
||||||
TEST_SH4(test_fsrra,(uint8_t *)"\x7d\xf0\x0b\x00\x09\x00",6,0x0,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x40800000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x3f000000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
TEST_SH4(test_fsrra,(uint8_t *)"\x7d\xf0\x0b\x00\x09\x00",6,0x0,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x40800000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x3f000000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
||||||
TEST_SH4(test_fsqrtd,(uint8_t *)"\x6d\xf0\x0b\x00\x09\x00\x6d\xf0\x0b\x00\x09\x00",12,0x0,0xc0001,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x0,0x40100000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x0,0x40000000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
TEST_SH4(test_fsqrtd,(uint8_t *)"\x6d\xf0\x0b\x00\x09\x00\x6d\xf0\x0b\x00\x09\x00",12,0x0,0xc0001,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x0,0x40100000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0x0,0x40000000,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d,0xbaadf00d)
|
||||||
|
|
Loading…
Reference in New Issue