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/insts/static_inst.cc | |
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/insts/static_inst.cc')
-rw-r--r-- | src/arch/sparc/insts/static_inst.cc | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/src/arch/sparc/insts/static_inst.cc b/src/arch/sparc/insts/static_inst.cc new file mode 100644 index 000000000..a1f5e60d7 --- /dev/null +++ b/src/arch/sparc/insts/static_inst.cc @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2006-2007 The Regents of The University of Michigan + * All rights reserved + * Copyright 2017 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/sparc/insts/static_inst.hh" + +namespace SparcISA +{ + +const char *CondTestAbbrev[] = +{ + [Never] = "nev", + [Equal] = "e", + [LessOrEqual] = "le", + [Less] = "l", + [LessOrEqualUnsigned] = "leu", + [CarrySet] = "c", + [Negative] = "n", + [OverflowSet] = "o", + [Always] = "a", + [NotEqual] = "ne", + [Greater] = "g", + [GreaterOrEqual] = "ge", + [GreaterUnsigned] = "gu", + [CarryClear] = "cc", + [Positive] = "p", + [OverflowClear] = "oc" +}; + +void +SparcStaticInst::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 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 +SparcStaticInst::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 +SparcStaticInst::passesCondition(uint32_t codes, uint32_t condition) +{ + BitUnion32(CondCodes) + Bitfield<0> c; + Bitfield<1> v; + Bitfield<2> z; + Bitfield<3> n; + EndBitUnion(CondCodes) + CondCodes condCodes = codes; + + 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); +} + +} |