Disassembly for implemented control/memory instructions.

This commit is contained in:
Ben Vanik 2013-01-29 01:55:03 -08:00
parent 8a560e4cbe
commit d1333db404
4 changed files with 328 additions and 31 deletions

View File

@ -256,7 +256,7 @@ public:
kOE = 1 << 0,
kRc = 1 << 1,
kCA = 1 << 2,
kCR = 1 << 3,
kLR = 1 << 4,
};
char name[16];
@ -265,6 +265,8 @@ public:
std::vector<InstrRegister> special_registers;
void Init(std::string name, std::string info, uint32_t flags);
void AddLR(InstrRegister::Access access);
void AddCTR(InstrRegister::Access access);
void AddCR(uint32_t bf, InstrRegister::Access access);
void AddRegOperand(InstrRegister::RegisterSet set, uint32_t ordinal,
InstrRegister::Access access, std::string display = "");

View File

@ -127,6 +127,18 @@ int XeEmitBranchTo(
return 0;
}
XEDISASMR(bx, 0x48000000, I )(InstrData& i, InstrDisasm& d) {
d.Init("b", "Branch", i.I.LK ? InstrDisasm::kLR : 0);
uint32_t nia;
if (i.I.AA) {
nia = XEEXTS26(i.I.LI << 2);
} else {
nia = i.address + XEEXTS26(i.I.LI << 2);
}
d.AddUImmOperand(nia, 4);
return d.Finish();
}
XEEMITTER(bx, 0x48000000, I )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if AA then
// NIA <- EXTS(LI || 0b00)
@ -148,6 +160,19 @@ XEEMITTER(bx, 0x48000000, I )(FunctionGenerator& g, IRBuilder<>& b, I
return XeEmitBranchTo(g, b, "bx", i.address, i.I.LK);
}
XEDISASMR(bcx, 0x40000000, B )(InstrData& i, InstrDisasm& d) {
// TODO(benvanik): mnemonics
d.Init("bc", "Branch Conditional", i.B.LK ? InstrDisasm::kLR : 0);
if (!XESELECTBITS(i.B.BO, 2, 2)) {
d.AddCTR(InstrRegister::kReadWrite);
}
if (!XESELECTBITS(i.B.BO, 4, 4)) {
d.AddCR(i.B.BI >> 2, InstrRegister::kRead);
}
d.AddUImmOperand(i.B.BO, 1);
d.AddUImmOperand(i.B.BI, 1);
return d.Finish();
}
XEEMITTER(bcx, 0x40000000, B )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if ¬BO[2] then
// CTR <- CTR - 1
@ -240,6 +265,18 @@ XEEMITTER(bcx, 0x40000000, B )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(bcctrx, 0x4C000420, XL )(InstrData& i, InstrDisasm& d) {
// TODO(benvanik): mnemonics
d.Init("bcctr", "Branch Conditional to Count Register",
i.XL.LK ? InstrDisasm::kLR : 0);
if (!XESELECTBITS(i.XL.BO, 4, 4)) {
d.AddCR(i.XL.BI >> 2, InstrRegister::kRead);
}
d.AddUImmOperand(i.XL.BO, 1);
d.AddUImmOperand(i.XL.BI, 1);
return d.Finish();
}
XEEMITTER(bcctrx, 0x4C000420, XL )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// cond_ok <- BO[0] | (CR[BI+32] ≡ BO[1])
// if cond_ok then
@ -300,6 +337,23 @@ XEEMITTER(bcctrx, 0x4C000420, XL )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(bclrx, 0x4C000020, XL )(InstrData& i, InstrDisasm& d) {
std::string name = "bclr";
if (i.code == 0x4E800020) {
name = "blr";
}
d.Init(name, "Branch Conditional to Link Register",
i.XL.LK ? InstrDisasm::kLR : 0);
if (!XESELECTBITS(i.B.BO, 2, 2)) {
d.AddCTR(InstrRegister::kReadWrite);
}
if (!XESELECTBITS(i.B.BO, 4, 4)) {
d.AddCR(i.B.BI >> 2, InstrRegister::kRead);
}
d.AddUImmOperand(i.XL.BO, 1);
d.AddUImmOperand(i.XL.BI, 1);
return d.Finish();
}
XEEMITTER(bclrx, 0x4C000020, XL )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if ¬BO[2] then
// CTR <- CTR - 1
@ -605,6 +659,23 @@ XEEMITTER(mfcr, 0x7C000026, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(mfspr, 0x7C0002A6, XFX)(InstrData& i, InstrDisasm& d) {
d.Init("mfspr", "Move From Special Purpose Register", 0);
d.AddRegOperand(InstrRegister::kGPR, i.XFX.RT, InstrRegister::kWrite);
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
switch (n) {
case 1:
d.AddRegOperand(InstrRegister::kXER, 0, InstrRegister::kRead);
break;
case 8:
d.AddRegOperand(InstrRegister::kLR, 0, InstrRegister::kRead);
break;
case 9:
d.AddRegOperand(InstrRegister::kCTR, 0, InstrRegister::kRead);
break;
}
return d.Finish();
}
XEEMITTER(mfspr, 0x7C0002A6, XFX)(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// n <- spr[5:9] || spr[0:4]
// if length(SPR(n)) = 64 then
@ -647,6 +718,23 @@ XEEMITTER(mtcrf, 0x7C000120, XFX)(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(mtspr, 0x7C0003A6, XFX)(InstrData& i, InstrDisasm& d) {
d.Init("mtspr", "Move To Special Purpose Register", 0);
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
switch (n) {
case 1:
d.AddRegOperand(InstrRegister::kXER, 0, InstrRegister::kWrite);
break;
case 8:
d.AddRegOperand(InstrRegister::kLR, 0, InstrRegister::kWrite);
break;
case 9:
d.AddRegOperand(InstrRegister::kCTR, 0, InstrRegister::kWrite);
break;
}
d.AddRegOperand(InstrRegister::kGPR, i.XFX.RT, InstrRegister::kRead);
return d.Finish();
}
XEEMITTER(mtspr, 0x7C0003A6, XFX)(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// n <- spr[5:9] || spr[0:4]
// if length(SPR(n)) = 64 then
@ -680,10 +768,10 @@ XEEMITTER(mtspr, 0x7C0003A6, XFX)(FunctionGenerator& g, IRBuilder<>& b, I
void RegisterEmitCategoryControl() {
XEREGISTEREMITTER(bx, 0x48000000);
XEREGISTEREMITTER(bcx, 0x40000000);
XEREGISTEREMITTER(bcctrx, 0x4C000420);
XEREGISTEREMITTER(bclrx, 0x4C000020);
XEREGISTERINSTR(bx, 0x48000000);
XEREGISTERINSTR(bcx, 0x40000000);
XEREGISTERINSTR(bcctrx, 0x4C000420);
XEREGISTERINSTR(bclrx, 0x4C000020);
XEREGISTEREMITTER(crand, 0x4C000202);
XEREGISTEREMITTER(crandc, 0x4C000102);
XEREGISTEREMITTER(creqv, 0x4C000242);
@ -699,10 +787,10 @@ void RegisterEmitCategoryControl() {
XEREGISTEREMITTER(tw, 0x7C000008);
XEREGISTEREMITTER(twi, 0x0C000000);
XEREGISTEREMITTER(mfcr, 0x7C000026);
XEREGISTEREMITTER(mfspr, 0x7C0002A6);
XEREGISTERINSTR(mfspr, 0x7C0002A6);
XEREGISTEREMITTER(mftb, 0x7C0002E6);
XEREGISTEREMITTER(mtcrf, 0x7C000120);
XEREGISTEREMITTER(mtspr, 0x7C0003A6);
XEREGISTERINSTR(mtspr, 0x7C0003A6);
}

View File

@ -24,6 +24,17 @@ namespace codegen {
// Integer load (A-13)
XEDISASMR(lbz, 0x88000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lbz", "Load Byte and Zero", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(lbz, 0x88000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -42,6 +53,13 @@ XEEMITTER(lbz, 0x88000000, D )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(lbzu, 0x8C000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lbzu", "Load Byte and Zero with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(lbzu, 0x8C000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// EA <- (RA) + EXTS(D)
// RT <- i56.0 || MEM(EA, 1)
@ -55,6 +73,13 @@ XEEMITTER(lbzu, 0x8C000000, D )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(lbzux, 0x7C0000EE, X )(InstrData& i, InstrDisasm& d) {
d.Init("lbzux", "Load Byte and Zero with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEEMITTER(lbzux, 0x7C0000EE, X )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// EA <- (RA) + (RB)
// RT <- i56.0 || MEM(EA, 1)
@ -68,6 +93,17 @@ XEEMITTER(lbzux, 0x7C0000EE, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(lbzx, 0x7C0000AE, X )(InstrData& i, InstrDisasm& d) {
d.Init("lbzx", "Load Byte and Zero Indexed", 0);
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();
}
XEEMITTER(lbzx, 0x7C0000AE, X )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -86,6 +122,17 @@ XEEMITTER(lbzx, 0x7C0000AE, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(ld, 0xE8000000, DS )(InstrData& i, InstrDisasm& d) {
d.Init("ld", "Load Doubleword", 0);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RT, InstrRegister::kWrite);
if (i.DS.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.DS.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.DS.DS << 2), 2);
return d.Finish();
}
XEEMITTER(ld, 0xE8000000, DS )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -104,6 +151,13 @@ XEEMITTER(ld, 0xE8000000, DS )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(ldu, 0xE8000001, DS )(InstrData& i, InstrDisasm& d) {
d.Init("ldu", "Load Doubleword with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.DS.DS << 2), 2);
return d.Finish();
}
XEEMITTER(ldu, 0xE8000001, DS )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// EA <- (RA) + EXTS(DS || 0b00)
// RT <- MEM(EA, 8)
@ -148,6 +202,17 @@ XEEMITTER(lhax, 0x7C0002AE, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(lhz, 0xA0000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lhz", "Load Halfword and Zero", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(lhz, 0xA0000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -196,6 +261,17 @@ XEEMITTER(lwax, 0x7C0002AA, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(lwz, 0x80000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lwz", "Load Word and Zero", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(lwz, 0x80000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -214,6 +290,13 @@ XEEMITTER(lwz, 0x80000000, D )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(lwzu, 0x84000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lwzu", "Load Word and Zero with Udpate", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(lwzu, 0x84000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// EA <- (RA) + EXTS(D)
// RT <- i32.0 || MEM(EA, 4)
@ -232,6 +315,17 @@ XEEMITTER(lwzux, 0x7C00006E, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(lwzx, 0x7C00002E, X )(InstrData& i, InstrDisasm& d) {
d.Init("lwzx", "Load Word and Zero Indexed", 0);
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();
}
XEEMITTER(lwzx, 0x7C00002E, X )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -253,6 +347,17 @@ XEEMITTER(lwzx, 0x7C00002E, X )(FunctionGenerator& g, IRBuilder<>& b, I
// Integer store (A-14)
XEDISASMR(stb, 0x98000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stb", "Store Byte", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(stb, 0x98000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -271,6 +376,13 @@ XEEMITTER(stb, 0x98000000, D )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(stbu, 0x9C000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stbu", "Store Byte with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(stbu, 0x9C000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 1) <- (RS)[56:63]
@ -294,6 +406,17 @@ XEEMITTER(stbx, 0x7C0001AE, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(std, 0xF8000000, DS )(InstrData& i, InstrDisasm& d) {
d.Init("std", "Store Doubleword", 0);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RT, InstrRegister::kRead);
if (i.DS.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.DS.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.DS.DS << 2), 2);
return d.Finish();
}
XEEMITTER(std, 0xF8000000, DS )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -312,6 +435,13 @@ XEEMITTER(std, 0xF8000000, DS )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(stdu, 0xF8000001, DS )(InstrData& i, InstrDisasm& d) {
d.Init("stdu", "Store Doubleword with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.DS.DS << 2), 2);
return d.Finish();
}
XEEMITTER(stdu, 0xF8000001, DS )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// EA <- (RA) + EXTS(DS || 0b00)
// MEM(EA, 8) <- (RS)
@ -336,6 +466,17 @@ XEEMITTER(stdx, 0x7C00012A, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(sth, 0xB0000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("sth", "Store Halfword", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(sth, 0xB0000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -354,6 +495,13 @@ XEEMITTER(sth, 0xB0000000, D )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(sthu, 0xB4000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("sthu", "Store Halfword with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(sthu, 0xB4000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 2) <- (RS)[48:63]
@ -373,6 +521,17 @@ XEEMITTER(sthux, 0x7C00036E, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(sthx, 0x7C00032E, X )(InstrData& i, InstrDisasm& d) {
d.Init("sth", "Store Halfword Indexed", 0);
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();
}
XEEMITTER(sthx, 0x7C00032E, X )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -391,6 +550,17 @@ XEEMITTER(sthx, 0x7C00032E, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(stw, 0x90000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stw", "Store Word", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(stw, 0x90000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -409,6 +579,13 @@ XEEMITTER(stw, 0x90000000, D )(FunctionGenerator& g, IRBuilder<>& b, I
return 0;
}
XEDISASMR(stwu, 0x94000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stwu", "Store Word with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEEMITTER(stwu, 0x94000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 4) <- (RS)[32:63]
@ -428,6 +605,17 @@ XEEMITTER(stwux, 0x7C00016E, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(stwx, 0x7C00012E, X )(InstrData& i, InstrDisasm& d) {
d.Init("stwx", "Store Word Indexed", 0);
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();
}
XEEMITTER(stwx, 0x7C00012E, X )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if RA = 0 then
// b <- 0
@ -682,45 +870,45 @@ XEEMITTER(icbi, 0x7C0007AC, X )(FunctionGenerator& g, IRBuilder<>& b, I
void RegisterEmitCategoryMemory() {
XEREGISTEREMITTER(lbz, 0x88000000);
XEREGISTEREMITTER(lbzu, 0x8C000000);
XEREGISTEREMITTER(lbzux, 0x7C0000EE);
XEREGISTEREMITTER(lbzx, 0x7C0000AE);
XEREGISTEREMITTER(ld, 0xE8000000);
XEREGISTEREMITTER(ldu, 0xE8000001);
XEREGISTERINSTR(lbz, 0x88000000);
XEREGISTERINSTR(lbzu, 0x8C000000);
XEREGISTERINSTR(lbzux, 0x7C0000EE);
XEREGISTERINSTR(lbzx, 0x7C0000AE);
XEREGISTERINSTR(ld, 0xE8000000);
XEREGISTERINSTR(ldu, 0xE8000001);
XEREGISTEREMITTER(ldux, 0x7C00006A);
XEREGISTEREMITTER(ldx, 0x7C00002A);
XEREGISTEREMITTER(lha, 0xA8000000);
XEREGISTEREMITTER(lhau, 0xAC000000);
XEREGISTEREMITTER(lhaux, 0x7C0002EE);
XEREGISTEREMITTER(lhax, 0x7C0002AE);
XEREGISTEREMITTER(lhz, 0xA0000000);
XEREGISTERINSTR(lhz, 0xA0000000);
XEREGISTEREMITTER(lhzu, 0xA4000000);
XEREGISTEREMITTER(lhzux, 0x7C00026E);
XEREGISTEREMITTER(lhzx, 0x7C00022E);
XEREGISTEREMITTER(lwa, 0xE8000002);
XEREGISTEREMITTER(lwaux, 0x7C0002EA);
XEREGISTEREMITTER(lwax, 0x7C0002AA);
XEREGISTEREMITTER(lwz, 0x80000000);
XEREGISTEREMITTER(lwzu, 0x84000000);
XEREGISTERINSTR(lwz, 0x80000000);
XEREGISTERINSTR(lwzu, 0x84000000);
XEREGISTEREMITTER(lwzux, 0x7C00006E);
XEREGISTEREMITTER(lwzx, 0x7C00002E);
XEREGISTEREMITTER(stb, 0x98000000);
XEREGISTEREMITTER(stbu, 0x9C000000);
XEREGISTERINSTR(lwzx, 0x7C00002E);
XEREGISTERINSTR(stb, 0x98000000);
XEREGISTERINSTR(stbu, 0x9C000000);
XEREGISTEREMITTER(stbux, 0x7C0001EE);
XEREGISTEREMITTER(stbx, 0x7C0001AE);
XEREGISTEREMITTER(std, 0xF8000000);
XEREGISTEREMITTER(stdu, 0xF8000001);
XEREGISTERINSTR(std, 0xF8000000);
XEREGISTERINSTR(stdu, 0xF8000001);
XEREGISTEREMITTER(stdux, 0x7C00016A);
XEREGISTEREMITTER(stdx, 0x7C00012A);
XEREGISTEREMITTER(sth, 0xB0000000);
XEREGISTEREMITTER(sthu, 0xB4000000);
XEREGISTERINSTR(sth, 0xB0000000);
XEREGISTERINSTR(sthu, 0xB4000000);
XEREGISTEREMITTER(sthux, 0x7C00036E);
XEREGISTEREMITTER(sthx, 0x7C00032E);
XEREGISTEREMITTER(stw, 0x90000000);
XEREGISTEREMITTER(stwu, 0x94000000);
XEREGISTERINSTR(sthx, 0x7C00032E);
XEREGISTERINSTR(stw, 0x90000000);
XEREGISTERINSTR(stwu, 0x94000000);
XEREGISTEREMITTER(stwux, 0x7C00016E);
XEREGISTEREMITTER(stwx, 0x7C00012E);
XEREGISTERINSTR(stwx, 0x7C00012E);
XEREGISTEREMITTER(lhbrx, 0x7C00062C);
XEREGISTEREMITTER(lwbrx, 0x7C00042C);
XEREGISTEREMITTER(ldbrx, 0x7C000428);

View File

@ -38,11 +38,30 @@ void InstrDisasm::Init(std::string name, std::string info, uint32_t flags) {
InstrRegister::kXER, 0, InstrRegister::kReadWrite
});
}
if (flags & InstrDisasm::kLR) {
name += "l";
special_registers.push_back((InstrRegister){
InstrRegister::kLR, 0, InstrRegister::kWrite
});
}
XEIGNORE(xestrcpya(this->name, XECOUNT(this->name), name.c_str()));
XEIGNORE(xestrcpya(this->info, XECOUNT(this->info), info.c_str()));
}
void InstrDisasm::AddLR(InstrRegister::Access access) {
special_registers.push_back((InstrRegister){
InstrRegister::kLR, 0, access
});
}
void InstrDisasm::AddCTR(InstrRegister::Access access) {
special_registers.push_back((InstrRegister){
InstrRegister::kCTR, 0, access
});
}
void InstrDisasm::AddCR(uint32_t bf, InstrRegister::Access access) {
special_registers.push_back((InstrRegister){
InstrRegister::kCR, bf, access
@ -137,16 +156,16 @@ void InstrDisasm::AddUImmOperand(uint64_t value, size_t width,
const size_t max_count = XECOUNT(o.display);
switch (width) {
case 1:
xesnprintfa(o.display, max_count, "%.2X", (uint8_t)value);
xesnprintfa(o.display, max_count, "0x%.2X", (uint8_t)value);
break;
case 2:
xesnprintfa(o.display, max_count, "%.4X", (uint16_t)value);
xesnprintfa(o.display, max_count, "0x%.4X", (uint16_t)value);
break;
case 4:
xesnprintfa(o.display, max_count, "%.8X", (uint32_t)value);
xesnprintfa(o.display, max_count, "0x%.8X", (uint32_t)value);
break;
case 8:
xesnprintfa(o.display, max_count, "%.16llX", value);
xesnprintfa(o.display, max_count, "0x%.16llX", value);
break;
}
}