lhbrx/lwbrx/ldbrx/sthbrx/stwbrx/stdbrx
This commit is contained in:
parent
d60cf676c3
commit
d62e8aaf78
|
@ -413,33 +413,75 @@ XEDISASMR(stwx, 0x7C00012E, X )(InstrData& i, InstrDisasm& d) {
|
||||||
// Integer load and store with byte reverse (A-1
|
// Integer load and store with byte reverse (A-1
|
||||||
|
|
||||||
XEDISASMR(lhbrx, 0x7C00062C, X )(InstrData& i, InstrDisasm& d) {
|
XEDISASMR(lhbrx, 0x7C00062C, X )(InstrData& i, InstrDisasm& d) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
d.Init("lhbrx", "Load Halfword Byte-Reverse Indexed", 0);
|
||||||
return 1;
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
|
||||||
|
if (i.X.RA) {
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
|
||||||
|
} else {
|
||||||
|
d.AddUImmOperand(0, 1);
|
||||||
|
}
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
|
||||||
|
return d.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
XEDISASMR(lwbrx, 0x7C00042C, X )(InstrData& i, InstrDisasm& d) {
|
XEDISASMR(lwbrx, 0x7C00042C, X )(InstrData& i, InstrDisasm& d) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
d.Init("lwbrx", "Load Word Byte-Reverse Indexed", 0);
|
||||||
return 1;
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
|
||||||
|
if (i.X.RA) {
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
|
||||||
|
} else {
|
||||||
|
d.AddUImmOperand(0, 1);
|
||||||
|
}
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
|
||||||
|
return d.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
XEDISASMR(ldbrx, 0x7C000428, X )(InstrData& i, InstrDisasm& d) {
|
XEDISASMR(ldbrx, 0x7C000428, X )(InstrData& i, InstrDisasm& d) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
d.Init("ldbrx", "Load Doubleword Byte-Reverse Indexed", 0);
|
||||||
return 1;
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
|
||||||
|
if (i.X.RA) {
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
|
||||||
|
} else {
|
||||||
|
d.AddUImmOperand(0, 1);
|
||||||
|
}
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
|
||||||
|
return d.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
XEDISASMR(sthbrx, 0x7C00072C, X )(InstrData& i, InstrDisasm& d) {
|
XEDISASMR(sthbrx, 0x7C00072C, X )(InstrData& i, InstrDisasm& d) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
d.Init("sthbrx", "Store Halfword Byte-Reverse Indexed", 0);
|
||||||
return 1;
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
|
||||||
|
if (i.X.RA) {
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
|
||||||
|
} else {
|
||||||
|
d.AddUImmOperand(0, 1);
|
||||||
|
}
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
|
||||||
|
return d.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
XEDISASMR(stwbrx, 0x7C00052C, X )(InstrData& i, InstrDisasm& d) {
|
XEDISASMR(stwbrx, 0x7C00052C, X )(InstrData& i, InstrDisasm& d) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
d.Init("stwbrx", "Store Word Byte-Reverse Indexed", 0);
|
||||||
return 1;
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
|
||||||
|
if (i.X.RA) {
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
|
||||||
|
} else {
|
||||||
|
d.AddUImmOperand(0, 1);
|
||||||
|
}
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
|
||||||
|
return d.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
XEDISASMR(stdbrx, 0x7C000528, X )(InstrData& i, InstrDisasm& d) {
|
XEDISASMR(stdbrx, 0x7C000528, X )(InstrData& i, InstrDisasm& d) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
d.Init("stdbrx", "Store Doubleword Byte-Reverse Indexed", 0);
|
||||||
return 1;
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
|
||||||
|
if (i.X.RA) {
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
|
||||||
|
} else {
|
||||||
|
d.AddUImmOperand(0, 1);
|
||||||
|
}
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
|
||||||
|
return d.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -911,33 +911,125 @@ XEEMITTER(stwx, 0x7C00012E, X )(X64Emitter& e, X86Compiler& c, InstrDat
|
||||||
// Integer load and store with byte reverse (A-1
|
// Integer load and store with byte reverse (A-1
|
||||||
|
|
||||||
XEEMITTER(lhbrx, 0x7C00062C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
XEEMITTER(lhbrx, 0x7C00062C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
// if RA = 0 then
|
||||||
return 1;
|
// b <- 0
|
||||||
|
// else
|
||||||
|
// b <- (RA)
|
||||||
|
// EA <- b + (RB)
|
||||||
|
// RT <- i48.0 || bswap(MEM(EA, 2))
|
||||||
|
|
||||||
|
GpVar ea(c.newGpVar());
|
||||||
|
c.mov(ea, e.gpr_value(i.X.RB));
|
||||||
|
if (i.X.RA) {
|
||||||
|
c.add(ea, e.gpr_value(i.X.RA));
|
||||||
|
}
|
||||||
|
GpVar v = e.ReadMemory(i.address, ea, 2, false, false);
|
||||||
|
// Zero extend done by ReadMemory.
|
||||||
|
e.update_gpr_value(i.X.RT, v);
|
||||||
|
|
||||||
|
e.clear_constant_gpr_value(i.X.RT);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(lwbrx, 0x7C00042C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
XEEMITTER(lwbrx, 0x7C00042C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
// if RA = 0 then
|
||||||
return 1;
|
// b <- 0
|
||||||
|
// else
|
||||||
|
// b <- (RA)
|
||||||
|
// EA <- b + (RB)
|
||||||
|
// RT <- i32.0 || bswap(MEM(EA, 4))
|
||||||
|
|
||||||
|
GpVar ea(c.newGpVar());
|
||||||
|
c.mov(ea, e.gpr_value(i.X.RB));
|
||||||
|
if (i.X.RA) {
|
||||||
|
c.add(ea, e.gpr_value(i.X.RA));
|
||||||
|
}
|
||||||
|
GpVar v = e.ReadMemory(i.address, ea, 4, false, false);
|
||||||
|
// Zero extend done by ReadMemory.
|
||||||
|
e.update_gpr_value(i.X.RT, v);
|
||||||
|
|
||||||
|
e.clear_constant_gpr_value(i.X.RT);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(ldbrx, 0x7C000428, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
XEEMITTER(ldbrx, 0x7C000428, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
// if RA = 0 then
|
||||||
return 1;
|
// b <- 0
|
||||||
|
// else
|
||||||
|
// b <- (RA)
|
||||||
|
// EA <- b + (RB)
|
||||||
|
// RT <- bswap(MEM(EA, 8))
|
||||||
|
|
||||||
|
GpVar ea(c.newGpVar());
|
||||||
|
c.mov(ea, e.gpr_value(i.X.RB));
|
||||||
|
if (i.X.RA) {
|
||||||
|
c.add(ea, e.gpr_value(i.X.RA));
|
||||||
|
}
|
||||||
|
GpVar v = e.ReadMemory(i.address, ea, 8, false, false);
|
||||||
|
e.update_gpr_value(i.X.RT, v);
|
||||||
|
|
||||||
|
e.clear_constant_gpr_value(i.X.RT);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(sthbrx, 0x7C00072C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
XEEMITTER(sthbrx, 0x7C00072C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
// if RA = 0 then
|
||||||
return 1;
|
// b <- 0
|
||||||
|
// else
|
||||||
|
// b <- (RA)
|
||||||
|
// EA <- b + (RB)
|
||||||
|
// MEM(EA, 2) <- bswap((RS)[48:63])
|
||||||
|
|
||||||
|
GpVar ea(c.newGpVar());
|
||||||
|
c.mov(ea, e.gpr_value(i.X.RB));
|
||||||
|
if (i.D.RA) {
|
||||||
|
c.add(ea, e.gpr_value(i.X.RA));
|
||||||
|
}
|
||||||
|
GpVar v = e.gpr_value(i.X.RT);
|
||||||
|
e.WriteMemory(i.address, ea, 2, v, false, false);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(stwbrx, 0x7C00052C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
XEEMITTER(stwbrx, 0x7C00052C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
// if RA = 0 then
|
||||||
return 1;
|
// b <- 0
|
||||||
|
// else
|
||||||
|
// b <- (RA)
|
||||||
|
// EA <- b + (RB)
|
||||||
|
// MEM(EA, 4) <- bswap((RS)[32:63])
|
||||||
|
|
||||||
|
GpVar ea(c.newGpVar());
|
||||||
|
c.mov(ea, e.gpr_value(i.X.RB));
|
||||||
|
if (i.X.RA) {
|
||||||
|
c.add(ea, e.gpr_value(i.X.RA));
|
||||||
|
}
|
||||||
|
GpVar v = e.gpr_value(i.X.RT);
|
||||||
|
e.WriteMemory(i.address, ea, 4, v, false, false);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(stdbrx, 0x7C000528, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
XEEMITTER(stdbrx, 0x7C000528, X )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
// if RA = 0 then
|
||||||
return 1;
|
// b <- 0
|
||||||
|
// else
|
||||||
|
// b <- (RA)
|
||||||
|
// EA <- b + (RB)
|
||||||
|
// MEM(EA, 8) <- bswap(RS)
|
||||||
|
|
||||||
|
GpVar ea(c.newGpVar());
|
||||||
|
c.mov(ea, e.gpr_value(i.X.RB));
|
||||||
|
if (i.X.RA) {
|
||||||
|
c.add(ea, e.gpr_value(i.X.RA));
|
||||||
|
}
|
||||||
|
GpVar v = e.gpr_value(i.X.RT);
|
||||||
|
e.WriteMemory(i.address, ea, 8, v, false, false);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1874,7 +1874,7 @@ GpVar X64Emitter::TouchMemoryAddress(uint32_t cia, GpVar& addr) {
|
||||||
uint64_t X64Emitter::reserved_addr_ = 0;
|
uint64_t X64Emitter::reserved_addr_ = 0;
|
||||||
|
|
||||||
GpVar X64Emitter::ReadMemory(
|
GpVar X64Emitter::ReadMemory(
|
||||||
uint32_t cia, GpVar& addr, uint32_t size, bool acquire) {
|
uint32_t cia, GpVar& addr, uint32_t size, bool acquire, bool bswap) {
|
||||||
X86Compiler& c = compiler_;
|
X86Compiler& c = compiler_;
|
||||||
|
|
||||||
// Rebase off of memory base pointer.
|
// Rebase off of memory base pointer.
|
||||||
|
@ -1900,16 +1900,22 @@ GpVar X64Emitter::ReadMemory(
|
||||||
case 2:
|
case 2:
|
||||||
c.mov(value.r16(), word_ptr(real_address));
|
c.mov(value.r16(), word_ptr(real_address));
|
||||||
c.and_(value, imm(0xFFFF));
|
c.and_(value, imm(0xFFFF));
|
||||||
c.xchg(value.r8Lo(), value.r8Hi());
|
if (bswap) {
|
||||||
|
c.xchg(value.r8Lo(), value.r8Hi());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
c.mov(value.r32(), dword_ptr(real_address));
|
c.mov(value.r32(), dword_ptr(real_address));
|
||||||
// No need to and -- the mov to e*x will extend for us.
|
// No need to and -- the mov to e*x will extend for us.
|
||||||
c.bswap(value.r32());
|
if (bswap) {
|
||||||
|
c.bswap(value.r32());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
c.mov(value, qword_ptr(real_address));
|
c.mov(value, qword_ptr(real_address));
|
||||||
c.bswap(value.r64());
|
if (bswap) {
|
||||||
|
c.bswap(value.r64());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
XEASSERTALWAYS();
|
XEASSERTALWAYS();
|
||||||
|
@ -1922,7 +1928,7 @@ GpVar X64Emitter::ReadMemory(
|
||||||
|
|
||||||
void X64Emitter::WriteMemory(
|
void X64Emitter::WriteMemory(
|
||||||
uint32_t cia, GpVar& addr, uint32_t size, GpVar& value,
|
uint32_t cia, GpVar& addr, uint32_t size, GpVar& value,
|
||||||
bool release) {
|
bool release, bool bswap) {
|
||||||
X86Compiler& c = compiler_;
|
X86Compiler& c = compiler_;
|
||||||
|
|
||||||
// Rebase off of memory base pointer.
|
// Rebase off of memory base pointer.
|
||||||
|
@ -1961,19 +1967,25 @@ void X64Emitter::WriteMemory(
|
||||||
case 2:
|
case 2:
|
||||||
tmp = c.newGpVar();
|
tmp = c.newGpVar();
|
||||||
c.mov(tmp, value);
|
c.mov(tmp, value);
|
||||||
c.xchg(tmp.r8Lo(), tmp.r8Hi());
|
if (bswap) {
|
||||||
|
c.xchg(tmp.r8Lo(), tmp.r8Hi());
|
||||||
|
}
|
||||||
c.mov(word_ptr(real_address), tmp.r16());
|
c.mov(word_ptr(real_address), tmp.r16());
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
tmp = c.newGpVar();
|
tmp = c.newGpVar();
|
||||||
c.mov(tmp, value);
|
c.mov(tmp, value);
|
||||||
c.bswap(tmp.r32());
|
if (bswap) {
|
||||||
|
c.bswap(tmp.r32());
|
||||||
|
}
|
||||||
c.mov(dword_ptr(real_address), tmp.r32());
|
c.mov(dword_ptr(real_address), tmp.r32());
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
tmp = c.newGpVar();
|
tmp = c.newGpVar();
|
||||||
c.mov(tmp, value);
|
c.mov(tmp, value);
|
||||||
c.bswap(tmp.r64());
|
if (bswap) {
|
||||||
|
c.bswap(tmp.r64());
|
||||||
|
}
|
||||||
c.mov(qword_ptr(real_address), tmp.r64());
|
c.mov(qword_ptr(real_address), tmp.r64());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -104,10 +104,11 @@ public:
|
||||||
|
|
||||||
AsmJit::GpVar TouchMemoryAddress(uint32_t cia, AsmJit::GpVar& addr);
|
AsmJit::GpVar TouchMemoryAddress(uint32_t cia, AsmJit::GpVar& addr);
|
||||||
AsmJit::GpVar ReadMemory(
|
AsmJit::GpVar ReadMemory(
|
||||||
uint32_t cia, AsmJit::GpVar& addr, uint32_t size, bool acquire = false);
|
uint32_t cia, AsmJit::GpVar& addr, uint32_t size, bool acquire = false,
|
||||||
|
bool bswap = true);
|
||||||
void WriteMemory(
|
void WriteMemory(
|
||||||
uint32_t cia, AsmJit::GpVar& addr, uint32_t size, AsmJit::GpVar& value,
|
uint32_t cia, AsmJit::GpVar& addr, uint32_t size, AsmJit::GpVar& value,
|
||||||
bool release = false);
|
bool release = false, bool bswap = true);
|
||||||
void ByteSwapXmm(AsmJit::XmmVar& value);
|
void ByteSwapXmm(AsmJit::XmmVar& value);
|
||||||
AsmJit::XmmVar ReadMemoryXmm(
|
AsmJit::XmmVar ReadMemoryXmm(
|
||||||
uint32_t cia, AsmJit::GpVar& addr, uint32_t alignment);
|
uint32_t cia, AsmJit::GpVar& addr, uint32_t alignment);
|
||||||
|
|
Loading…
Reference in New Issue