Fixing decoding of the rld* instructions.
This commit is contained in:
parent
dc16653164
commit
9bb36c7404
|
@ -474,75 +474,76 @@ 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);
|
||||||
return d.Finish();
|
d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1);
|
||||||
}
|
d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
|
||||||
|
return d.Finish();
|
||||||
XEDISASMR(rldcrx, 0x78000012, MDS)(InstrData& i, InstrDisasm& d) {
|
} else if (i.MD.idx == 1) {
|
||||||
d.Init("rldcr", "Rotate Left Doubleword then Clear Right",
|
// XEDISASMR(rldicrx, 0x78000004, MD )
|
||||||
i.MDS.Rc ? InstrDisasm::kRc : 0);
|
d.Init("rldicr", "Rotate Left Doubleword Immediate then Clear Right",
|
||||||
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RA, InstrRegister::kWrite);
|
i.MD.Rc ? InstrDisasm::kRc : 0);
|
||||||
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RT, InstrRegister::kRead);
|
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
|
||||||
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RB, InstrRegister::kRead);
|
d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead);
|
||||||
d.AddUImmOperand((i.MDS.MB5 << 5) | i.MDS.MB, 1);
|
d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1);
|
||||||
return d.Finish();
|
d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
|
||||||
}
|
return d.Finish();
|
||||||
|
} else if (i.MD.idx == 2) {
|
||||||
XEDISASMR(rldicx, 0x78000008, MD )(InstrData& i, InstrDisasm& d) {
|
// XEDISASMR(rldicx, 0x78000008, MD )
|
||||||
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;
|
||||||
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
|
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
|
||||||
if (mb == 0x3E) {
|
if (mb == 0x3E) {
|
||||||
name = "sldi";
|
name = "sldi";
|
||||||
desc = "Shift Left Immediate";
|
desc = "Shift Left Immediate";
|
||||||
|
} else {
|
||||||
|
name = "rldic";
|
||||||
|
desc = "Rotate Left Doubleword Immediate then Clear";
|
||||||
|
}
|
||||||
|
d.Init(name, desc,
|
||||||
|
i.MD.Rc ? InstrDisasm::kRc : 0);
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead);
|
||||||
|
d.AddUImmOperand(sh, 1);
|
||||||
|
d.AddUImmOperand(mb, 1);
|
||||||
|
return d.Finish();
|
||||||
|
} else if (i.MDS.idx == 8) {
|
||||||
|
// XEDISASMR(rldclx, 0x78000010, MDS)
|
||||||
|
d.Init("rldcl", "Rotate Left Doubleword then Clear Left",
|
||||||
|
i.MDS.Rc ? InstrDisasm::kRc : 0);
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RA, InstrRegister::kWrite);
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RT, InstrRegister::kRead);
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RB, InstrRegister::kRead);
|
||||||
|
d.AddUImmOperand((i.MDS.MB5 << 5) | i.MDS.MB, 1);
|
||||||
|
return d.Finish();
|
||||||
|
} else if (i.MDS.idx == 9) {
|
||||||
|
// XEDISASMR(rldcrx, 0x78000012, MDS)
|
||||||
|
d.Init("rldcr", "Rotate Left Doubleword then Clear Right",
|
||||||
|
i.MDS.Rc ? InstrDisasm::kRc : 0);
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RA, InstrRegister::kWrite);
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RT, InstrRegister::kRead);
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RB, InstrRegister::kRead);
|
||||||
|
d.AddUImmOperand((i.MDS.MB5 << 5) | i.MDS.MB, 1);
|
||||||
|
return d.Finish();
|
||||||
|
} else if (i.MD.idx == 3) {
|
||||||
|
// XEDISASMR(rldimix, 0x7800000C, MD )
|
||||||
|
d.Init("rldimi", "Rotate Left Doubleword Immediate then Mask Insert",
|
||||||
|
i.MD.Rc ? InstrDisasm::kRc : 0);
|
||||||
|
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kReadWrite);
|
||||||
|
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();
|
||||||
} else {
|
} else {
|
||||||
name = "rldic";
|
XEASSERTALWAYS();
|
||||||
desc = "Rotate Left Doubleword Immediate then Clear";
|
return 1;
|
||||||
}
|
}
|
||||||
d.Init(name, desc,
|
|
||||||
i.MD.Rc ? InstrDisasm::kRc : 0);
|
|
||||||
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
|
|
||||||
d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead);
|
|
||||||
d.AddUImmOperand(sh, 1);
|
|
||||||
d.AddUImmOperand(mb, 1);
|
|
||||||
return d.Finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
XEDISASMR(rldiclx, 0x78000000, MD )(InstrData& i, InstrDisasm& d) {
|
|
||||||
d.Init("rldicl", "Rotate Left Doubleword Immediate then Clear Left",
|
|
||||||
i.MD.Rc ? InstrDisasm::kRc : 0);
|
|
||||||
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
XEDISASMR(rldicrx, 0x78000004, MD )(InstrData& i, InstrDisasm& d) {
|
|
||||||
d.Init("rldicr", "Rotate Left Doubleword Immediate then Clear Right",
|
|
||||||
i.MD.Rc ? InstrDisasm::kRc : 0);
|
|
||||||
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
XEDISASMR(rldimix, 0x7800000C, MD )(InstrData& i, InstrDisasm& d) {
|
|
||||||
d.Init("rldimi", "Rotate Left Doubleword Immediate then Mask Insert",
|
|
||||||
i.MD.Rc ? InstrDisasm::kRc : 0);
|
|
||||||
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kReadWrite);
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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[] = {
|
||||||
|
|
|
@ -1023,90 +1023,91 @@ 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 )
|
||||||
}
|
// n <- sh[5] || sh[0:4]
|
||||||
|
// r <- ROTL64((RS), n)
|
||||||
|
// b <- mb[5] || mb[0:4]
|
||||||
|
// m <- MASK(b, 63)
|
||||||
|
// RA <- r & m
|
||||||
|
|
||||||
XEEMITTER(rldcrx, 0x78000012, MDS)(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
|
||||||
XEINSTRNOTIMPLEMENTED();
|
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
|
||||||
return 1;
|
uint64_t m = XEMASK(mb, 63);
|
||||||
}
|
|
||||||
|
|
||||||
XEEMITTER(rldicx, 0x78000008, MD )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
GpVar v(c.newGpVar());
|
||||||
XEINSTRNOTIMPLEMENTED();
|
c.mov(v, e.gpr_value(i.MD.RT));
|
||||||
return 1;
|
if (sh) {
|
||||||
}
|
c.rol(v, imm(sh));
|
||||||
|
}
|
||||||
|
if (m != 0xFFFFFFFFFFFFFFFF) {
|
||||||
|
GpVar mask(c.newGpVar());
|
||||||
|
c.mov(mask, imm(m));
|
||||||
|
c.and_(v, mask);
|
||||||
|
}
|
||||||
|
e.update_gpr_value(i.MD.RA, v);
|
||||||
|
|
||||||
XEEMITTER(rldiclx, 0x78000000, MD )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
if (i.MD.Rc) {
|
||||||
// n <- sh[5] || sh[0:4]
|
// With cr0 update.
|
||||||
// r <- ROTL64((RS), n)
|
e.update_cr_with_cond(0, v);
|
||||||
// b <- mb[5] || mb[0:4]
|
}
|
||||||
// m <- MASK(b, 63)
|
|
||||||
// RA <- r & m
|
|
||||||
|
|
||||||
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
|
e.clear_constant_gpr_value(i.MD.RA);
|
||||||
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
|
|
||||||
uint64_t m = XEMASK(mb, 63);
|
|
||||||
|
|
||||||
GpVar v(c.newGpVar());
|
return 0;
|
||||||
c.mov(v, e.gpr_value(i.MD.RT));
|
} else if (i.MD.idx == 1) {
|
||||||
if (sh) {
|
// XEEMITTER(rldicrx, 0x78000004, MD )
|
||||||
c.rol(v, imm(sh));
|
// n <- sh[5] || sh[0:4]
|
||||||
|
// r <- ROTL64((RS), n)
|
||||||
|
// e <- me[5] || me[0:4]
|
||||||
|
// m <- MASK(0, e)
|
||||||
|
// RA <- r & m
|
||||||
|
|
||||||
|
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
|
||||||
|
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
|
||||||
|
uint64_t m = XEMASK(0, mb);
|
||||||
|
|
||||||
|
GpVar v(c.newGpVar());
|
||||||
|
c.mov(v, e.gpr_value(i.MD.RT));
|
||||||
|
if (sh) {
|
||||||
|
c.rol(v, imm(sh));
|
||||||
|
}
|
||||||
|
if (m != 0xFFFFFFFFFFFFFFFF) {
|
||||||
|
GpVar mask(c.newGpVar());
|
||||||
|
c.mov(mask, imm(m));
|
||||||
|
c.and_(v, mask);
|
||||||
|
}
|
||||||
|
e.update_gpr_value(i.MD.RA, v);
|
||||||
|
|
||||||
|
if (i.MD.Rc) {
|
||||||
|
// With cr0 update.
|
||||||
|
e.update_cr_with_cond(0, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
e.clear_constant_gpr_value(i.MD.RA);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} else if (i.MD.idx == 2) {
|
||||||
|
// XEEMITTER(rldicx, 0x78000008, MD )
|
||||||
|
XEINSTRNOTIMPLEMENTED();
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
if (m != 0xFFFFFFFFFFFFFFFF) {
|
|
||||||
GpVar mask(c.newGpVar());
|
|
||||||
c.mov(mask, imm(m));
|
|
||||||
c.and_(v, mask);
|
|
||||||
}
|
|
||||||
e.update_gpr_value(i.MD.RA, v);
|
|
||||||
|
|
||||||
if (i.MD.Rc) {
|
|
||||||
// With cr0 update.
|
|
||||||
e.update_cr_with_cond(0, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
e.clear_constant_gpr_value(i.MD.RA);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
XEEMITTER(rldicrx, 0x78000004, MD )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
|
||||||
// n <- sh[5] || sh[0:4]
|
|
||||||
// r <- ROTL64((RS), n)
|
|
||||||
// e <- me[5] || me[0:4]
|
|
||||||
// m <- MASK(0, e)
|
|
||||||
// RA <- r & m
|
|
||||||
|
|
||||||
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
|
|
||||||
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
|
|
||||||
uint64_t m = XEMASK(0, mb);
|
|
||||||
|
|
||||||
GpVar v(c.newGpVar());
|
|
||||||
c.mov(v, e.gpr_value(i.MD.RT));
|
|
||||||
if (sh) {
|
|
||||||
c.rol(v, imm(sh));
|
|
||||||
}
|
|
||||||
if (m != 0xFFFFFFFFFFFFFFFF) {
|
|
||||||
GpVar mask(c.newGpVar());
|
|
||||||
c.mov(mask, imm(m));
|
|
||||||
c.and_(v, mask);
|
|
||||||
}
|
|
||||||
e.update_gpr_value(i.MD.RA, v);
|
|
||||||
|
|
||||||
if (i.MD.Rc) {
|
|
||||||
// With cr0 update.
|
|
||||||
e.update_cr_with_cond(0, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
e.clear_constant_gpr_value(i.MD.RA);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
XEEMITTER(rldimix, 0x7800000C, MD )(X64Emitter& e, X86Compiler& c, InstrData& i) {
|
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue