From a95ff3f43e0f03048506f37b01dbd2cf9d820be0 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:17:42 +0530 Subject: [PATCH] arch-power: Add PC-relative arithmetic instructions This adds the following instructions. * Add PC Immediate Shifted (addpcis) Change-Id: Ib88b8e123ffb328e6f692e0fddb237e420ce38a7 Signed-off-by: Sandipan Das --- src/arch/power/insts/integer.cc | 52 ++++++++++++++++++++++++++ src/arch/power/insts/integer.hh | 21 +++++++++++ src/arch/power/isa/decoder.isa | 6 +++ src/arch/power/isa/formats/integer.isa | 11 ++++++ 4 files changed, 90 insertions(+) diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index 015ed723d..d2862ff39 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -223,6 +223,58 @@ 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.compare("addpcis")) { + printSrcs = false; + if (disp == 0) { + myMnemonic = "lnia"; + printDisp = false; + } else if (disp < 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) { + if (negateDisp) { + ss << ", " << -disp; + } else { + ss << ", " << disp; + } + } + + 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 32c1ccd37..a75f38b0c 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -180,6 +180,27 @@ class IntImmArithOp : public IntArithOp }; +/** + * Class for integer arithmetic operations with displacement. + */ +class IntDispArithOp : public IntArithOp +{ + protected: + + int32_t disp; + + /// Constructor + IntDispArithOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntArithOp(mnem, _machInst, __opClass), + disp((int16_t)((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 e678f0e7a..ff4fecea9 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -120,6 +120,12 @@ decode PO default Unknown::unknown() { format MiscOp { 150: isync({{ }}, [ IsSerializeAfter ]); } + + default: decode DX_XO { + format IntDispArithOp { + 2: addpcis({{ Rt = NIA + (disp << 16); }}); + } + } } 17: IntOp::sc({{ return std::make_shared(); }}); diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa index aa9cc2539..cb858a8e3 100644 --- a/src/arch/power/isa/formats/integer.isa +++ b/src/arch/power/isa/formats/integer.isa @@ -206,6 +206,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 -- 2.30.2