diff options
author | Gabe Black <gabeblack@google.com> | 2017-11-05 15:41:59 -0800 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2017-11-20 07:49:48 +0000 |
commit | d626f4f7aaa4d2c9f7ae1afc35577fa025b4de38 (patch) | |
tree | 0249e5f16b3603bb67a6bc3b09a4f4682cde7df2 /src/arch/sparc/isa | |
parent | 205add5769e3978341cb9aa71d563dfb048e1f13 (diff) | |
download | gem5-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.isa | 439 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/basic.isa | 156 | ||||
-rw-r--r-- | src/arch/sparc/isa/includes.isa | 1 |
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" |