diff --git a/InstructionSets/PowerPC/Decoder.cpp b/InstructionSets/PowerPC/Decoder.cpp index ca73462d9..2c740a54a 100644 --- a/InstructionSets/PowerPC/Decoder.cpp +++ b/InstructionSets/PowerPC/Decoder.cpp @@ -209,7 +209,7 @@ template 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 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::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::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::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(opcode); + case 0b011110'00000'00000'00000'000000'001'00: return instruction(opcode); + case 0b011110'00000'00000'00000'000000'010'00: return instruction(opcode); + case 0b011110'00000'00000'00000'000000'011'00: return instruction(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(opcode); case 0b011111'0000'0000'0000'0000'011010110'1: if(is64bit(model)) return instruction(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(opcode); - case 0b111110'00'00000000'00000000'000000'01: - if(is64bit(model)) return instruction(opcode); - return Instruction(opcode); - case 0b111010'00'00000000'00000000'000000'10: - if(is64bit(model)) return instruction(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(opcode); + case 0b111010'00'00000000'00000000'000000'01: return instruction(opcode); + case 0b111010'00'00000000'00000000'000000'10: return instruction(opcode); + case 0b111110'00'00000000'00000000'000000'00: return instruction(opcode); + case 0b111110'00'00000000'00000000'000000'01: return instruction(opcode); + } } // sc diff --git a/InstructionSets/PowerPC/Instruction.hpp b/InstructionSets/PowerPC/Instruction.hpp index b86aa2a23..a27e6c921 100644 --- a/InstructionSets/PowerPC/Instruction.hpp +++ b/InstructionSets/PowerPC/Instruction.hpp @@ -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.