diff --git a/src/arch/alpha/decoder.hh b/src/arch/alpha/decoder.hh index d33722867..522359c28 100644 --- a/src/arch/alpha/decoder.hh +++ b/src/arch/alpha/decoder.hh @@ -39,6 +39,7 @@ namespace AlphaISA { +class ISA; class Decoder { protected: @@ -47,7 +48,7 @@ class Decoder bool instDone; public: - Decoder() : instDone(false) + Decoder(ISA* isa = nullptr) : instDone(false) {} void diff --git a/src/arch/arm/ArmISA.py b/src/arch/arm/ArmISA.py index f5c56cfd5..7ef8afd88 100644 --- a/src/arch/arm/ArmISA.py +++ b/src/arch/arm/ArmISA.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2013 ARM Limited +# Copyright (c) 2012-2013, 2015 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -42,6 +42,9 @@ from m5.SimObject import SimObject from ArmPMU import ArmPMU +# Enum for DecoderFlavour +class DecoderFlavour(Enum): vals = ['Generic'] + class ArmISA(SimObject): type = 'ArmISA' cxx_class = 'ArmISA::ISA' @@ -50,6 +53,7 @@ class ArmISA(SimObject): system = Param.System(Parent.any, "System this ISA object belongs to") pmu = Param.ArmPMU(NULL, "Performance Monitoring Unit") + decoderFlavour = Param.DecoderFlavour('Generic', "Decoder flavour specification") midr = Param.UInt32(0x410fc0f0, "MIDR value") diff --git a/src/arch/arm/decoder.cc b/src/arch/arm/decoder.cc index 23fa89a3f..1502b061f 100644 --- a/src/arch/arm/decoder.cc +++ b/src/arch/arm/decoder.cc @@ -41,6 +41,8 @@ */ #include "arch/arm/decoder.hh" + +#include "arch/arm/isa.hh" #include "arch/arm/isa_traits.hh" #include "arch/arm/utility.hh" #include "base/trace.hh" @@ -51,8 +53,10 @@ namespace ArmISA GenericISA::BasicDecodeCache Decoder::defaultCache; -Decoder::Decoder() - : data(0), fpscrLen(0), fpscrStride(0) +Decoder::Decoder(ISA* isa) + : data(0), fpscrLen(0), fpscrStride(0), decoderFlavour(isa + ? isa->decoderFlavour() + : Enums::Generic) { reset(); } diff --git a/src/arch/arm/decoder.hh b/src/arch/arm/decoder.hh index 757b6d683..f8748ab5e 100644 --- a/src/arch/arm/decoder.hh +++ b/src/arch/arm/decoder.hh @@ -50,10 +50,12 @@ #include "arch/generic/decode_cache.hh" #include "base/types.hh" #include "cpu/static_inst.hh" +#include "enums/DecoderFlavour.hh" namespace ArmISA { +class ISA; class Decoder { protected: @@ -70,6 +72,8 @@ class Decoder int fpscrLen; int fpscrStride; + Enums::DecoderFlavour decoderFlavour; + /// A cache of decoded instruction objects. static GenericISA::BasicDecodeCache defaultCache; @@ -86,7 +90,7 @@ class Decoder void consumeBytes(int numBytes); public: // Decoder API - Decoder(); + Decoder(ISA* isa = nullptr); /** Reset the decoders internal state. */ void reset(); diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index f90b8a2df..6f66e5ae1 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -127,6 +127,7 @@ const struct ISA::MiscRegInitializerEntry ISA::ISA(Params *p) : SimObject(p), system(NULL), + _decoderFlavour(p->decoderFlavour), pmu(p->pmu), lookUpMiscReg(NUM_MISCREGS, {0,0}) { diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index a07017c17..ab5c72e6a 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -50,6 +50,7 @@ #include "arch/arm/types.hh" #include "debug/Checkpoint.hh" #include "sim/sim_object.hh" +#include "enums/DecoderFlavour.hh" struct ArmISAParams; struct DummyArmISADeviceParams; @@ -132,6 +133,9 @@ namespace ArmISA // Parent system ArmSystem *system; + // Micro Architecture + const Enums::DecoderFlavour _decoderFlavour; + /** Dummy device for to handle non-existing ISA devices */ DummyISADevice dummyDevice; @@ -429,6 +433,8 @@ namespace ArmISA void startup(ThreadContext *tc) {} + Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; } + /// Explicitly import the otherwise hidden startup using SimObject::startup; diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa index b5a4dfa21..2d94aff51 100644 --- a/src/arch/arm/isa/formats/aarch64.isa +++ b/src/arch/arm/isa/formats/aarch64.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 ARM Limited +// Copyright (c) 2011-2015 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -46,8 +46,10 @@ namespace Aarch64 StaticInstPtr decodeLoadsStores(ExtMachInst machInst); StaticInstPtr decodeDataProcReg(ExtMachInst machInst); + template StaticInstPtr decodeFpAdvSIMD(ExtMachInst machInst); StaticInstPtr decodeFp(ExtMachInst machInst); + template StaticInstPtr decodeAdvSIMD(ExtMachInst machInst); StaticInstPtr decodeAdvSIMDScalar(ExtMachInst machInst); @@ -1278,12 +1280,13 @@ namespace Aarch64 output decoder {{ namespace Aarch64 { + template StaticInstPtr decodeAdvSIMD(ExtMachInst machInst) { if (bits(machInst, 24) == 1) { if (bits(machInst, 10) == 0) { - return decodeNeonIndexedElem(machInst); + return decodeNeonIndexedElem(machInst); } else if (bits(machInst, 23) == 1) { return new Unknown64(machInst); } else { @@ -1295,7 +1298,7 @@ namespace Aarch64 } } else if (bits(machInst, 21) == 1) { if (bits(machInst, 10) == 1) { - return decodeNeon3Same(machInst); + return decodeNeon3Same(machInst); } else if (bits(machInst, 11) == 0) { return decodeNeon3Diff(machInst); } else if (bits(machInst, 20, 17) == 0x0) { @@ -1957,13 +1960,14 @@ namespace Aarch64 output decoder {{ namespace Aarch64 { + template StaticInstPtr decodeFpAdvSIMD(ExtMachInst machInst) { if (bits(machInst, 28) == 0) { if (bits(machInst, 31) == 0) { - return decodeAdvSIMD(machInst); + return decodeAdvSIMD(machInst); } else { return new Unknown64(machInst); } @@ -1978,6 +1982,18 @@ namespace Aarch64 } }}; +let {{ + decoder_output =''' +namespace Aarch64 +{''' + for decoderFlavour, type_dict in decoders.iteritems(): + decoder_output +=''' +template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst); +''' % { "df" : decoderFlavour } + decoder_output +=''' +}''' +}}; + output decoder {{ namespace Aarch64 { @@ -2041,7 +2057,10 @@ def format Aarch64() {{ return decodeGem5Ops(machInst); } else { // bit 27:25=111 - return decodeFpAdvSIMD(machInst); + switch(decoderFlavour){ + default: + return decodeFpAdvSIMD(machInst); + } } } ''' diff --git a/src/arch/arm/isa/formats/neon64.isa b/src/arch/arm/isa/formats/neon64.isa index 72bbd0c60..e0a913a6b 100644 --- a/src/arch/arm/isa/formats/neon64.isa +++ b/src/arch/arm/isa/formats/neon64.isa @@ -40,51 +40,54 @@ output header {{ namespace Aarch64 { // AdvSIMD three same + template StaticInstPtr decodeNeon3Same(ExtMachInst machInst); // AdvSIMD three different - StaticInstPtr decodeNeon3Diff(ExtMachInst machInst); + inline StaticInstPtr decodeNeon3Diff(ExtMachInst machInst); // AdvSIMD two-reg misc - StaticInstPtr decodeNeon2RegMisc(ExtMachInst machInst); + inline StaticInstPtr decodeNeon2RegMisc(ExtMachInst machInst); // AdvSIMD across lanes - StaticInstPtr decodeNeonAcrossLanes(ExtMachInst machInst); + inline StaticInstPtr decodeNeonAcrossLanes(ExtMachInst machInst); // AdvSIMD copy - StaticInstPtr decodeNeonCopy(ExtMachInst machInst); + inline StaticInstPtr decodeNeonCopy(ExtMachInst machInst); // AdvSIMD vector x indexed element + template StaticInstPtr decodeNeonIndexedElem(ExtMachInst machInst); // AdvSIMD modified immediate - StaticInstPtr decodeNeonModImm(ExtMachInst machInst); + inline StaticInstPtr decodeNeonModImm(ExtMachInst machInst); // AdvSIMD shift by immediate - StaticInstPtr decodeNeonShiftByImm(ExtMachInst machInst); + inline StaticInstPtr decodeNeonShiftByImm(ExtMachInst machInst); // AdvSIMD TBL/TBX - StaticInstPtr decodeNeonTblTbx(ExtMachInst machInst); + inline StaticInstPtr decodeNeonTblTbx(ExtMachInst machInst); // AdvSIMD ZIP/UZP/TRN - StaticInstPtr decodeNeonZipUzpTrn(ExtMachInst machInst); + inline StaticInstPtr decodeNeonZipUzpTrn(ExtMachInst machInst); // AdvSIMD EXT - StaticInstPtr decodeNeonExt(ExtMachInst machInst); + inline StaticInstPtr decodeNeonExt(ExtMachInst machInst); // AdvSIMD scalar three same - StaticInstPtr decodeNeonSc3Same(ExtMachInst machInst); + inline StaticInstPtr decodeNeonSc3Same(ExtMachInst machInst); // AdvSIMD scalar three different - StaticInstPtr decodeNeonSc3Diff(ExtMachInst machInst); + inline StaticInstPtr decodeNeonSc3Diff(ExtMachInst machInst); // AdvSIMD scalar two-reg misc - StaticInstPtr decodeNeonSc2RegMisc(ExtMachInst machInst); + inline StaticInstPtr decodeNeonSc2RegMisc(ExtMachInst machInst); // AdvSIMD scalar pairwise - StaticInstPtr decodeNeonScPwise(ExtMachInst machInst); + inline StaticInstPtr decodeNeonScPwise(ExtMachInst machInst); // AdvSIMD scalar copy - StaticInstPtr decodeNeonScCopy(ExtMachInst machInst); + inline StaticInstPtr decodeNeonScCopy(ExtMachInst machInst); // AdvSIMD scalar x indexed element - StaticInstPtr decodeNeonScIndexedElem(ExtMachInst machInst); + inline StaticInstPtr decodeNeonScIndexedElem(ExtMachInst machInst); // AdvSIMD scalar shift by immediate - StaticInstPtr decodeNeonScShiftByImm(ExtMachInst machInst); + inline StaticInstPtr decodeNeonScShiftByImm(ExtMachInst machInst); // AdvSIMD load/store - StaticInstPtr decodeNeonMem(ExtMachInst machInst); + inline StaticInstPtr decodeNeonMem(ExtMachInst machInst); } }}; output decoder {{ namespace Aarch64 { + template StaticInstPtr decodeNeon3Same(ExtMachInst machInst) { @@ -1267,6 +1270,7 @@ namespace Aarch64 } } + template StaticInstPtr decodeNeonIndexedElem(ExtMachInst machInst) { diff --git a/src/arch/arm/isa/includes.isa b/src/arch/arm/isa/includes.isa index 8f44e7e86..4fa032f55 100644 --- a/src/arch/arm/isa/includes.isa +++ b/src/arch/arm/isa/includes.isa @@ -67,6 +67,7 @@ output header {{ #include "arch/arm/isa_traits.hh" #include "mem/packet.hh" #include "sim/faults.hh" +#include "enums/DecoderFlavour.hh" }}; output decoder {{ diff --git a/src/arch/arm/isa/insts/neon64.isa b/src/arch/arm/isa/insts/neon64.isa index f6565efe5..697ea80e2 100644 --- a/src/arch/arm/isa/insts/neon64.isa +++ b/src/arch/arm/isa/insts/neon64.isa @@ -1,6 +1,6 @@ // -*- mode: c++ -*- -// Copyright (c) 2012-2013 ARM Limited +// Copyright (c) 2012-2013, 2015 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -42,6 +42,7 @@ let {{ header_output = "" exec_output = "" + decoders = { 'Generic' : {} } # FP types (FP operations always work with unsigned representations) floatTypes = ("uint32_t", "uint64_t") @@ -49,9 +50,9 @@ let {{ def threeEqualRegInstX(name, Name, opClass, types, rCount, op, readDest=False, pairwise=False, scalar=False, - byElem=False): + byElem=False, decoder='Generic'): assert (not pairwise) or ((not byElem) and (not scalar)) - global header_output, exec_output + global header_output, exec_output, decoders eWalkCode = simd64EnabledCheckCode + ''' RegVect srcReg1, destReg; ''' @@ -3356,4 +3357,16 @@ let {{ threeRegScrambleInstX("zip2", "Zip2QX", "SimdAluOp", unsignedTypes, 4, zipCode % "eCount / 2") + for decoderFlavour, type_dict in decoders.iteritems(): + header_output += ''' + class %(decoder_flavour)sDecoder { + public: + ''' % { "decoder_flavour" : decoderFlavour } + for type,name in type_dict.iteritems(): + header_output += ''' + template using %(type)s = %(new_name)s;''' % { + "type" : type, "new_name" : name + } + header_output += ''' + };''' }}; diff --git a/src/arch/mips/decoder.hh b/src/arch/mips/decoder.hh index a3a68ad07..59e040658 100644 --- a/src/arch/mips/decoder.hh +++ b/src/arch/mips/decoder.hh @@ -40,6 +40,7 @@ namespace MipsISA { +class ISA; class Decoder { protected: @@ -48,7 +49,7 @@ class Decoder bool instDone; public: - Decoder() : instDone(false) + Decoder(ISA* isa = nullptr) : instDone(false) {} void diff --git a/src/arch/power/decoder.hh b/src/arch/power/decoder.hh index a70802ced..cc086adc5 100644 --- a/src/arch/power/decoder.hh +++ b/src/arch/power/decoder.hh @@ -38,6 +38,7 @@ namespace PowerISA { +class ISA; class Decoder { protected: @@ -46,7 +47,7 @@ class Decoder bool instDone; public: - Decoder() : instDone(false) + Decoder(ISA* isa = nullptr) : instDone(false) { } diff --git a/src/arch/sparc/decoder.hh b/src/arch/sparc/decoder.hh index b87ee682e..897d112dc 100644 --- a/src/arch/sparc/decoder.hh +++ b/src/arch/sparc/decoder.hh @@ -39,6 +39,7 @@ namespace SparcISA { +class ISA; class Decoder { protected: @@ -48,7 +49,7 @@ class Decoder MiscReg asi; public: - Decoder() : instDone(false), asi(0) + Decoder(ISA* isa = nullptr) : instDone(false), asi(0) {} void process() {} diff --git a/src/arch/x86/decoder.hh b/src/arch/x86/decoder.hh index 6cd0c6199..d42751d21 100644 --- a/src/arch/x86/decoder.hh +++ b/src/arch/x86/decoder.hh @@ -47,6 +47,7 @@ namespace X86ISA { +class ISA; class Decoder { private: @@ -230,7 +231,7 @@ class Decoder static InstCacheMap instCacheMap; public: - Decoder() : basePC(0), origPC(0), offset(0), + Decoder(ISA* isa = nullptr) : basePC(0), origPC(0), offset(0), outOfBytes(true), instDone(false), state(ResetState) { diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 1d0cfd137..cb123afd2 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -73,6 +73,7 @@ #include "sim/eventq.hh" #include "sim/full_system.hh" #include "sim/system.hh" +#include "cpu/o3/isa_specific.hh" using namespace std; @@ -151,7 +152,7 @@ DefaultFetch::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params) branchPred = params->branchPred; for (ThreadID tid = 0; tid < numThreads; tid++) { - decoder[tid] = new TheISA::Decoder; + decoder[tid] = new TheISA::Decoder(params->isa[tid]); // Create space to buffer the cache line data, // which may not hold the entire cache line. fetchBuffer[tid] = new uint8_t[fetchBufferSize];