cpu: Added interface for vector reg file
authorRekai Gonzalez-Alberquilla <Rekai.GonzalezAlberquilla@arm.com>
Wed, 5 Apr 2017 18:24:00 +0000 (13:24 -0500)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Wed, 5 Jul 2017 14:43:49 +0000 (14:43 +0000)
This patch adds some more functionality to the cpu model and the arch to
interface with the vector register file.

This change consists mainly of augmenting ThreadContexts and ExecContexts
with calls to get/set full vectors, underlying microarchitectural elements
or lanes. Those are meant to interface with the vector register file. All
classes that implement this interface also get an appropriate implementation.

This requires implementing the vector register file for the different
models using the VecRegContainer class.

This change set also updates the Result abstraction to contemplate the
possibility of having a vector as result.

The changes also affect how the remote_gdb connection works.

There are some (nasty) side effects, such as the need to define dummy
numPhysVecRegs parameter values for architectures that do not implement
vector extensions.

Nathanael Premillieu's work with an increasing number of fixes and
improvements of mine.

Change-Id: Iee65f4e8b03abfe1e94e6940a51b68d0977fd5bb
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
[ Fix RISCV build issues and CC reg free list initialisation ]
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2705

65 files changed:
configs/common/cores/arm/O3_ARM_v7a.py
src/arch/SConscript
src/arch/alpha/isa.hh
src/arch/alpha/registers.hh
src/arch/arm/ArmISA.py
src/arch/arm/insts/static_inst.cc
src/arch/arm/insts/static_inst.hh
src/arch/arm/isa.cc
src/arch/arm/isa.hh
src/arch/arm/nativetrace.cc
src/arch/arm/registers.hh
src/arch/arm/remote_gdb.cc
src/arch/arm/remote_gdb.hh
src/arch/arm/utility.cc
src/arch/generic/ISACommon.py [new file with mode: 0644]
src/arch/generic/SConscript
src/arch/generic/traits.hh [new file with mode: 0644]
src/arch/generic/types.hh
src/arch/isa_parser.py
src/arch/mips/isa.hh
src/arch/mips/registers.hh
src/arch/null/registers.hh
src/arch/power/isa.hh
src/arch/power/registers.hh
src/arch/riscv/isa.hh
src/arch/riscv/registers.hh
src/arch/sparc/isa.hh
src/arch/sparc/registers.hh
src/arch/x86/isa.hh
src/arch/x86/registers.hh
src/cpu/base_dyn_inst.hh
src/cpu/checker/cpu.hh
src/cpu/checker/cpu_impl.hh
src/cpu/checker/thread_context.hh
src/cpu/exec_context.hh
src/cpu/inst_res.hh
src/cpu/minor/dyn_inst.cc
src/cpu/minor/exec_context.hh
src/cpu/minor/scoreboard.cc
src/cpu/minor/scoreboard.hh
src/cpu/o3/O3CPU.py
src/cpu/o3/comm.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/dyn_inst.hh
src/cpu/o3/free_list.hh
src/cpu/o3/inst_queue_impl.hh
src/cpu/o3/regfile.cc
src/cpu/o3/regfile.hh
src/cpu/o3/rename.hh
src/cpu/o3/rename_impl.hh
src/cpu/o3/rename_map.cc
src/cpu/o3/rename_map.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_context_impl.hh
src/cpu/reg_class.cc
src/cpu/reg_class.hh
src/cpu/reg_class_impl.hh
src/cpu/simple/base.cc
src/cpu/simple/exec_context.hh
src/cpu/simple_thread.hh
src/cpu/static_inst.hh
src/cpu/thread_context.cc
src/cpu/thread_context.hh
src/sim/serialize.cc

index f5c2c711a7626a034abb1fb4b86511b6b6a72a1b..fde4d3c60d24ff8102b2cf1f17936519fc902dd8 100644 (file)
@@ -139,6 +139,7 @@ class O3_ARM_v7a_3(DerivO3CPU):
     forwardComSize = 5
     numPhysIntRegs = 128
     numPhysFloatRegs = 192
+    numPhysVecRegs = 48
     numIQEntries = 32
     numROBEntries = 40
 
index ea940560d08fd2d59e807cd954f52eb8a81c9022..e30069c046142ff1150ce6e5dfa7c07ed6218ec0 100644 (file)
@@ -1,5 +1,17 @@
 # -*- mode:python -*-
 
+# Copyright (c) 2016 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.
+#
 # Copyright (c) 2006 The Regents of The University of Michigan
 # All rights reserved.
 #
@@ -202,6 +214,7 @@ env.Append(BUILDERS = {'ScanISA' :
 
 DebugFlag('IntRegs')
 DebugFlag('FloatRegs')
+DebugFlag('VecRegs')
 DebugFlag('CCRegs')
 DebugFlag('MiscRegs')
 CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'MiscRegs' ])
index 80d8ab149ab3f871cace66457ffeea06b12047c4..36e708450967b7b77b6baf7c65d527d57035b8ba 100644 (file)
@@ -110,6 +110,18 @@ namespace AlphaISA
             return reg;
         }
 
+        int
+        flattenVecIndex(int reg) const
+        {
+            return reg;
+        }
+
+        int
+        flattenVecElemIndex(int reg) const
+        {
+            return reg;
+        }
+
         // dummy
         int
         flattenCCIndex(int reg) const
index 03bbd8aaf634b3c8bf0a9156554f6ca4f0161f09..151ea7d7c444b5eb0780351978b3ae22411a0159 100644 (file)
@@ -34,6 +34,7 @@
 #include "arch/alpha/generated/max_inst_regs.hh"
 #include "arch/alpha/ipr.hh"
 #include "arch/generic/types.hh"
+#include "arch/generic/vec_reg.hh"
 #include "base/types.hh"
 
 namespace AlphaISA {
@@ -56,6 +57,15 @@ typedef uint64_t MiscReg;
 // dummy typedef since we don't have CC regs
 typedef uint8_t CCReg;
 
+// dummy typedefs since we don't have vector regs
+constexpr unsigned NumVecElemPerVecReg = 2;
+using VecElem = uint32_t;
+using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
+using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
+using VecRegContainer = VecReg::Container;
+// This has to be one to prevent warnings that are treated as errors
+constexpr unsigned NumVecRegs = 1;
+
 union AnyReg
 {
     IntReg  intreg;
index 73ef4a09d72fc3ea499b2fc0b03f5c12c5c0d463..7956570bd0ee7d6ec6f2206e3f54618456205c47 100644 (file)
@@ -41,6 +41,7 @@ from m5.proxy import *
 from m5.SimObject import SimObject
 
 from ArmPMU import ArmPMU
+from ISACommon import VecRegRenameMode
 
 # Enum for DecoderFlavour
 class DecoderFlavour(Enum): vals = ['Generic']
@@ -86,6 +87,10 @@ class ArmISA(SimObject):
     id_aa64afr1_el1 = Param.UInt64(0x0000000000000000,
         "AArch64 Auxiliary Feature Register 1")
 
+    # Initial vector register rename mode
+    vecRegRenameMode = Param.VecRegRenameMode('Full',
+        "Initial rename mode for vecregs")
+
     # 1 CTX CMPs | 2 WRPs | 2 BRPs | !PMU | !Trace | Debug v8-A
     id_aa64dfr0_el1 = Param.UInt64(0x0000000000101006,
         "AArch64 Debug Feature Register 0")
index 99d1b817d3cb00a640d911ff6d5ffa97732d9b24..8501715d5dee6f528fefbe89e3f8d171df5ab416 100644 (file)
@@ -330,6 +330,12 @@ ArmStaticInst::printFloatReg(std::ostream &os, RegIndex reg_idx) const
     ccprintf(os, "f%d", reg_idx);
 }
 
+void
+ArmStaticInst::printVecReg(std::ostream &os, RegIndex reg_idx) const
+{
+    ccprintf(os, "v%d", reg_idx);
+}
+
 void
 ArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const
 {
index 19af99a0f44dc33c713a683aae209365184d0532..486d30fe4039cad3f63f2c6c42ea193193eefbe6 100644 (file)
@@ -157,6 +157,7 @@ class ArmStaticInst : public StaticInst
     /// dependence tag number (FP or int).
     void printIntReg(std::ostream &os, RegIndex reg_idx) const;
     void printFloatReg(std::ostream &os, RegIndex reg_idx) const;
+    void printVecReg(std::ostream &os, RegIndex reg_idx) const;
     void printCCReg(std::ostream &os, RegIndex reg_idx) const;
     void printMiscReg(std::ostream &os, RegIndex reg_idx) const;
     void printMnemonic(std::ostream &os,
index c54d7746dec9cdef97566d0c6dd6f1917c5c9605..a490e5fb79ca079a464e6339271eec751cb42e1a 100644 (file)
@@ -209,6 +209,7 @@ ISA::ISA(Params *p)
     : SimObject(p),
       system(NULL),
       _decoderFlavour(p->decoderFlavour),
+      _vecRegRenameMode(p->vecRegRenameMode),
       pmu(p->pmu),
       lookUpMiscReg(NUM_MISCREGS, {0,0})
 {
index 8de90dc9329449dfba8fe240a71d678e01fec76f..e96de79225f31f32a01e3f1a38b0c22d3a5a3933 100644 (file)
@@ -48,7 +48,9 @@
 #include "arch/arm/system.hh"
 #include "arch/arm/tlb.hh"
 #include "arch/arm/types.hh"
+#include "arch/generic/traits.hh"
 #include "debug/Checkpoint.hh"
+#include "enums/VecRegRenameMode.hh"
 #include "sim/sim_object.hh"
 #include "enums/DecoderFlavour.hh"
 
@@ -68,6 +70,7 @@ namespace ArmISA
 
         // Micro Architecture
         const Enums::DecoderFlavour _decoderFlavour;
+        const Enums::VecRegRenameMode _vecRegRenameMode;
 
         /** Dummy device for to handle non-existing ISA devices */
         DummyISADevice dummyDevice;
@@ -185,6 +188,10 @@ namespace ArmISA
                 return RegId(IntRegClass, flattenIntIndex(regId.index()));
               case FloatRegClass:
                 return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
+              case VecRegClass:
+                return RegId(VecRegClass, flattenVecIndex(regId.index()));
+              case VecElemClass:
+                return RegId(VecElemClass, flattenVecElemIndex(regId.index()));
               case CCRegClass:
                 return RegId(CCRegClass, flattenCCIndex(regId.index()));
               case MiscRegClass:
@@ -232,6 +239,20 @@ namespace ArmISA
             return reg;
         }
 
+        int
+        flattenVecIndex(int reg) const
+        {
+            assert(reg >= 0);
+            return reg;
+        }
+
+        int
+        flattenVecElemIndex(int reg) const
+        {
+            assert(reg >= 0);
+            return reg;
+        }
+
         int
         flattenCCIndex(int reg) const
         {
@@ -406,6 +427,12 @@ namespace ArmISA
 
         Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
 
+        Enums::VecRegRenameMode
+        vecRegRenameMode() const
+        {
+            return _vecRegRenameMode;
+        }
+
         /// Explicitly import the otherwise hidden startup
         using SimObject::startup;
 
@@ -417,4 +444,17 @@ namespace ArmISA
     };
 }
 
+template<>
+struct initRenameMode<ArmISA::ISA>
+{
+    static Enums::VecRegRenameMode mode(const ArmISA::ISA* isa)
+    {
+        return isa->vecRegRenameMode();
+    }
+    static bool equals(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
+    {
+        return mode(isa1) == mode(isa2);
+    }
+};
+
 #endif
index fcb13fb2a8a79751c8d2b6c16bf0d066f511dc9e..395232e00dba8da1f25da1cf14525131e9f2592d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, 2014 ARM Limited
+ * Copyright (c) 2010-2011, 2014, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -125,10 +125,10 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
     newState[STATE_CPSR] = cpsr;
     changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
 
-    for (int i = 0; i < NumFloatV7ArchRegs; i += 2) {
-        newState[STATE_F0 + (i >> 1)] =
-            static_cast<uint64_t>(tc->readFloatRegBits(i + 1)) << 32 |
-            tc->readFloatRegBits(i);
+    for (int i = 0; i < NumVecV7ArchRegs; i++) {
+        auto vec(tc->readVecReg(RegId(VecRegClass,i)).as<uint64_t, 2>());
+        newState[STATE_F0 + 2*i] = vec[0];
+        newState[STATE_F0 + 2*i + 1] = vec[1];
     }
     newState[STATE_FPSCR] = tc->readMiscRegNoEffect(MISCREG_FPSCR) |
                             tc->readCCReg(CCREG_FP);
index 2e1ad1881c18189e7e71663a69b4714c4b0600bc..0a617e4dca9a3b31e45c7ba291d4fb28605a0957 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, 2014 ARM Limited
+ * Copyright (c) 2010-2011, 2014, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
 #ifndef __ARCH_ARM_REGISTERS_HH__
 #define __ARCH_ARM_REGISTERS_HH__
 
+#include "arch/arm/ccregs.hh"
 #include "arch/arm/generated/max_inst_regs.hh"
 #include "arch/arm/intregs.hh"
-#include "arch/arm/ccregs.hh"
 #include "arch/arm/miscregs.hh"
+#include "arch/generic/vec_reg.hh"
 
 namespace ArmISA {
 
@@ -64,6 +65,13 @@ typedef uint64_t IntReg;
 typedef uint32_t FloatRegBits;
 typedef float FloatReg;
 
+// Number of VecElem per Vector Register, computed based on the vector length
+constexpr unsigned NumVecElemPerVecReg = 4;
+using VecElem = uint32_t;
+using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
+using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
+using VecRegContainer = VecReg::Container;
+
 // cop-0/cop-1 system control register
 typedef uint64_t MiscReg;
 
@@ -76,15 +84,19 @@ const int NumIntArchRegs = NUM_ARCH_INTREGS;
 const int NumFloatV7ArchRegs  = 64;
 const int NumFloatV8ArchRegs  = 128;
 const int NumFloatSpecialRegs = 32;
+const int NumVecV7ArchRegs  = 64;
+const int NumVecV8ArchRegs  = 32;
+const int NumVecSpecialRegs = 8;
 
 const int NumIntRegs = NUM_INTREGS;
 const int NumFloatRegs = NumFloatV8ArchRegs + NumFloatSpecialRegs;
+const int NumVecRegs = NumVecV8ArchRegs + NumVecSpecialRegs;
 const int NumCCRegs = NUM_CCREGS;
 const int NumMiscRegs = NUM_MISCREGS;
 
 #define ISA_HAS_CC_REGS
 
-const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
+const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumVecRegs + NumMiscRegs;
 
 // semantically meaningful register indices
 const int ReturnValueReg = 0;
index eefe62b425963baf459929c56fffed9ef1893195..d934d53d356eb3f10dc9ff5cc76200b0c7185dd3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2015 LabWare
  * Copyright 2014 Google Inc.
- * Copyright (c) 2010, 2013 ARM Limited
+ * Copyright (c) 2010, 2013, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -212,6 +212,10 @@ RemoteGDB::AArch64GdbRegCache::getRegs(ThreadContext *context)
         r.v[i + 2] = context->readFloatRegBits(i + 0);
         r.v[i + 3] = context->readFloatRegBits(i + 1);
     }
+
+    for (int i = 0; i < 32; i ++) {
+        r.vec[i] = context->readVecReg(RegId(VecRegClass,i));
+    }
 }
 
 void
@@ -234,6 +238,10 @@ RemoteGDB::AArch64GdbRegCache::setRegs(ThreadContext *context) const
         context->setFloatRegBits(i + 0, r.v[i + 2]);
         context->setFloatRegBits(i + 1, r.v[i + 3]);
     }
+
+    for (int i = 0; i < 32; i ++) {
+        context->setVecReg(RegId(VecRegClass, i), r.vec[i]);
+    }
 }
 
 void
index acd6f32d25a2c6c218e8ca4f8a17d76dae062d85..328fbadb377fd72b5f479fc2600262cde2afcb93 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2015 LabWare
  * Copyright 2014 Google, Inc.
- * Copyright (c) 2013 ARM Limited
+ * Copyright (c) 2013, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -51,6 +51,7 @@
 #include <algorithm>
 
 #include "arch/arm/utility.hh"
+#include "arch/generic/vec_reg.hh"
 #include "base/remote_gdb.hh"
 
 class System;
@@ -96,6 +97,7 @@ class RemoteGDB : public BaseRemoteGDB
           uint64_t pc;
           uint64_t cpsr;
           uint32_t v[32*4];
+          ArmISA::VecRegContainer vec[32];
         } r;
       public:
         char *data() const { return (char *)&r; }
index 1437801a26aa93f730199e25290efe203a6381a7..a58ca8111a7f0cbd3b018fb0c182f0c05fb855fc 100644 (file)
@@ -154,6 +154,9 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     for (int i = 0; i < NumFloatRegs; i++)
         dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
 
+    for (int i = 0; i < NumVecRegs; i++)
+        dest->setVecRegFlat(i, src->readVecRegFlat(i));
+
     for (int i = 0; i < NumCCRegs; i++)
         dest->setCCReg(i, src->readCCReg(i));
 
diff --git a/src/arch/generic/ISACommon.py b/src/arch/generic/ISACommon.py
new file mode 100644 (file)
index 0000000..7777dc2
--- /dev/null
@@ -0,0 +1,50 @@
+# Copyright (c) 2016 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: Rekai Gonzalez
+
+from m5.params import *
+from m5.proxy import *
+from m5.SimObject import SimObject
+
+class VecRegRenameMode(Enum):
+    '''Enum for Rename Mode in rename map
+        Elem: Each native-elem in a vector register is renamed independently.
+        Full: Vectors are renamed as one unit.'''
+
+    vals = ['Full', 'Elem']
+
+
+__all__ = ['VecRegRenameMode']
index c87ad671f1caa4d82a9f2d53e8e1b1caf69ff550..7123eaf4a12aebc587d11628f901fb71df8f3d34 100644 (file)
@@ -1,3 +1,15 @@
+# Copyright (c) 2016 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.
+#
 # Copyright (c) 2012 Google
 # All rights reserved.
 #
@@ -36,6 +48,7 @@ Source('mmapped_ipr.cc')
 Source('tlb.cc')
 
 SimObject('BaseTLB.py')
+SimObject('ISACommon.py')
 
 DebugFlag('TLB')
 Source('pseudo_inst.cc')
diff --git a/src/arch/generic/traits.hh b/src/arch/generic/traits.hh
new file mode 100644 (file)
index 0000000..3dc6b30
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 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: Rekai Gonzalez
+ */
+
+/* Auxiliary structs for architecture traits. */
+
+#ifndef __ARCH_COMMON_TRAITS_HH__
+#define __ARCH_COMMON_TRAITS_HH__
+
+#include "enums/VecRegRenameMode.hh"
+
+/** Helper structure to get the vector register mode for a given ISA.
+ * This way we implement a default 'full' mode, and only those ISA that care
+ * have to actually specialise the template to forward the call to the
+ * appropriate member of the ISA.
+ */
+template <typename ISA>
+struct initRenameMode
+{
+    static Enums::VecRegRenameMode mode(const ISA*) { return Enums::Full; }
+    /**
+     * Compare the initial rename mode of two instances of the ISA.
+     * Result is true by definition, as the default mode is Full.
+     * */
+    static bool equals(const ISA*, const ISA*) { return true; }
+};
+
+#endif /* __ARCH_COMMON_TRAITS_HH__ */
index bb6eafd6645b068ad3d4424a2d6660f2ad984249..353112913eba3042e4793a08f2934d7870f8f9b6 100644 (file)
@@ -40,6 +40,9 @@
 // Logical register index type.
 typedef uint16_t RegIndex;
 
+/** Logical vector register elem index type. */
+using ElemIndex = uint16_t;
+
 namespace GenericISA
 {
 
index 610197e38125c07037e421c5749dc54510cb24a5..759b50c0d1a9e8071d9f764d625c7ad1af451b8e 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (c) 2014 ARM Limited
+# Copyright (c) 2014, 2016 ARM Limited
 # All rights reserved
 #
 # The license below extends only to copyright in the software and shall
@@ -865,8 +865,8 @@ class OperandList(object):
             op_desc = self.find_base(op_base)
             if op_desc:
                 if op_desc.ext != op_ext:
-                    error('Inconsistent extensions for operand %s' % \
-                          op_base)
+                    error ('Inconsistent extensions for operand %s' % \
+                            op_base)
                 op_desc.is_src = op_desc.is_src or is_src
                 op_desc.is_dest = op_desc.is_dest or is_dest
             else:
index c751cb16825a889a58c89f3b4b58e5edd2bcc3b7..c38b7cec0b8151ad66ab02daa511c455bfd4a35c 100644 (file)
@@ -180,6 +180,18 @@ namespace MipsISA
             return reg;
         }
 
+        int
+        flattenVecIndex(int reg) const
+        {
+            return reg;
+        }
+
+        int
+        flattenVecElemIndex(int reg) const
+        {
+            return reg;
+        }
+
         // dummy
         int
         flattenCCIndex(int reg) const
index c7cdb652278b000e968aa1f26048429a09c2faf8..f5dd325cd17e7b25e5e255dd8e6860f72442f6a3 100644 (file)
@@ -32,6 +32,7 @@
 #ifndef __ARCH_MIPS_REGISTERS_HH__
 #define __ARCH_MIPS_REGISTERS_HH__
 
+#include "arch/generic/vec_reg.hh"
 #include "arch/mips/generated/max_inst_regs.hh"
 #include "base/misc.hh"
 #include "base/types.hh"
@@ -289,6 +290,15 @@ typedef uint64_t MiscReg;
 // dummy typedef since we don't have CC regs
 typedef uint8_t CCReg;
 
+// dummy typedefs since we don't have vector regs
+constexpr unsigned NumVecElemPerVecReg = 2;
+using VecElem = uint32_t;
+using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
+using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
+using VecRegContainer = VecReg::Container;
+// This has to be one to prevent warnings that are treated as errors
+constexpr unsigned NumVecRegs = 1;
+
 typedef union {
     IntReg   intreg;
     FloatReg fpreg;
index 6d1ecf1c508c778c8f0a7428ef6f96391335a2f5..3d27d95a2d492fce8c8074c857f73087e1c02d6e 100644 (file)
@@ -40,6 +40,7 @@
 #ifndef __ARCH_NULL_REGISTERS_HH__
 #define __ARCH_NULL_REGISTERS_HH__
 
+#include "arch/generic/vec_reg.hh"
 #include "arch/types.hh"
 #include "base/types.hh"
 
@@ -52,6 +53,15 @@ typedef uint8_t CCReg;
 typedef uint64_t MiscReg;
 const RegIndex ZeroReg = 0;
 
+// dummy typedefs since we don't have vector regs
+constexpr unsigned NumVecElemPerVecReg = 2;
+using VecElem = uint32_t;
+using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
+using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
+using VecRegContainer = VecReg::Container;
+// This has to be one to prevent warnings that are treated as errors
+constexpr unsigned NumVecRegs = 1;
+
 }
 
 #endif // __ARCH_NULL_REGISTERS_HH__
index 475b4d2f828c62e891fdee4a85a67a5695e49aee..edac96d597b1366b51c02ee3657238e0aa789808 100644 (file)
@@ -101,6 +101,18 @@ class ISA : public SimObject
         return reg;
     }
 
+    int
+    flattenVecIndex(int reg) const
+    {
+        return reg;
+    }
+
+    int
+    flattenVecElemIndex(int reg) const
+    {
+        return reg;
+    }
+
     // dummy
     int
     flattenCCIndex(int reg) const
index 742809db1ce6406fd5a09d96eb579535c732f204..4e8c9e9f4dc714e5872471a19765daa524fd5872 100644 (file)
@@ -31,6 +31,7 @@
 #ifndef __ARCH_POWER_REGISTERS_HH__
 #define __ARCH_POWER_REGISTERS_HH__
 
+#include "arch/generic/vec_reg.hh"
 #include "arch/power/generated/max_inst_regs.hh"
 #include "arch/power/miscregs.hh"
 
@@ -53,6 +54,15 @@ typedef uint64_t MiscReg;
 // dummy typedef since we don't have CC regs
 typedef uint8_t CCReg;
 
+// dummy typedefs since we don't have vector regs
+constexpr unsigned NumVecElemPerVecReg = 2;
+using VecElem = uint32_t;
+using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
+using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
+using VecRegContainer = VecReg::Container;
+// This has to be one to prevent warnings that are treated as errors
+constexpr unsigned NumVecRegs = 1;
+
 // Constants Related to the number of registers
 const int NumIntArchRegs = 32;
 
index 3f241230356e1580579a078d70a0c51117d1b6ba..578057aa0bffa7a8471b52796d32570ff3f2ffcb 100644 (file)
@@ -97,6 +97,18 @@ class ISA : public SimObject
         return reg;
     }
 
+    int
+    flattenVecIndex(int reg) const
+    {
+        return reg;
+    }
+
+    int
+    flattenVecElemIndex(int reg) const
+    {
+        return reg;
+    }
+
     // dummy
     int
     flattenCCIndex(int reg) const
index 2666784e58a6a374016a4375e2b261faf70161d4..6ae1c1691084b47cd40f52367d10c7fecdd4df51 100644 (file)
@@ -51,6 +51,7 @@
 #include <string>
 
 #include "arch/generic/types.hh"
+#include "arch/generic/vec_reg.hh"
 #include "arch/isa_traits.hh"
 #include "arch/riscv/generated/max_inst_regs.hh"
 #include "base/types.hh"
@@ -67,10 +68,19 @@ typedef double FloatReg;
 typedef uint8_t CCReg; // Not applicable to Riscv
 typedef uint64_t MiscReg;
 
+// dummy typedefs since we don't have vector regs
+const unsigned NumVecElemPerVecReg = 2;
+using VecElem = uint32_t;
+using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
+using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
+using VecRegContainer = VecReg::Container;
+
 const int NumIntArchRegs = 32;
 const int NumMicroIntRegs = 1;
 const int NumIntRegs = NumIntArchRegs + NumMicroIntRegs;
 const int NumFloatRegs = 32;
+// This has to be one to prevent warnings that are treated as errors
+const unsigned NumVecRegs = 1;
 const int NumCCRegs = 0;
 const int NumMiscRegs = 4096;
 
index ded5b34ffdbe94462c04617b193b95aa03f296b4..82fee0d0048bd6427ecbe661bb7e5fd61e7b3bcf 100644 (file)
@@ -202,6 +202,8 @@ class ISA : public SimObject
             return RegId(CCRegClass, flattenCCIndex(regId.index()));
           case MiscRegClass:
             return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+          default:
+            break;
         }
         return regId;
     }
@@ -221,6 +223,18 @@ class ISA : public SimObject
         return reg;
     }
 
+    int
+    flattenVecIndex(int reg) const
+    {
+        return reg;
+    }
+
+    int
+    flattenVecElemIndex(int reg) const
+    {
+        return reg;
+    }
+
     // dummy
     int
     flattenCCIndex(int reg) const
index 62c876f3d8937fe281947aba7d12aee3cc6f6e25..596fdf4d0f212380946c9f1e717f18b2b1bd4423 100644 (file)
@@ -32,6 +32,7 @@
 #ifndef __ARCH_SPARC_REGISTERS_HH__
 #define __ARCH_SPARC_REGISTERS_HH__
 
+#include "arch/generic/vec_reg.hh"
 #include "arch/sparc/generated/max_inst_regs.hh"
 #include "arch/sparc/miscregs.hh"
 #include "arch/sparc/sparc_traits.hh"
@@ -52,6 +53,15 @@ typedef uint32_t FloatRegBits;
 // dummy typedef since we don't have CC regs
 typedef uint8_t CCReg;
 
+// dummy typedefs since we don't have vector regs
+constexpr unsigned NumVecElemPerVecReg = 2;
+using VecElem = uint32_t;
+using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
+using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
+using VecRegContainer = VecReg::Container;
+// This has to be one to prevent warnings that are treated as errors
+constexpr unsigned NumVecRegs = 1;
+
 typedef union
 {
     IntReg intReg;
index 099d27c7c5202b6681b7ff3530efab979062a80f..b61face0950eea7763b4d203bda24ab98b0b95c3 100644 (file)
@@ -82,6 +82,8 @@ namespace X86ISA
                 return RegId(CCRegClass, flattenCCIndex(regId.index()));
               case MiscRegClass:
                 return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+              default:
+                break;
             }
             return regId;
         }
@@ -102,6 +104,18 @@ namespace X86ISA
             return reg;
         }
 
+        int
+        flattenVecIndex(int reg) const
+        {
+            return reg;
+        }
+
+        int
+        flattenVecElemIndex(int reg) const
+        {
+            return reg;
+        }
+
         int
         flattenCCIndex(int reg) const
         {
index d23731977ccdb681cb44acb44801145f156d566e..9db3349f07f8cd6256d1189297692414e3360bf5 100644 (file)
@@ -41,6 +41,7 @@
 #ifndef __ARCH_X86_REGISTERS_HH__
 #define __ARCH_X86_REGISTERS_HH__
 
+#include "arch/generic/vec_reg.hh"
 #include "arch/x86/generated/max_inst_regs.hh"
 #include "arch/x86/regs/int.hh"
 #include "arch/x86/regs/ccr.hh"
@@ -93,6 +94,15 @@ typedef uint64_t IntReg;
 typedef uint64_t CCReg;
 typedef uint64_t MiscReg;
 
+// dummy typedefs since we don't have vector regs
+constexpr unsigned NumVecElemPerVecReg = 2;
+using VecElem = uint32_t;
+using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
+using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
+using VecRegContainer = VecReg::Container;
+// This has to be one to prevent warnings that are treated as errors
+constexpr unsigned NumVecRegs = 1;
+
 //These floating point types are correct for mmx, but not
 //technically for x87 (80 bits) or at all for xmm (128 bits)
 typedef double FloatReg;
index a8e619cd941186cc3c1a96e7c5b3e4c7e6f3ed87..132c390b370120d5a7b3141f0ec0609e6fa2fa87 100644 (file)
@@ -48,8 +48,8 @@
 
 #include <array>
 #include <bitset>
+#include <deque>
 #include <list>
-#include <queue>
 #include <string>
 
 #include "arch/generic/tlb.hh"
@@ -82,6 +82,7 @@ class BaseDynInst : public ExecContext, public RefCounted
     // Typedef for the CPU.
     typedef typename Impl::CPUType ImplCPU;
     typedef typename ImplCPU::ImplState ImplState;
+    using VecRegContainer = TheISA::VecRegContainer;
 
     // The DynInstPtr type.
     typedef typename Impl::DynInstPtr DynInstPtr;
@@ -591,6 +592,10 @@ class BaseDynInst : public ExecContext, public RefCounted
     int8_t numFPDestRegs()  const { return staticInst->numFPDestRegs(); }
     int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); }
     int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); }
+    int8_t numVecDestRegs() const { return staticInst->numVecDestRegs(); }
+    int8_t numVecElemDestRegs() const {
+        return staticInst->numVecElemDestRegs();
+    }
 
     /** Returns the logical register index of the i'th destination register. */
     const RegId& destRegIdx(int i) const { return staticInst->destRegIdx(i); }
@@ -615,6 +620,8 @@ class BaseDynInst : public ExecContext, public RefCounted
     }
 
     /** Pushes a result onto the instResult queue. */
+    /** @{ */
+    /** Scalar result. */
     template<typename T>
     void setScalarResult(T&& t)
     {
@@ -624,6 +631,27 @@ class BaseDynInst : public ExecContext, public RefCounted
         }
     }
 
+    /** Full vector result. */
+    template<typename T>
+    void setVecResult(T&& t)
+    {
+        if (instFlags[RecordResult]) {
+            instResult.push(InstResult(std::forward<T>(t),
+                        InstResult::ResultType::VecReg));
+        }
+    }
+
+    /** Vector element result. */
+    template<typename T>
+    void setVecElemResult(T&& t)
+    {
+        if (instFlags[RecordResult]) {
+            instResult.push(InstResult(std::forward<T>(t),
+                        InstResult::ResultType::VecElem));
+        }
+    }
+    /** @} */
+
     /** Records an integer register being set to a value. */
     void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
     {
@@ -642,6 +670,13 @@ class BaseDynInst : public ExecContext, public RefCounted
         setScalarResult(val);
     }
 
+    /** Record a vector register being set to a value */
+    void setVecRegOperand(const StaticInst *si, int idx,
+            const VecRegContainer& val)
+    {
+        setVecResult(val);
+    }
+
     /** Records an fp register being set to an integer value. */
     void
     setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val)
@@ -649,6 +684,12 @@ class BaseDynInst : public ExecContext, public RefCounted
         setScalarResult(val);
     }
 
+    /** Record a vector register being set to a value */
+    void setVecElemOperand(const StaticInst *si, int idx, const VecElem val)
+    {
+        setVecElemResult(val);
+    }
+
     /** Records that one of the source registers is ready. */
     void markSrcRegReady();
 
index 6571d034addcb22fb67a31c44d82638915ba3651..213106bd29605e018be264e5f75d899c197b0fd6 100644 (file)
@@ -96,6 +96,7 @@ class CheckerCPU : public BaseCPU, public ExecContext
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::MiscReg MiscReg;
+    using VecRegContainer = TheISA::VecRegContainer;
 
     /** id attached to all issued requests */
     MasterID masterId;
@@ -225,6 +226,111 @@ class CheckerCPU : public BaseCPU, public ExecContext
         return thread->readFloatRegBits(reg.index());
     }
 
+    /**
+     * Read source vector register operand.
+     */
+    const VecRegContainer& readVecRegOperand(const StaticInst *si,
+                                             int idx) const override
+    {
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->readVecReg(reg);
+    }
+
+    /**
+     * Read destination vector register operand for modification.
+     */
+    VecRegContainer& getWritableVecRegOperand(const StaticInst *si,
+                                             int idx) override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->getWritableVecReg(reg);
+    }
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector 8bit operand. */
+    virtual ConstVecLane8
+    readVec8BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->readVec8BitLaneReg(reg);
+    }
+
+    /** Reads source vector 16bit operand. */
+    virtual ConstVecLane16
+    readVec16BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->readVec16BitLaneReg(reg);
+    }
+
+    /** Reads source vector 32bit operand. */
+    virtual ConstVecLane32
+    readVec32BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->readVec32BitLaneReg(reg);
+    }
+
+    /** Reads source vector 64bit operand. */
+    virtual ConstVecLane64
+    readVec64BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->readVec64BitLaneReg(reg);
+    }
+
+    /** Write a lane of the destination vector operand. */
+    template <typename LD>
+    void
+    setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->setVecLane(reg, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::Byte>& val) override
+    {
+        setVecLaneOperandT(si, idx, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::TwoByte>& val) override
+    {
+        setVecLaneOperandT(si, idx, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::FourByte>& val) override
+    {
+        setVecLaneOperandT(si, idx, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::EightByte>& val) override
+    {
+        setVecLaneOperandT(si, idx, val);
+    }
+    /** @} */
+
+    VecElem readVecElemOperand(const StaticInst *si, int idx) const override
+    {
+        const RegId& reg = si->srcRegIdx(idx);
+        return thread->readVecElem(reg);
+    }
+
     CCReg readCCRegOperand(const StaticInst *si, int idx) override
     {
         const RegId& reg = si->srcRegIdx(idx);
@@ -239,6 +345,20 @@ class CheckerCPU : public BaseCPU, public ExecContext
                         InstResult::ResultType::Scalar));
     }
 
+    template<typename T>
+    void setVecResult(T&& t)
+    {
+        result.push(InstResult(std::forward<T>(t),
+                        InstResult::ResultType::VecReg));
+    }
+
+    template<typename T>
+    void setVecElemResult(T&& t)
+    {
+        result.push(InstResult(std::forward<T>(t),
+                        InstResult::ResultType::VecElem));
+    }
+
     void setIntRegOperand(const StaticInst *si, int idx,
                           IntReg val) override
     {
@@ -274,6 +394,24 @@ class CheckerCPU : public BaseCPU, public ExecContext
         setScalarResult((uint64_t)val);
     }
 
+    void setVecRegOperand(const StaticInst *si, int idx,
+                                const VecRegContainer& val) override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        thread->setVecReg(reg, val);
+        setVecResult(val);
+    }
+
+    void setVecElemOperand(const StaticInst *si, int idx,
+                           const VecElem val) override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecElem());
+        thread->setVecElem(reg, val);
+        setVecElemResult(val);
+    }
+
     bool readPredicate() override { return thread->readPredicate(); }
     void setPredicate(bool val) override
     {
index ed86aec844d44b5f687c1364098e5f9580d83ec4..d81858c145cc32e4f82d3159773c4f5f4e8d5d9c 100644 (file)
@@ -486,6 +486,7 @@ Checker<Impl>::validateExecution(DynInstPtr &inst)
     int idx = -1;
     bool result_mismatch = false;
     bool scalar_mismatch = false;
+    bool vector_mismatch = false;
 
     if (inst->isUnverifiable()) {
         // Unverifiable instructions assume they were executed
@@ -503,8 +504,10 @@ Checker<Impl>::validateExecution(DynInstPtr &inst)
             if (checker_val != inst_val) {
                 result_mismatch = true;
                 idx = i;
-                scalar_mismatch = true;
-                break;
+                scalar_mismatch = checker_val.isScalar();
+                vector_mismatch = checker_val.isVector();
+                panic_if(!(scalar_mismatch || vector_mismatch),
+                        "Unknown type of result\n");
             }
         }
     } // Checker CPU checks all the saved results in the dyninst passed by
@@ -610,6 +613,15 @@ Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
             panic_if(!mismatch_val.isScalar(), "Unexpected type of result");
             thread->setFloatRegBits(idx.index(), mismatch_val.asInteger());
             break;
+          case VecRegClass:
+            panic_if(!mismatch_val.isVector(), "Unexpected type of result");
+            thread->setVecReg(idx, mismatch_val.asVector());
+            break;
+          case VecElemClass:
+            panic_if(!mismatch_val.isVecElem(),
+                     "Unexpected type of result");
+            thread->setVecElem(idx, mismatch_val.asVectorElem());
+            break;
           case CCRegClass:
             panic_if(!mismatch_val.isScalar(), "Unexpected type of result");
             thread->setCCReg(idx.index(), mismatch_val.asInteger());
@@ -618,6 +630,8 @@ Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
             panic_if(!mismatch_val.isScalar(), "Unexpected type of result");
             thread->setMiscReg(idx.index(), mismatch_val.asInteger());
             break;
+          default:
+            panic("Unknown register class: %d", (int)idx.classValue());
         }
     }
     start_idx++;
@@ -634,6 +648,14 @@ Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
             panic_if(!res.isScalar(), "Unexpected type of result");
             thread->setFloatRegBits(idx.index(), res.asInteger());
             break;
+          case VecRegClass:
+            panic_if(!res.isVector(), "Unexpected type of result");
+            thread->setVecReg(idx, res.asVector());
+            break;
+          case VecElemClass:
+            panic_if(!res.isVecElem(), "Unexpected type of result");
+            thread->setVecElem(idx, res.asVectorElem());
+            break;
           case CCRegClass:
             panic_if(!res.isScalar(), "Unexpected type of result");
             thread->setCCReg(idx.index(), res.asInteger());
@@ -644,6 +666,8 @@ Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
             thread->setMiscReg(idx.index(), 0);
             break;
             // else Register is out of range...
+          default:
+            panic("Unknown register class: %d", (int)idx.classValue());
         }
     }
 }
index e48f5936b8fb70d096fabffe81f2f11371cacf7c..5208932decaf697ab7c9c4087b196511c26791b1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2011-2012, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -215,6 +215,55 @@ class CheckerThreadContext : public ThreadContext
     FloatRegBits readFloatRegBits(int reg_idx)
     { return actualTC->readFloatRegBits(reg_idx); }
 
+    const VecRegContainer& readVecReg(const RegId& reg) const
+    { return actualTC->readVecReg(reg); }
+
+    /**
+     * Read vector register for modification, hierarchical indexing.
+     */
+    VecRegContainer& getWritableVecReg(const RegId& reg)
+    { return actualTC->getWritableVecReg(reg); }
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector 8bit operand. */
+    ConstVecLane8
+    readVec8BitLaneReg(const RegId& reg) const
+    { return actualTC->readVec8BitLaneReg(reg); }
+
+    /** Reads source vector 16bit operand. */
+    ConstVecLane16
+    readVec16BitLaneReg(const RegId& reg) const
+    { return actualTC->readVec16BitLaneReg(reg); }
+
+    /** Reads source vector 32bit operand. */
+    ConstVecLane32
+    readVec32BitLaneReg(const RegId& reg) const
+    { return actualTC->readVec32BitLaneReg(reg); }
+
+    /** Reads source vector 64bit operand. */
+    ConstVecLane64
+    readVec64BitLaneReg(const RegId& reg) const
+    { return actualTC->readVec64BitLaneReg(reg); }
+
+    /** Write a lane of the destination vector register. */
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::Byte>& val)
+    { return actualTC->setVecLane(reg, val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::TwoByte>& val)
+    { return actualTC->setVecLane(reg, val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::FourByte>& val)
+    { return actualTC->setVecLane(reg, val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::EightByte>& val)
+    { return actualTC->setVecLane(reg, val); }
+    /** @} */
+
+    const VecElem& readVecElem(const RegId& reg) const
+    { return actualTC->readVecElem(reg); }
+
     CCReg readCCReg(int reg_idx)
     { return actualTC->readCCReg(reg_idx); }
 
@@ -236,6 +285,18 @@ class CheckerThreadContext : public ThreadContext
         checkerTC->setFloatRegBits(reg_idx, val);
     }
 
+    void setVecReg(const RegId& reg, const VecRegContainer& val)
+    {
+        actualTC->setVecReg(reg, val);
+        checkerTC->setVecReg(reg, val);
+    }
+
+    void setVecElem(const RegId& reg, const VecElem& val)
+    {
+        actualTC->setVecElem(reg, val);
+        checkerTC->setVecElem(reg, val);
+    }
+
     void setCCReg(int reg_idx, CCReg val)
     {
         actualTC->setCCReg(reg_idx, val);
@@ -333,6 +394,26 @@ class CheckerThreadContext : public ThreadContext
     void setFloatRegBitsFlat(int idx, FloatRegBits val)
     { actualTC->setFloatRegBitsFlat(idx, val); }
 
+    const VecRegContainer& readVecRegFlat(int idx) const
+    { return actualTC->readVecRegFlat(idx); }
+
+    /**
+     * Read vector register for modification, flat indexing.
+     */
+    VecRegContainer& getWritableVecRegFlat(int idx)
+    { return actualTC->getWritableVecRegFlat(idx); }
+
+    void setVecRegFlat(int idx, const VecRegContainer& val)
+    { actualTC->setVecRegFlat(idx, val); }
+
+    const VecElem& readVecElemFlat(const RegIndex& idx,
+                                   const ElemIndex& elem_idx) const
+    { return actualTC->readVecElemFlat(idx, elem_idx); }
+
+    void setVecElemFlat(const RegIndex& idx,
+                        const ElemIndex& elem_idx, const VecElem& val)
+    { actualTC->setVecElemFlat(idx, elem_idx, val); }
+
     CCReg readCCRegFlat(int idx)
     { return actualTC->readCCRegFlat(idx); }
 
index d331472407c4f7f7d254f90f5126fb9f618101f3..e7f5d37ac790c39d36735bc1d30595a75f97a1e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 ARM Limited
+ * Copyright (c) 2014, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -79,6 +79,8 @@ class ExecContext {
     typedef TheISA::MiscReg MiscReg;
 
     typedef TheISA::CCReg CCReg;
+    using VecRegContainer = TheISA::VecRegContainer;
+    using VecElem = TheISA::VecElem;
 
   public:
     /**
@@ -121,6 +123,63 @@ class ExecContext {
 
     /** @} */
 
+    /** Vector Register Interfaces. */
+    /** @{ */
+    /** Reads source vector register operand. */
+    virtual const VecRegContainer&
+    readVecRegOperand(const StaticInst *si, int idx) const = 0;
+
+    /** Gets destination vector register operand for modification. */
+    virtual VecRegContainer&
+    getWritableVecRegOperand(const StaticInst *si, int idx) = 0;
+
+    /** Sets a destination vector register operand to a value. */
+    virtual void
+    setVecRegOperand(const StaticInst *si, int idx,
+                     const VecRegContainer& val) = 0;
+    /** @} */
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector 8bit operand. */
+    virtual ConstVecLane8
+    readVec8BitLaneOperand(const StaticInst *si, int idx) const = 0;
+
+    /** Reads source vector 16bit operand. */
+    virtual ConstVecLane16
+    readVec16BitLaneOperand(const StaticInst *si, int idx) const = 0;
+
+    /** Reads source vector 32bit operand. */
+    virtual ConstVecLane32
+    readVec32BitLaneOperand(const StaticInst *si, int idx) const = 0;
+
+    /** Reads source vector 64bit operand. */
+    virtual ConstVecLane64
+    readVec64BitLaneOperand(const StaticInst *si, int idx) const = 0;
+
+    /** Write a lane of the destination vector operand. */
+    /** @{ */
+    virtual void setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::Byte>& val) = 0;
+    virtual void setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::TwoByte>& val) = 0;
+    virtual void setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::FourByte>& val) = 0;
+    virtual void setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::EightByte>& val) = 0;
+    /** @} */
+
+    /** Vector Elem Interfaces. */
+    /** @{ */
+    /** Reads an element of a vector register. */
+    virtual VecElem readVecElemOperand(const StaticInst *si,
+                                        int idx) const = 0;
+
+    /** Sets a vector register to a value. */
+    virtual void setVecElemOperand(const StaticInst *si, int idx,
+                                   const VecElem val) = 0;
+    /** @} */
+
     /**
      * @{
      * @name Condition Code Registers
index f6f14fe199e36616ee21fd215d748e5b145a6c90..9b6a23d954f2d0f53cb5b2c673af0e9a11b11214 100644 (file)
 #include <type_traits>
 
 #include "arch/generic/types.hh"
+#include "arch/generic/vec_reg.hh"
 
 class InstResult {
+    using VecRegContainer = TheISA::VecRegContainer;
+    using VecElem = TheISA::VecElem;
   public:
     union MultiResult {
         uint64_t integer;
         double dbl;
+        VecRegContainer vector;
+        VecElem vecElem;
         MultiResult() {}
     };
 
     enum class ResultType {
         Scalar,
+        VecElem,
+        VecReg,
         NumResultTypes,
         Invalid
     };
@@ -77,7 +84,32 @@ class InstResult {
             result.dbl = i;
         }
     }
+    /** Vector result. */
+    explicit InstResult(const VecRegContainer& v, const ResultType& t)
+        : type(t) { result.vector = v; }
 
+    InstResult& operator=(const InstResult& that) {
+        type = that.type;
+        switch (type) {
+        /* Given that misc regs are not written to, there may be invalids in
+         * the result stack. */
+        case ResultType::Invalid:
+            break;
+        case ResultType::Scalar:
+            result.integer = that.result.integer;
+            break;
+        case ResultType::VecElem:
+            result.vecElem = that.result.vecElem;
+            break;
+        case ResultType::VecReg:
+            result.vector = that.result.vector;
+            break;
+        default:
+            panic("Assigning result from unknown result type");
+            break;
+        }
+        return *this;
+    }
     /**
      * Result comparison
      * Two invalid results always differ.
@@ -88,6 +120,10 @@ class InstResult {
         switch (type) {
         case ResultType::Scalar:
             return result.integer == that.result.integer;
+        case ResultType::VecElem:
+            return result.vecElem == that.result.vecElem;
+        case ResultType::VecReg:
+            return result.vector == that.result.vector;
         case ResultType::Invalid:
             return false;
         default:
@@ -103,6 +139,10 @@ class InstResult {
     /** @{ */
     /** Is this a scalar result?. */
     bool isScalar() const { return type == ResultType::Scalar; }
+    /** Is this a vector result?. */
+    bool isVector() const { return type == ResultType::VecReg; }
+    /** Is this a vector element result?. */
+    bool isVecElem() const { return type == ResultType::VecElem; }
     /** Is this a valid result?. */
     bool isValid() const { return type != ResultType::Invalid; }
     /** @} */
@@ -125,6 +165,18 @@ class InstResult {
     {
         return result.integer;
     }
+    const VecRegContainer&
+    asVector() const
+    {
+        panic_if(!isVector(), "Converting scalar (or invalid) to vector!!");
+        return result.vector;
+    }
+    const VecElem&
+    asVectorElem() const
+    {
+        panic_if(!isVecElem(), "Converting scalar (or invalid) to vector!!");
+        return result.vecElem;
+    }
     /** @} */
 };
 
index 1ed5988333c01f4843c2b09ed04f815ee64c6fff..756b214bd7d62b828b116d5674de34f5e2794c43 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014 ARM Limited
+ * Copyright (c) 2013-2014, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -153,6 +153,13 @@ printRegName(std::ostream &os, const RegId& reg)
       case FloatRegClass:
         os << 'f' << static_cast<unsigned int>(reg.index());
         break;
+      case VecRegClass:
+        os << 'v' << static_cast<unsigned int>(reg.index());
+        break;
+      case VecElemClass:
+        os << 'v' << static_cast<unsigned int>(reg.index()) << '[' <<
+              static_cast<unsigned int>(reg.elemIndex()) << ']';
+        break;
       case IntRegClass:
         if (reg.isZeroReg()) {
             os << 'z';
@@ -162,6 +169,8 @@ printRegName(std::ostream &os, const RegId& reg)
         break;
       case CCRegClass:
         os << 'c' << static_cast<unsigned int>(reg.index());
+      default:
+        panic("Unknown register class: %d", (int)reg.classValue());
     }
 }
 
index e91b7a6dde912560daca554caf24e1e08527aa43..4b3a02fca4c1e96800c8c3406020bff21bfea2cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014 ARM Limited
+ * Copyright (c) 2011-2014, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -145,6 +145,30 @@ class ExecContext : public ::ExecContext
         return thread.readFloatRegBits(reg.index());
     }
 
+    const TheISA::VecRegContainer&
+    readVecRegOperand(const StaticInst *si, int idx) const override
+    {
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread.readVecReg(reg);
+    }
+
+    TheISA::VecRegContainer&
+    getWritableVecRegOperand(const StaticInst *si, int idx) override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread.getWritableVecReg(reg);
+    }
+
+    TheISA::VecElem
+    readVecElemOperand(const StaticInst *si, int idx) const override
+    {
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread.readVecElem(reg);
+    }
+
     void
     setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
     {
@@ -171,6 +195,102 @@ class ExecContext : public ::ExecContext
         thread.setFloatRegBits(reg.index(), val);
     }
 
+    void
+    setVecRegOperand(const StaticInst *si, int idx,
+                     const TheISA::VecRegContainer& val) override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        thread.setVecReg(reg, val);
+    }
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector 8bit operand. */
+    ConstVecLane8
+    readVec8BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    {
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread.readVec8BitLaneReg(reg);
+    }
+
+    /** Reads source vector 16bit operand. */
+    ConstVecLane16
+    readVec16BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    {
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread.readVec16BitLaneReg(reg);
+    }
+
+    /** Reads source vector 32bit operand. */
+    ConstVecLane32
+    readVec32BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    {
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread.readVec32BitLaneReg(reg);
+    }
+
+    /** Reads source vector 64bit operand. */
+    ConstVecLane64
+    readVec64BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    {
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread.readVec64BitLaneReg(reg);
+    }
+
+    /** Write a lane of the destination vector operand. */
+    template <typename LD>
+    void
+    setVecLaneOperandT(const StaticInst *si, int idx,
+            const LD& val)
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread.setVecLane(reg, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::Byte>& val) override
+    {
+        setVecLaneOperandT(si, idx, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::TwoByte>& val) override
+    {
+        setVecLaneOperandT(si, idx, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::FourByte>& val) override
+    {
+        setVecLaneOperandT(si, idx, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::EightByte>& val) override
+    {
+        setVecLaneOperandT(si, idx, val);
+    }
+    /** @} */
+
+    void
+    setVecElemOperand(const StaticInst *si, int idx,
+                      const TheISA::VecElem val) override
+    {
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        thread.setVecElem(reg, val);
+    }
+
     bool
     readPredicate() override
     {
index e3497a5cfe05270ac089eed2ae3ed5f4828d303f..c56d3b30302da887ebd0bc3fcfc6f9396c29934d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014 ARM Limited
+ * Copyright (c) 2013-2014, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -67,6 +67,16 @@ Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
                 reg.index();
             ret = true;
             break;
+          case VecRegClass:
+            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
+                TheISA::NumFloatRegs + reg.index();
+            ret = true;
+            break;
+          case VecElemClass:
+            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
+                TheISA::NumFloatRegs + TheISA::NumVecRegs + reg.index();
+            ret = true;
+            break;
           case CCRegClass:
             scoreboard_index = TheISA::NumIntRegs + reg.index();
             ret = true;
@@ -75,6 +85,9 @@ Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
               /* Don't bother with Misc registers */
             ret = false;
             break;
+          default:
+            panic("Unknown register class: %d",
+                    static_cast<int>(reg.classValue()));
         }
     }
 
index 7fe5002f9e4e2cd37fbe2470dc37a2fa94f1cea6..9e42c2a6b184bcdc1f3493df70d495f89b02807c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014 ARM Limited
+ * Copyright (c) 2013-2014, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -94,7 +94,7 @@ class Scoreboard : public Named
     Scoreboard(const std::string &name) :
         Named(name),
         numRegs(TheISA::NumIntRegs + TheISA::NumCCRegs +
-            TheISA::NumFloatRegs),
+            TheISA::NumFloatRegs + TheISA::NumVecRegs),
         numResults(numRegs, 0),
         numUnpredictableResults(numRegs, 0),
         fuIndices(numRegs, 0),
index cab2cf34f820da522683e5a47af674f3ed00b1c6..8507ab6ff38bd07c7e1dd2289dfb1d66ab49d9eb 100644 (file)
@@ -1,3 +1,15 @@
+# Copyright (c) 2016 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.
+#
 # Copyright (c) 2005-2007 The Regents of The University of Michigan
 # All rights reserved.
 #
@@ -125,6 +137,8 @@ class DerivO3CPU(BaseCPU):
         # (it's a side effect of int reg renaming), so they should
         # never be the bottleneck here.
         _defaultNumPhysCCRegs = Self.numPhysIntRegs * 5
+    numPhysVecRegs = Param.Unsigned(256, "Number of physical vector "
+                                      "registers")
     numPhysCCRegs = Param.Unsigned(_defaultNumPhysCCRegs,
                                    "Number of physical cc registers")
     numIQEntries = Param.Unsigned(64, "Number of instruction queue entries")
index 49e153a52568d4bb9c391c4554ef82318e4ad85f..f5be5a804a2ed66d2d36baa71cb44b5ae3090b55 100644 (file)
@@ -75,12 +75,18 @@ class PhysRegId : private RegId {
         : RegId(_regClass, _regIdx), flatIdx(_flatIdx)
     {}
 
+    /** Vector PhysRegId constructor (w/ elemIndex). */
+    explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
+              ElemIndex elem_idx, PhysRegIndex flat_idx)
+        : RegId(_regClass, _regIdx, elem_idx), flatIdx(flat_idx) { }
+
     /** Visible RegId methods */
     /** @{ */
     using RegId::index;
     using RegId::classValue;
     using RegId::isZeroReg;
     using RegId::className;
+    using RegId::elemIndex;
      /** @} */
     /**
      * Explicit forward methods, to prevent comparisons of PhysRegId with
@@ -109,6 +115,12 @@ class PhysRegId : private RegId {
     /** @Return true if it is a  condition-code physical register. */
     bool isCCPhysReg() const { return isCCReg(); }
 
+    /** @Return true if it is a vector physical register. */
+    bool isVectorPhysReg() const { return isVecReg(); }
+
+    /** @Return true if it is a vector element physical register. */
+    bool isVectorPhysElem() const { return isVecElem(); }
+
     /** @Return true if it is a  condition-code physical register. */
     bool isMiscPhysReg() const { return isMiscReg(); }
 
@@ -123,11 +135,18 @@ class PhysRegId : private RegId {
 
     /** Flat index accessor */
     const PhysRegIndex& flatIndex() const { return flatIdx; }
+
+    static PhysRegId elemId(const PhysRegId* vid, ElemIndex elem)
+    {
+        assert(vid->isVectorPhysReg());
+        return PhysRegId(VecElemClass, vid->index(), elem);
+    }
 };
 
-// PhysRegIds only need to be created once and then we can use the following
-// to work with them
-typedef const PhysRegId* PhysRegIdPtr;
+/** Constant pointer definition.
+ * PhysRegIds only need to be created once and then we can just share
+ * pointers */
+using PhysRegIdPtr = const PhysRegId*;
 
 /** Struct that defines the information passed from fetch to decode. */
 template<class Impl>
index a7a39b72a5219344b90f1a0d1b737c2eb45fc57d..c249d90ba1aedc4cea4717464be10d750fd28b76 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, 2014 ARM Limited
+ * Copyright (c) 2011-2012, 2014, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -46,6 +46,7 @@
 
 #include "cpu/o3/cpu.hh"
 
+#include "arch/generic/traits.hh"
 #include "arch/kernel_stats.hh"
 #include "config/the_isa.hh"
 #include "cpu/activity.hh"
@@ -171,9 +172,14 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
       iew(this, params),
       commit(this, params),
 
+      /* It is mandatory that all SMT threads use the same renaming mode as
+       * they are sharing registers and rename */
+      vecMode(initRenameMode<TheISA::ISA>::mode(params->isa[0])),
       regFile(params->numPhysIntRegs,
               params->numPhysFloatRegs,
-              params->numPhysCCRegs),
+              params->numPhysVecRegs,
+              params->numPhysCCRegs,
+              vecMode),
 
       freeList(name() + ".freelist", &regFile),
 
@@ -270,6 +276,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
     //Make Sure That this a Valid Architeture
     assert(params->numPhysIntRegs   >= numThreads * TheISA::NumIntRegs);
     assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
+    assert(params->numPhysVecRegs >= numThreads * TheISA::NumVecRegs);
     assert(params->numPhysCCRegs >= numThreads * TheISA::NumCCRegs);
 
     rename.setScoreboard(&scoreboard);
@@ -278,6 +285,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
     // Setup the rename map for whichever stages need it.
     for (ThreadID tid = 0; tid < numThreads; tid++) {
         isa[tid] = params->isa[tid];
+        assert(initRenameMode<TheISA::ISA>::equals(isa[tid], isa[0]));
 
         // Only Alpha has an FP zero register, so for other ISAs we
         // use an invalid FP register index to avoid special treatment
@@ -287,10 +295,11 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
             (THE_ISA == ALPHA_ISA) ? TheISA::ZeroReg : invalidFPReg;
 
         commitRenameMap[tid].init(&regFile, TheISA::ZeroReg, fpZeroReg,
-                                  &freeList);
+                                  &freeList,
+                                  vecMode);
 
         renameMap[tid].init(&regFile, TheISA::ZeroReg, fpZeroReg,
-                            &freeList);
+                            &freeList, vecMode);
     }
 
     // Initialize rename map to assign physical registers to the
@@ -311,6 +320,30 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
                     RegId(FloatRegClass, ridx), phys_reg);
         }
 
+        /* Here we need two 'interfaces' the 'whole register' and the
+         * 'register element'. At any point only one of them will be
+         * active. */
+        if (vecMode == Enums::Full) {
+            /* Initialize the full-vector interface */
+            for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
+                RegId rid = RegId(VecRegClass, ridx);
+                PhysRegIdPtr phys_reg = freeList.getVecReg();
+                renameMap[tid].setEntry(rid, phys_reg);
+                commitRenameMap[tid].setEntry(rid, phys_reg);
+            }
+        } else {
+            /* Initialize the vector-element interface */
+            for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
+                for (ElemIndex ldx = 0; ldx < TheISA::NumVecElemPerVecReg;
+                        ++ldx) {
+                    RegId lrid = RegId(VecElemClass, ridx, ldx);
+                    PhysRegIdPtr phys_elem = freeList.getVecElem();
+                    renameMap[tid].setEntry(lrid, phys_elem);
+                    commitRenameMap[tid].setEntry(lrid, phys_elem);
+                }
+            }
+        }
+
         for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
             PhysRegIdPtr phys_reg = freeList.getCCReg();
             renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
@@ -514,6 +547,16 @@ FullO3CPU<Impl>::regStats()
         .desc("number of floating regfile writes")
         .prereq(fpRegfileWrites);
 
+    vecRegfileReads
+        .name(name() + ".vec_regfile_reads")
+        .desc("number of vector regfile reads")
+        .prereq(vecRegfileReads);
+
+    vecRegfileWrites
+        .name(name() + ".vec_regfile_writes")
+        .desc("number of vector regfile writes")
+        .prereq(vecRegfileWrites);
+
     ccRegfileReads
         .name(name() + ".cc_regfile_reads")
         .desc("number of cc regfile reads")
@@ -1256,6 +1299,32 @@ FullO3CPU<Impl>::readFloatRegBits(PhysRegIdPtr phys_reg)
     return regFile.readFloatRegBits(phys_reg);
 }
 
+template <class Impl>
+auto
+FullO3CPU<Impl>::readVecReg(PhysRegIdPtr phys_reg) const
+        -> const VecRegContainer&
+{
+    vecRegfileReads++;
+    return regFile.readVecReg(phys_reg);
+}
+
+template <class Impl>
+auto
+FullO3CPU<Impl>::getWritableVecReg(PhysRegIdPtr phys_reg)
+        -> VecRegContainer&
+{
+    vecRegfileWrites++;
+    return regFile.getWritableVecReg(phys_reg);
+}
+
+template <class Impl>
+auto
+FullO3CPU<Impl>::readVecElem(PhysRegIdPtr phys_reg) const -> const VecElem&
+{
+    vecRegfileReads++;
+    return regFile.readVecElem(phys_reg);
+}
+
 template <class Impl>
 CCReg
 FullO3CPU<Impl>::readCCReg(PhysRegIdPtr phys_reg)
@@ -1288,6 +1357,22 @@ FullO3CPU<Impl>::setFloatRegBits(PhysRegIdPtr phys_reg, FloatRegBits val)
     regFile.setFloatRegBits(phys_reg, val);
 }
 
+template <class Impl>
+void
+FullO3CPU<Impl>::setVecReg(PhysRegIdPtr phys_reg, const VecRegContainer& val)
+{
+    vecRegfileWrites++;
+    regFile.setVecReg(phys_reg, val);
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::setVecElem(PhysRegIdPtr phys_reg, const VecElem& val)
+{
+    vecRegfileWrites++;
+    regFile.setVecElem(phys_reg, val);
+}
+
 template <class Impl>
 void
 FullO3CPU<Impl>::setCCReg(PhysRegIdPtr phys_reg, CCReg val)
@@ -1329,6 +1414,36 @@ FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid)
     return regFile.readFloatRegBits(phys_reg);
 }
 
+template <class Impl>
+auto
+FullO3CPU<Impl>::readArchVecReg(int reg_idx, ThreadID tid) const
+        -> const VecRegContainer&
+{
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+                RegId(VecRegClass, reg_idx));
+    return readVecReg(phys_reg);
+}
+
+template <class Impl>
+auto
+FullO3CPU<Impl>::getWritableArchVecReg(int reg_idx, ThreadID tid)
+        -> VecRegContainer&
+{
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+                RegId(VecRegClass, reg_idx));
+    return getWritableVecReg(phys_reg);
+}
+
+template <class Impl>
+auto
+FullO3CPU<Impl>::readArchVecElem(const RegIndex& reg_idx, const ElemIndex& ldx,
+                                 ThreadID tid) const -> const VecElem&
+{
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+                                RegId(VecRegClass, reg_idx, ldx));
+    return readVecElem(phys_reg);
+}
+
 template <class Impl>
 CCReg
 FullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid)
@@ -1373,6 +1488,26 @@ FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
     regFile.setFloatRegBits(phys_reg, val);
 }
 
+template <class Impl>
+void
+FullO3CPU<Impl>::setArchVecReg(int reg_idx, const VecRegContainer& val,
+                               ThreadID tid)
+{
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+                RegId(VecRegClass, reg_idx));
+    setVecReg(phys_reg, val);
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::setArchVecElem(const RegIndex& reg_idx, const ElemIndex& ldx,
+                                const VecElem& val, ThreadID tid)
+{
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+                RegId(VecRegClass, reg_idx, ldx));
+    setVecElem(phys_reg, val);
+}
+
 template <class Impl>
 void
 FullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid)
index b5cbc5fe2a6895d3db23af391120a47be5c745c8..d78d1b9d3b6a00edb1118bac54ff8c1ab10da58d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2013 ARM Limited
+ * Copyright (c) 2011-2013, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -53,6 +53,7 @@
 #include <set>
 #include <vector>
 
+#include "arch/generic/types.hh"
 #include "arch/types.hh"
 #include "base/statistics.hh"
 #include "config/the_isa.hh"
@@ -103,6 +104,9 @@ class FullO3CPU : public BaseO3CPU
     typedef typename Impl::DynInstPtr DynInstPtr;
     typedef typename Impl::O3CPU O3CPU;
 
+    using VecElem =  TheISA::VecElem;
+    using VecRegContainer =  TheISA::VecRegContainer;
+
     typedef O3ThreadState<Impl> ImplState;
     typedef O3ThreadState<Impl> Thread;
 
@@ -417,6 +421,46 @@ class FullO3CPU : public BaseO3CPU
 
     TheISA::FloatRegBits readFloatRegBits(PhysRegIdPtr phys_reg);
 
+    const VecRegContainer& readVecReg(PhysRegIdPtr reg_idx) const;
+
+    /**
+     * Read physical vector register for modification.
+     */
+    VecRegContainer& getWritableVecReg(PhysRegIdPtr reg_idx);
+
+    /**
+     * Read physical vector register lane
+     */
+    template<typename VecElem, int LaneIdx>
+    VecLaneT<VecElem, true>
+    readVecLane(PhysRegIdPtr phys_reg) const
+    {
+        vecRegfileReads++;
+        return regFile.readVecLane<VecElem, LaneIdx>(phys_reg);
+    }
+
+    /**
+     * Read physical vector register lane
+     */
+    template<typename VecElem>
+    VecLaneT<VecElem, true>
+    readVecLane(PhysRegIdPtr phys_reg) const
+    {
+        vecRegfileReads++;
+        return regFile.readVecLane<VecElem>(phys_reg);
+    }
+
+    /** Write a lane of the destination vector register. */
+    template<typename LD>
+    void
+    setVecLane(PhysRegIdPtr phys_reg, const LD& val)
+    {
+        vecRegfileWrites++;
+        return regFile.setVecLane(phys_reg, val);
+    }
+
+    const VecElem& readVecElem(PhysRegIdPtr reg_idx) const;
+
     TheISA::CCReg readCCReg(PhysRegIdPtr phys_reg);
 
     void setIntReg(PhysRegIdPtr phys_reg, uint64_t val);
@@ -425,6 +469,10 @@ class FullO3CPU : public BaseO3CPU
 
     void setFloatRegBits(PhysRegIdPtr phys_reg, TheISA::FloatRegBits val);
 
+    void setVecReg(PhysRegIdPtr reg_idx, const VecRegContainer& val);
+
+    void setVecElem(PhysRegIdPtr reg_idx, const VecElem& val);
+
     void setCCReg(PhysRegIdPtr phys_reg, TheISA::CCReg val);
 
     uint64_t readArchIntReg(int reg_idx, ThreadID tid);
@@ -433,6 +481,34 @@ class FullO3CPU : public BaseO3CPU
 
     uint64_t readArchFloatRegInt(int reg_idx, ThreadID tid);
 
+    const VecRegContainer& readArchVecReg(int reg_idx, ThreadID tid) const;
+    /** Read architectural vector register for modification. */
+    VecRegContainer& getWritableArchVecReg(int reg_idx, ThreadID tid);
+
+    /** Read architectural vector register lane. */
+    template<typename VecElem>
+    VecLaneT<VecElem, true>
+    readArchVecLane(int reg_idx, int lId, ThreadID tid) const
+    {
+        PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+                    RegId(VecRegClass, reg_idx));
+        return readVecLane<VecElem>(phys_reg);
+    }
+
+
+    /** Write a lane of the destination vector register. */
+    template<typename LD>
+    void
+    setArchVecLane(int reg_idx, int lId, ThreadID tid, const LD& val)
+    {
+        PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+                    RegId(VecRegClass, reg_idx));
+        setVecLane(phys_reg, val);
+    }
+
+    const VecElem& readArchVecElem(const RegIndex& reg_idx,
+                                   const ElemIndex& ldx, ThreadID tid) const;
+
     TheISA::CCReg readArchCCReg(int reg_idx, ThreadID tid);
 
     /** Architectural register accessors.  Looks up in the commit
@@ -446,6 +522,11 @@ class FullO3CPU : public BaseO3CPU
 
     void setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid);
 
+    void setArchVecReg(int reg_idx, const VecRegContainer& val, ThreadID tid);
+
+    void setArchVecElem(const RegIndex& reg_idx, const ElemIndex& ldx,
+                        const VecElem& val, ThreadID tid);
+
     void setArchCCReg(int reg_idx, TheISA::CCReg val, ThreadID tid);
 
     /** Sets the commit PC state of a specific thread. */
@@ -540,6 +621,9 @@ class FullO3CPU : public BaseO3CPU
     /** The commit stage. */
     typename CPUPolicy::Commit commit;
 
+    /** The rename mode of the vector registers */
+    Enums::VecRegRenameMode vecMode;
+
     /** The register file. */
     PhysRegFile regFile;
 
@@ -722,6 +806,9 @@ class FullO3CPU : public BaseO3CPU
     //number of float register file accesses
     Stats::Scalar fpRegfileReads;
     Stats::Scalar fpRegfileWrites;
+    //number of vector register file accesses
+    mutable Stats::Scalar vecRegfileReads;
+    Stats::Scalar vecRegfileWrites;
     //number of CC register file accesses
     Stats::Scalar ccRegfileReads;
     Stats::Scalar ccRegfileWrites;
index a6adb4c2080b60c89856a09fbb734f62195dc1d6..0643e7e30cea555319c1c71ca27791d618aaa91b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -72,6 +72,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg   CCReg;
+    using VecRegContainer = TheISA::VecRegContainer;
+    using VecElem = TheISA::VecElem;
+    static constexpr auto NumVecElemPerVecReg = TheISA::NumVecElemPerVecReg;
 
     /** Misc register type. */
     typedef TheISA::MiscReg  MiscReg;
@@ -83,9 +86,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
 
   public:
     /** BaseDynInst constructor given a binary instruction. */
-    BaseO3DynInst(const StaticInstPtr &staticInst, const StaticInstPtr &macroop,
-                  TheISA::PCState pc, TheISA::PCState predPC,
-                  InstSeqNum seq_num, O3CPU *cpu);
+    BaseO3DynInst(const StaticInstPtr &staticInst, const StaticInstPtr
+            &macroop, TheISA::PCState pc, TheISA::PCState predPC,
+            InstSeqNum seq_num, O3CPU *cpu);
 
     /** BaseDynInst constructor given a static inst pointer. */
     BaseO3DynInst(const StaticInstPtr &_staticInst,
@@ -107,6 +110,11 @@ class BaseO3DynInst : public BaseDynInst<Impl>
     void initVars();
 
   protected:
+    /** Explicitation of dependent names. */
+    using BaseDynInst<Impl>::cpu;
+    using BaseDynInst<Impl>::_srcRegIdx;
+    using BaseDynInst<Impl>::_destRegIdx;
+
     /** Values to be written to the destination misc. registers. */
     std::array<MiscReg, TheISA::MaxMiscDestRegs> _destMiscRegVal;
 
@@ -213,19 +221,30 @@ class BaseO3DynInst : public BaseDynInst<Impl>
             switch (original_dest_reg.classValue()) {
               case IntRegClass:
                 this->setIntRegOperand(this->staticInst.get(), idx,
-                                       this->cpu->readIntReg(prev_phys_reg));
+                               this->cpu->readIntReg(prev_phys_reg));
                 break;
               case FloatRegClass:
                 this->setFloatRegOperandBits(this->staticInst.get(), idx,
-                                             this->cpu->readFloatRegBits(prev_phys_reg));
+                               this->cpu->readFloatRegBits(prev_phys_reg));
+                break;
+              case VecRegClass:
+                this->setVecRegOperand(this->staticInst.get(), idx,
+                               this->cpu->readVecReg(prev_phys_reg));
+                break;
+              case VecElemClass:
+                this->setVecElemOperand(this->staticInst.get(), idx,
+                               this->cpu->readVecElem(prev_phys_reg));
                 break;
               case CCRegClass:
                 this->setCCRegOperand(this->staticInst.get(), idx,
-                                      this->cpu->readCCReg(prev_phys_reg));
+                               this->cpu->readCCReg(prev_phys_reg));
                 break;
               case MiscRegClass:
                 // no need to forward misc reg values
                 break;
+              default:
+                panic("Unknown register class: %d",
+                        (int)original_dest_reg.classValue());
             }
         }
     }
@@ -266,6 +285,89 @@ class BaseO3DynInst : public BaseDynInst<Impl>
         return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
     }
 
+    const VecRegContainer&
+    readVecRegOperand(const StaticInst *si, int idx) const
+    {
+        return this->cpu->readVecReg(this->_srcRegIdx[idx]);
+    }
+
+    /**
+     * Read destination vector register operand for modification.
+     */
+    VecRegContainer&
+    getWritableVecRegOperand(const StaticInst *si, int idx)
+    {
+        return this->cpu->getWritableVecReg(this->_destRegIdx[idx]);
+    }
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector 8bit operand. */
+    ConstVecLane8
+    readVec8BitLaneOperand(const StaticInst *si, int idx) const
+    {
+        return cpu->template readVecLane<uint8_t>(_srcRegIdx[idx]);
+    }
+
+    /** Reads source vector 16bit operand. */
+    ConstVecLane16
+    readVec16BitLaneOperand(const StaticInst *si, int idx) const
+    {
+        return cpu->template readVecLane<uint16_t>(_srcRegIdx[idx]);
+    }
+
+    /** Reads source vector 32bit operand. */
+    ConstVecLane32
+    readVec32BitLaneOperand(const StaticInst *si, int idx) const
+    {
+        return cpu->template readVecLane<uint32_t>(_srcRegIdx[idx]);
+    }
+
+    /** Reads source vector 64bit operand. */
+    ConstVecLane64
+    readVec64BitLaneOperand(const StaticInst *si, int idx) const
+    {
+        return cpu->template readVecLane<uint64_t>(_srcRegIdx[idx]);
+    }
+
+    /** Write a lane of the destination vector operand. */
+    template <typename LD>
+    void
+    setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
+    {
+        return cpu->template setVecLane(_destRegIdx[idx], val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::Byte>& val)
+    {
+        return setVecLaneOperandT(si, idx, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::TwoByte>& val)
+    {
+        return setVecLaneOperandT(si, idx, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::FourByte>& val)
+    {
+        return setVecLaneOperandT(si, idx, val);
+    }
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::EightByte>& val)
+    {
+        return setVecLaneOperandT(si, idx, val);
+    }
+    /** @} */
+
+    VecElem readVecElemOperand(const StaticInst *si, int idx) const
+    {
+        return this->cpu->readVecElem(this->_srcRegIdx[idx]);
+    }
+
     CCReg readCCRegOperand(const StaticInst *si, int idx)
     {
         return this->cpu->readCCReg(this->_srcRegIdx[idx]);
@@ -293,6 +395,22 @@ class BaseO3DynInst : public BaseDynInst<Impl>
         BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
     }
 
+    void
+    setVecRegOperand(const StaticInst *si, int idx,
+                     const VecRegContainer& val)
+    {
+        this->cpu->setVecReg(this->_destRegIdx[idx], val);
+        BaseDynInst<Impl>::setVecRegOperand(si, idx, val);
+    }
+
+    void setVecElemOperand(const StaticInst *si, int idx,
+                           const VecElem val)
+    {
+        int reg_idx = idx;
+        this->cpu->setVecElem(this->_destRegIdx[reg_idx], val);
+        BaseDynInst<Impl>::setVecElemOperand(si, idx, val);
+    }
+
     void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
     {
         this->cpu->setCCReg(this->_destRegIdx[idx], val);
index 6fc6cc909a748e69a95e8e62b45d01c4515cc324..f4c26a6973c82196cbf73e5dc43eada18cfe4774 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2016 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.
+ *
  * Copyright (c) 2004-2005 The Regents of The University of Michigan
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
@@ -63,6 +75,16 @@ class SimpleFreeList
     /** Add a physical register to the free list */
     void addReg(PhysRegIdPtr reg) { freeRegs.push(reg); }
 
+    /** Add physical registers to the free list */
+    template<class InputIt>
+    void
+    addRegs(InputIt first, InputIt last) {
+        std::for_each(first, last,
+            [this](const typename InputIt::value_type& reg) {
+                this->freeRegs.push(&reg);
+            });
+    }
+
     /** Get the next available register from the free list */
     PhysRegIdPtr getReg()
     {
@@ -107,6 +129,15 @@ class UnifiedFreeList
     /** The list of free floating point registers. */
     SimpleFreeList floatList;
 
+    /** The following two are exclusive interfaces. */
+    /** @{ */
+    /** The list of free vector registers. */
+    SimpleFreeList vecList;
+
+    /** The list of free vector element registers. */
+    SimpleFreeList vecElemList;
+    /** @} */
+
     /** The list of free condition-code registers. */
     SimpleFreeList ccList;
 
@@ -146,18 +177,36 @@ class UnifiedFreeList
     /** Gets a free fp register. */
     PhysRegIdPtr getFloatReg() { return floatList.getReg(); }
 
+    /** Gets a free vector register. */
+    PhysRegIdPtr getVecReg() { return vecList.getReg(); }
+
+    /** Gets a free vector elemenet register. */
+    PhysRegIdPtr getVecElem() { return vecElemList.getReg(); }
+
     /** Gets a free cc register. */
     PhysRegIdPtr getCCReg() { return ccList.getReg(); }
 
     /** Adds a register back to the free list. */
     void addReg(PhysRegIdPtr freed_reg);
 
+    /** Adds a register back to the free list. */
+    template<class InputIt>
+    void addRegs(InputIt first, InputIt last);
+
     /** Adds an integer register back to the free list. */
     void addIntReg(PhysRegIdPtr freed_reg) { intList.addReg(freed_reg); }
 
     /** Adds a fp register back to the free list. */
     void addFloatReg(PhysRegIdPtr freed_reg) { floatList.addReg(freed_reg); }
 
+    /** Adds a vector register back to the free list. */
+    void addVecReg(PhysRegIdPtr freed_reg) { vecList.addReg(freed_reg); }
+
+    /** Adds a vector element register back to the free list. */
+    void addVecElem(PhysRegIdPtr freed_reg) {
+        vecElemList.addReg(freed_reg);
+    }
+
     /** Adds a cc register back to the free list. */
     void addCCReg(PhysRegIdPtr freed_reg) { ccList.addReg(freed_reg); }
 
@@ -167,6 +216,12 @@ class UnifiedFreeList
     /** Checks if there are any free fp registers. */
     bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); }
 
+    /** Checks if there are any free vector registers. */
+    bool hasFreeVecRegs() const { return vecList.hasFreeRegs(); }
+
+    /** Checks if there are any free vector registers. */
+    bool hasFreeVecElems() const { return vecElemList.hasFreeRegs(); }
+
     /** Checks if there are any free cc registers. */
     bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); }
 
@@ -176,10 +231,49 @@ class UnifiedFreeList
     /** Returns the number of free fp registers. */
     unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); }
 
+    /** Returns the number of free vector registers. */
+    unsigned numFreeVecRegs() const { return vecList.numFreeRegs(); }
+
     /** Returns the number of free cc registers. */
     unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); }
 };
 
+template<class InputIt>
+inline void
+UnifiedFreeList::addRegs(InputIt first, InputIt last)
+{
+    // Are there any registers to add?
+    if (first == last)
+        return;
+
+    panic_if((first != last) &&
+            first->classValue() != (last-1)->classValue(),
+            "Attempt to add mixed type regs: %s and %s",
+            first->className(),
+            (last-1)->className());
+    switch (first->classValue()) {
+        case IntRegClass:
+            intList.addRegs(first, last);
+            break;
+        case FloatRegClass:
+            floatList.addRegs(first, last);
+            break;
+        case VecRegClass:
+            vecList.addRegs(first, last);
+            break;
+        case VecElemClass:
+            vecElemList.addRegs(first, last);
+            break;
+        case CCRegClass:
+            ccList.addRegs(first, last);
+            break;
+        default:
+            panic("Unexpected RegClass (%s)",
+                                   first->className());
+    }
+
+}
+
 inline void
 UnifiedFreeList::addReg(PhysRegIdPtr freed_reg)
 {
@@ -194,6 +288,12 @@ UnifiedFreeList::addReg(PhysRegIdPtr freed_reg)
         case FloatRegClass:
             floatList.addReg(freed_reg);
             break;
+        case VecRegClass:
+            vecList.addReg(freed_reg);
+            break;
+        case VecElemClass:
+            vecElemList.addReg(freed_reg);
+            break;
         case CCRegClass:
             ccList.addReg(freed_reg);
             break;
index f52cf2d6c2163d3b04afb24e064f60353e47f689..2b113ae04518b70a1e21399513e44848f3a15fb7 100644 (file)
@@ -98,8 +98,11 @@ InstructionQueue<Impl>::InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr,
     numThreads = params->numThreads;
 
     // Set the number of total physical registers
+    // As the vector registers have two addressing modes, they are added twice
     numPhysRegs = params->numPhysIntRegs + params->numPhysFloatRegs +
-        params->numPhysCCRegs;
+                    params->numPhysVecRegs +
+                    params->numPhysVecRegs * TheISA::NumVecElemPerVecReg +
+                    params->numPhysCCRegs;
 
     //Create an entry for each physical register within the
     //dependency graph.
index ea4370f48b6eb0f30b5aa8c774b0c92a1e67e20f..2f41e2ac2f786e5fc6adc65484eed91bf591f89b 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2016 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.
+ *
  * Copyright (c) 2004-2005 The Regents of The University of Michigan
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
 
 #include "cpu/o3/regfile.hh"
 
+#include "cpu/o3/free_list.hh"
+#include "arch/generic/types.hh"
 #include "cpu/o3/free_list.hh"
 
 PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
                          unsigned _numPhysicalFloatRegs,
-                         unsigned _numPhysicalCCRegs)
+                         unsigned _numPhysicalVecRegs,
+                         unsigned _numPhysicalCCRegs,
+                         VecMode vmode)
     : intRegFile(_numPhysicalIntRegs),
       floatRegFile(_numPhysicalFloatRegs),
+      vectorRegFile(_numPhysicalVecRegs),
       ccRegFile(_numPhysicalCCRegs),
       numPhysicalIntRegs(_numPhysicalIntRegs),
       numPhysicalFloatRegs(_numPhysicalFloatRegs),
+      numPhysicalVecRegs(_numPhysicalVecRegs),
+      numPhysicalVecElemRegs(_numPhysicalVecRegs *
+                             NumVecElemPerVecReg),
       numPhysicalCCRegs(_numPhysicalCCRegs),
       totalNumRegs(_numPhysicalIntRegs
                    + _numPhysicalFloatRegs
-                   + _numPhysicalCCRegs)
+                   + _numPhysicalVecRegs
+                   + _numPhysicalVecRegs * NumVecElemPerVecReg
+                   + _numPhysicalCCRegs),
+      vecMode(vmode)
 {
     PhysRegIndex phys_reg;
     PhysRegIndex flat_reg_idx = 0;
@@ -68,6 +91,23 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
         floatRegIds.emplace_back(FloatRegClass, phys_reg, flat_reg_idx++);
     }
 
+    // The next batch of the registers are the vector physical
+    // registers; put them onto the vector free list.
+    for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) {
+        vectorRegFile[phys_reg].zero();
+        vecRegIds.emplace_back(VecRegClass, phys_reg, flat_reg_idx++);
+    }
+    // The next batch of the registers are the vector element physical
+    // registers; they refer to the same containers as the vector
+    // registers, just a different (and incompatible) way to access
+    // them; put them onto the vector free list.
+    for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) {
+        for (ElemIndex eIdx = 0; eIdx < NumVecElemPerVecReg; eIdx++) {
+            vecElemIds.emplace_back(VecElemClass, phys_reg,
+                    eIdx, flat_reg_idx++);
+        }
+    }
+
     // The rest of the registers are the condition-code physical
     // registers; put them onto the condition-code free list.
     for (phys_reg = 0; phys_reg < numPhysicalCCRegs; phys_reg++) {
@@ -90,20 +130,90 @@ PhysRegFile::initFreeList(UnifiedFreeList *freeList)
     // The initial batch of registers are the integer ones
     for (reg_idx = 0; reg_idx < numPhysicalIntRegs; reg_idx++) {
         assert(intRegIds[reg_idx].index() == reg_idx);
-        freeList->addIntReg(&intRegIds[reg_idx]);
     }
+    freeList->addRegs(intRegIds.begin(), intRegIds.end());
 
     // The next batch of the registers are the floating-point physical
     // registers; put them onto the floating-point free list.
     for (reg_idx = 0; reg_idx < numPhysicalFloatRegs; reg_idx++) {
         assert(floatRegIds[reg_idx].index() == reg_idx);
-        freeList->addFloatReg(&floatRegIds[reg_idx]);
     }
+    freeList->addRegs(floatRegIds.begin(), floatRegIds.end());
+
+    /* The next batch of the registers are the vector physical
+     * registers; put them onto the vector free list. */
+    for (reg_idx = 0; reg_idx < numPhysicalVecRegs; reg_idx++) {
+        assert(vecRegIds[reg_idx].index() == reg_idx);
+        for (ElemIndex elemIdx = 0; elemIdx < NumVecElemPerVecReg; elemIdx++) {
+            assert(vecElemIds[reg_idx * NumVecElemPerVecReg +
+                    elemIdx].index() == reg_idx);
+            assert(vecElemIds[reg_idx * NumVecElemPerVecReg +
+                    elemIdx].elemIndex() == elemIdx);
+        }
+    }
+
+    /* depending on the mode we add the vector registers as whole units or
+     * as different elements. */
+    if (vecMode == Enums::Full)
+        freeList->addRegs(vecRegIds.begin(), vecRegIds.end());
+    else
+        freeList->addRegs(vecElemIds.begin(), vecElemIds.end());
 
     // The rest of the registers are the condition-code physical
     // registers; put them onto the condition-code free list.
     for (reg_idx = 0; reg_idx < numPhysicalCCRegs; reg_idx++) {
         assert(ccRegIds[reg_idx].index() == reg_idx);
-        freeList->addCCReg(&ccRegIds[reg_idx]);
     }
+    freeList->addRegs(ccRegIds.begin(), ccRegIds.end());
 }
+
+auto
+PhysRegFile::getRegElemIds(PhysRegIdPtr reg) -> IdRange
+{
+    panic_if(!reg->isVectorPhysReg(),
+            "Trying to get elems of a %s register", reg->className());
+    auto idx = reg->index();
+    return std::make_pair(
+                vecElemIds.begin() + idx * NumVecElemPerVecReg,
+                vecElemIds.begin() + (idx+1) * NumVecElemPerVecReg);
+}
+
+auto
+PhysRegFile::getRegIds(RegClass cls) -> IdRange
+{
+    switch (cls)
+    {
+      case IntRegClass:
+        return std::make_pair(intRegIds.begin(), intRegIds.end());
+      case FloatRegClass:
+        return std::make_pair(floatRegIds.begin(), floatRegIds.end());
+      case VecRegClass:
+        return std::make_pair(vecRegIds.begin(), vecRegIds.end());
+      case VecElemClass:
+        return std::make_pair(vecElemIds.begin(), vecElemIds.end());
+      case CCRegClass:
+        return std::make_pair(ccRegIds.begin(), ccRegIds.end());
+      case MiscRegClass:
+        return std::make_pair(miscRegIds.begin(), miscRegIds.end());
+    }
+    /* There is no way to make an empty iterator */
+    return std::make_pair(PhysIds::const_iterator(),
+                          PhysIds::const_iterator());
+}
+
+PhysRegIdPtr
+PhysRegFile::getTrueId(PhysRegIdPtr reg)
+{
+    switch (reg->classValue()) {
+    case VecRegClass:
+        return &vecRegIds[reg->index()];
+    case VecElemClass:
+        return &vecElemIds[reg->index() * NumVecElemPerVecReg +
+            reg->elemIndex()];
+    default:
+        panic_if(!reg->isVectorPhysElem(),
+            "Trying to get the register of a %s register", reg->className());
+    }
+    return nullptr;
+}
+
index c353b2746f48e0a12285cfeac441815f962509b7..7feec933fe3d8be0338367b52543fa6ebbe891d3 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2016 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.
+ *
  * Copyright (c) 2004-2005 The Regents of The University of Michigan
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
@@ -42,6 +54,7 @@
 #include "config/the_isa.hh"
 #include "cpu/o3/comm.hh"
 #include "debug/IEW.hh"
+#include "enums/VecRegRenameMode.hh"
 
 class UnifiedFreeList;
 
@@ -56,6 +69,15 @@ class PhysRegFile
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg CCReg;
+    using VecElem = TheISA::VecElem;
+    using VecRegContainer = TheISA::VecRegContainer;
+    using PhysIds = std::vector<PhysRegId>;
+    using VecMode = Enums::VecRegRenameMode;
+  public:
+    using IdRange = std::pair<PhysIds::const_iterator,
+                              PhysIds::const_iterator>;
+  private:
+    static constexpr auto NumVecElemPerVecReg = TheISA::NumVecElemPerVecReg;
 
     typedef union {
         FloatReg d;
@@ -70,6 +92,11 @@ class PhysRegFile
     std::vector<PhysFloatReg> floatRegFile;
     std::vector<PhysRegId> floatRegIds;
 
+    /** Vector register file. */
+    std::vector<VecRegContainer> vectorRegFile;
+    std::vector<PhysRegId> vecRegIds;
+    std::vector<PhysRegId> vecElemIds;
+
     /** Condition-code register file. */
     std::vector<CCReg> ccRegFile;
     std::vector<PhysRegId> ccRegIds;
@@ -83,18 +110,31 @@ class PhysRegFile
     unsigned numPhysicalIntRegs;
 
     /**
-     * Number of physical general purpose registers
+     * Number of physical floating point registers
      */
     unsigned numPhysicalFloatRegs;
 
     /**
-     * Number of physical general purpose registers
+     * Number of physical vector registers
+     */
+    unsigned numPhysicalVecRegs;
+
+    /**
+     * Number of physical vector element registers
+     */
+    unsigned numPhysicalVecElemRegs;
+
+    /**
+     * Number of physical CC registers
      */
     unsigned numPhysicalCCRegs;
 
     /** Total number of physical registers. */
     unsigned totalNumRegs;
 
+    /** Mode in which vector registers are addressed. */
+    VecMode vecMode;
+
   public:
     /**
      * Constructs a physical register file with the specified amount of
@@ -102,7 +142,10 @@ class PhysRegFile
      */
     PhysRegFile(unsigned _numPhysicalIntRegs,
                 unsigned _numPhysicalFloatRegs,
-                unsigned _numPhysicalCCRegs);
+                unsigned _numPhysicalVecRegs,
+                unsigned _numPhysicalCCRegs,
+                VecMode vmode
+                );
 
     /**
      * Destructor to free resources
@@ -117,6 +160,11 @@ class PhysRegFile
 
     /** @return the number of floating-point physical registers. */
     unsigned numFloatPhysRegs() const { return numPhysicalFloatRegs; }
+    /** @return the number of vector physical registers. */
+    unsigned numVecPhysRegs() const { return numPhysicalVecRegs; }
+
+    /** @return the number of vector physical registers. */
+    unsigned numVecElemPhysRegs() const { return numPhysicalVecElemRegs; }
 
     /** @return the number of condition-code physical registers. */
     unsigned numCCPhysRegs() const { return numPhysicalCCRegs; }
@@ -164,6 +212,68 @@ class PhysRegFile
         return floatRegBits;
     }
 
+    /** Reads a vector register. */
+    const VecRegContainer& readVecReg(PhysRegIdPtr phys_reg) const
+    {
+        assert(phys_reg->isVectorPhysReg());
+
+        DPRINTF(IEW, "RegFile: Access to vector register %i, has "
+                "data %s\n", int(phys_reg->index()),
+                vectorRegFile[phys_reg->index()].as<VecElem>().print());
+
+        return vectorRegFile[phys_reg->index()];
+    }
+
+    /** Reads a vector register for modification. */
+    VecRegContainer& getWritableVecReg(PhysRegIdPtr phys_reg)
+    {
+        /* const_cast for not duplicating code above. */
+        return const_cast<VecRegContainer&>(readVecReg(phys_reg));
+    }
+
+    /** Reads a vector register lane. */
+    template <typename VecElem, int LaneIdx>
+    VecLaneT<VecElem, true>
+    readVecLane(PhysRegIdPtr phys_reg) const
+    {
+        return readVecReg(phys_reg).laneView<VecElem, LaneIdx>();
+    }
+
+    /** Reads a vector register lane. */
+    template <typename VecElem>
+    VecLaneT<VecElem, true>
+    readVecLane(PhysRegIdPtr phys_reg) const
+    {
+        return readVecReg(phys_reg).laneView<VecElem>(phys_reg->elemIndex());
+    }
+
+    /** Get a vector register lane for modification. */
+    template <typename LD>
+    void
+    setVecLane(PhysRegIdPtr phys_reg, const LD& val)
+    {
+        assert(phys_reg->isVectorPhysReg());
+
+        DPRINTF(IEW, "RegFile: Setting vector register %i[%d] to %lx\n",
+                int(phys_reg->index()), phys_reg->elemIndex(), val);
+
+        vectorRegFile[phys_reg->index()].laneView<typename LD::UnderlyingType>(
+                phys_reg->elemIndex()) = val;
+    }
+
+    /** Reads a vector element. */
+    const VecElem& readVecElem(PhysRegIdPtr phys_reg) const
+    {
+        assert(phys_reg->isVectorPhysElem());
+        auto ret = vectorRegFile[phys_reg->index()].as<VecElem>();
+        const VecElem& val = ret[phys_reg->elemIndex()];
+        DPRINTF(IEW, "RegFile: Access to element %d of vector register %i,"
+                " has data %#x\n", phys_reg->elemIndex(),
+                int(phys_reg->index()), val);
+
+        return val;
+    }
+
     /** Reads a condition-code register. */
     CCReg readCCReg(PhysRegIdPtr phys_reg)
     {
@@ -207,7 +317,31 @@ class PhysRegFile
         DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
                 phys_reg->index(), (uint64_t)val);
 
-        floatRegFile[phys_reg->index()].q = val;
+        if (!phys_reg->isZeroReg())
+            floatRegFile[phys_reg->index()].q = val;
+    }
+
+    /** Sets a vector register to the given value. */
+    void setVecReg(PhysRegIdPtr phys_reg, const VecRegContainer& val)
+    {
+        assert(phys_reg->isVectorPhysReg());
+
+        DPRINTF(IEW, "RegFile: Setting vector register %i to %s\n",
+                int(phys_reg->index()), val.print());
+
+        vectorRegFile[phys_reg->index()] = val;
+    }
+
+    /** Sets a vector register to the given value. */
+    void setVecElem(PhysRegIdPtr phys_reg, const VecElem val)
+    {
+        assert(phys_reg->isVectorPhysElem());
+
+        DPRINTF(IEW, "RegFile: Setting element %d of vector register %i to"
+                " %#x\n", phys_reg->elemIndex(), int(phys_reg->index()), val);
+
+        vectorRegFile[phys_reg->index()].as<VecElem>()[phys_reg->elemIndex()] =
+                val;
     }
 
     /** Sets a condition-code register to the given value. */
@@ -220,6 +354,25 @@ class PhysRegFile
 
         ccRegFile[phys_reg->index()] = val;
     }
+
+    /** Get the PhysRegIds of the elems of a vector register.
+     * Auxiliary function to transition from Full vector mode to Elem mode.
+     */
+    IdRange getRegElemIds(PhysRegIdPtr reg);
+
+    /**
+     * Get the PhysRegIds of the elems of all vector registers.
+     * Auxiliary function to transition from Full vector mode to Elem mode
+     * and to initialise the rename map.
+     */
+    IdRange getRegIds(RegClass cls);
+
+     /**
+      * Get the true physical register id.
+      * As many parts work with PhysRegIdPtr, we need to be able to produce
+      * the pointer out of just class and register idx.
+      */
+     PhysRegIdPtr getTrueId(PhysRegIdPtr reg);
 };
 
 
index 6d3861ba69c04006532f95d22fdd1425a1bcdbe1..d0f6ba13d1a79620884ce3a629c3dbf02063530c 100644 (file)
@@ -464,8 +464,6 @@ class DefaultRename
     /** The maximum skid buffer size. */
     unsigned skidBufferMax;
 
-    PhysRegIndex maxPhysicalRegs;
-
     /** Enum to record the source of a structure full stall.  Can come from
      * either ROB, IQ, LSQ, and it is priortized in that order.
      */
@@ -515,6 +513,7 @@ class DefaultRename
     Stats::Scalar renameRenameLookups;
     Stats::Scalar intRenameLookups;
     Stats::Scalar fpRenameLookups;
+    Stats::Scalar vecRenameLookups;
     /** Stat for total number of committed renaming mappings. */
     Stats::Scalar renameCommittedMaps;
     /** Stat for total number of mappings that were undone due to a squash. */
index 9c9b030f57b8963a8be7ff7c5fa0ea821e93b97e..b9adcdff7e8429c35451645ea70e4e8715d3f93d 100644 (file)
@@ -67,9 +67,7 @@ DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params)
       commitToRenameDelay(params->commitToRenameDelay),
       renameWidth(params->renameWidth),
       commitWidth(params->commitWidth),
-      numThreads(params->numThreads),
-      maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs
-                      + params->numPhysCCRegs)
+      numThreads(params->numThreads)
 {
     if (renameWidth > Impl::MaxWidth)
         fatal("renameWidth (%d) is larger than compiled limit (%d),\n"
@@ -182,6 +180,10 @@ DefaultRename<Impl>::regStats()
         .name(name() + ".fp_rename_lookups")
         .desc("Number of floating rename lookups")
         .prereq(fpRenameLookups);
+    vecRenameLookups
+        .name(name() + ".vec_rename_lookups")
+        .desc("Number of vector rename lookups")
+        .prereq(vecRenameLookups);
 }
 
 template <class Impl>
@@ -645,6 +647,8 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
         // to rename to.  Otherwise block.
         if (!renameMap[tid]->canRename(inst->numIntDestRegs(),
                                        inst->numFPDestRegs(),
+                                       inst->numVecDestRegs(),
+                                       inst->numVecElemDestRegs(),
                                        inst->numCCDestRegs())) {
             DPRINTF(Rename, "Blocking due to lack of free "
                     "physical registers to rename to.\n");
@@ -1239,12 +1243,17 @@ DefaultRename<Impl>::readFreeEntries(ThreadID tid)
     }
 
     DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, "
-                    "Free LQ: %i, Free SQ: %i\n",
+                    "Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i)\n",
             tid,
             freeEntries[tid].iqEntries,
             freeEntries[tid].robEntries,
             freeEntries[tid].lqEntries,
-            freeEntries[tid].sqEntries);
+            freeEntries[tid].sqEntries,
+            renameMap[tid]->numFreeEntries(),
+            renameMap[tid]->numFreeIntEntries(),
+            renameMap[tid]->numFreeFloatEntries(),
+            renameMap[tid]->numFreeVecEntries(),
+            renameMap[tid]->numFreeCCEntries());
 
     DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n",
             tid, instsInProgress[tid]);
index 38ccc7ec9ca2117dd5e45ca7605d9de382d6c148..bde2a692195de02b2ddc39ddd0d8bc33e58dde8d 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2016 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.
+ *
  * Copyright (c) 2004-2005 The Regents of The University of Michigan
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
@@ -93,15 +105,92 @@ void
 UnifiedRenameMap::init(PhysRegFile *_regFile,
                        RegIndex _intZeroReg,
                        RegIndex _floatZeroReg,
-                       UnifiedFreeList *freeList)
+                       UnifiedFreeList *freeList,
+                       VecMode _mode)
 {
     regFile = _regFile;
+    vecMode = _mode;
 
     intMap.init(TheISA::NumIntRegs, &(freeList->intList), _intZeroReg);
 
     floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg);
 
+    vecMap.init(TheISA::NumVecRegs, &(freeList->vecList), (RegIndex)-1);
+
+    vecElemMap.init(TheISA::NumVecRegs * NVecElems,
+            &(freeList->vecElemList), (RegIndex)-1);
+
     ccMap.init(TheISA::NumCCRegs, &(freeList->ccList), (RegIndex)-1);
 
 }
 
+void
+UnifiedRenameMap::switchMode(VecMode newVecMode, UnifiedFreeList* freeList)
+{
+    if (newVecMode == Enums::Elem && vecMode == Enums::Full) {
+        /* Switch to vector element rename mode. */
+        /* The free list should currently be tracking full registers. */
+        panic_if(freeList->hasFreeVecElems(),
+                "The free list is already tracking Vec elems");
+        panic_if(freeList->numFreeVecRegs() !=
+                regFile->numVecPhysRegs() - TheISA::NumVecRegs,
+                "The free list has lost vector registers");
+        /* Split the mapping of each arch reg. */
+        int reg = 0;
+        for (auto &e: vecMap) {
+            PhysRegFile::IdRange range = this->regFile->getRegElemIds(e);
+            uint32_t i;
+            for (i = 0; range.first != range.second; i++, range.first++) {
+                vecElemMap.setEntry(RegId(VecElemClass, reg, i),
+                                    &(*range.first));
+            }
+            panic_if(i != NVecElems,
+                "Wrong name of elems: expecting %u, got %d\n",
+                TheISA::NumVecElemPerVecReg, i);
+            reg++;
+        }
+        /* Split the free regs. */
+        while (freeList->hasFreeVecRegs()) {
+            auto vr = freeList->getVecReg();
+            auto range = this->regFile->getRegElemIds(vr);
+            freeList->addRegs(range.first, range.second);
+        }
+        vecMode = Enums::Elem;
+    } else if (newVecMode == Enums::Full && vecMode == Enums::Elem) {
+        /* Switch to full vector register rename mode. */
+        /* The free list should currently be tracking register elems. */
+        panic_if(freeList->hasFreeVecRegs(),
+                "The free list is already tracking full Vec");
+        panic_if(freeList->numFreeVecRegs() !=
+                regFile->numVecElemPhysRegs() - TheISA::NumFloatRegs,
+                "The free list has lost vector register elements");
+        /* To rebuild the arch regs we take the easy road:
+         *  1.- Stitch the elems together into vectors.
+         *  2.- Replace the contents of the register file with the vectors
+         *  3.- Set the remaining registers as free
+         */
+        TheISA::VecRegContainer new_RF[TheISA::NumVecRegs];
+        for (uint32_t i = 0; i < TheISA::NumVecRegs; i++) {
+            VecReg dst = new_RF[i].as<TheISA::VecElem>();
+            for (uint32_t l = 0; l < NVecElems; l++) {
+                RegId s_rid(VecElemClass, i, l);
+                PhysRegIdPtr s_prid = vecElemMap.lookup(s_rid);
+                dst[l] = regFile->readVecElem(s_prid);
+            }
+        }
+
+        for (uint32_t i = 0; i < TheISA::NumVecRegs; i++) {
+            PhysRegId pregId(VecRegClass, i, 0);
+            regFile->setVecReg(regFile->getTrueId(&pregId), new_RF[i]);
+        }
+
+        auto range = regFile->getRegIds(VecRegClass);
+        freeList->addRegs(range.first + TheISA::NumVecRegs, range.second);
+
+        /* We remove the elems from the free list. */
+        while (freeList->hasFreeVecElems())
+            freeList->getVecElem();
+        vecMode = Enums::Full;
+    }
+}
+
index 028c32e3abe873423571fb99c40ee6b1643ed1c2..ab909f0902971dc0338cfb6299ed10b369540bcb 100644 (file)
@@ -54,6 +54,7 @@
 #include "cpu/o3/free_list.hh"
 #include "cpu/o3/regfile.hh"
 #include "cpu/reg_class.hh"
+#include "enums/VecRegRenameMode.hh"
 
 /**
  * Register rename map for a single class of registers (e.g., integer
@@ -68,6 +69,10 @@ class SimpleRenameMap
     using Arch2PhysMap = std::vector<PhysRegIdPtr>;
     /** The acutal arch-to-phys register map */
     Arch2PhysMap map;
+  public:
+    using iterator = Arch2PhysMap::iterator;
+    using const_iterator = Arch2PhysMap::const_iterator;
+  private:
 
     /**
      * Pointer to the free list from which new physical registers
@@ -139,6 +144,20 @@ class SimpleRenameMap
 
     /** Return the number of free entries on the associated free list. */
     unsigned numFreeEntries() const { return freeList->numFreeRegs(); }
+
+    /** Forward begin/cbegin to the map. */
+    /** @{ */
+    iterator begin() { return map.begin(); }
+    const_iterator begin() const { return map.begin(); }
+    const_iterator cbegin() const { return map.cbegin(); }
+    /** @} */
+
+    /** Forward end/cend to the map. */
+    /** @{ */
+    iterator end() { return map.end(); }
+    const_iterator end() const { return map.end(); }
+    const_iterator cend() const { return map.cend(); }
+    /** @} */
 };
 
 
@@ -152,6 +171,8 @@ class SimpleRenameMap
 class UnifiedRenameMap
 {
   private:
+    static constexpr uint32_t NVecElems = TheISA::NumVecElemPerVecReg;
+    using VecReg = TheISA::VecReg;
 
     /** The integer register rename map */
     SimpleRenameMap intMap;
@@ -162,6 +183,15 @@ class UnifiedRenameMap
     /** The condition-code register rename map */
     SimpleRenameMap ccMap;
 
+    /** The vector register rename map */
+    SimpleRenameMap vecMap;
+
+    /** The vector element register rename map */
+    SimpleRenameMap vecElemMap;
+
+    using VecMode = Enums::VecRegRenameMode;
+    VecMode vecMode;
+
     /**
      * The register file object is used only to get PhysRegIdPtr
      * on MiscRegs, as they are stored in it.
@@ -182,7 +212,8 @@ class UnifiedRenameMap
     void init(PhysRegFile *_regFile,
               RegIndex _intZeroReg,
               RegIndex _floatZeroReg,
-              UnifiedFreeList *freeList);
+              UnifiedFreeList *freeList,
+              VecMode _mode);
 
     /**
      * Tell rename map to get a new free physical register to remap
@@ -199,6 +230,12 @@ class UnifiedRenameMap
             return intMap.rename(arch_reg);
           case FloatRegClass:
             return floatMap.rename(arch_reg);
+          case VecRegClass:
+            assert(vecMode == Enums::Full);
+            return vecMap.rename(arch_reg);
+          case VecElemClass:
+            assert(vecMode == Enums::Elem);
+            return vecElemMap.rename(arch_reg);
           case CCRegClass:
             return ccMap.rename(arch_reg);
           case MiscRegClass:
@@ -232,6 +269,14 @@ class UnifiedRenameMap
           case FloatRegClass:
             return  floatMap.lookup(arch_reg);
 
+          case VecRegClass:
+            assert(vecMode == Enums::Full);
+            return  vecMap.lookup(arch_reg);
+
+          case VecElemClass:
+            assert(vecMode == Enums::Elem);
+            return  vecElemMap.lookup(arch_reg);
+
           case CCRegClass:
             return ccMap.lookup(arch_reg);
 
@@ -265,6 +310,16 @@ class UnifiedRenameMap
             assert(phys_reg->isFloatPhysReg());
             return floatMap.setEntry(arch_reg, phys_reg);
 
+          case VecRegClass:
+            assert(phys_reg->isVectorPhysReg());
+            assert(vecMode == Enums::Full);
+            return vecMap.setEntry(arch_reg, phys_reg);
+
+          case VecElemClass:
+            assert(phys_reg->isVectorPhysElem());
+            assert(vecMode == Enums::Elem);
+            return vecElemMap.setEntry(arch_reg, phys_reg);
+
           case CCRegClass:
             assert(phys_reg->isCCPhysReg());
             return ccMap.setEntry(arch_reg, phys_reg);
@@ -291,18 +346,39 @@ class UnifiedRenameMap
      */
     unsigned numFreeEntries() const
     {
-        return std::min(intMap.numFreeEntries(), floatMap.numFreeEntries());
+        return std::min(
+                std::min(intMap.numFreeEntries(), floatMap.numFreeEntries()),
+                vecMode == Enums::Full ? vecMap.numFreeEntries()
+                                    : vecElemMap.numFreeEntries());
     }
 
+    unsigned numFreeIntEntries() const { return intMap.numFreeEntries(); }
+    unsigned numFreeFloatEntries() const { return floatMap.numFreeEntries(); }
+    unsigned numFreeVecEntries() const
+    {
+        return vecMode == Enums::Full
+                ? vecMap.numFreeEntries()
+                : vecElemMap.numFreeEntries();
+    }
+    unsigned numFreeCCEntries() const { return ccMap.numFreeEntries(); }
+
     /**
      * Return whether there are enough registers to serve the request.
      */
-    bool canRename(uint32_t intRegs, uint32_t floatRegs, uint32_t ccRegs) const
+    bool canRename(uint32_t intRegs, uint32_t floatRegs, uint32_t vectorRegs,
+                    uint32_t vecElemRegs, uint32_t ccRegs) const
     {
         return intRegs <= intMap.numFreeEntries() &&
             floatRegs <= floatMap.numFreeEntries() &&
+            vectorRegs <= vecMap.numFreeEntries() &&
+            vecElemRegs <= vecElemMap.numFreeEntries() &&
             ccRegs <= ccMap.numFreeEntries();
     }
+    /**
+     * Set vector mode to Full or Elem.
+     * Ignore 'silent' modifications.
+     */
+    void switchMode(VecMode newVecMode, UnifiedFreeList* freeList);
 
 };
 
index 161d70b2849595fa8c2e8fd478096f854e1c57e6..ac4ceed02fb430edae57a00441d4709546a8552f 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2011-2012, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -194,6 +194,70 @@ class O3ThreadContext : public ThreadContext
                                                  reg_idx)).index());
     }
 
+    virtual const VecRegContainer& readVecReg(const RegId& id) const {
+        return readVecRegFlat(flattenRegId(id).index());
+    }
+
+    /**
+     * Read vector register operand for modification, hierarchical indexing.
+     */
+    virtual VecRegContainer& getWritableVecReg(const RegId& id) {
+        return getWritableVecRegFlat(flattenRegId(id).index());
+    }
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector 8bit operand. */
+    virtual ConstVecLane8
+    readVec8BitLaneReg(const RegId& id) const
+    {
+        return readVecLaneFlat<uint8_t>(flattenRegId(id).index(),
+                    id.elemIndex());
+    }
+
+    /** Reads source vector 16bit operand. */
+    virtual ConstVecLane16
+    readVec16BitLaneReg(const RegId& id) const
+    {
+        return readVecLaneFlat<uint16_t>(flattenRegId(id).index(),
+                    id.elemIndex());
+    }
+
+    /** Reads source vector 32bit operand. */
+    virtual ConstVecLane32
+    readVec32BitLaneReg(const RegId& id) const
+    {
+        return readVecLaneFlat<uint32_t>(flattenRegId(id).index(),
+                    id.elemIndex());
+    }
+
+    /** Reads source vector 64bit operand. */
+    virtual ConstVecLane64
+    readVec64BitLaneReg(const RegId& id) const
+    {
+        return readVecLaneFlat<uint64_t>(flattenRegId(id).index(),
+                    id.elemIndex());
+    }
+
+    /** Write a lane of the destination vector register. */
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::Byte>& val)
+    { return setVecLaneFlat(flattenRegId(reg).index(), reg.elemIndex(), val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::TwoByte>& val)
+    { return setVecLaneFlat(flattenRegId(reg).index(), reg.elemIndex(), val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::FourByte>& val)
+    { return setVecLaneFlat(flattenRegId(reg).index(), reg.elemIndex(), val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::EightByte>& val)
+    { return setVecLaneFlat(flattenRegId(reg).index(), reg.elemIndex(), val); }
+    /** @} */
+
+    virtual const VecElem& readVecElem(const RegId& reg) const {
+        return readVecElemFlat(flattenRegId(reg).index(), reg.elemIndex());
+    }
+
     virtual CCReg readCCReg(int reg_idx) {
         return readCCRegFlat(flattenRegId(RegId(CCRegClass,
                                                  reg_idx)).index());
@@ -214,6 +278,14 @@ class O3ThreadContext : public ThreadContext
                                                reg_idx)).index(), val);
     }
 
+    virtual void setVecReg(const RegId& reg, const VecRegContainer& val) {
+        setVecRegFlat(flattenRegId(reg).index(), val);
+    }
+
+    virtual void setVecElem(const RegId& reg, const VecElem& val) {
+        setVecElemFlat(flattenRegId(reg).index(), reg.elemIndex(), val);
+    }
+
     virtual void setCCReg(int reg_idx, CCReg val) {
         setCCRegFlat(flattenRegId(RegId(CCRegClass, reg_idx)).index(), val);
     }
@@ -298,6 +370,29 @@ class O3ThreadContext : public ThreadContext
     virtual FloatRegBits readFloatRegBitsFlat(int idx);
     virtual void setFloatRegBitsFlat(int idx, FloatRegBits val);
 
+    virtual const VecRegContainer& readVecRegFlat(int idx) const;
+    /** Read vector register operand for modification, flat indexing. */
+    virtual VecRegContainer& getWritableVecRegFlat(int idx);
+    virtual void setVecRegFlat(int idx, const VecRegContainer& val);
+
+    template <typename VecElem>
+    VecLaneT<VecElem, true> readVecLaneFlat(int idx, int lId) const
+    {
+        return cpu->template readArchVecLane<VecElem>(idx, lId,
+                thread->threadId());
+    }
+
+    template <typename LD>
+    void setVecLaneFlat(int idx, int lId, const LD& val)
+    {
+        cpu->template setArchVecLane(idx, lId, thread->threadId(), val);
+    }
+
+    virtual const VecElem& readVecElemFlat(const RegIndex& idx,
+                                           const ElemIndex& elemIndex) const;
+    virtual void setVecElemFlat(const RegIndex& idx, const ElemIndex& elemIdx,
+                                const VecElem& val);
+
     virtual CCReg readCCRegFlat(int idx);
     virtual void setCCRegFlat(int idx, CCReg val);
 };
index c3f894275b7c73da1ce371c73d24702e425acf63..2d109aea94c7e6557de31888287cf077ca11a7a2 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 ARM Limited
+ * Copyright (c) 2010-2012, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -208,6 +208,28 @@ O3ThreadContext<Impl>::readFloatRegBitsFlat(int reg_idx)
     return cpu->readArchFloatRegInt(reg_idx, thread->threadId());
 }
 
+template <class Impl>
+const TheISA::VecRegContainer&
+O3ThreadContext<Impl>::readVecRegFlat(int reg_id) const
+{
+    return cpu->readArchVecReg(reg_id, thread->threadId());
+}
+
+template <class Impl>
+TheISA::VecRegContainer&
+O3ThreadContext<Impl>::getWritableVecRegFlat(int reg_id)
+{
+    return cpu->getWritableArchVecReg(reg_id, thread->threadId());
+}
+
+template <class Impl>
+const TheISA::VecElem&
+O3ThreadContext<Impl>::readVecElemFlat(const RegIndex& idx,
+                                           const ElemIndex& elemIndex) const
+{
+    return cpu->readArchVecElem(idx, elemIndex, thread->threadId());
+}
+
 template <class Impl>
 TheISA::CCReg
 O3ThreadContext<Impl>::readCCRegFlat(int reg_idx)
@@ -242,6 +264,24 @@ O3ThreadContext<Impl>::setFloatRegBitsFlat(int reg_idx, FloatRegBits val)
     conditionalSquash();
 }
 
+template <class Impl>
+void
+O3ThreadContext<Impl>::setVecRegFlat(int reg_idx, const VecRegContainer& val)
+{
+    cpu->setArchVecReg(reg_idx, val, thread->threadId());
+
+    conditionalSquash();
+}
+
+template <class Impl>
+void
+O3ThreadContext<Impl>::setVecElemFlat(const RegIndex& idx,
+        const ElemIndex& elemIndex, const VecElem& val)
+{
+    cpu->setArchVecElem(idx, elemIndex, val, thread->threadId());
+    conditionalSquash();
+}
+
 template <class Impl>
 void
 O3ThreadContext<Impl>::setCCRegFlat(int reg_idx, TheISA::CCReg val)
index 53a50ce8e3e266f86548874e61458d51ebf3640a..16c1949ee7d8e03fada256d7290e604515153000 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2016 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.
+ *
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -33,6 +45,8 @@
 const char *RegId::regClassStrings[] = {
     "IntRegClass",
     "FloatRegClass",
+    "VecRegClass",
+    "VecElemClass",
     "CCRegClass",
     "MiscRegClass"
 };
index 05869e8fbed702e3a40fc1fee30bc26394a4dca9..27bf59b196fe4e2a4613cf939ca663034e2f12d6 100644 (file)
@@ -39,6 +39,7 @@
  *
  * Authors: Steve Reinhardt
  *          Nathanael Premillieu
+ *          Rekai Gonzalez
  */
 
 #ifndef __CPU__REG_CLASS_HH__
 enum RegClass {
     IntRegClass,        ///< Integer register
     FloatRegClass,      ///< Floating-point register
+    /** Vector Register. */
+    VecRegClass,
+    /** Vector Register Native Elem lane. */
+    VecElemClass,
     CCRegClass,         ///< Condition-code register
     MiscRegClass        ///< Control (misc) register
 };
@@ -75,14 +80,27 @@ class RegId {
     static const char* regClassStrings[];
     RegClass regClass;
     RegIndex regIdx;
+    ElemIndex elemIdx;
+    static constexpr size_t Scale = TheISA::NumVecElemPerVecReg;
   public:
     RegId() {};
     RegId(RegClass reg_class, RegIndex reg_idx)
-        : regClass(reg_class), regIdx(reg_idx)
-    {}
+        : regClass(reg_class), regIdx(reg_idx), elemIdx(-1)
+    {
+        panic_if(regClass == VecElemClass,
+                "Creating vector physical index w/o element index");
+    }
+
+    explicit RegId(RegClass reg_class, RegIndex reg_idx, ElemIndex elem_idx)
+        : regClass(reg_class), regIdx(reg_idx), elemIdx(elem_idx)
+    {
+        panic_if(regClass != VecElemClass,
+                "Creating non-vector physical index w/ element index");
+    }
 
     bool operator==(const RegId& that) const {
-        return regClass == that.classValue() && regIdx == that.index();
+        return regClass == that.classValue() && regIdx == that.index()
+                                             && elemIdx == that.elemIndex();
     }
 
     bool operator!=(const RegId& that) const {
@@ -94,7 +112,9 @@ class RegId {
      */
     bool operator<(const RegId& that) const {
         return regClass < that.classValue() ||
-                (regClass == that.classValue() && regIdx < that.index());
+            (regClass == that.classValue() && (
+                   regIdx < that.index() ||
+                   (regIdx == that.index() && elemIdx < that.elemIndex())));
     }
 
     /**
@@ -119,12 +139,26 @@ class RegId {
     /** @return true if it is a floating-point physical register. */
     bool isFloatReg() const { return regClass == FloatRegClass; }
 
+    /** @Return true if it is a  condition-code physical register. */
+    bool isVecReg() const { return regClass == VecRegClass; }
+
+    /** @Return true if it is a  condition-code physical register. */
+    bool isVecElem() const { return regClass == VecElemClass; }
+
     /** @Return true if it is a  condition-code physical register. */
     bool isCCReg() const { return regClass == CCRegClass; }
 
     /** @Return true if it is a  condition-code physical register. */
     bool isMiscReg() const { return regClass == MiscRegClass; }
 
+    /**
+     * Return true if this register can be renamed
+     */
+    bool isRenameable()
+    {
+        return regClass != MiscRegClass;
+    }
+
     /** Index accessors */
     /** @{ */
     const RegIndex& index() const { return regIdx; }
@@ -136,6 +170,8 @@ class RegId {
     inline RegIndex flatIndex() const;
     /** @} */
 
+    /** Elem accessor */
+    const RegIndex& elemIndex() const { return elemIdx; }
     /** Class accessor */
     const RegClass& classValue() const { return regClass; }
     /** Return a const char* with the register class name. */
index a47328b10d67dfb7655eaa07c0f79d64d66fdb72..98b341e86cdaa49b2a911a3996d5870d931353dd 100644 (file)
@@ -55,13 +55,18 @@ bool RegId::isZeroReg() const
              regIdx == TheISA::ZeroReg));
 }
 
+static constexpr size_t Scale = TheISA::NumVecElemPerVecReg;
+
 RegIndex RegId::flatIndex() const {
     switch (regClass) {
     case IntRegClass:
     case FloatRegClass:
+    case VecRegClass:
     case CCRegClass:
     case MiscRegClass:
         return regIdx;
+    case VecElemClass:
+        return Scale*regIdx + elemIdx;
     }
     panic("Trying to flatten a register without class!");
     return -1;
index 77d2fb4accbb79970311ac0e2476c58e6dcab0cc..57cea4ba769ebc7c905fc8d2aaa56300216cbf65 100644 (file)
@@ -292,6 +292,16 @@ BaseSimpleCPU::regStats()
             .desc("number of times the floating registers were written")
             ;
 
+        t_info.numVecRegReads
+            .name(thread_str + ".num_vec_register_reads")
+            .desc("number of times the vector registers were read")
+            ;
+
+        t_info.numVecRegWrites
+            .name(thread_str + ".num_vec_register_writes")
+            .desc("number of times the vector registers were written")
+            ;
+
         t_info.numCCRegReads
             .name(thread_str + ".num_cc_register_reads")
             .desc("number of times the CC registers were read")
index f221d6c93852e0a47a9e7abd5008345b4ca37a3a..0f546407d59368c444de143c83bc34d889dcb571 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 ARM Limited
+ * Copyright (c) 2014-2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -64,6 +64,8 @@ class SimpleExecContext : public ExecContext {
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg CCReg;
+    using VecRegContainer = TheISA::VecRegContainer;
+    using VecElem = TheISA::VecElem;
 
   public:
     BaseSimpleCPU *cpu;
@@ -112,6 +114,10 @@ class SimpleExecContext : public ExecContext {
     Stats::Scalar numFpRegReads;
     Stats::Scalar numFpRegWrites;
 
+    // Number of vector register file accesses
+    mutable Stats::Scalar numVecRegReads;
+    Stats::Scalar numVecRegWrites;
+
     // Number of condition code register file accesses
     Stats::Scalar numCCRegReads;
     Stats::Scalar numCCRegWrites;
@@ -219,6 +225,124 @@ class SimpleExecContext : public ExecContext {
         thread->setFloatRegBits(reg.index(), val);
     }
 
+    /** Reads a vector register. */
+    const VecRegContainer&
+    readVecRegOperand(const StaticInst *si, int idx) const override
+    {
+        numVecRegReads++;
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->readVecReg(reg);
+    }
+
+    /** Reads a vector register for modification. */
+    VecRegContainer&
+    getWritableVecRegOperand(const StaticInst *si, int idx) override
+    {
+        numVecRegWrites++;
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->getWritableVecReg(reg);
+    }
+
+    /** Sets a vector register to a value. */
+    void setVecRegOperand(const StaticInst *si, int idx,
+                          const VecRegContainer& val) override
+    {
+        numVecRegWrites++;
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        thread->setVecReg(reg, val);
+    }
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector lane. */
+    template <typename VecElem>
+    VecLaneT<VecElem, true>
+    readVecLaneOperand(const StaticInst *si, int idx) const
+    {
+        numVecRegReads++;
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->readVecLane<VecElem>(reg);
+    }
+    /** Reads source vector 8bit operand. */
+    virtual ConstVecLane8
+    readVec8BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    { return readVecLaneOperand<uint8_t>(si, idx); }
+
+    /** Reads source vector 16bit operand. */
+    virtual ConstVecLane16
+    readVec16BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    { return readVecLaneOperand<uint16_t>(si, idx); }
+
+    /** Reads source vector 32bit operand. */
+    virtual ConstVecLane32
+    readVec32BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    { return readVecLaneOperand<uint32_t>(si, idx); }
+
+    /** Reads source vector 64bit operand. */
+    virtual ConstVecLane64
+    readVec64BitLaneOperand(const StaticInst *si, int idx) const
+                            override
+    { return readVecLaneOperand<uint64_t>(si, idx); }
+
+    /** Write a lane of the destination vector operand. */
+    template <typename LD>
+    void
+    setVecLaneOperandT(const StaticInst *si, int idx,
+            const LD& val)
+    {
+        numVecRegWrites++;
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->setVecLane(reg, val);
+    }
+    /** Write a lane of the destination vector operand. */
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::Byte>& val) override
+    { return setVecLaneOperandT(si, idx, val); }
+    /** Write a lane of the destination vector operand. */
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::TwoByte>& val) override
+    { return setVecLaneOperandT(si, idx, val); }
+    /** Write a lane of the destination vector operand. */
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::FourByte>& val) override
+    { return setVecLaneOperandT(si, idx, val); }
+    /** Write a lane of the destination vector operand. */
+    virtual void
+    setVecLaneOperand(const StaticInst *si, int idx,
+            const LaneData<LaneSize::EightByte>& val) override
+    { return setVecLaneOperandT(si, idx, val); }
+    /** @} */
+
+    /** Reads an element of a vector register. */
+    VecElem readVecElemOperand(const StaticInst *si, int idx) const override
+    {
+        numVecRegReads++;
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecElem());
+        return thread->readVecElem(reg);
+    }
+
+    /** Sets an element of a vector register to a value. */
+    void setVecElemOperand(const StaticInst *si, int idx,
+                           const VecElem val) override
+    {
+        numVecRegWrites++;
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecElem());
+        thread->setVecElem(reg, val);
+    }
+
     CCReg readCCRegOperand(const StaticInst *si, int idx) override
     {
         numCCRegReads++;
index 286d917668ed7e3238b4313113cad1a6cc30b4c9..4ea8b91badead300ad58587ebb3b2dcae04fd77c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2011-2012, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -58,6 +58,7 @@
 #include "debug/CCRegs.hh"
 #include "debug/FloatRegs.hh"
 #include "debug/IntRegs.hh"
+#include "debug/VecRegs.hh"
 #include "mem/page_table.hh"
 #include "mem/request.hh"
 #include "sim/byteswap.hh"
@@ -102,6 +103,8 @@ class SimpleThread : public ThreadState
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg CCReg;
+    using VecRegContainer = TheISA::VecRegContainer;
+    using VecElem = TheISA::VecElem;
   public:
     typedef ThreadContext::Status Status;
 
@@ -111,6 +114,7 @@ class SimpleThread : public ThreadState
         FloatRegBits i[TheISA::NumFloatRegs];
     } floatRegs;
     TheISA::IntReg intRegs[TheISA::NumIntRegs];
+    VecRegContainer vecRegs[TheISA::NumVecRegs];
 #ifdef ISA_HAS_CC_REGS
     TheISA::CCReg ccRegs[TheISA::NumCCRegs];
 #endif
@@ -227,6 +231,9 @@ class SimpleThread : public ThreadState
         _pcState = 0;
         memset(intRegs, 0, sizeof(intRegs));
         memset(floatRegs.i, 0, sizeof(floatRegs.i));
+        for (int i = 0; i < TheISA::NumVecRegs; i++) {
+            vecRegs[i].zero();
+        }
 #ifdef ISA_HAS_CC_REGS
         memset(ccRegs, 0, sizeof(ccRegs));
 #endif
@@ -266,6 +273,98 @@ class SimpleThread : public ThreadState
         return regVal;
     }
 
+    const VecRegContainer&
+    readVecReg(const RegId& reg) const
+    {
+        int flatIndex = isa->flattenVecIndex(reg.index());
+        assert(flatIndex < TheISA::NumVecRegs);
+        const VecRegContainer& regVal = readVecRegFlat(flatIndex);
+        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n",
+                reg.index(), flatIndex, regVal.as<TheISA::VecElem>().print());
+        return regVal;
+    }
+
+    VecRegContainer&
+    getWritableVecReg(const RegId& reg)
+    {
+        int flatIndex = isa->flattenVecIndex(reg.index());
+        assert(flatIndex < TheISA::NumVecRegs);
+        VecRegContainer& regVal = getWritableVecRegFlat(flatIndex);
+        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n",
+                reg.index(), flatIndex, regVal.as<TheISA::VecElem>().print());
+        return regVal;
+    }
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector <T> operand. */
+    template <typename T>
+    VecLaneT<T, true>
+    readVecLane(const RegId& reg) const
+    {
+        int flatIndex = isa->flattenVecIndex(reg.index());
+        assert(flatIndex < TheISA::NumVecRegs);
+        auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex());
+        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n",
+                reg.index(), flatIndex, reg.elemIndex(), regVal);
+        return regVal;
+    }
+
+    /** Reads source vector 8bit operand. */
+    virtual ConstVecLane8
+    readVec8BitLaneReg(const RegId& reg) const
+    { return readVecLane<uint8_t>(reg); }
+
+    /** Reads source vector 16bit operand. */
+    virtual ConstVecLane16
+    readVec16BitLaneReg(const RegId& reg) const
+    { return readVecLane<uint16_t>(reg); }
+
+    /** Reads source vector 32bit operand. */
+    virtual ConstVecLane32
+    readVec32BitLaneReg(const RegId& reg) const
+    { return readVecLane<uint32_t>(reg); }
+
+    /** Reads source vector 64bit operand. */
+    virtual ConstVecLane64
+    readVec64BitLaneReg(const RegId& reg) const
+    { return readVecLane<uint64_t>(reg); }
+
+    /** Write a lane of the destination vector register. */
+    template <typename LD>
+    void setVecLaneT(const RegId& reg, const LD& val)
+    {
+        int flatIndex = isa->flattenVecIndex(reg.index());
+        assert(flatIndex < TheISA::NumVecRegs);
+        setVecLaneFlat(flatIndex, reg.elemIndex(), val);
+        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n",
+                reg.index(), flatIndex, reg.elemIndex(), val);
+    }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::Byte>& val)
+    { return setVecLaneT(reg, val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::TwoByte>& val)
+    { return setVecLaneT(reg, val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::FourByte>& val)
+    { return setVecLaneT(reg, val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::EightByte>& val)
+    { return setVecLaneT(reg, val); }
+    /** @} */
+
+    const VecElem& readVecElem(const RegId& reg) const
+    {
+        int flatIndex = isa->flattenVecElemIndex(reg.index());
+        assert(flatIndex < TheISA::NumVecRegs);
+        const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex());
+        DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as"
+                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal);
+        return regVal;
+    }
+
+
     CCReg readCCReg(int reg_idx)
     {
 #ifdef ISA_HAS_CC_REGS
@@ -312,6 +411,24 @@ class SimpleThread : public ThreadState
                 reg_idx, flatIndex, val, floatRegs.f[flatIndex]);
     }
 
+    void setVecReg(const RegId& reg, const VecRegContainer& val)
+    {
+        int flatIndex = isa->flattenVecIndex(reg.index());
+        assert(flatIndex < TheISA::NumVecRegs);
+        setVecRegFlat(flatIndex, val);
+        DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n",
+                reg.index(), flatIndex, val.print());
+    }
+
+    void setVecElem(const RegId& reg, const VecElem& val)
+    {
+        int flatIndex = isa->flattenVecElemIndex(reg.index());
+        assert(flatIndex < TheISA::NumVecRegs);
+        setVecElemFlat(flatIndex, reg.elemIndex(), val);
+        DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to"
+                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val);
+    }
+
     void setCCReg(int reg_idx, CCReg val)
     {
 #ifdef ISA_HAS_CC_REGS
@@ -428,6 +545,45 @@ class SimpleThread : public ThreadState
         floatRegs.i[idx] = val;
     }
 
+    const VecRegContainer& readVecRegFlat(const RegIndex& reg) const
+    {
+        return vecRegs[reg];
+    }
+
+    VecRegContainer& getWritableVecRegFlat(const RegIndex& reg)
+    {
+        return vecRegs[reg];
+    }
+
+    void setVecRegFlat(const RegIndex& reg, const VecRegContainer& val)
+    {
+        vecRegs[reg] = val;
+    }
+
+    template <typename T>
+    VecLaneT<T, true> readVecLaneFlat(const RegIndex& reg, int lId) const
+    {
+        return vecRegs[reg].laneView<T>(lId);
+    }
+
+    template <typename LD>
+    void setVecLaneFlat(const RegIndex& reg, int lId, const LD& val)
+    {
+        vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val;
+    }
+
+    const VecElem& readVecElemFlat(const RegIndex& reg,
+                                   const ElemIndex& elemIndex) const
+    {
+        return vecRegs[reg].as<TheISA::VecElem>()[elemIndex];
+    }
+
+    void setVecElemFlat(const RegIndex& reg, const ElemIndex& elemIndex,
+                        const VecElem val)
+    {
+        vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val;
+    }
+
 #ifdef ISA_HAS_CC_REGS
     CCReg readCCRegFlat(int idx) { return ccRegs[idx]; }
     void setCCRegFlat(int idx, CCReg val) { ccRegs[idx] = val; }
index d60afc019231f542544aaed9118e1a7d4eaa6758..e7507c6a63ec7457f30371d21077c37787c88706 100644 (file)
@@ -100,13 +100,20 @@ class StaticInst : public RefCounted, public StaticInstFlags
     int8_t _numCCDestRegs;
     //@}
 
+    /** To use in architectures with vector register file. */
+    /** @{ */
+    int8_t _numVecDestRegs;
+    int8_t _numVecElemDestRegs;
+    /** @} */
+
   public:
 
     /// @name Register information.
-    /// The sum of numFPDestRegs() and numIntDestRegs() equals
-    /// numDestRegs().  The former two functions are used to track
-    /// physical register usage for machines with separate int & FP
-    /// reg files.
+    /// The sum of numFPDestRegs(), numIntDestRegs(), numVecDestRegs() and
+    /// numVecelemDestRegs() equals numDestRegs().  The former two functions
+    /// are used to track physical register usage for machines with separate
+    /// int & FP reg files, the next two is for machines with vector register
+    /// file.
     //@{
     /// Number of source registers.
     int8_t numSrcRegs()  const { return _numSrcRegs; }
@@ -116,7 +123,10 @@ class StaticInst : public RefCounted, public StaticInstFlags
     int8_t numFPDestRegs()  const { return _numFPDestRegs; }
     /// Number of integer destination regs.
     int8_t numIntDestRegs() const { return _numIntDestRegs; }
-    //@}
+    /// Number of vector destination regs.
+    int8_t numVecDestRegs() const { return _numVecDestRegs; }
+    /// Number of vector element destination regs.
+    int8_t numVecElemDestRegs() const { return _numVecElemDestRegs; }
     /// Number of coprocesor destination regs.
     int8_t numCCDestRegs() const { return _numCCDestRegs; }
     //@}
@@ -252,7 +262,8 @@ class StaticInst : public RefCounted, public StaticInstFlags
     StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass)
         : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
           _numFPDestRegs(0), _numIntDestRegs(0), _numCCDestRegs(0),
-          machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
+          _numVecDestRegs(0), _numVecElemDestRegs(0), machInst(_machInst),
+          mnemonic(_mnemonic), cachedDisassembly(0)
     { }
 
   public:
index cea21e7906159a4ebed1d574ad8b44c3c1078d05..0d288de6fa1eb26a7a9a5a3006c627500453c9ee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -76,6 +76,16 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
             panic("Float reg idx %d doesn't match, one: %#x, two: %#x",
                   i, t1, t2);
     }
+
+    // Then loop through the vector registers.
+    for (int i = 0; i < TheISA::NumVecRegs; ++i) {
+        RegId rid(VecRegClass, i);
+        const TheISA::VecRegContainer& t1 = one->readVecReg(rid);
+        const TheISA::VecRegContainer& t2 = two->readVecReg(rid);
+        if (t1 != t2)
+            panic("Vec reg idx %d doesn't match, one: %#x, two: %#x",
+                  i, t1, t2);
+    }
     for (int i = 0; i < TheISA::NumMiscRegs; ++i) {
         TheISA::MiscReg t1 = one->readMiscRegNoEffect(i);
         TheISA::MiscReg t2 = two->readMiscRegNoEffect(i);
@@ -152,6 +162,12 @@ serialize(ThreadContext &tc, CheckpointOut &cp)
     // compatibility.
     arrayParamOut(cp, "floatRegs.i", floatRegs, NumFloatRegs);
 
+    std::vector<TheISA::VecRegContainer> vecRegs(NumVecRegs);
+    for (int i = 0; i < NumVecRegs; ++i) {
+        vecRegs[i] = tc.readVecRegFlat(i);
+    }
+    SERIALIZE_CONTAINER(vecRegs);
+
     IntReg intRegs[NumIntRegs];
     for (int i = 0; i < NumIntRegs; ++i)
         intRegs[i] = tc.readIntRegFlat(i);
@@ -181,6 +197,12 @@ unserialize(ThreadContext &tc, CheckpointIn &cp)
     for (int i = 0; i < NumFloatRegs; ++i)
         tc.setFloatRegBitsFlat(i, floatRegs[i]);
 
+    std::vector<TheISA::VecRegContainer> vecRegs(NumVecRegs);
+    UNSERIALIZE_CONTAINER(vecRegs);
+    for (int i = 0; i < NumVecRegs; ++i) {
+        tc.setVecRegFlat(i, vecRegs[i]);
+    }
+
     IntReg intRegs[NumIntRegs];
     UNSERIALIZE_ARRAY(intRegs, NumIntRegs);
     for (int i = 0; i < NumIntRegs; ++i)
index 43c40481e8792042e16894aa2fcdfa7a573c6ec7..66b2f7554ee2c56ea7ad3dbd5738e861c26b3b02 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2011-2012, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -100,6 +100,8 @@ class ThreadContext
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg CCReg;
     typedef TheISA::MiscReg MiscReg;
+    using VecRegContainer = TheISA::VecRegContainer;
+    using VecElem = TheISA::VecElem;
   public:
 
     enum Status
@@ -212,6 +214,40 @@ class ThreadContext
 
     virtual FloatRegBits readFloatRegBits(int reg_idx) = 0;
 
+    virtual const VecRegContainer& readVecReg(const RegId& reg) const = 0;
+    virtual VecRegContainer& getWritableVecReg(const RegId& reg) = 0;
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector 8bit operand. */
+    virtual ConstVecLane8
+    readVec8BitLaneReg(const RegId& reg) const = 0;
+
+    /** Reads source vector 16bit operand. */
+    virtual ConstVecLane16
+    readVec16BitLaneReg(const RegId& reg) const = 0;
+
+    /** Reads source vector 32bit operand. */
+    virtual ConstVecLane32
+    readVec32BitLaneReg(const RegId& reg) const = 0;
+
+    /** Reads source vector 64bit operand. */
+    virtual ConstVecLane64
+    readVec64BitLaneReg(const RegId& reg) const = 0;
+
+    /** Write a lane of the destination vector register. */
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::Byte>& val) = 0;
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::TwoByte>& val) = 0;
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::FourByte>& val) = 0;
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::EightByte>& val) = 0;
+    /** @} */
+
+    virtual const VecElem& readVecElem(const RegId& reg) const = 0;
+
     virtual CCReg readCCReg(int reg_idx) = 0;
 
     virtual void setIntReg(int reg_idx, uint64_t val) = 0;
@@ -220,6 +256,10 @@ class ThreadContext
 
     virtual void setFloatRegBits(int reg_idx, FloatRegBits val) = 0;
 
+    virtual void setVecReg(const RegId& reg, const VecRegContainer& val) = 0;
+
+    virtual void setVecElem(const RegId& reg, const VecElem& val) = 0;
+
     virtual void setCCReg(int reg_idx, CCReg val) = 0;
 
     virtual TheISA::PCState pcState() = 0;
@@ -303,6 +343,15 @@ class ThreadContext
     virtual FloatRegBits readFloatRegBitsFlat(int idx) = 0;
     virtual void setFloatRegBitsFlat(int idx, FloatRegBits val) = 0;
 
+    virtual const VecRegContainer& readVecRegFlat(int idx) const = 0;
+    virtual VecRegContainer& getWritableVecRegFlat(int idx) = 0;
+    virtual void setVecRegFlat(int idx, const VecRegContainer& val) = 0;
+
+    virtual const VecElem& readVecElemFlat(const RegIndex& idx,
+                                           const ElemIndex& elemIdx) const = 0;
+    virtual void setVecElemFlat(const RegIndex& idx, const ElemIndex& elemIdx,
+                                const VecElem& val) = 0;
+
     virtual CCReg readCCRegFlat(int idx) = 0;
     virtual void setCCRegFlat(int idx, CCReg val) = 0;
     /** @} */
@@ -421,6 +470,52 @@ class ProxyThreadContext : public ThreadContext
     FloatRegBits readFloatRegBits(int reg_idx)
     { return actualTC->readFloatRegBits(reg_idx); }
 
+    const VecRegContainer& readVecReg(const RegId& reg) const
+    { return actualTC->readVecReg(reg); }
+
+    VecRegContainer& getWritableVecReg(const RegId& reg)
+    { return actualTC->getWritableVecReg(reg); }
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector 8bit operand. */
+    ConstVecLane8
+    readVec8BitLaneReg(const RegId& reg) const
+    { return actualTC->readVec8BitLaneReg(reg); }
+
+    /** Reads source vector 16bit operand. */
+    ConstVecLane16
+    readVec16BitLaneReg(const RegId& reg) const
+    { return actualTC->readVec16BitLaneReg(reg); }
+
+    /** Reads source vector 32bit operand. */
+    ConstVecLane32
+    readVec32BitLaneReg(const RegId& reg) const
+    { return actualTC->readVec32BitLaneReg(reg); }
+
+    /** Reads source vector 64bit operand. */
+    ConstVecLane64
+    readVec64BitLaneReg(const RegId& reg) const
+    { return actualTC->readVec64BitLaneReg(reg); }
+
+    /** Write a lane of the destination vector register. */
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::Byte>& val)
+    { return actualTC->setVecLane(reg, val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::TwoByte>& val)
+    { return actualTC->setVecLane(reg, val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::FourByte>& val)
+    { return actualTC->setVecLane(reg, val); }
+    virtual void setVecLane(const RegId& reg,
+            const LaneData<LaneSize::EightByte>& val)
+    { return actualTC->setVecLane(reg, val); }
+    /** @} */
+
+    const VecElem& readVecElem(const RegId& reg) const
+    { return actualTC->readVecElem(reg); }
+
     CCReg readCCReg(int reg_idx)
     { return actualTC->readCCReg(reg_idx); }
 
@@ -433,6 +528,12 @@ class ProxyThreadContext : public ThreadContext
     void setFloatRegBits(int reg_idx, FloatRegBits val)
     { actualTC->setFloatRegBits(reg_idx, val); }
 
+    void setVecReg(const RegId& reg, const VecRegContainer& val)
+    { actualTC->setVecReg(reg, val); }
+
+    void setVecElem(const RegId& reg, const VecElem& val)
+    { actualTC->setVecElem(reg, val); }
+
     void setCCReg(int reg_idx, CCReg val)
     { actualTC->setCCReg(reg_idx, val); }
 
@@ -495,6 +596,23 @@ class ProxyThreadContext : public ThreadContext
     void setFloatRegBitsFlat(int idx, FloatRegBits val)
     { actualTC->setFloatRegBitsFlat(idx, val); }
 
+    const VecRegContainer& readVecRegFlat(int id) const
+    { return actualTC->readVecRegFlat(id); }
+
+    VecRegContainer& getWritableVecRegFlat(int id)
+    { return actualTC->getWritableVecRegFlat(id); }
+
+    void setVecRegFlat(int idx, const VecRegContainer& val)
+    { actualTC->setVecRegFlat(idx, val); }
+
+    const VecElem& readVecElemFlat(const RegIndex& id,
+                                   const ElemIndex& elemIndex) const
+    { return actualTC->readVecElemFlat(id, elemIndex); }
+
+    void setVecElemFlat(const RegIndex& id, const ElemIndex& elemIndex,
+                        const VecElem& val)
+    { actualTC->setVecElemFlat(id, elemIndex, val); }
+
     CCReg readCCRegFlat(int idx)
     { return actualTC->readCCRegFlat(idx); }
 
index f06aaf8994a610a958fa38a42ad650775f6c7488..f49092d4d5f9ffef606336437ac11a4214119253 100644 (file)
@@ -57,6 +57,7 @@
 #include <string>
 #include <vector>
 
+#include "arch/generic/vec_reg.hh"
 #include "base/framebuffer.hh"
 #include "base/inifile.hh"
 #include "base/misc.hh"
@@ -471,6 +472,8 @@ INSTANTIATE_PARAM_TEMPLATES(float)
 INSTANTIATE_PARAM_TEMPLATES(double)
 INSTANTIATE_PARAM_TEMPLATES(string)
 INSTANTIATE_PARAM_TEMPLATES(Pixel)
+INSTANTIATE_PARAM_TEMPLATES(VecRegContainer<8>)
+INSTANTIATE_PARAM_TEMPLATES(VecRegContainer<16>)
 
 // set is only used with strings and furthermore doesn't agree with Pixel
 template void