isa: Add parameter to pick different decoder inside ISA
authorRekai Gonzalez Alberquilla <Rekai.GonzalezAlberquilla@arm.com>
Fri, 9 Oct 2015 19:50:54 +0000 (14:50 -0500)
committerRekai Gonzalez Alberquilla <Rekai.GonzalezAlberquilla@arm.com>
Fri, 9 Oct 2015 19:50:54 +0000 (14:50 -0500)
The decoder is responsible for splitting instructions in micro
operations (uops). Given that different micro architectures may split
operations differently, this patch allows to specify which micro
architecture each isa implements, so different cores in the system can
split instructions differently, also decoupling uop splitting
(microArch) from ISA (Arch). This is done making the decodification
calls templates that receive a type 'DecoderFlavour' that maps the
name of the operation to the class that implements it. This way there
is only one selection point (converting the command line enum to the
appropriate DecodeFeatures object). In addition, there is no explicit
code replication: template instantiation hides that, and the compiler
should be able to resolve a number of things at compile-time.

15 files changed:
src/arch/alpha/decoder.hh
src/arch/arm/ArmISA.py
src/arch/arm/decoder.cc
src/arch/arm/decoder.hh
src/arch/arm/isa.cc
src/arch/arm/isa.hh
src/arch/arm/isa/formats/aarch64.isa
src/arch/arm/isa/formats/neon64.isa
src/arch/arm/isa/includes.isa
src/arch/arm/isa/insts/neon64.isa
src/arch/mips/decoder.hh
src/arch/power/decoder.hh
src/arch/sparc/decoder.hh
src/arch/x86/decoder.hh
src/cpu/o3/fetch_impl.hh

index d3372286770a8112ce04629b5f1f16f3afd7748b..522359c28598d67ca1fb8fa99d339e81a885e792 100644 (file)
@@ -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
index f5c56cfd502b1bd092b745b9a6448ca9e1f03f0e..7ef8afd88d37305ab23525c5365965e9a401e6f0 100644 (file)
@@ -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")
 
index 23fa89a3f829883c367800c3e5a14b3f810a7f6f..1502b061ff54c680d3756820c991c1bcc0bac672 100644 (file)
@@ -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();
 }
index 757b6d6833d461e2cc082db5bd7c28bbcedbf330..f8748ab5e79f936802e44a6149aa6a9b8823f370 100644 (file)
 #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();
index f90b8a2df2e810af5aa69f0d34b3fcbd2c223b1d..6f66e5ae19a54f049690fa690b53571ab0f54661 100644 (file)
@@ -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})
 {
index a07017c17dadbf8a1a6cd4e16250fb54ee7f290a..ab5c72e6a7c16469b903c464fa79337b7671af49 100644 (file)
@@ -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;
 
index b5a4dfa219f9e18885989a25e73348a6b1858953..2d94aff518a87a73926f22a4b218d07bda461561 100644 (file)
@@ -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 <typename DecoderFeatures>
     StaticInstPtr decodeFpAdvSIMD(ExtMachInst machInst);
     StaticInstPtr decodeFp(ExtMachInst machInst);
+    template <typename DecoderFeatures>
     StaticInstPtr decodeAdvSIMD(ExtMachInst machInst);
     StaticInstPtr decodeAdvSIMDScalar(ExtMachInst machInst);
 
@@ -1278,12 +1280,13 @@ namespace Aarch64
 output decoder {{
 namespace Aarch64
 {
+    template <typename DecoderFeatures>
     StaticInstPtr
     decodeAdvSIMD(ExtMachInst machInst)
     {
         if (bits(machInst, 24) == 1) {
             if (bits(machInst, 10) == 0) {
-                return decodeNeonIndexedElem(machInst);
+                return decodeNeonIndexedElem<DecoderFeatures>(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<DecoderFeatures>(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 <typename DecoderFeatures>
     StaticInstPtr
     decodeFpAdvSIMD(ExtMachInst machInst)
     {
 
         if (bits(machInst, 28) == 0) {
             if (bits(machInst, 31) == 0) {
-                return decodeAdvSIMD(machInst);
+                return decodeAdvSIMD<DecoderFeatures>(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<GenericDecoder>(machInst);
+            }
         }
     }
     '''
index 72bbd0c60aa015751b5a5c744870e711270998ed..e0a913a6bb0cd89a0683e8c636788a4f24b1b0a3 100644 (file)
@@ -40,51 +40,54 @@ output header {{
 namespace Aarch64
 {
     // AdvSIMD three same
+    template <typename DecoderFeatures>
     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 <typename DecoderFeatures>
     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 <typename DecoderFeatures>
     StaticInstPtr
     decodeNeon3Same(ExtMachInst machInst)
     {
@@ -1267,6 +1270,7 @@ namespace Aarch64
         }
     }
 
+    template <typename DecoderFeatures>
     StaticInstPtr
     decodeNeonIndexedElem(ExtMachInst machInst)
     {
index 8f44e7e862ce6f3779275bbaab0f6654057ce8c1..4fa032f55c22bfa36aba37068c863b2441bd0ad2 100644 (file)
@@ -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 {{
index f6565efe57a3efd4b47a15dddbb032a5c791651c..697ea80e2b89f79fbe0cdc299d508deae35b8c19 100644 (file)
@@ -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<typename Elem> using %(type)s = %(new_name)s<Elem>;''' % {
+               "type" : type, "new_name" : name
+            }
+        header_output += '''
+        };'''
 }};
index a3a68ad07477be87aef7b7befb07a4cee8c5e8e9..59e0406582632099a469d149fc26ffc0dded85e7 100644 (file)
@@ -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
index a70802cedcc8f6c36f087e6d479f7c489afb48a0..cc086adc558be30fd6172a1fd2a53b6ce5ef0ba3 100644 (file)
@@ -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)
     {
     }
 
index b87ee682e4bdd28d431b4be64399549abcc89678..897d112dc4de50778d87c39dfbb850867a7e6711 100644 (file)
@@ -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() {}
index 6cd0c6199a9d73c9aa5beffb1665b1d947770a9d..d42751d21bfdbdf142f17ed1e69f50b9cc6ab902 100644 (file)
@@ -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)
     {
index 1d0cfd1379781da7e71420999f650e8e2dd8ba48..cb123afd28e89709e44808d84fc7353166f11ada 100644 (file)
@@ -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<Impl>::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];