From 432fa0aad6092d6a9252f6a9c83c8b36509c1341 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 8 Nov 2010 13:58:24 -0600 Subject: ARM: Add support for M5 ops in the ARM ISA --- src/arch/arm/isa/decoder/arm.isa | 8 +- src/arch/arm/isa/decoder/thumb.isa | 3 +- src/arch/arm/isa/formats/formats.isa | 3 + src/arch/arm/isa/formats/m5ops.isa | 78 ++++++++++ src/arch/arm/isa/includes.isa | 1 + src/arch/arm/isa/insts/insts.isa | 3 + src/arch/arm/isa/insts/m5ops.isa | 275 +++++++++++++++++++++++++++++++++++ src/arch/arm/isa/operands.isa | 3 + src/arch/arm/types.hh | 2 +- 9 files changed, 373 insertions(+), 3 deletions(-) create mode 100644 src/arch/arm/isa/formats/m5ops.isa create mode 100644 src/arch/arm/isa/insts/m5ops.isa (limited to 'src/arch') diff --git a/src/arch/arm/isa/decoder/arm.isa b/src/arch/arm/isa/decoder/arm.isa index 3f43b23e1..9ab95b82f 100644 --- a/src/arch/arm/isa/decoder/arm.isa +++ b/src/arch/arm/isa/decoder/arm.isa @@ -90,7 +90,12 @@ format DataOp { 0x0: ArmParallelAddSubtract::armParallelAddSubtract(); 0x1: ArmPackUnpackSatReverse::armPackUnpackSatReverse(); 0x2: ArmSignedMultiplies::armSignedMultiplies(); - 0x3: ArmMiscMedia::armMiscMedia(); + 0x3: decode MEDIA_OPCODE { + 0x1F: decode OPC2 { + default: ArmMiscMedia::armMiscMedia(); + } + default: ArmMiscMedia::armMiscMedia(); + } } } 0x4: ArmMacroMem::armMacroMem(); @@ -107,6 +112,7 @@ format DataOp { 0xa, 0xb: VfpData::vfpData(); } // CPNUM 1: decode CPNUM { // 27-24=1110,4 ==1 + 0x1: M5ops::m5ops(); 0xa, 0xb: ShortFpTransfer::shortFpTransfer(); 0xf: McrMrc15::mcrMrc15(); } // CPNUM (OP4 == 1) diff --git a/src/arch/arm/isa/decoder/thumb.isa b/src/arch/arm/isa/decoder/thumb.isa index d0f5b8646..f144e3003 100644 --- a/src/arch/arm/isa/decoder/thumb.isa +++ b/src/arch/arm/isa/decoder/thumb.isa @@ -84,6 +84,7 @@ decode BIGTHUMB { default: WarnUnimpl::cdp(); // cdp2 } 0x1: decode LTCOPROC { + 0x1: M5ops::m5ops(); 0xa, 0xb: ShortFpTransfer::shortFpTransfer(); 0xf: McrMrc15::mcrMrc15(); } @@ -125,7 +126,6 @@ decode BIGTHUMB { 0x0: LoadByteMemoryHints::loadByteMemoryHints(); 0x1: LoadHalfwordMemoryHints::loadHalfwordMemoryHints(); 0x2: Thumb32LoadWord::thumb32LoadWord(); - 0x3: Unknown::undefined(); } } 0x1: decode HTOPCODE_8_7 { @@ -140,6 +140,7 @@ decode BIGTHUMB { default: WarnUnimpl::cdp(); // cdp2 } 0x1: decode LTCOPROC { + 0x1: M5ops::m5ops(); 0xa, 0xb: ShortFpTransfer::shortFpTransfer(); 0xf: McrMrc15::mcrMrc15(); } diff --git a/src/arch/arm/isa/formats/formats.isa b/src/arch/arm/isa/formats/formats.isa index a42a33365..90144c101 100644 --- a/src/arch/arm/isa/formats/formats.isa +++ b/src/arch/arm/isa/formats/formats.isa @@ -79,3 +79,6 @@ //Unconditional instructions ##include "uncond.isa" + +//M5 Psuedo-ops +##include "m5ops.isa" diff --git a/src/arch/arm/isa/formats/m5ops.isa b/src/arch/arm/isa/formats/m5ops.isa new file mode 100644 index 000000000..2f5fe2c3a --- /dev/null +++ b/src/arch/arm/isa/formats/m5ops.isa @@ -0,0 +1,78 @@ +// +// Copyright (c) 2010 ARM Limited +// All rights reserved +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// 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: Gene Wu +/// + +def format M5ops() {{ + decode_block = ''' + { + const uint32_t m5func = bits(machInst, 23, 16); + switch(m5func) { +#if FULL_SYSTEM + case 0x00: return new Arm(machInst); + case 0x01: return new Quiesce(machInst); + case 0x02: return new QuiesceNs(machInst); + case 0x03: return new QuiesceCycles(machInst); + case 0x04: return new QuiesceTime(machInst); +#endif + case 0x07: return new Rpns(machInst); + case 0x09: return new WakeCPU(machInst); + case 0x10: return new Deprecated_ivlb(machInst); + case 0x11: return new Deprecated_ivle(machInst); + case 0x20: return new Deprecated_exit (machInst); + case 0x21: return new M5exit(machInst); +#if FULL_SYSTEM + case 0x31: return new Loadsymbol(machInst); + case 0x30: return new Initparam(machInst); +#endif + case 0x40: return new Resetstats(machInst); + case 0x41: return new Dumpstats(machInst); + case 0x42: return new Dumpresetstats(machInst); + case 0x43: return new M5checkpoint(machInst); +#if FULL_SYSTEM + case 0x50: return new M5readfile(machInst); +#endif + case 0x51: return new M5break(machInst); + case 0x52: return new M5switchcpu(machInst); +#if FULL_SYSTEM + case 0x53: return new M5addsymbol(machInst); +#endif + case 0x54: return new M5panic(machInst); + } + } + ''' +}}; diff --git a/src/arch/arm/isa/includes.isa b/src/arch/arm/isa/includes.isa index 111552c78..5840cc9b2 100644 --- a/src/arch/arm/isa/includes.isa +++ b/src/arch/arm/isa/includes.isa @@ -86,6 +86,7 @@ output exec {{ #include #endif +#include "base/cp_annotate.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" #include "sim/sim_exit.hh" diff --git a/src/arch/arm/isa/insts/insts.isa b/src/arch/arm/isa/insts/insts.isa index 9c51f3cf0..c01e87df8 100644 --- a/src/arch/arm/isa/insts/insts.isa +++ b/src/arch/arm/isa/insts/insts.isa @@ -75,3 +75,6 @@ //Neon ##include "neon.isa" + +//m5 Psuedo-ops +##include "m5ops.isa" diff --git a/src/arch/arm/isa/insts/m5ops.isa b/src/arch/arm/isa/insts/m5ops.isa new file mode 100644 index 000000000..da3609bbc --- /dev/null +++ b/src/arch/arm/isa/insts/m5ops.isa @@ -0,0 +1,275 @@ +// +// Copyright (c) 2010 ARM Limited +// All rights reserved +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// 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: Gene Wu + + +let {{ + header_output = "" + decoder_output = "" + exec_output = "" + + armCode = ''' +#if FULL_SYSTEM + PseudoInst::arm(xc->tcBase()); +#endif + ''' + armIop = InstObjParams("arm", "Arm", "PredOp", + { "code": armCode, + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(armIop) + decoder_output += BasicConstructor.subst(armIop) + exec_output += PredOpExecute.subst(armIop) + + quiesceCode = ''' +#if FULL_SYSTEM + PseudoInst::quiesceNs(xc->tcBase(), R0); +#endif + ''' + quiesceIop = InstObjParams("quiesce", "Quiesce", "PredOp", + { "code": quiesceCode, + "predicate_test": predicateTest }, + ["IsNonSpeculative", "IsQuiesce"]) + header_output += BasicDeclare.subst(quiesceIop) + decoder_output += BasicConstructor.subst(quiesceIop) + exec_output += PredOpExecute.subst(quiesceIop) + + quiesceNsCode = ''' +#if FULL_SYSTEM + PseudoInst::quiesceNs(xc->tcBase(), R0); +#endif + ''' + + quiesceNsIop = InstObjParams("quiesceNs", "QuiesceNs", "PredOp", + { "code": quiesceNsCode, + "predicate_test": predicateTest }, + ["IsNonSpeculative", "IsQuiesce"]) + header_output += BasicDeclare.subst(quiesceNsIop) + decoder_output += BasicConstructor.subst(quiesceNsIop) + exec_output += PredOpExecute.subst(quiesceNsIop) + + quiesceCyclesCode = ''' +#if FULL_SYSTEM + PseudoInst::quiesceCycles(xc->tcBase(), R0); +#endif + ''' + + quiesceCyclesIop = InstObjParams("quiesceCycles", "QuiesceCycles", "PredOp", + { "code": quiesceCyclesCode, + "predicate_test": predicateTest }, + ["IsNonSpeculative", "IsQuiesce", "IsUnverifiable"]) + header_output += BasicDeclare.subst(quiesceCyclesIop) + decoder_output += BasicConstructor.subst(quiesceCyclesIop) + exec_output += PredOpExecute.subst(quiesceCyclesIop) + + quiesceTimeCode = ''' +#if FULL_SYSTEM + R0 = PseudoInst::quiesceTime(xc->tcBase()); +#endif + ''' + + quiesceTimeIop = InstObjParams("quiesceTime", "QuiesceTime", "PredOp", + { "code": quiesceTimeCode, + "predicate_test": predicateTest }, + ["IsNonSpeculative", "IsUnverifiable"]) + header_output += BasicDeclare.subst(quiesceTimeIop) + decoder_output += BasicConstructor.subst(quiesceTimeIop) + exec_output += PredOpExecute.subst(quiesceTimeIop) + + rpnsIop = InstObjParams("rpns", "Rpns", "PredOp", + { "code": "R0 = PseudoInst::rpns(xc->tcBase());", + "predicate_test": predicateTest }, + ["IsNonSpeculative", "IsUnverifiable"]) + header_output += BasicDeclare.subst(rpnsIop) + decoder_output += BasicConstructor.subst(rpnsIop) + exec_output += PredOpExecute.subst(rpnsIop) + + wakeCPUIop = InstObjParams("wakeCPU", "WakeCPU", "PredOp", + { "code": "PseudoInst::wakeCPU(xc->tcBase(), R0);", + "predicate_test": predicateTest }, + ["IsNonSpeculative", "IsUnverifiable"]) + header_output += BasicDeclare.subst(wakeCPUIop) + decoder_output += BasicConstructor.subst(wakeCPUIop) + exec_output += PredOpExecute.subst(wakeCPUIop) + + deprecated_ivlbIop = InstObjParams("deprecated_ivlb", "Deprecated_ivlb", "PredOp", + { "code": '''warn_once("Obsolete M5 ivlb instruction encountered.\\n");''', + "predicate_test": predicateTest }) + header_output += BasicDeclare.subst(deprecated_ivlbIop) + decoder_output += BasicConstructor.subst(deprecated_ivlbIop) + exec_output += PredOpExecute.subst(deprecated_ivlbIop) + + deprecated_ivleIop = InstObjParams("deprecated_ivle", "Deprecated_ivle", "PredOp", + { "code": '''warn_once("Obsolete M5 ivle instruction encountered.\\n");''', + "predicate_test": predicateTest }) + header_output += BasicDeclare.subst(deprecated_ivleIop) + decoder_output += BasicConstructor.subst(deprecated_ivleIop) + exec_output += PredOpExecute.subst(deprecated_ivleIop) + + deprecated_exit_code = ''' + warn_once("Obsolete M5 exit instruction encountered.\\n"); + PseudoInst::m5exit(xc->tcBase(), 0); + ''' + + deprecated_exitIop = InstObjParams("deprecated_exit", "Deprecated_exit", "PredOp", + { "code": deprecated_exit_code, + "predicate_test": predicateTest }, + ["No_OpClass", "IsNonSpeculative"]) + header_output += BasicDeclare.subst(deprecated_exitIop) + decoder_output += BasicConstructor.subst(deprecated_exitIop) + exec_output += PredOpExecute.subst(deprecated_exitIop) + + m5exitIop = InstObjParams("m5exit", "M5exit", "PredOp", + { "code": "PseudoInst::m5exit(xc->tcBase(), R0)", + "predicate_test": predicateTest }, + ["No_OpClass", "IsNonSpeculative"]) + header_output += BasicDeclare.subst(m5exitIop) + decoder_output += BasicConstructor.subst(m5exitIop) + exec_output += PredOpExecute.subst(m5exitIop) + + loadsymbolCode = ''' +#if FULL_SYSTEM + PseudoInst::loadsymbol(xc->tcBase()); +#endif + ''' + + loadsymbolIop = InstObjParams("loadsymbol", "Loadsymbol", "PredOp", + { "code": loadsymbolCode, + "predicate_test": predicateTest }, + ["No_OpClass", "IsNonSpeculative"]) + header_output += BasicDeclare.subst(loadsymbolIop) + decoder_output += BasicConstructor.subst(loadsymbolIop) + exec_output += PredOpExecute.subst(loadsymbolIop) + + initparamCode = ''' +#if FULL_SYSTEM + Rt = xc->tcBase()->getCpuPtr()->system->init_param; +#endif + ''' + + initparamIop = InstObjParams("initparam", "Initparam", "PredOp", + { "code": initparamCode, + "predicate_test": predicateTest }) + header_output += BasicDeclare.subst(initparamIop) + decoder_output += BasicConstructor.subst(initparamIop) + exec_output += PredOpExecute.subst(initparamIop) + + resetstatsIop = InstObjParams("resetstats", "Resetstats", "PredOp", + { "code": "PseudoInst::resetstats(xc->tcBase(), R0, R1);", + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(resetstatsIop) + decoder_output += BasicConstructor.subst(resetstatsIop) + exec_output += PredOpExecute.subst(resetstatsIop) + + dumpstatsIop = InstObjParams("dumpstats", "Dumpstats", "PredOp", + { "code": "PseudoInst::dumpstats(xc->tcBase(), R0, R1);", + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(dumpstatsIop) + decoder_output += BasicConstructor.subst(dumpstatsIop) + exec_output += PredOpExecute.subst(dumpstatsIop) + + dumpresetstatsIop = InstObjParams("dumpresetstats", "Dumpresetstats", "PredOp", + { "code": "PseudoInst::dumpresetstats(xc->tcBase(), R0, R1);", + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(dumpresetstatsIop) + decoder_output += BasicConstructor.subst(dumpresetstatsIop) + exec_output += PredOpExecute.subst(dumpresetstatsIop) + + m5checkpointIop = InstObjParams("m5checkpoint", "M5checkpoint", "PredOp", + { "code": "PseudoInst::m5checkpoint(xc->tcBase(), R0, R1);", + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(m5checkpointIop) + decoder_output += BasicConstructor.subst(m5checkpointIop) + exec_output += PredOpExecute.subst(m5checkpointIop) + + m5readfileCode = ''' +#if FULL_SYSTEM + R0 = PseudoInst::readfile(xc->tcBase(), R0, R1, R2); +#endif + ''' + m5readfileIop = InstObjParams("m5readfile", "M5readfile", "PredOp", + { "code": m5readfileCode, + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(m5readfileIop) + decoder_output += BasicConstructor.subst(m5readfileIop) + exec_output += PredOpExecute.subst(m5readfileIop) + + m5breakIop = InstObjParams("m5break", "M5break", "PredOp", + { "code": "PseudoInst::debugbreak(xc->tcBase());", + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(m5breakIop) + decoder_output += BasicConstructor.subst(m5breakIop) + exec_output += PredOpExecute.subst(m5breakIop) + + m5switchcpuIop = InstObjParams("m5switchcpu", "M5switchcpu", "PredOp", + { "code": "PseudoInst::switchcpu(xc->tcBase());", + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(m5switchcpuIop) + decoder_output += BasicConstructor.subst(m5switchcpuIop) + exec_output += PredOpExecute.subst(m5switchcpuIop) + + m5addsymbolCode = ''' +#if FULL_SYSTEM + PseudoInst::addsymbol(xc->tcBase(), R0, R1); +#endif + ''' + m5addsymbolIop = InstObjParams("m5addsymbol", "M5addsymbol", "PredOp", + { "code": m5addsymbolCode, + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(m5addsymbolIop) + decoder_output += BasicConstructor.subst(m5addsymbolIop) + exec_output += PredOpExecute.subst(m5addsymbolIop) + + m5panicCode = '''panic("M5 panic instruction called at pc=%#x.", + xc->pcState().pc());''' + m5panicIop = InstObjParams("m5panic", "M5panic", "PredOp", + { "code": m5panicCode, + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(m5panicIop) + decoder_output += BasicConstructor.subst(m5panicIop) + exec_output += PredOpExecute.subst(m5panicIop) + +}}; diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 8e856e74d..3c32d98d1 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -170,6 +170,9 @@ def operands {{ 'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 3, maybePCRead, maybePCWrite), 'R7': ('IntReg', 'uw', '7', 'IsInteger', 3), 'R0': ('IntReg', 'uw', '0', 'IsInteger', 3), + 'R1': ('IntReg', 'uw', '0', 'IsInteger', 3), + 'R2': ('IntReg', 'uw', '1', 'IsInteger', 3), + 'Rt' : ('IntReg', 'uw', 'RT', 'IsInteger', 3, maybePCRead, maybePCWrite), 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 3), 'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', None, 3), diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 57f34e3c2..a679686c7 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -141,7 +141,7 @@ namespace ArmISA Bitfield<2, 0> fpImm; Bitfield<24, 20> punwl; - Bitfield<7, 0> m5Func; + Bitfield<15, 8> m5Func; // 16 bit thumb bitfields Bitfield<15, 13> topcode15_13; -- cgit v1.2.3