Fixing decoding of the rld* instructions.

This commit is contained in:
Ben Vanik
2013-05-31 00:38:26 -07:00
parent dc16653164
commit 9bb36c7404
5 changed files with 177 additions and 167 deletions

View File

@@ -474,27 +474,27 @@ XEDISASMR(xoris, 0x6C000000, D )(InstrData& i, InstrDisasm& d) {
// Integer rotate (A-6) // Integer rotate (A-6)
XEDISASMR(rldclx, 0x78000010, MDS)(InstrData& i, InstrDisasm& d) { XEDISASMR(rld, 0x78000000, MDS)(InstrData& i, InstrDisasm& d) {
d.Init("rldcl", "Rotate Left Doubleword then Clear Left", if (i.MD.idx == 0) {
i.MDS.Rc ? InstrDisasm::kRc : 0); // XEDISASMR(rldiclx, 0x78000000, MD )
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RA, InstrRegister::kWrite); d.Init("rldicl", "Rotate Left Doubleword Immediate then Clear Left",
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RT, InstrRegister::kRead); i.MD.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RB, InstrRegister::kRead); d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
d.AddUImmOperand((i.MDS.MB5 << 5) | i.MDS.MB, 1); d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead);
d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1);
d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
return d.Finish(); return d.Finish();
} } else if (i.MD.idx == 1) {
// XEDISASMR(rldicrx, 0x78000004, MD )
XEDISASMR(rldcrx, 0x78000012, MDS)(InstrData& i, InstrDisasm& d) { d.Init("rldicr", "Rotate Left Doubleword Immediate then Clear Right",
d.Init("rldcr", "Rotate Left Doubleword then Clear Right", i.MD.Rc ? InstrDisasm::kRc : 0);
i.MDS.Rc ? InstrDisasm::kRc : 0); d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RA, InstrRegister::kWrite); d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RT, InstrRegister::kRead); d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RB, InstrRegister::kRead); d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
d.AddUImmOperand((i.MDS.MB5 << 5) | i.MDS.MB, 1);
return d.Finish(); return d.Finish();
} } else if (i.MD.idx == 2) {
// XEDISASMR(rldicx, 0x78000008, MD )
XEDISASMR(rldicx, 0x78000008, MD )(InstrData& i, InstrDisasm& d) {
const char* name; const char* name;
const char* desc; const char* desc;
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH; uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
@@ -513,29 +513,26 @@ XEDISASMR(rldicx, 0x78000008, MD )(InstrData& i, InstrDisasm& d) {
d.AddUImmOperand(sh, 1); d.AddUImmOperand(sh, 1);
d.AddUImmOperand(mb, 1); d.AddUImmOperand(mb, 1);
return d.Finish(); return d.Finish();
} } else if (i.MDS.idx == 8) {
// XEDISASMR(rldclx, 0x78000010, MDS)
XEDISASMR(rldiclx, 0x78000000, MD )(InstrData& i, InstrDisasm& d) { d.Init("rldcl", "Rotate Left Doubleword then Clear Left",
d.Init("rldicl", "Rotate Left Doubleword Immediate then Clear Left", i.MDS.Rc ? InstrDisasm::kRc : 0);
i.MD.Rc ? InstrDisasm::kRc : 0); d.AddRegOperand(InstrRegister::kGPR, i.MDS.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite); d.AddRegOperand(InstrRegister::kGPR, i.MDS.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead); d.AddRegOperand(InstrRegister::kGPR, i.MDS.RB, InstrRegister::kRead);
d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1); d.AddUImmOperand((i.MDS.MB5 << 5) | i.MDS.MB, 1);
d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
return d.Finish(); return d.Finish();
} } else if (i.MDS.idx == 9) {
// XEDISASMR(rldcrx, 0x78000012, MDS)
XEDISASMR(rldicrx, 0x78000004, MD )(InstrData& i, InstrDisasm& d) { d.Init("rldcr", "Rotate Left Doubleword then Clear Right",
d.Init("rldicr", "Rotate Left Doubleword Immediate then Clear Right", i.MDS.Rc ? InstrDisasm::kRc : 0);
i.MD.Rc ? InstrDisasm::kRc : 0); d.AddRegOperand(InstrRegister::kGPR, i.MDS.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite); d.AddRegOperand(InstrRegister::kGPR, i.MDS.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead); d.AddRegOperand(InstrRegister::kGPR, i.MDS.RB, InstrRegister::kRead);
d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1); d.AddUImmOperand((i.MDS.MB5 << 5) | i.MDS.MB, 1);
d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
return d.Finish(); return d.Finish();
} } else if (i.MD.idx == 3) {
// XEDISASMR(rldimix, 0x7800000C, MD )
XEDISASMR(rldimix, 0x7800000C, MD )(InstrData& i, InstrDisasm& d) {
d.Init("rldimi", "Rotate Left Doubleword Immediate then Mask Insert", d.Init("rldimi", "Rotate Left Doubleword Immediate then Mask Insert",
i.MD.Rc ? InstrDisasm::kRc : 0); i.MD.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kReadWrite); d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kReadWrite);
@@ -543,6 +540,10 @@ XEDISASMR(rldimix, 0x7800000C, MD )(InstrData& i, InstrDisasm& d) {
d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1); d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1);
d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1); d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
return d.Finish(); return d.Finish();
} else {
XEASSERTALWAYS();
return 1;
}
} }
XEDISASMR(rlwimix, 0x50000000, M )(InstrData& i, InstrDisasm& d) { XEDISASMR(rlwimix, 0x50000000, M )(InstrData& i, InstrDisasm& d) {
@@ -701,12 +702,13 @@ void RegisterDisasmCategoryALU() {
XEREGISTERINSTR(xorx, 0x7C000278); XEREGISTERINSTR(xorx, 0x7C000278);
XEREGISTERINSTR(xori, 0x68000000); XEREGISTERINSTR(xori, 0x68000000);
XEREGISTERINSTR(xoris, 0x6C000000); XEREGISTERINSTR(xoris, 0x6C000000);
XEREGISTERINSTR(rldclx, 0x78000010); XEREGISTERINSTR(rld, 0x78000000);
XEREGISTERINSTR(rldcrx, 0x78000012); // XEREGISTERINSTR(rldclx, 0x78000010);
XEREGISTERINSTR(rldicx, 0x78000008); // XEREGISTERINSTR(rldcrx, 0x78000012);
XEREGISTERINSTR(rldiclx, 0x78000000); // XEREGISTERINSTR(rldicx, 0x78000008);
XEREGISTERINSTR(rldicrx, 0x78000004); // XEREGISTERINSTR(rldiclx, 0x78000000);
XEREGISTERINSTR(rldimix, 0x7800000C); // XEREGISTERINSTR(rldicrx, 0x78000004);
// XEREGISTERINSTR(rldimix, 0x7800000C);
XEREGISTERINSTR(rlwimix, 0x50000000); XEREGISTERINSTR(rlwimix, 0x50000000);
XEREGISTERINSTR(rlwinmx, 0x54000000); XEREGISTERINSTR(rlwinmx, 0x54000000);
XEREGISTERINSTR(rlwnmx, 0x5C000000); XEREGISTERINSTR(rlwnmx, 0x5C000000);

View File

@@ -362,7 +362,9 @@ InstrType* xe::cpu::ppc::GetInstrType(uint32_t code) {
break; break;
case 30: case 30:
// Opcode = 30, index = bits 4-1 (4) // Opcode = 30, index = bits 4-1 (4)
slot = &xe::cpu::ppc::tables::instr_table_30[XESELECTBITS(code, 1, 4)]; // Special cased to an uber instruction.
slot = &xe::cpu::ppc::tables::instr_table_30[XESELECTBITS(code, 0, 0)];
// slot = &xe::cpu::ppc::tables::instr_table_30[XESELECTBITS(code, 1, 4)];
break; break;
case 31: case 31:
// Opcode = 31, index = bits 10-1 (10) // Opcode = 31, index = bits 10-1 (10)

View File

@@ -193,7 +193,7 @@ typedef struct {
struct { struct {
uint32_t Rc : 1; uint32_t Rc : 1;
uint32_t SH5 : 1; uint32_t SH5 : 1;
uint32_t : 3; uint32_t idx : 3;
uint32_t MB5 : 1; uint32_t MB5 : 1;
uint32_t MB : 5; uint32_t MB : 5;
uint32_t SH : 5; uint32_t SH : 5;
@@ -204,7 +204,7 @@ typedef struct {
// kXEPPCInstrFormatMDS // kXEPPCInstrFormatMDS
struct { struct {
uint32_t Rc : 1; uint32_t Rc : 1;
uint32_t : 4; uint32_t idx : 4;
uint32_t MB5 : 1; uint32_t MB5 : 1;
uint32_t MB : 5; uint32_t MB : 5;
uint32_t RB : 5; uint32_t RB : 5;

View File

@@ -93,15 +93,19 @@ static InstrType* instr_table_19 = instr_table_prep(
// Opcode = 30, index = bits 4-1 (4) // Opcode = 30, index = bits 4-1 (4)
static InstrType instr_table_30_unprep[] = { static InstrType instr_table_30_unprep[] = {
INSTRUCTION(rldiclx, 0x78000000, MD , General , 0), // Decoding these instrunctions in this table is difficult because the
INSTRUCTION(rldicrx, 0x78000004, MD , General , 0), // index bits are kind of random. This is special cased by an uber
INSTRUCTION(rldicx, 0x78000008, MD , General , 0), // instruction handler.
INSTRUCTION(rldimix, 0x7800000C, MD , General , 0), INSTRUCTION(rld, 0x78000000, MD , General , 0),
INSTRUCTION(rldclx, 0x78000010, MDS, General , 0), // INSTRUCTION(rldiclx, 0x78000000, MD , General , 0),
INSTRUCTION(rldcrx, 0x78000012, MDS, General , 0), // INSTRUCTION(rldicrx, 0x78000004, MD , General , 0),
// INSTRUCTION(rldicx, 0x78000008, MD , General , 0),
// INSTRUCTION(rldimix, 0x7800000C, MD , General , 0),
// INSTRUCTION(rldclx, 0x78000010, MDS, General , 0),
// INSTRUCTION(rldcrx, 0x78000012, MDS, General , 0),
}; };
static InstrType* instr_table_30 = instr_table_prep( static InstrType* instr_table_30 = instr_table_prep(
instr_table_30_unprep, XECOUNT(instr_table_30_unprep), 1, 4); instr_table_30_unprep, XECOUNT(instr_table_30_unprep), 0, 0);
// Opcode = 31, index = bits 10-1 (10) // Opcode = 31, index = bits 10-1 (10)
static InstrType instr_table_31_unprep[] = { static InstrType instr_table_31_unprep[] = {

View File

@@ -1023,22 +1023,9 @@ XEEMITTER(xoris, 0x6C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// Integer rotate (A-6) // Integer rotate (A-6)
XEEMITTER(rldclx, 0x78000010, MDS)(X64Emitter& e, X86Compiler& c, InstrData& i) { XEEMITTER(rld, 0x78000000, MDS)(X64Emitter& e, X86Compiler& c, InstrData& i) {
XEINSTRNOTIMPLEMENTED(); if (i.MD.idx == 0) {
return 1; // XEEMITTER(rldiclx, 0x78000000, MD )
}
XEEMITTER(rldcrx, 0x78000012, MDS)(X64Emitter& e, X86Compiler& c, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(rldicx, 0x78000008, MD )(X64Emitter& e, X86Compiler& c, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(rldiclx, 0x78000000, MD )(X64Emitter& e, X86Compiler& c, InstrData& i) {
// n <- sh[5] || sh[0:4] // n <- sh[5] || sh[0:4]
// r <- ROTL64((RS), n) // r <- ROTL64((RS), n)
// b <- mb[5] || mb[0:4] // b <- mb[5] || mb[0:4]
@@ -1069,9 +1056,8 @@ XEEMITTER(rldiclx, 0x78000000, MD )(X64Emitter& e, X86Compiler& c, InstrDat
e.clear_constant_gpr_value(i.MD.RA); e.clear_constant_gpr_value(i.MD.RA);
return 0; return 0;
} } else if (i.MD.idx == 1) {
// XEEMITTER(rldicrx, 0x78000004, MD )
XEEMITTER(rldicrx, 0x78000004, MD )(X64Emitter& e, X86Compiler& c, InstrData& i) {
// n <- sh[5] || sh[0:4] // n <- sh[5] || sh[0:4]
// r <- ROTL64((RS), n) // r <- ROTL64((RS), n)
// e <- me[5] || me[0:4] // e <- me[5] || me[0:4]
@@ -1102,11 +1088,26 @@ XEEMITTER(rldicrx, 0x78000004, MD )(X64Emitter& e, X86Compiler& c, InstrDat
e.clear_constant_gpr_value(i.MD.RA); e.clear_constant_gpr_value(i.MD.RA);
return 0; return 0;
} } else if (i.MD.idx == 2) {
// XEEMITTER(rldicx, 0x78000008, MD )
XEEMITTER(rldimix, 0x7800000C, MD )(X64Emitter& e, X86Compiler& c, InstrData& i) {
XEINSTRNOTIMPLEMENTED(); XEINSTRNOTIMPLEMENTED();
return 1; return 1;
} else if (i.MDS.idx == 8) {
// XEEMITTER(rldclx, 0x78000010, MDS)
XEINSTRNOTIMPLEMENTED();
return 1;
} else if (i.MDS.idx == 9) {
// XEEMITTER(rldcrx, 0x78000012, MDS)
XEINSTRNOTIMPLEMENTED();
return 1;
} else if (i.MD.idx == 3) {
// XEEMITTER(rldimix, 0x7800000C, MD )
XEINSTRNOTIMPLEMENTED();
return 1;
} else {
XEINSTRNOTIMPLEMENTED();
return 1;
}
} }
XEEMITTER(rlwimix, 0x50000000, M )(X64Emitter& e, X86Compiler& c, InstrData& i) { XEEMITTER(rlwimix, 0x50000000, M )(X64Emitter& e, X86Compiler& c, InstrData& i) {
@@ -1404,12 +1405,13 @@ void X64RegisterEmitCategoryALU() {
XEREGISTERINSTR(xorx, 0x7C000278); XEREGISTERINSTR(xorx, 0x7C000278);
XEREGISTERINSTR(xori, 0x68000000); XEREGISTERINSTR(xori, 0x68000000);
XEREGISTERINSTR(xoris, 0x6C000000); XEREGISTERINSTR(xoris, 0x6C000000);
XEREGISTERINSTR(rldclx, 0x78000010); XEREGISTERINSTR(rld, 0x78000000);
XEREGISTERINSTR(rldcrx, 0x78000012); // XEREGISTERINSTR(rldclx, 0x78000010);
XEREGISTERINSTR(rldicx, 0x78000008); // XEREGISTERINSTR(rldcrx, 0x78000012);
XEREGISTERINSTR(rldiclx, 0x78000000); // XEREGISTERINSTR(rldicx, 0x78000008);
XEREGISTERINSTR(rldicrx, 0x78000004); // XEREGISTERINSTR(rldiclx, 0x78000000);
XEREGISTERINSTR(rldimix, 0x7800000C); // XEREGISTERINSTR(rldicrx, 0x78000004);
// XEREGISTERINSTR(rldimix, 0x7800000C);
XEREGISTERINSTR(rlwimix, 0x50000000); XEREGISTERINSTR(rlwimix, 0x50000000);
XEREGISTERINSTR(rlwinmx, 0x54000000); XEREGISTERINSTR(rlwinmx, 0x54000000);
XEREGISTERINSTR(rlwnmx, 0x5C000000); XEREGISTERINSTR(rlwnmx, 0x5C000000);