Sandipan Das has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/40934 )
Change subject: arch-power: Add trap instructions
......................................................................
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 <[email protected]>
---
M src/arch/power/faults.hh
M src/arch/power/insts/integer.cc
M src/arch/power/insts/integer.hh
M src/arch/power/isa/decoder.isa
M src/arch/power/isa/formats/integer.isa
M src/arch/power/types.hh
6 files changed, 229 insertions(+), 0 deletions(-)
diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh
index e20ef8e..6932271 100644
--- a/src/arch/power/faults.hh
+++ b/src/arch/power/faults.hh
@@ -82,6 +82,15 @@
}
};
+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 0631749..115b867 100644
--- a/src/arch/power/insts/integer.cc
+++ b/src/arch/power/insts/integer.cc
@@ -878,3 +878,103 @@
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 59566e8..a2692e2 100644
--- a/src/arch/power/insts/integer.hh
+++ b/src/arch/power/insts/integer.hh
@@ -733,6 +733,82 @@
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 73b0973..5f95834 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -209,6 +209,11 @@
}});
}
+ 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 @@
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 6f8d038..3ab9ad9 100644
--- a/src/arch/power/isa/formats/integer.isa
+++ b/src/arch/power/isa/formats/integer.isa
@@ -583,3 +583,34 @@
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)
+}};
diff --git a/src/arch/power/types.hh b/src/arch/power/types.hh
index 74cd7b4..a76e6e2 100644
--- a/src/arch/power/types.hh
+++ b/src/arch/power/types.hh
@@ -87,6 +87,9 @@
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)
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/40934
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I029147ef643c2ee6794426e5e90af4d75f22e92e
Gerrit-Change-Number: 40934
Gerrit-PatchSet: 1
Gerrit-Owner: Sandipan Das <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s