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 | |
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')
-rw-r--r-- | src/arch/sparc/insts/SConscript | 35 | ||||
-rw-r--r-- | src/arch/sparc/insts/static_inst.cc | 372 | ||||
-rw-r--r-- | src/arch/sparc/insts/static_inst.hh | 112 | ||||
-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 |
6 files changed, 598 insertions, 517 deletions
diff --git a/src/arch/sparc/insts/SConscript b/src/arch/sparc/insts/SConscript new file mode 100644 index 000000000..94996f6b2 --- /dev/null +++ b/src/arch/sparc/insts/SConscript @@ -0,0 +1,35 @@ +# -*- mode:python -*- + +# Copyright (c) 2004-2005 The Regents of The University of Michigan +# All rights reserved. +# +# 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 +# Steve Reinhardt + +Import('*') + +if env['TARGET_ISA'] == 'sparc': + Source('static_inst.cc') 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); +} + +} diff --git a/src/arch/sparc/insts/static_inst.hh b/src/arch/sparc/insts/static_inst.hh new file mode 100644 index 000000000..cc5a60225 --- /dev/null +++ b/src/arch/sparc/insts/static_inst.hh @@ -0,0 +1,112 @@ +/* + * 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 + */ +#ifndef __ARCH_SPARC_INSTS_STATIC_INST_HH__ +#define __ARCH_SPARC_INSTS_STATIC_INST_HH__ + +#include <cstdint> + +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "cpu/static_inst.hh" + +namespace SparcISA +{ + +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 +}; + +extern const char *CondTestAbbrev[]; + +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 +}; + +/** + * Base class for all SPARC static instructions. + */ +class SparcStaticInst : public StaticInst +{ + protected: + using StaticInst::StaticInst; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + static void printMnemonic(std::ostream &os, const char *mnemonic); + static void printReg(std::ostream &os, RegId reg); + + 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(PCState &pcState) const; + + static bool passesFpCondition(uint32_t fcc, uint32_t condition); + static bool passesCondition(uint32_t codes, uint32_t condition); +}; + +} + +#endif //__ARCH_SPARC_INSTS_STATIC_INST_HH__ 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" |