From b619ed69b90932744016e7402d0864d58a63a321 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:22:15 +0530 Subject: [PATCH] arch-power: Add trap instructions This introduces new classes and new formats for D and X form instructions, the TO field that is used to encode the trap conditions and adds the following instructions. * Trap Word Immediate (twi) * Trap Word (tw) * Trap Doubleword Immediate (tdi) * Trap Doubleword (td) Change-Id: I029147ef643c2ee6794426e5e90af4d75f22e92e Signed-off-by: Sandipan Das --- src/arch/power/faults.hh | 9 +++ src/arch/power/insts/integer.cc | 100 +++++++++++++++++++++++++ src/arch/power/insts/integer.hh | 76 +++++++++++++++++++ src/arch/power/isa/decoder.isa | 10 +++ src/arch/power/isa/formats/integer.isa | 31 ++++++++ src/arch/power/types.hh | 3 + 6 files changed, 229 insertions(+) diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh index e20ef8eb5..6932271ac 100644 --- a/src/arch/power/faults.hh +++ b/src/arch/power/faults.hh @@ -82,6 +82,15 @@ class AlignmentFault : public PowerFault } }; +class TrapFault : public PowerFault +{ + public: + TrapFault() + : PowerFault("Trap") + { + } +}; + } // namespace PowerISA #endif // __ARCH_POWER_FAULTS_HH__ diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index 0631749e2..115b8674f 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -878,3 +878,103 @@ IntConcatRotateOp::generateDisassembly( return ss.str(); } + + +std::string +IntTrapOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::string ext; + std::stringstream ss; + bool printSrcs = true; + bool printCond = false; + + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("tw") && + (srcRegIdx(0).index() == 0) && (srcRegIdx(1).index() == 0)) { + myMnemonic = "trap"; + printSrcs = false; + } else { + ext = suffix(); + if (!ext.empty() && + (!myMnemonic.compare("tw") || !myMnemonic.compare("td"))) { + myMnemonic += ext; + } else { + printCond = true; + } + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the trap condition + if (printCond) { + ss << unsigned(tcond); + } + + // Print the source registers + if (printSrcs) { + if (_numSrcRegs > 0) { + if (printCond) { + ss << ", "; + } + printReg(ss, srcRegIdx(0)); + } + + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, srcRegIdx(1)); + } + } + + return ss.str(); +} + + +std::string +IntImmTrapOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::string ext; + std::stringstream ss; + bool printCond = false; + + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + ext = suffix(); + if (!ext.empty()) { + if (!myMnemonic.compare("twi")) { + myMnemonic = "tw" + ext + "i"; + } else if (!myMnemonic.compare("tdi")) { + myMnemonic = "td" + ext + "i"; + } else { + printCond = true; + } + } else { + printCond = true; + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the trap condition + if (printCond) { + ss << unsigned(tcond); + } + + // Print the source registers + if (_numSrcRegs > 0) { + if (printCond) { + ss << ", "; + } + printReg(ss, srcRegIdx(0)); + } + + // Print the immediate value + ss << ", " << simm; + + return ss.str(); +} diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh index 59566e88b..a2692e2cb 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -733,6 +733,82 @@ class IntConcatRotateOp : public IntConcatShiftOp Addr pc, const Loader::SymbolTable *symtab) const override; }; + +/** + * Class for integer trap operations. + */ +class IntTrapOp : public IntOp +{ + protected: + uint8_t tcond; + + /// Constructor + IntTrapOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntOp(mnem, _machInst, __opClass), + tcond(machInst.to) + { + } + + inline bool + checkTrap(int64_t ra, int64_t rb) const + { + if (((tcond & 0x10) && (ra < rb)) || + ((tcond & 0x08) && (ra > rb)) || + ((tcond & 0x04) && (ra == rb)) || + ((tcond & 0x02) && ((uint64_t)ra < (uint64_t)rb)) || + ((tcond & 0x01) && ((uint64_t)ra > (uint64_t)rb))) { + return true; + } + + return false; + } + + inline std::string + suffix() const + { + std::string str; + + switch (tcond) { + case 1: str = "lgt"; break; + case 2: str = "llt"; break; + case 4: str = "eq"; break; + case 5: str = "lge"; break; + case 6: str = "lle"; break; + case 8: str = "gt"; break; + case 12: str = "ge"; break; + case 16: str = "lt"; break; + case 20: str = "le"; break; + case 24: str = "ne"; break; + case 31: str = "u"; break; + } + + return str; + } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; +}; + + +/** + * Class for integer immediate trap operations. + */ +class IntImmTrapOp : public IntTrapOp +{ + protected: + int16_t simm; + + /// Constructor + IntImmTrapOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntTrapOp(mnem, _machInst, __opClass), + simm((int16_t)machInst.si) + { + } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; +}; + } // namespace PowerISA #endif //__ARCH_POWER_INSTS_INTEGER_HH__ diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index 73b0973f7..5f9583436 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -209,6 +209,11 @@ decode PO default Unknown::unknown() { }}); } + format IntImmTrapOp { + 3: twi({{ Ra_sw }}); + 2: tdi({{ Ra }}); + } + 4: decode VA_XO { // Arithmetic instructions that use source registers Ra, Rb and Rc, @@ -710,6 +715,11 @@ decode PO default Unknown::unknown() { true); } + format IntTrapOp { + 4: tw({{ Ra_sw }}, {{ Rb_sw }}); + 68: td({{ Ra }}, {{ Rb }}); + } + format StoreIndexOp { 663: stfsx({{ Mem_sf = Fs_sf; }}); 727: stfdx({{ Mem_df = Fs; }}); diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa index 6f8d03861..3ab9ad923 100644 --- a/src/arch/power/isa/formats/integer.isa +++ b/src/arch/power/isa/formats/integer.isa @@ -583,3 +583,34 @@ def format IntConcatRotateOp(code, inst_flags = []) {{ decoder_output += decoder_output_rc1 exec_output += exec_output_rc1 }}; + + +def format IntTrapOp(src1, src2, inst_flags = []) {{ + + # Add code to set up variables and check for a trap + code = 'int64_t src1 = ' + src1 + ';\n' + code += 'int64_t src2 = ' + src2 + ';\n' + code += 'if (checkTrap(src1, src2)) {\n' + code += ' panic("trap generated at %#x", xc->pcState().pc());\n' + code += ' return std::make_shared();\n' + code += '}\n' + + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntTrapOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +def format IntImmTrapOp(src, inst_flags = []) {{ + + # Add code to set up variables and check for a trap + code = 'int64_t src = ' + src + ';\n' + code += 'if (checkTrap(src, this->simm)) {\n' + code += ' panic("trap generated at %#x", xc->pcState().pc());\n' + code += ' return std::make_shared();\n' + code += '}\n' + + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmTrapOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; diff --git a/src/arch/power/types.hh b/src/arch/power/types.hh index 74cd7b43a..a76e6e29f 100644 --- a/src/arch/power/types.hh +++ b/src/arch/power/types.hh @@ -87,6 +87,9 @@ BitUnion32(ExtMachInst) Bitfield<20, 16> ba; Bitfield<15, 11> bb; + // Trap instruction fields + Bitfield<25, 21> to; + // FXM field for mtcrf instruction Bitfield<19, 12> fxm; EndBitUnion(ExtMachInst) -- 2.30.2