}
};
+class TrapFault : public PowerFault
+{
+ public:
+ TrapFault()
+ : PowerFault("Trap")
+ {
+ }
+};
+
} // namespace PowerISA
#endif // __ARCH_POWER_FAULTS_HH__
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();
+}
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__
}});
}
+ format IntImmTrapOp {
+ 3: twi({{ Ra_sw }});
+ 2: tdi({{ Ra }});
+ }
+
4: decode VA_XO {
// Arithmetic instructions that use source registers Ra, Rb and Rc,
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; }});
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<TrapFault>();\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<TrapFault>();\n'
+ code += '}\n'
+
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntImmTrapOp', code, inst_flags, BasicDecode,
+ BasicConstructor)
+}};
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)