summaryrefslogtreecommitdiff
path: root/src/arch/sparc/isa
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2017-11-05 15:41:59 -0800
committerGabe Black <gabeblack@google.com>2017-11-20 07:49:48 +0000
commitd626f4f7aaa4d2c9f7ae1afc35577fa025b4de38 (patch)
tree0249e5f16b3603bb67a6bc3b09a4f4682cde7df2 /src/arch/sparc/isa
parent205add5769e3978341cb9aa71d563dfb048e1f13 (diff)
downloadgem5-d626f4f7aaa4d2c9f7ae1afc35577fa025b4de38.tar.xz
sparc: Pull StaticInst base classes out of the ISA description.
Also, do some minor refactoring to use a BitUnion to pull apart condition codes, etc. Change-Id: I0c88878b07a731d0c0fe30f264f53dd795db99ae Reviewed-on: https://gem5-review.googlesource.com/5421 Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/arch/sparc/isa')
-rw-r--r--src/arch/sparc/isa/base.isa439
-rw-r--r--src/arch/sparc/isa/formats/basic.isa156
-rw-r--r--src/arch/sparc/isa/includes.isa1
3 files changed, 79 insertions, 517 deletions
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index 5d54d0ea9..8bcac0b05 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -28,128 +28,6 @@
// Gabe Black
// Steve Reinhardt
-////////////////////////////////////////////////////////////////////
-//
-// Base class for sparc instructions, and some support functions
-//
-
-output header {{
-
- union CondCodes
- {
- struct
- {
- uint8_t c:1;
- uint8_t v:1;
- uint8_t z:1;
- uint8_t n:1;
- };
- uint32_t bits;
- };
-
- enum CondTest
- {
- Always=0x8,
- Never=0x0,
- NotEqual=0x9,
- Equal=0x1,
- Greater=0xA,
- LessOrEqual=0x2,
- GreaterOrEqual=0xB,
- Less=0x3,
- GreaterUnsigned=0xC,
- LessOrEqualUnsigned=0x4,
- CarryClear=0xD,
- CarrySet=0x5,
- Positive=0xE,
- Negative=0x6,
- OverflowClear=0xF,
- OverflowSet=0x7
- };
-
- enum FpCondTest
- {
- FAlways=0x8,
- FNever=0x0,
- FUnordered=0x7,
- FGreater=0x6,
- FUnorderedOrGreater=0x5,
- FLess=0x4,
- FUnorderedOrLess=0x3,
- FLessOrGreater=0x2,
- FNotEqual=0x1,
- FEqual=0x9,
- FUnorderedOrEqual=0xA,
- FGreaterOrEqual=0xB,
- FUnorderedOrGreaterOrEqual=0xC,
- FLessOrEqual=0xD,
- FUnorderedOrLessOrEqual=0xE,
- FOrdered=0xF
- };
-
- extern const char *CondTestAbbrev[];
-
- /**
- * Base class for all SPARC static instructions.
- */
- class SparcStaticInst : public StaticInst
- {
- protected:
- // Constructor.
- SparcStaticInst(const char *mnem,
- ExtMachInst _machInst, OpClass __opClass)
- : StaticInst(mnem, _machInst, __opClass)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
-
- void printReg(std::ostream &os, RegId reg) const;
- void printSrcReg(std::ostream &os, int reg) const;
- void printDestReg(std::ostream &os, int reg) const;
-
- void printRegArray(std::ostream &os,
- const RegId indexArray[], int num) const;
-
- void advancePC(SparcISA::PCState &pcState) const;
- };
-
- bool passesFpCondition(uint32_t fcc, uint32_t condition);
-
- bool passesCondition(uint32_t codes, uint32_t condition);
-
- inline int64_t
- sign_ext(uint64_t data, int origWidth)
- {
- int shiftAmount = 64 - origWidth;
- return (((int64_t)data) << shiftAmount) >> shiftAmount;
- }
-}};
-
-output decoder {{
-
- const char *CondTestAbbrev[] =
- {
- "nev", // Never
- "e", // Equal
- "le", // Less or Equal
- "l", // Less
- "leu", // Less or Equal Unsigned
- "c", // Carry set
- "n", // Negative
- "o", // Overflow set
- "a", // Always
- "ne", // Not Equal
- "g", // Greater
- "ge", // Greater or Equal
- "gu", // Greater Unsigned
- "cc", // Carry clear
- "p", // Positive
- "oc" // Overflow Clear
- };
-}};
-
def template ROrImmDecode {{
{
return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
@@ -243,322 +121,6 @@ let {{
return (True, code, imm_code, rString, iString)
}};
-output decoder {{
-
- inline void printMnemonic(std::ostream &os, const char * mnemonic)
- {
- ccprintf(os, "\t%s ", mnemonic);
- }
-
- void SparcStaticInst::printRegArray(std::ostream &os,
- const RegId indexArray[], int num) const
- {
- if (num <= 0)
- return;
- printReg(os, indexArray[0]);
- for (int x = 1; x < num; x++) {
- os << ", ";
- printReg(os, indexArray[x]);
- }
- }
-
- void
- SparcStaticInst::advancePC(SparcISA::PCState &pcState) const
- {
- pcState.advance();
- }
-
- void
- SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
- {
- if (_numSrcRegs > reg)
- printReg(os, _srcRegIdx[reg]);
- }
-
- void
- SparcStaticInst::printDestReg(std::ostream &os, int reg) const
- {
- if (_numDestRegs > reg)
- printReg(os, _destRegIdx[reg]);
- }
-
- void
- SparcStaticInst::printReg(std::ostream &os, RegId reg) const
- {
- const int MaxGlobal = 8;
- const int MaxOutput = 16;
- const int MaxLocal = 24;
- const int MaxInput = 32;
- const int MaxMicroReg = 40;
- RegIndex reg_idx = reg.index();
- if (reg.isIntReg()) {
- // If we used a register from the next or previous window,
- // take out the offset.
- while (reg_idx >= MaxMicroReg)
- reg_idx -= MaxMicroReg;
- if (reg_idx == FramePointerReg)
- ccprintf(os, "%%fp");
- else if (reg_idx == StackPointerReg)
- ccprintf(os, "%%sp");
- else if (reg_idx < MaxGlobal)
- ccprintf(os, "%%g%d", reg_idx);
- else if (reg_idx < MaxOutput)
- ccprintf(os, "%%o%d", reg_idx - MaxGlobal);
- else if (reg_idx < MaxLocal)
- ccprintf(os, "%%l%d", reg_idx - MaxOutput);
- else if (reg_idx < MaxInput)
- ccprintf(os, "%%i%d", reg_idx - MaxLocal);
- else if (reg_idx < MaxMicroReg)
- ccprintf(os, "%%u%d", reg_idx - MaxInput);
- // The fake int regs that are really control regs
- else {
- switch (reg_idx - MaxMicroReg) {
- case 1:
- ccprintf(os, "%%y");
- break;
- case 2:
- ccprintf(os, "%%ccr");
- break;
- case 3:
- ccprintf(os, "%%cansave");
- break;
- case 4:
- ccprintf(os, "%%canrestore");
- break;
- case 5:
- ccprintf(os, "%%cleanwin");
- break;
- case 6:
- ccprintf(os, "%%otherwin");
- break;
- case 7:
- ccprintf(os, "%%wstate");
- break;
- }
- }
- } else if (reg.isFloatReg()) {
- ccprintf(os, "%%f%d", reg_idx);
- } else {
- switch (reg_idx) {
- case MISCREG_ASI:
- ccprintf(os, "%%asi");
- break;
- case MISCREG_FPRS:
- ccprintf(os, "%%fprs");
- break;
- case MISCREG_PCR:
- ccprintf(os, "%%pcr");
- break;
- case MISCREG_PIC:
- ccprintf(os, "%%pic");
- break;
- case MISCREG_GSR:
- ccprintf(os, "%%gsr");
- break;
- case MISCREG_SOFTINT:
- ccprintf(os, "%%softint");
- break;
- case MISCREG_SOFTINT_SET:
- ccprintf(os, "%%softint_set");
- break;
- case MISCREG_SOFTINT_CLR:
- ccprintf(os, "%%softint_clr");
- break;
- case MISCREG_TICK_CMPR:
- ccprintf(os, "%%tick_cmpr");
- break;
- case MISCREG_STICK:
- ccprintf(os, "%%stick");
- break;
- case MISCREG_STICK_CMPR:
- ccprintf(os, "%%stick_cmpr");
- break;
- case MISCREG_TPC:
- ccprintf(os, "%%tpc");
- break;
- case MISCREG_TNPC:
- ccprintf(os, "%%tnpc");
- break;
- case MISCREG_TSTATE:
- ccprintf(os, "%%tstate");
- break;
- case MISCREG_TT:
- ccprintf(os, "%%tt");
- break;
- case MISCREG_TICK:
- ccprintf(os, "%%tick");
- break;
- case MISCREG_TBA:
- ccprintf(os, "%%tba");
- break;
- case MISCREG_PSTATE:
- ccprintf(os, "%%pstate");
- break;
- case MISCREG_TL:
- ccprintf(os, "%%tl");
- break;
- case MISCREG_PIL:
- ccprintf(os, "%%pil");
- break;
- case MISCREG_CWP:
- ccprintf(os, "%%cwp");
- break;
- case MISCREG_GL:
- ccprintf(os, "%%gl");
- break;
- case MISCREG_HPSTATE:
- ccprintf(os, "%%hpstate");
- break;
- case MISCREG_HTSTATE:
- ccprintf(os, "%%htstate");
- break;
- case MISCREG_HINTP:
- ccprintf(os, "%%hintp");
- break;
- case MISCREG_HTBA:
- ccprintf(os, "%%htba");
- break;
- case MISCREG_HSTICK_CMPR:
- ccprintf(os, "%%hstick_cmpr");
- break;
- case MISCREG_HVER:
- ccprintf(os, "%%hver");
- break;
- case MISCREG_STRAND_STS_REG:
- ccprintf(os, "%%strand_sts_reg");
- break;
- case MISCREG_FSR:
- ccprintf(os, "%%fsr");
- break;
- default:
- ccprintf(os, "%%ctrl%d", reg_idx);
- }
- }
- }
-
- std::string
- SparcStaticInst::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream ss;
-
- printMnemonic(ss, mnemonic);
-
- // just print the first two source regs... if there's
- // a third one, it's a read-modify-write dest (Rc),
- // e.g. for CMOVxx
- if (_numSrcRegs > 0)
- printReg(ss, _srcRegIdx[0]);
- if (_numSrcRegs > 1) {
- ss << ",";
- printReg(ss, _srcRegIdx[1]);
- }
-
- // just print the first dest... if there's a second one,
- // it's generally implicit
- if (_numDestRegs > 0) {
- if (_numSrcRegs > 0)
- ss << ",";
- printReg(ss, _destRegIdx[0]);
- }
-
- return ss.str();
- }
-
- bool
- passesFpCondition(uint32_t fcc, uint32_t condition)
- {
- bool u = (fcc == 3);
- bool g = (fcc == 2);
- bool l = (fcc == 1);
- bool e = (fcc == 0);
- switch (condition) {
- case FAlways:
- return 1;
- case FNever:
- return 0;
- case FUnordered:
- return u;
- case FGreater:
- return g;
- case FUnorderedOrGreater:
- return u || g;
- case FLess:
- return l;
- case FUnorderedOrLess:
- return u || l;
- case FLessOrGreater:
- return l || g;
- case FNotEqual:
- return l || g || u;
- case FEqual:
- return e;
- case FUnorderedOrEqual:
- return u || e;
- case FGreaterOrEqual:
- return g || e;
- case FUnorderedOrGreaterOrEqual:
- return u || g || e;
- case FLessOrEqual:
- return l || e;
- case FUnorderedOrLessOrEqual:
- return u || l || e;
- case FOrdered:
- return e || l || g;
- }
- panic("Tried testing condition nonexistant "
- "condition code %d", condition);
- }
-
- bool
- passesCondition(uint32_t codes, uint32_t condition)
- {
- CondCodes condCodes;
- condCodes.bits = 0;
- condCodes.c = codes & 0x1 ? 1 : 0;
- condCodes.v = codes & 0x2 ? 1 : 0;
- condCodes.z = codes & 0x4 ? 1 : 0;
- condCodes.n = codes & 0x8 ? 1 : 0;
-
- switch (condition) {
- case Always:
- return true;
- case Never:
- return false;
- case NotEqual:
- return !condCodes.z;
- case Equal:
- return condCodes.z;
- case Greater:
- return !(condCodes.z | (condCodes.n ^ condCodes.v));
- case LessOrEqual:
- return condCodes.z | (condCodes.n ^ condCodes.v);
- case GreaterOrEqual:
- return !(condCodes.n ^ condCodes.v);
- case Less:
- return (condCodes.n ^ condCodes.v);
- case GreaterUnsigned:
- return !(condCodes.c | condCodes.z);
- case LessOrEqualUnsigned:
- return (condCodes.c | condCodes.z);
- case CarryClear:
- return !condCodes.c;
- case CarrySet:
- return condCodes.c;
- case Positive:
- return !condCodes.n;
- case Negative:
- return condCodes.n;
- case OverflowClear:
- return !condCodes.v;
- case OverflowSet:
- return condCodes.v;
- }
- panic("Tried testing condition nonexistant "
- "condition code %d", condition);
- }
-}};
-
output exec {{
/// Check "FP enabled" machine status bit. Called when executing any FP
/// instruction.
@@ -578,6 +140,7 @@ output exec {{
return NoFault;
}
}
+
static inline Fault
checkVecEnableFault(ExecContext *xc)
{
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 63f3e4a6c..a6b15388d 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -30,121 +30,119 @@
// Basic instruction class declaration template.
def template BasicDeclare {{
- /**
- * Static instruction class for "%(mnemonic)s".
- */
- class %(class_name)s : public %(base_class)s
- {
- public:
- // Constructor.
- %(class_name)s(ExtMachInst machInst);
- Fault execute(ExecContext *, Trace::InstRecord *) const;
- };
+/**
+ * Static instruction class for "%(mnemonic)s".
+ */
+class %(class_name)s : public %(base_class)s
+{
+ public:
+ // Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ Fault execute(ExecContext *, Trace::InstRecord *) const;
+};
}};
// Basic instruction class declaration template.
def template FpBasicDeclare {{
- /**
- * Static instruction class for "%(mnemonic)s".
- */
- class %(class_name)s : public %(base_class)s
- {
- public:
- // Constructor.
- %(class_name)s(ExtMachInst machInst);
- Fault execute(ExecContext *, Trace::InstRecord *) const;
- Fault doFpOp(ExecContext *,
- Trace::InstRecord *) const M5_NO_INLINE;
- };
+/**
+ * Static instruction class for "%(mnemonic)s".
+ */
+class %(class_name)s : public %(base_class)s
+{
+ public:
+ // Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ Fault execute(ExecContext *, Trace::InstRecord *) const;
+ Fault doFpOp(ExecContext *, Trace::InstRecord *) const M5_NO_INLINE;
+};
}};
// Basic instruction class declaration template.
def template BasicDeclareWithMnemonic {{
- /**
- * Static instruction class for "%(mnemonic)s".
- */
- class %(class_name)s : public %(base_class)s
- {
- public:
- // Constructor.
- %(class_name)s(const char * mnemonic, ExtMachInst machInst);
- Fault execute(ExecContext *, Trace::InstRecord *) const;
- };
+/**
+ * Static instruction class for "%(mnemonic)s".
+ */
+class %(class_name)s : public %(base_class)s
+{
+ public:
+ // Constructor.
+ %(class_name)s(const char *mnemonic, ExtMachInst machInst);
+ Fault execute(ExecContext *, Trace::InstRecord *) const;
+};
}};
// Basic instruction class constructor template.
def template BasicConstructor {{
- %(class_name)s::%(class_name)s(ExtMachInst machInst)
- : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
- {
- %(constructor)s;
- }
+%(class_name)s::%(class_name)s(ExtMachInst machInst) :
+ %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+{
+ %(constructor)s;
+}
}};
// Basic instruction class constructor template.
def template BasicConstructorWithMnemonic {{
- %(class_name)s::%(class_name)s(const char * mnemonic,
- ExtMachInst machInst)
- : %(base_class)s(mnemonic, machInst, %(op_class)s)
- {
- %(constructor)s;
- }
+%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst) :
+ %(base_class)s(mnemonic, machInst, %(op_class)s)
+{
+ %(constructor)s;
+}
}};
// Basic instruction class execute method template.
def template BasicExecute {{
- Fault
- %(class_name)s::execute(ExecContext *xc,
- Trace::InstRecord *traceData) const
- {
- Fault fault = NoFault;
+Fault
+%(class_name)s::execute(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+{
+ Fault fault = NoFault;
- %(fp_enable_check)s;
- %(op_decl)s;
- %(op_rd)s;
- %(code)s;
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
- if (fault == NoFault) {
- %(op_wb)s;
- }
- return fault;
- }
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+ return fault;
+}
}};
def template DoFpOpExecute {{
- Fault
- %(class_name)s::doFpOp(ExecContext *xc,
- Trace::InstRecord *traceData) const
- {
- Fault fault = NoFault;
- %(op_decl)s;
- %(op_rd)s;
- %(fp_code)s;
- if (fault == NoFault) {
- %(op_wb)s;
- }
- return fault;
- }
+Fault
+%(class_name)s::doFpOp(ExecContext *xc, Trace::InstRecord *traceData) const
+{
+ Fault fault = NoFault;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(fp_code)s;
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+ return fault;
+}
}};
// Basic decode template.
def template BasicDecode {{
- return new %(class_name)s(machInst);
+return new %(class_name)s(machInst);
}};
// Basic decode template, passing mnemonic in as string arg to constructor.
def template BasicDecodeWithMnemonic {{
- return new %(class_name)s("%(mnemonic)s", machInst);
+return new %(class_name)s("%(mnemonic)s", machInst);
}};
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
- code = filterDoubles(code)
- iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
+ code = filterDoubles(code)
+ iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+
}};
def format FpBasic(code, *flags) {{
@@ -168,7 +166,7 @@ def format FpBasic(code, *flags) {{
"""
fp_code = filterDoubles(code)
iop = InstObjParams(name, Name, 'SparcStaticInst',
- { "code" : exec_code, "fp_code" : fp_code }, flags)
+ { "code" : exec_code, "fp_code" : fp_code }, flags)
header_output = FpBasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 79c90a50e..4b745f4c0 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -39,6 +39,7 @@ output header {{
#include <sstream>
#include "arch/sparc/faults.hh"
+#include "arch/sparc/insts/static_inst.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/registers.hh"
#include "base/condcodes.hh"