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 <sandipan@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40934
Reviewed-by: Boris Shingarov <shingarov@labware.com>
Maintainer: Boris Shingarov <shingarov@labware.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Sandipan Das
2021-02-06 17:22:15 +05:30
committed by Boris Shingarov
parent 84837422d8
commit 57181ee613
6 changed files with 225 additions and 0 deletions

View File

@@ -82,6 +82,16 @@ class AlignmentFault : public PowerFault
}
};
class TrapFault : public PowerFault
{
public:
TrapFault()
: PowerFault("Trap")
{
}
};
} // namespace PowerISA
#endif // __ARCH_POWER_FAULTS_HH__

View File

@@ -820,3 +820,99 @@ 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 == "tw" &&
(srcRegIdx(0).index() == 0) && (srcRegIdx(1).index() == 0)) {
myMnemonic = "trap";
printSrcs = false;
} else {
ext = suffix();
if (!ext.empty() &&
(myMnemonic == "tw" || myMnemonic == "td")) {
myMnemonic += ext;
} else {
printCond = true;
}
}
ccprintf(ss, "%-10s ", myMnemonic);
// Print the trap condition
if (printCond)
ss << (int) to;
// 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 == "twi") {
myMnemonic = "tw" + ext + "i";
} else if (myMnemonic == "tdi") {
myMnemonic = "td" + ext + "i";
} else {
printCond = true;
}
} else {
printCond = true;
}
ccprintf(ss, "%-10s ", myMnemonic);
// Print the trap condition
if (printCond)
ss << (int) to;
// Print the source registers
if (_numSrcRegs > 0) {
if (printCond)
ss << ", ";
printReg(ss, srcRegIdx(0));
}
// Print the immediate value
ss << ", " << si;
return ss.str();
}

View File

@@ -713,6 +713,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 to;
/// Constructor
IntTrapOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: IntOp(mnem, _machInst, __opClass),
to(machInst.to)
{
}
inline bool
checkTrap(int64_t a, int64_t b) const
{
if (((to & 0x10) && (a < b)) ||
((to & 0x08) && (a > b)) ||
((to & 0x04) && (a == b)) ||
((to & 0x02) && ((uint64_t)a < (uint64_t)b)) ||
((to & 0x01) && ((uint64_t)a > (uint64_t)b))) {
return true;
}
return false;
}
inline std::string
suffix() const
{
std::string str;
switch (to) {
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:
int32_t si;
/// Constructor
IntImmTrapOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: IntTrapOp(mnem, _machInst, __opClass),
si(sext<16>(machInst.si))
{
}
std::string generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const override;
};
} // namespace PowerISA
#endif //__ARCH_POWER_INSTS_INTEGER_HH__

View File

@@ -36,6 +36,11 @@
//
decode PO default Unknown::unknown() {
format IntImmTrapOp {
2: tdi({{ Ra }});
3: twi({{ Ra_sw }});
}
4: decode VA_XO {
// Arithmetic instructions that use source registers Ra, Rb and Rc,
@@ -325,6 +330,8 @@ decode PO default Unknown::unknown() {
cr = makeCRFieldSigned((int32_t)Ra, (int32_t)Rb, xer.so);
}});
4: IntTrapOp::tw({{ Ra_sw }}, {{ Rb_sw }});
format LoadIndexOp {
20: lwarx({{
Rt = Mem_uw;
@@ -379,6 +386,8 @@ decode PO default Unknown::unknown() {
60: andc({{ Ra = Rs & ~Rb; }}, true);
}
68: IntTrapOp::td({{ Ra }}, {{ Rb }});
format LoadIndexOp {
84: ldarx({{
Rt = Mem_ud;

View File

@@ -545,3 +545,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<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, si)) {\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)
}};

View File

@@ -88,6 +88,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)