1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-25 16:31:42 +00:00

Introduce overlooked: ld, ldu, rldclx, rldcrx, rldicx, rldiclx, rldicrx, rldimix.

This commit is contained in:
Thomas Harte 2022-04-09 18:28:51 -04:00
parent da0f7d7907
commit 9e0755bc86
2 changed files with 157 additions and 115 deletions

View File

@ -209,7 +209,7 @@ template <Model model, bool validate_reserved_bits, Operation operation> Instruc
case Operation::lhz: case Operation::lhzu:
case Operation::lmw: case Operation::lwa:
case Operation::lwz: case Operation::lwzu:
case Operation::mulld: case Operation::mulli: case Operation::mullwx:
case Operation::mulldx: case Operation::mulli: case Operation::mullwx:
case Operation::nandx: case Operation::norx:
case Operation::orx: case Operation::orcx:
case Operation::ori: case Operation::oris:
@ -229,9 +229,10 @@ template <Model model, bool validate_reserved_bits, Operation operation> Instruc
case Operation::subfic:
case Operation::tdi: case Operation::twi:
case Operation::xorx: case Operation::xori: case Operation::xoris:
// TODO: ld ldu
// TODO: rldclx rldcrx rldicx rldicrx rldimix
case Operation::ld: case Operation::ldu:
case Operation::rldclx: case Operation::rldcrx:
case Operation::rldicx: case Operation::rldiclx:
case Operation::rldicrx: case Operation::rldimix:
break;
}
@ -341,7 +342,7 @@ Instruction Decoder<model, validate_reserved_bits>::decode(uint32_t opcode) {
BindConditional(is64bit, SixTen(0b011111, 0b0001010100), ldarx);
BindConditional(is64bit, SixTen(0b011111, 0b0010010101), stdx);
BindConditional(is64bit, SixTen(0b011111, 0b0010110101), stdux);
BindConditional(is64bit, SixTen(0b011111, 0b0011101001), mulld); BindConditional(is64bit, SixTen(0b011111, 0b1011101001), mulld);
BindConditional(is64bit, SixTen(0b011111, 0b0011101001), mulldx); BindConditional(is64bit, SixTen(0b011111, 0b1011101001), mulldx);
BindConditional(is64bit, SixTen(0b011111, 0b0101010101), lwax);
BindConditional(is64bit, SixTen(0b011111, 0b0101110101), lwaux);
BindConditional(is64bit, SixTen(0b011111, 0b1100111011), sradix); BindConditional(is64bit, SixTen(0b011111, 0b1100111010), sradix);
@ -539,6 +540,8 @@ Instruction Decoder<model, validate_reserved_bits>::decode(uint32_t opcode) {
BindConditional(is64bit, SixTen(0b111011, 0b10110), fsqrtsx);
BindConditional(is64bit, SixTen(0b111011, 0b11000), fresx);
BindConditional(is64bit, SixTen(0b011110, 0b01000), rldclx);
BindConditional(is64bit, SixTen(0b011110, 0b01001), rldcrx);
// Optional...
Bind(SixTen(0b111111, 0b10110), fsqrtx);
@ -546,23 +549,36 @@ Instruction Decoder<model, validate_reserved_bits>::decode(uint32_t opcode) {
Bind(SixTen(0b111111, 0b11010), frsqrtex);
}
// rldicx, rldiclx, rldicrx, rldimix
if(is64bit(model)) {
switch(opcode & 0b111111'00000'00000'00000'000000'111'00) {
default: break;
case 0b011110'00000'00000'00000'000000'000'00: return instruction<model, validate_reserved_bits, Operation::rldiclx>(opcode);
case 0b011110'00000'00000'00000'000000'001'00: return instruction<model, validate_reserved_bits, Operation::rldicrx>(opcode);
case 0b011110'00000'00000'00000'000000'010'00: return instruction<model, validate_reserved_bits, Operation::rldicx>(opcode);
case 0b011110'00000'00000'00000'000000'011'00: return instruction<model, validate_reserved_bits, Operation::rldimix>(opcode);
}
}
// stwcx. and stdcx.
switch(opcode & 0b111111'0000'0000'0000'0000'111111111'1) {
default: break;
case 0b011111'0000'0000'0000'0000'010010110'1: return instruction<model, validate_reserved_bits, Operation::stwcx_>(opcode);
case 0b011111'0000'0000'0000'0000'011010110'1:
if(is64bit(model)) return instruction<model, validate_reserved_bits, Operation::stdcx_>(opcode);
return Instruction(opcode);
}
// std and stdu [TODO: or ld and ldu?]
switch(opcode & 0b111111'00'00000000'00000000'000000'11) {
case 0b111110'00'00000000'00000000'000000'00: return instruction<model, validate_reserved_bits, Operation::std>(opcode);
case 0b111110'00'00000000'00000000'000000'01:
if(is64bit(model)) return instruction<model, validate_reserved_bits, Operation::stdu>(opcode);
return Instruction(opcode);
case 0b111010'00'00000000'00000000'000000'10:
if(is64bit(model)) return instruction<model, validate_reserved_bits, Operation::lwa>(opcode);
return Instruction(opcode);
// std, stdu, ld, ldu, lwa
if(is64bit(model)) {
switch(opcode & 0b111111'00'00000000'00000000'000000'11) {
default: break;
case 0b111010'00'00000000'00000000'000000'00: return instruction<model, validate_reserved_bits, Operation::ld>(opcode);
case 0b111010'00'00000000'00000000'000000'01: return instruction<model, validate_reserved_bits, Operation::ldu>(opcode);
case 0b111010'00'00000000'00000000'000000'10: return instruction<model, validate_reserved_bits, Operation::lwa>(opcode);
case 0b111110'00'00000000'00000000'000000'00: return instruction<model, validate_reserved_bits, Operation::std>(opcode);
case 0b111110'00'00000000'00000000'000000'01: return instruction<model, validate_reserved_bits, Operation::stdu>(opcode);
}
}
// sc

View File

@ -219,6 +219,11 @@ enum class Operation: uint8_t {
// MARK: - 32- and 64-bit PowerPC instructions.
//
/// Add.
/// add add. addo addo.
/// rD(), rA(), rB() [rc(), oe()]
addx,
/// Add carrying.
/// addc addc. addco addco.
/// rD(), rA(), rB() [rc(), oe()]
@ -254,16 +259,16 @@ enum class Operation: uint8_t {
/// rD(), rA() [rc(), oe()]
addmex,
/// Add.
/// add add. addo addo.
/// rD(), rA(), rB() [rc(), oe()]
addx,
/// Add to zero extended.
/// addze addze. addzeo addzeo.
/// rD(), rA() [rc(), oe()]
addzex,
/// And.
/// and, and.
/// rA(), rS(), rB() [rc()]
andx,
/// And with complement.
/// andc, andc.
/// rA(), rS(), rB() [rc()]
@ -279,10 +284,10 @@ enum class Operation: uint8_t {
/// rA(), rS(), uimm()
andis_,
/// And.
/// and, and.
/// rA(), rS(), rB() [rc()]
andx,
/// Branch unconditional.
/// b bl ba bla
/// li() [aa(), lk()]
bx,
/// Branch conditional.
/// bne bne+ beq bdnzt+ bdnzf bdnzt bdnzfla ...
@ -299,11 +304,6 @@ enum class Operation: uint8_t {
/// bo(), bi() [aa(), lk()]
bclrx,
/// Branch unconditional.
/// b bl ba bla
/// li() [aa(), lk()]
bx,
/// Compare
/// cmp
/// crfD(), l(), rA(), rB()
@ -394,16 +394,16 @@ enum class Operation: uint8_t {
/// rA(), rB()
dcbz,
/// Divide word unsigned.
/// divwu divwu. divwuo divwuo.
/// rD(), rA(), rB() [rc(), oe()]
divwux,
/// Divide word.
/// divw divw. divwo divwo.
/// rD(), rA(), rB() [rc(), oe()]
divwx,
/// Divide word unsigned.
/// divwu divwu. divwuo divwuo.
/// rD(), rA(), rB() [rc(), oe()]
divwux,
/// External control in word indexed.
/// eciwx
/// rD(), rA(), rB()
@ -438,16 +438,16 @@ enum class Operation: uint8_t {
/// frD(), frB() [rc()]
fabsx,
/// Floating point add single precision.
/// fadds fadds.
/// frD(), frA(), frB() [rc()]
faddsx,
/// Floating point add.
/// fadd fadd.
/// frD(), frA(), frB() [rc()]
faddx,
/// Floating point add single precision.
/// fadds fadds.
/// frD(), frA(), frB() [rc()]
faddsx,
/// Floating point compare ordered.
/// fcmpo
/// crfD(), frA(), frB()
@ -468,51 +468,51 @@ enum class Operation: uint8_t {
/// frD(), frB() [rc()]
fctiwzx,
/// Floating point divide single precision.
/// fdiv fdiv.
/// frD(), frA(), frB() [rc()]
fdivsx,
/// Floating point divide.
/// fdiv fdiv.
/// frD(), frA(), frB() [rc()]
fdivx,
/// Floating point multiply add single precision.
/// fmadds fmadds.
/// frD(), frA(), frC(), frB() [rc()]
fmaddsx,
/// Floating point divide single precision.
/// fdiv fdiv.
/// frD(), frA(), frB() [rc()]
fdivsx,
/// Floating point multiply add.
/// fmadd fmadd.
/// frD(), frA(), frC(), frB() [rc()]
fmaddx,
/// Floating point multiply add single precision.
/// fmadds fmadds.
/// frD(), frA(), frC(), frB() [rc()]
fmaddsx,
/// Floating point register move.
/// fmr fmr.
/// frD(), frB() [rc()]
fmrx,
/// Floating point multiply subtract single precision.
/// fmsubx fmsubx.
/// frD(), frA(), frC(), frB() [rc()]
fmsubsx,
/// Floating point multiply subtract.
/// fmsub fmsub.
/// frD(), frA(), frC(), frB() [rc()]
fmsubx,
/// Floating point multiply single precision.
/// fmuls fmuls.
/// frD(), frA(), frC() [rc()]
fmulsx,
/// Floating point multiply subtract single precision.
/// fmsubx fmsubx.
/// frD(), frA(), frC(), frB() [rc()]
fmsubsx,
/// Floating point multiply.
/// fmul fmul.
/// frD(), frA(), frC() [rc()]
fmulx,
/// Floating point multiply single precision.
/// fmuls fmuls.
/// frD(), frA(), frC() [rc()]
fmulsx,
/// Floating negative absolute value.
/// fnabs fnabs.
/// frD(), frB() [rc()]
@ -523,41 +523,41 @@ enum class Operation: uint8_t {
/// frD(), frB() [rc()]
fnegx,
/// Floating point negative multiply add single precision.
/// fnmadds fnmadds.
/// frD(), frA(), frC(), frB() [rc()]
fnmaddsx,
/// Floating point negative multiply add.
/// fnmadd fnmadd.
/// frD(), frA(), frC(), frB() [rc()]
fnmaddx,
/// Floating point negative multiply add.
/// fnmsubs fnmsubs.
/// Floating point negative multiply add single precision.
/// fnmadds fnmadds.
/// frD(), frA(), frC(), frB() [rc()]
fnmsubsx,
fnmaddsx,
/// Floating point negative multiply subtract.
/// fnmsub fnmsub.
/// frD(), frA(), frC(), frB() [rc()]
fnmsubx,
/// Floating point negative multiply add.
/// fnmsubs fnmsubs.
/// frD(), frA(), frC(), frB() [rc()]
fnmsubsx,
/// Floating point round to single precision.
/// frsp frsp.
/// frD(), frB() [rc()]
frspx,
/// Floating point subtract single precision.
/// fsubs fsubs.
/// frD(), frA(), frB() [rc()]
fsubsx,
/// Floating point subtract.
/// fsub fsub.
/// frD(), frA(), frB() [rc()]
fsubx,
/// Floating point subtract single precision.
/// fsubs fsubs.
/// frD(), frA(), frB() [rc()]
fsubsx,
/// Instruction cache block invalidate.
/// icbi
/// rA(), rB()
@ -840,6 +840,11 @@ enum class Operation: uint8_t {
/// rA(), rS(), rB() [rc()]
norx,
/// OR.
/// or or.
/// rA(), rS(), rB() [rc()]
orx,
/// OR with complement.
/// orc orc.
/// rA(), rS(), rB() [rc()]
@ -855,11 +860,6 @@ enum class Operation: uint8_t {
/// rA(), rS(), uimm()
oris,
/// OR.
/// or or.
/// rA(), rS(), rB() [rc()]
orx,
/// Return from interrupt.
/// rfi
rfi,
@ -888,21 +888,26 @@ enum class Operation: uint8_t {
/// rA(), rS(), rB() [rc()]
slwx,
/// Shift right algebraic word immediate.
/// srawi srawi.
/// rA(), rS(), sh() [rc()]
srawix,
/// Shift right algebraic word.
/// sraw sraw.
/// rA(), rS(), rB() [rc()]
srawx,
/// Shift right algebraic word immediate.
/// srawi srawi.
/// rA(), rS(), sh() [rc()]
srawix,
/// Shift right word.
/// srw srw.
/// rA(), rS(), rB() [rc()]
srwx,
/// Store byte indexed.
/// stbx
/// rS(), rA(), rB()
stbx,
/// Store byte.
/// stb
/// rS(), d() [ rA() ]
@ -918,11 +923,6 @@ enum class Operation: uint8_t {
/// rS(), rA(), rB()
stbux,
/// Store byte indexed.
/// stbx
/// rS(), rA(), rB()
stbx,
/// Store floating point double precision.
/// stfd
/// frS(), d() [ rA() ]
@ -1033,6 +1033,11 @@ enum class Operation: uint8_t {
/// rS(), rA(), rB()
stwx,
/// Subtract from.
/// subf subf. subfo subfo.
/// rD(), rA(), rB() [rc(), oe()]
subfx,
/// Subtract from carrying.
/// subfc subfc. subfco subfco.
/// rD(), rA(), rB() [rc(), oe()]
@ -1053,11 +1058,6 @@ enum class Operation: uint8_t {
/// rD(), rA() [rc(), oe()]
subfmex,
/// Subtract from.
/// subf subf. subfo subfo.
/// rD(), rA(), rB() [rc(), oe()]
subfx,
/// Subtract from zero extended.
/// subfze subfze. subfzeo subfzeo.
/// rD(), rA() [rc(), oe()]
@ -1077,6 +1077,11 @@ enum class Operation: uint8_t {
/// to(), rA(), simm()
twi,
/// Xor.
/// xor xor.
/// rA(), rS(), rB() [rc()]
xorx,
/// Xor immediate.
/// xori
/// rA(), rs(), uimm()
@ -1087,11 +1092,6 @@ enum class Operation: uint8_t {
/// rA(), rS(), uimm()
xoris,
/// Xor.
/// xor xor.
/// rA(), rS(), rB() [rc()]
xorx,
//
// MARK: - 32-bit, supervisor level.
//
@ -1142,16 +1142,16 @@ enum class Operation: uint8_t {
/// frD(), frA(), frC(), frB() [rc()]
fselx,
/// Floating point square root single precision.
/// fsqrts fsqrts.
/// frD(), frB() [rc()]
fsqrtsx,
/// Floating Point square root.
/// fsqrt fsqrt.
/// frD(), frB() [rc()]
fsqrtx,
/// Floating point square root single precision.
/// fsqrts fsqrts.
/// frD(), frB() [rc()]
fsqrtsx,
/// Store floating point as integer word indexed.
/// stfiwx
/// frS(), rA(), rB()
@ -1166,16 +1166,16 @@ enum class Operation: uint8_t {
/// rA(), rS() [rc()]
cntlzdx,
/// Divide double word unsigned.
/// divdu divdu. divduo divduo.
/// rD(), rA(), rB() [rc(), oe()]
divdux,
/// Divide double word.
/// divd divd. divdo divdo.
/// rD(), rA(), rB() [rc(), oe()]
divdx,
/// Divide double word unsigned.
/// divdu divdu. divduo divduo.
/// rD(), rA(), rB() [rc(), oe()]
divdux,
/// Extend sign word.
/// extsw extsw.
/// rA(), rS() [rc()]
@ -1196,11 +1196,17 @@ enum class Operation: uint8_t {
/// frD(), frB() [rc()]
fctidzx,
/// TODO
ld,
/// Load double word and reserve indezed.
/// ldarx
/// rD(), rA(), rB()
ldarx,
/// TODO
ldu,
/// Load double word with update indexed.
/// ldux
/// frD(), rA(), rB()
@ -1226,20 +1232,38 @@ enum class Operation: uint8_t {
/// rD(), rA(), rB()
lwax,
/// Multiply high double word unsigned.
/// mulhdy mulhdu.
/// rD(), rA(), rB() [rc()]
mulhdux,
/// Multiply high double word.
/// mulhd mulhd.
/// rD(), rA(), rB() [rc()]
mulhdx,
/// Multiply high double word unsigned.
/// mulhdy mulhdu.
/// rD(), rA(), rB() [rc()]
mulhdux,
/// Multiply low double word.
/// mulld mulld. mulldo mulldo.
/// rD(), rA(), rB() [rc()]
mulld,
mulldx,
/// TODO
rldclx,
/// TODO
rldcrx,
/// TODO
rldicx,
/// TODO
rldiclx,
/// TODO
rldicrx,
/// TODO
rldimix,
/// Segment lookaside buffer ('SLB') invalidate all.
/// slbia
@ -1255,16 +1279,16 @@ enum class Operation: uint8_t {
/// rA(), rS(), rB()
sldx,
/// Shift right algebraic double word immediate.
/// sradi sradi.
/// rA(), rS(),sh() [rc()]
sradix,
/// Shift right algebraic double word.
/// srad srad,
/// rA(), rS(), rB() [rc()]
sradx,
/// Shift right algebraic double word immediate.
/// sradi sradi.
/// rA(), rS(),sh() [rc()]
sradix,
/// Shift right double word.
/// srd srd.
/// rA(), rS(), rB() [rc()]
@ -1383,6 +1407,8 @@ struct Instruction {
/// Branch displacement; provided as already sign extended.
int16_t bd() const { return int16_t(opcode & 0xfffc); }
// TODO: both MB/ME and mb/me fields seem to be defined. Investigate.
/// Specifies the first 1 bit of a 32/64-bit mask for rotate operations.
uint32_t mb() const { return (opcode >> 6) & 0x1f; }
/// Specifies the first 1 bit of a 32/64-bit mask for rotate operations.