diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index 2035b5c78f..25c8691d71 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -218,6 +218,51 @@ IntImmArithOp::generateDisassembly( } +std::string +IntDispArithOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::stringstream ss; + bool printSrcs = true; + bool printDisp = true; + bool negateDisp = false; + + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + if (myMnemonic == "addpcis") { + printSrcs = false; + if (d == 0) { + myMnemonic = "lnia"; + printDisp = false; + } else if (d < 0) { + myMnemonic = "subpcis"; + negateDisp = true; + } + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (_numDestRegs > 0) + printReg(ss, destRegIdx(0)); + + // Print the source register + if (_numSrcRegs > 0 && printSrcs) { + if (_numDestRegs > 0) + ss << ", "; + printReg(ss, srcRegIdx(0)); + } + + // Print the displacement + if (printDisp) + ss << ", " << (negateDisp ? -d : d); + + return ss.str(); +} + + std::string IntShiftOp::generateDisassembly( Addr pc, const loader::SymbolTable *symtab) const diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh index daef626e21..aafbbec0fc 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -160,6 +160,27 @@ class IntImmArithOp : public IntArithOp }; +/** + * Class for integer arithmetic operations with displacement. + */ +class IntDispArithOp : public IntArithOp +{ + protected: + + int64_t d; + + /// Constructor + IntDispArithOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntArithOp(mnem, _machInst, __opClass), + d(sext<16>((machInst.d0 << 6) | (machInst.d1 << 1) | machInst.d2)) + { + } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; +}; + + /** * Class for integer operations with a shift. */ diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index cc3b9f4013..beacd6facf 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -163,6 +163,10 @@ decode PO default Unknown::unknown() { 528: bcctr({{ NIA = CTR & -4ULL; }}); 560: bctar({{ NIA = TAR & -4ULL; }}, true); } + + default: decode DX_XO { + 2: IntDispArithOp::addpcis({{ Rt = NIA + (d << 16); }}); + } } format IntRotateOp { diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa index 8583ba09a9..183c08bdc4 100644 --- a/src/arch/power/isa/formats/integer.isa +++ b/src/arch/power/isa/formats/integer.isa @@ -168,6 +168,17 @@ def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{ }}; +// Integer instructions with displacement that perform arithmetic. +// There are no control flags to set. +def format IntDispArithOp(code, inst_flags = []) {{ + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntDispArithOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + // Integer instructions that perform logic operations. The result is // always written into Ra. All instructions have 2 versions depending on // whether the Rc bit is set to compute the CR0 code. This is determined