summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorGiacomo Gabrielli <giacomo.gabrielli@arm.com>2017-11-08 16:06:12 +0000
committerGiacomo Gabrielli <giacomo.gabrielli@arm.com>2019-05-11 12:49:15 +0000
commit8ddec45de48ddca443064212600c2583df2fe882 (patch)
treee2d88e8094ac9b13712815d437b1be3986fe9fed /src/arch/arm
parentc58cb8c9dbeef377da180f1fdaaa1c0eadf85550 (diff)
downloadgem5-8ddec45de48ddca443064212600c2583df2fe882.tar.xz
arch-arm: Add initial support for SVE contiguous loads/stores
Thanks to Pau Cabre and Adria Armejach Sanosa for their contribution of bugfixes. Change-Id: If8983cf85d95cddb187c90967a94ddfe2414bc46 Signed-off-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/13519 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/SConscript1
-rw-r--r--src/arch/arm/insts/sve_mem.cc116
-rw-r--r--src/arch/arm/insts/sve_mem.hh153
-rw-r--r--src/arch/arm/isa/formats/sve_2nd_level.isa316
-rw-r--r--src/arch/arm/isa/includes.isa1
-rw-r--r--src/arch/arm/isa/insts/insts.isa1
-rw-r--r--src/arch/arm/isa/insts/sve_mem.isa453
-rw-r--r--src/arch/arm/isa/templates/sve.isa2
-rw-r--r--src/arch/arm/isa/templates/sve_mem.isa386
-rw-r--r--src/arch/arm/isa/templates/templates.isa1
10 files changed, 1429 insertions, 1 deletions
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
index 58a13cd72..caea1c470 100644
--- a/src/arch/arm/SConscript
+++ b/src/arch/arm/SConscript
@@ -61,6 +61,7 @@ if env['TARGET_ISA'] == 'arm':
Source('insts/pseudo.cc')
Source('insts/static_inst.cc')
Source('insts/sve.cc')
+ Source('insts/sve_mem.cc')
Source('insts/vfp.cc')
Source('insts/fplib.cc')
Source('insts/crypto.cc')
diff --git a/src/arch/arm/insts/sve_mem.cc b/src/arch/arm/insts/sve_mem.cc
new file mode 100644
index 000000000..0f24d899b
--- /dev/null
+++ b/src/arch/arm/insts/sve_mem.cc
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 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: Giacomo Gabrielli
+ */
+
+#include "arch/arm/insts/sve_mem.hh"
+
+namespace ArmISA
+{
+
+std::string
+SveMemVecFillSpill::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+ printMnemonic(ss, "", false);
+ printVecReg(ss, dest, true);
+ ccprintf(ss, ", [");
+ printIntReg(ss, base);
+ if (imm != 0) {
+ ccprintf(ss, ", #%d, mul vl", imm);
+ }
+ ccprintf(ss, "]");
+ return ss.str();
+}
+
+std::string
+SveMemPredFillSpill::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+ printMnemonic(ss, "", false);
+ printVecPredReg(ss, dest);
+ ccprintf(ss, ", [");
+ printIntReg(ss, base);
+ if (imm != 0) {
+ ccprintf(ss, ", #%d, mul vl", imm);
+ }
+ ccprintf(ss, "]");
+ return ss.str();
+}
+
+std::string
+SveContigMemSS::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ // TODO: add suffix to transfer register and scaling factor (LSL #<x>)
+ std::stringstream ss;
+ printMnemonic(ss, "", false);
+ ccprintf(ss, "{");
+ printVecReg(ss, dest, true);
+ ccprintf(ss, "}, ");
+ printVecPredReg(ss, gp);
+ ccprintf(ss, "/z, ");
+ ccprintf(ss, ", [");
+ printIntReg(ss, base);
+ ccprintf(ss, ", ");
+ printIntReg(ss, offset);
+ ccprintf(ss, "]");
+ return ss.str();
+}
+
+std::string
+SveContigMemSI::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ // TODO: add suffix to transfer register
+ std::stringstream ss;
+ printMnemonic(ss, "", false);
+ ccprintf(ss, "{");
+ printVecReg(ss, dest, true);
+ ccprintf(ss, "}, ");
+ printVecPredReg(ss, gp);
+ ccprintf(ss, "/z, ");
+ ccprintf(ss, ", [");
+ printIntReg(ss, base);
+ if (imm != 0) {
+ ccprintf(ss, ", #%d, mul vl", imm);
+ }
+ ccprintf(ss, "]");
+ return ss.str();
+}
+
+} // namespace ArmISA
diff --git a/src/arch/arm/insts/sve_mem.hh b/src/arch/arm/insts/sve_mem.hh
new file mode 100644
index 000000000..de6b69cd5
--- /dev/null
+++ b/src/arch/arm/insts/sve_mem.hh
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2017 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: Giacomo Gabrielli
+ */
+
+#ifndef __ARCH_ARM_SVE_MEM_HH__
+#define __ARCH_ARM_SVE_MEM_HH__
+
+#include "arch/arm/insts/static_inst.hh"
+#include "arch/arm/tlb.hh"
+
+namespace ArmISA
+{
+
+class SveMemVecFillSpill : public ArmStaticInst
+{
+ protected:
+ IntRegIndex dest;
+ IntRegIndex base;
+ uint64_t imm;
+
+ /// True if the base register is SP (used for SP alignment checking).
+ bool baseIsSP;
+
+ unsigned memAccessFlags;
+
+ SveMemVecFillSpill(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _dest,
+ IntRegIndex _base, uint64_t _imm)
+ : ArmStaticInst(mnem, _machInst, __opClass),
+ dest(_dest), base(_base), imm(_imm),
+ memAccessFlags(ArmISA::TLB::AllowUnaligned | ArmISA::TLB::MustBeOne)
+ {
+ baseIsSP = isSP(_base);
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+class SveMemPredFillSpill : public ArmStaticInst
+{
+ protected:
+ IntRegIndex dest;
+ IntRegIndex base;
+ uint64_t imm;
+
+ /// True if the base register is SP (used for SP alignment checking).
+ bool baseIsSP;
+
+ unsigned memAccessFlags;
+
+ SveMemPredFillSpill(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _dest,
+ IntRegIndex _base, uint64_t _imm)
+ : ArmStaticInst(mnem, _machInst, __opClass),
+ dest(_dest), base(_base), imm(_imm),
+ memAccessFlags(ArmISA::TLB::AllowUnaligned | ArmISA::TLB::MustBeOne)
+ {
+ baseIsSP = isSP(_base);
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+class SveContigMemSS : public ArmStaticInst
+{
+ protected:
+ IntRegIndex dest;
+ IntRegIndex gp;
+ IntRegIndex base;
+ IntRegIndex offset;
+
+ /// True if the base register is SP (used for SP alignment checking).
+ bool baseIsSP;
+
+ unsigned memAccessFlags;
+
+ SveContigMemSS(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+ IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
+ IntRegIndex _offset)
+ : ArmStaticInst(mnem, _machInst, __opClass),
+ dest(_dest), gp(_gp), base(_base), offset(_offset),
+ memAccessFlags(ArmISA::TLB::AllowUnaligned | ArmISA::TLB::MustBeOne)
+ {
+ baseIsSP = isSP(_base);
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+class SveContigMemSI : public ArmStaticInst
+{
+ protected:
+ IntRegIndex dest;
+ IntRegIndex gp;
+ IntRegIndex base;
+ uint64_t imm;
+
+ /// True if the base register is SP (used for SP alignment checking).
+ bool baseIsSP;
+
+ unsigned memAccessFlags;
+
+ SveContigMemSI(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+ IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
+ uint64_t _imm)
+ : ArmStaticInst(mnem, _machInst, __opClass),
+ dest(_dest), gp(_gp), base(_base), imm(_imm),
+ memAccessFlags(ArmISA::TLB::AllowUnaligned | ArmISA::TLB::MustBeOne)
+ {
+ baseIsSP = isSP(_base);
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // namespace ArmISA
+
+#endif // __ARCH_ARM_SVE_MEM_HH__
diff --git a/src/arch/arm/isa/formats/sve_2nd_level.isa b/src/arch/arm/isa/formats/sve_2nd_level.isa
index ff7e50ee5..e81ab3ed7 100644
--- a/src/arch/arm/isa/formats/sve_2nd_level.isa
+++ b/src/arch/arm/isa/formats/sve_2nd_level.isa
@@ -2896,12 +2896,152 @@ namespace Aarch64
StaticInstPtr
decodeSveMemGather32(ExtMachInst machInst)
{
+ // TODO: for now only LDR and LD1R are implemented
+ if (bits(machInst, 22) && bits(machInst, 15)) {
+ IntRegIndex zt = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
+ IntRegIndex rn = makeSP(
+ (IntRegIndex) (uint8_t) bits(machInst, 9, 5));
+ uint64_t imm = bits(machInst, 21, 16);
+ IntRegIndex pg = (IntRegIndex) (uint8_t) bits(machInst, 12, 10);
+ uint8_t dtype = (bits(machInst, 24, 23) << 2) |
+ bits(machInst, 14, 13);
+ return decodeSveContigLoadSIInsts<SveLoadAndRepl>(
+ dtype, machInst, zt, pg, rn, imm, false, true);
+ } else if (bits(machInst, 24, 22) == 0x6 &&
+ bits(machInst, 15, 13) == 0x0 &&
+ bits(machInst, 4) == 0x0) {
+ IntRegIndex pt = (IntRegIndex) (uint8_t) bits(machInst, 3, 0);
+ IntRegIndex rn = makeSP(
+ (IntRegIndex) (uint8_t) bits(machInst, 9, 5));
+ uint64_t imm = sext<9>((bits(machInst, 21, 16) << 3) |
+ bits(machInst, 12, 10));
+ return new SveLdrPred(machInst, pt, rn, imm);
+ } else if (bits(machInst, 24, 22) == 0x6 &&
+ bits(machInst, 15, 13) == 0x2) {
+ IntRegIndex zt = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
+ IntRegIndex rn = makeSP(
+ (IntRegIndex) (uint8_t) bits(machInst, 9, 5));
+ uint64_t imm = sext<9>((bits(machInst, 21, 16) << 3) |
+ bits(machInst, 12, 10));
+ return new SveLdrVec(machInst, zt, rn, imm);
+ }
return new Unknown64(machInst);
} // decodeSveMemGather32
StaticInstPtr
+ decodeSveLoadBcastQuadSS(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveLoadBcastQuadSS
+
+ StaticInstPtr
+ decodeSveLoadBcastQuadSI(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveLoadBcastQuadSI
+
+ StaticInstPtr
+ decodeSveContigLoadSS(ExtMachInst machInst)
+ {
+ IntRegIndex zt = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
+ IntRegIndex rn = makeSP((IntRegIndex) (uint8_t) bits(machInst, 9, 5));
+ IntRegIndex rm = makeSP(
+ (IntRegIndex) (uint8_t) bits(machInst, 20, 16));
+ IntRegIndex pg = (IntRegIndex) (uint8_t) bits(machInst, 12, 10);
+
+ if (rm == 0x1f) {
+ return new Unknown64(machInst);
+ }
+
+ return decodeSveContigLoadSSInsts<SveContigLoadSS>(
+ bits(machInst, 24, 21), machInst, zt, pg, rn, rm, false);
+ } // decodeSveContigLoadSS
+
+ StaticInstPtr
+ decodeSveContigFFLoadSS(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveContigFFLoadSS
+
+ StaticInstPtr
+ decodeSveContigLoadSI(ExtMachInst machInst)
+ {
+ IntRegIndex zt = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
+ IntRegIndex rn = makeSP((IntRegIndex) (uint8_t) bits(machInst, 9, 5));
+ uint64_t imm = sext<4>(bits(machInst, 19, 16));
+ IntRegIndex pg = (IntRegIndex) (uint8_t) bits(machInst, 12, 10);
+
+ return decodeSveContigLoadSIInsts<SveContigLoadSI>(
+ bits(machInst, 24, 21), machInst, zt, pg, rn, imm, false);
+ } // decodeSveContigLoadSI
+
+ StaticInstPtr
+ decodeSveContigNFLoadSI(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveContigNFLoadSI
+
+ StaticInstPtr
+ decodeSveContigNTLoadSS(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveContigNTLoadSS
+
+ StaticInstPtr
+ decodeSveLoadStructsSS(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveLoadStructsSS
+
+ StaticInstPtr
+ decodeSveContigNTLoadSI(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveContigNTLoadSI
+
+ StaticInstPtr
+ decodeSveLoadStructsSI(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveLoadStructsSI
+
+ StaticInstPtr
decodeSveMemContigLoad(ExtMachInst machInst)
{
+ switch (bits(machInst, 15, 13)) {
+ case 0x0:
+ return decodeSveLoadBcastQuadSS(machInst);
+ case 0x1:
+ if (bits(machInst, 20) == 0x0) {
+ return decodeSveLoadBcastQuadSI(machInst);
+ }
+ break;
+ case 0x2:
+ return decodeSveContigLoadSS(machInst);
+ case 0x3:
+ return decodeSveContigFFLoadSS(machInst);
+ case 0x5:
+ if (bits(machInst, 20) == 0x0) {
+ return decodeSveContigLoadSI(machInst);
+ } else {
+ return decodeSveContigNFLoadSI(machInst);
+ }
+ case 0x6:
+ if (bits(machInst, 22, 21) == 0x0) {
+ return decodeSveContigNTLoadSS(machInst);
+ } else {
+ return decodeSveLoadStructsSS(machInst);
+ }
+ case 0x7:
+ if (bits(machInst, 20) == 0) {
+ if (bits(machInst, 22, 21) == 0x0) {
+ return decodeSveContigNTLoadSI(machInst);
+ } else {
+ return decodeSveLoadStructsSI(machInst);
+ }
+ }
+ break;
+ }
return new Unknown64(machInst);
} // decodeSveMemContigLoad
@@ -2912,8 +3052,184 @@ namespace Aarch64
} // decodeSveMemGather64
StaticInstPtr
+ decodeSveContigStoreSS(ExtMachInst machInst)
+ {
+ IntRegIndex zt = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
+ IntRegIndex rn = makeSP((IntRegIndex) (uint8_t) bits(machInst, 9, 5));
+ IntRegIndex rm = makeSP(
+ (IntRegIndex) (uint8_t) bits(machInst, 20, 16));
+ IntRegIndex pg = (IntRegIndex) (uint8_t) bits(machInst, 12, 10);
+
+ if (rm == 0x1f) {
+ return new Unknown64(machInst);
+ }
+
+ return decodeSveContigStoreSSInsts<SveContigStoreSS>(
+ bits(machInst, 24, 21), machInst, zt, pg, rn, rm);
+ } // decodeSveContigStoreSS
+
+ StaticInstPtr
+ decodeSveContigStoreSI(ExtMachInst machInst)
+ {
+ IntRegIndex zt = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
+ IntRegIndex rn = makeSP((IntRegIndex) (uint8_t) bits(machInst, 9, 5));
+ int8_t imm = sext<4>(bits(machInst, 19, 16));
+ IntRegIndex pg = (IntRegIndex) (uint8_t) bits(machInst, 12, 10);
+
+ return decodeSveContigStoreSIInsts<SveContigStoreSI>(
+ bits(machInst, 24, 21), machInst, zt, pg, rn, imm);
+ } // decodeSveContigStoreSI
+
+ StaticInstPtr
+ decodeSveContigNTStoreSS(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveContigNTStoreSS
+
+ StaticInstPtr
+ decodeSveScatterStore64SV32U(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveScatterStore64SV32U
+
+ StaticInstPtr
+ decodeSveScatterStore64SV64U(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveScatterStore64SV64U
+
+ StaticInstPtr
+ decodeSveContigNTStoreSI(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveContigNTStoreSI
+
+ StaticInstPtr
+ decodeSveScatterStore64VI(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveScatterStore64VI
+
+ StaticInstPtr
+ decodeSveScatterStore32SV32S(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveScatterStore32SV32S
+
+ StaticInstPtr
+ decodeSveStoreStructsSS(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveStoreStructsSS
+
+ StaticInstPtr
+ decodeSveStoreStructsSI(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveStoreStructsSI
+
+ StaticInstPtr
+ decodeSveScatterStore32SV32U(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveScatterStore32SV32U
+
+ StaticInstPtr
+ decodeSveScatterStore32VI(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveScatterStore32VI
+
+ StaticInstPtr
+ decodeSveScatterStore64SV32S(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveScatterStore64SV32S
+
+ StaticInstPtr
+ decodeSveScatterStore64SV64S(ExtMachInst machInst)
+ {
+ return new Unknown64(machInst);
+ } // decodeSveScatterStore64SV64S
+
+ StaticInstPtr
decodeSveMemStore(ExtMachInst machInst)
{
+ switch (bits(machInst, 15, 13)) {
+ case 0x0:
+ if (bits(machInst, 24, 22) == 0x6 && bits(machInst, 4) == 0x0) {
+ IntRegIndex pt = (IntRegIndex) (uint8_t) bits(machInst, 3, 0);
+ IntRegIndex rn = makeSP(
+ (IntRegIndex) (uint8_t) bits(machInst, 9, 5));
+ int16_t imm = sext<9>((bits(machInst, 21, 16) << 3) |
+ bits(machInst, 12, 10));
+ return new SveStrPred(machInst, pt, rn, imm);
+ }
+ break;
+ case 0x2:
+ if (bits(machInst, 24, 22) == 0x6) {
+ IntRegIndex zt = (IntRegIndex) (uint8_t) bits(machInst, 4, 0);
+ IntRegIndex rn = makeSP(
+ (IntRegIndex) (uint8_t) bits(machInst, 9, 5));
+ int16_t imm = sext<9>((bits(machInst, 21, 16) << 3) |
+ bits(machInst, 12, 10));
+ return new SveStrVec(machInst, zt, rn, imm);
+ } else {
+ return decodeSveContigStoreSS(machInst);
+ }
+ break;
+ case 0x3:
+ if (bits(machInst, 22, 21) == 0x0) {
+ return decodeSveContigNTStoreSS(machInst);
+ } else {
+ return decodeSveStoreStructsSS(machInst);
+ }
+ case 0x4:
+ case 0x6:
+ switch (bits(machInst, 22, 21)) {
+ case 0x0:
+ return decodeSveScatterStore64SV32U(machInst);
+ case 0x1:
+ if (bits(machInst, 24, 23) != 0x0) {
+ return decodeSveScatterStore64SV32S(machInst);
+ }
+ break;
+ case 0x2:
+ if (bits(machInst, 24, 23) != 0x3) {
+ return decodeSveScatterStore32SV32U(machInst);
+ }
+ break;
+ case 0x3:
+ return decodeSveScatterStore32SV32S(machInst);
+ }
+ break;
+ case 0x5:
+ switch (bits(machInst, 22, 21)) {
+ case 0x0:
+ return decodeSveScatterStore64SV64U(machInst);
+ case 0x1:
+ if (bits(machInst, 24, 23) != 0x0) {
+ return decodeSveScatterStore64SV64S(machInst);
+ }
+ break;
+ case 0x2:
+ return decodeSveScatterStore64VI(machInst);
+ case 0x3:
+ if (bits(machInst, 24, 23) != 0x3) {
+ return decodeSveScatterStore64VI(machInst);
+ }
+ break;
+ }
+ break;
+ case 0x7:
+ if (bits(machInst, 20) == 0x0) {
+ return decodeSveContigStoreSI(machInst);
+ } else if (bits(machInst, 22, 21) == 0x0) {
+ return decodeSveContigNTStoreSI(machInst);
+ } else {
+ return decodeSveStoreStructsSI(machInst);
+ }
+ }
return new Unknown64(machInst);
} // decodeSveMemStore
diff --git a/src/arch/arm/isa/includes.isa b/src/arch/arm/isa/includes.isa
index b89a67432..9aef8c651 100644
--- a/src/arch/arm/isa/includes.isa
+++ b/src/arch/arm/isa/includes.isa
@@ -65,6 +65,7 @@ output header {{
#include "arch/arm/insts/pseudo.hh"
#include "arch/arm/insts/static_inst.hh"
#include "arch/arm/insts/sve.hh"
+#include "arch/arm/insts/sve_mem.hh"
#include "arch/arm/insts/vfp.hh"
#include "arch/arm/isa_traits.hh"
#include "mem/packet.hh"
diff --git a/src/arch/arm/isa/insts/insts.isa b/src/arch/arm/isa/insts/insts.isa
index 623657efc..a1b35efc4 100644
--- a/src/arch/arm/isa/insts/insts.isa
+++ b/src/arch/arm/isa/insts/insts.isa
@@ -99,6 +99,7 @@ split decoder;
//SVE
##include "sve.isa"
+##include "sve_mem.isa"
//m5 Pseudo-ops
##include "m5ops.isa"
diff --git a/src/arch/arm/isa/insts/sve_mem.isa b/src/arch/arm/isa/insts/sve_mem.isa
new file mode 100644
index 000000000..f4ca4c3c9
--- /dev/null
+++ b/src/arch/arm/isa/insts/sve_mem.isa
@@ -0,0 +1,453 @@
+// Copyright (c) 2017 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: Giacomo Gabrielli
+
+// @file Definition of SVE memory access instructions.
+
+output header {{
+
+ // Decodes SVE contiguous load instructions, scalar plus scalar form.
+ template <template <typename T1, typename T2> class Base>
+ StaticInstPtr
+ decodeSveContigLoadSSInsts(uint8_t dtype, ExtMachInst machInst,
+ IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
+ IntRegIndex rm, bool firstFaulting)
+ {
+ const char* mn = firstFaulting ? "ldff1" : "ld1";
+ switch (dtype) {
+ case 0x0:
+ return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x1:
+ return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x2:
+ return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x3:
+ return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x4:
+ return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x5:
+ return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x6:
+ return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x7:
+ return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x8:
+ return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x9:
+ return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, rm);
+ case 0xa:
+ return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
+ case 0xb:
+ return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
+ case 0xc:
+ return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0xd:
+ return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0xe:
+ return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0xf:
+ return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm);
+ }
+ return new Unknown64(machInst);
+ }
+
+ // Decodes SVE contiguous load instructions, scalar plus immediate form.
+ template <template <typename T1, typename T2> class Base>
+ StaticInstPtr
+ decodeSveContigLoadSIInsts(uint8_t dtype, ExtMachInst machInst,
+ IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
+ uint64_t imm, bool firstFaulting,
+ bool replicate = false)
+ {
+ assert(!(replicate && firstFaulting));
+
+ const char* mn = replicate ? "ld1r" :
+ (firstFaulting ? "ldff1" : "ld1");
+ switch (dtype) {
+ case 0x0:
+ return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x1:
+ return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x2:
+ return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x3:
+ return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x4:
+ return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x5:
+ return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x6:
+ return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x7:
+ return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x8:
+ return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x9:
+ return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, imm);
+ case 0xa:
+ return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
+ case 0xb:
+ return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
+ case 0xc:
+ return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0xd:
+ return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0xe:
+ return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0xf:
+ return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm);
+ }
+ return new Unknown64(machInst);
+ }
+
+ // Decodes SVE contiguous store instructions, scalar plus scalar form.
+ template <template <typename T1, typename T2> class Base>
+ StaticInstPtr
+ decodeSveContigStoreSSInsts(uint8_t dtype, ExtMachInst machInst,
+ IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
+ IntRegIndex rm)
+ {
+ const char* mn = "st1";
+ switch (dtype) {
+ case 0x0:
+ return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x1:
+ return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x2:
+ return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x3:
+ return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x5:
+ return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x6:
+ return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
+ case 0x7:
+ return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
+ case 0xa:
+ return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
+ case 0xb:
+ return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
+ case 0xf:
+ return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm);
+ }
+ return new Unknown64(machInst);
+ }
+
+ // Decodes SVE contiguous store instructions, scalar plus immediate form.
+ template <template <typename T1, typename T2> class Base>
+ StaticInstPtr
+ decodeSveContigStoreSIInsts(uint8_t dtype, ExtMachInst machInst,
+ IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
+ int8_t imm)
+ {
+ const char* mn = "st1";
+ switch (dtype) {
+ case 0x0:
+ return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x1:
+ return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x2:
+ return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x3:
+ return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x5:
+ return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x6:
+ return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
+ case 0x7:
+ return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
+ case 0xa:
+ return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
+ case 0xb:
+ return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
+ case 0xf:
+ return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm);
+ }
+ return new Unknown64(machInst);
+ }
+
+ // NOTE: SVE load-and-replicate instructions are decoded with
+ // decodeSveContigLoadSIInsts(...).
+
+}};
+
+let {{
+
+ header_output = ''
+ exec_output = ''
+ decoders = { 'Generic': {} }
+
+ SPAlignmentCheckCode = '''
+ if (this->baseIsSP && bits(XBase, 3, 0) &&
+ SPAlignmentCheckEnabled(xc->tcBase())) {
+ return std::make_shared<SPAlignmentFault>();
+ }
+ '''
+
+ def emitSveMemFillSpill(isPred):
+ global header_output, exec_output, decoders
+ eaCode = SPAlignmentCheckCode + '''
+ int memAccessSize = %(memacc_size)s;
+ EA = XBase + ((int64_t) imm * %(memacc_size)s)''' % {
+ 'memacc_size': 'eCount / 8' if isPred else 'eCount'}
+ if isPred:
+ loadMemAccCode = '''
+ int index = 0;
+ uint8_t byte;
+ for (int i = 0; i < eCount / 8; i++) {
+ byte = memDataView[i];
+ for (int j = 0; j < 8; j++, index++) {
+ PDest_x[index] = (byte >> j) & 1;
+ }
+ }
+ '''
+ storeMemAccCode = '''
+ int index = 0;
+ uint8_t byte;
+ for (int i = 0; i < eCount / 8; i++) {
+ byte = 0;
+ for (int j = 0; j < 8; j++, index++) {
+ byte |= PDest_x[index] << j;
+ }
+ memDataView[i] = byte;
+ }
+ '''
+ storeWrEnableCode = '''
+ auto wrEn = std::vector<bool>(eCount / 8, true);
+ '''
+ else:
+ loadMemAccCode = '''
+ for (int i = 0; i < eCount; i++) {
+ AA64FpDest_x[i] = memDataView[i];
+ }
+ '''
+ storeMemAccCode = '''
+ for (int i = 0; i < eCount; i++) {
+ memDataView[i] = AA64FpDest_x[i];
+ }
+ '''
+ storeWrEnableCode = '''
+ auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true);
+ '''
+ loadIop = InstObjParams('ldr',
+ 'SveLdrPred' if isPred else 'SveLdrVec',
+ 'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill',
+ {'tpl_header': '',
+ 'tpl_args': '',
+ 'memacc_code': loadMemAccCode,
+ 'ea_code' : sveEnabledCheckCode + eaCode,
+ 'fa_code' : ''},
+ ['IsMemRef', 'IsLoad'])
+ storeIop = InstObjParams('str',
+ 'SveStrPred' if isPred else 'SveStrVec',
+ 'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill',
+ {'tpl_header': '',
+ 'tpl_args': '',
+ 'wren_code': storeWrEnableCode,
+ 'memacc_code': storeMemAccCode,
+ 'ea_code' : sveEnabledCheckCode + eaCode,
+ 'fa_code' : ''},
+ ['IsMemRef', 'IsStore'])
+ header_output += SveMemFillSpillOpDeclare.subst(loadIop)
+ header_output += SveMemFillSpillOpDeclare.subst(storeIop)
+ exec_output += (
+ SveContigLoadExecute.subst(loadIop) +
+ SveContigLoadInitiateAcc.subst(loadIop) +
+ SveContigLoadCompleteAcc.subst(loadIop) +
+ SveContigStoreExecute.subst(storeIop) +
+ SveContigStoreInitiateAcc.subst(storeIop) +
+ SveContigStoreCompleteAcc.subst(storeIop))
+
+ loadTplArgs = (
+ ('uint8_t', 'uint8_t'),
+ ('uint16_t', 'uint8_t'),
+ ('uint32_t', 'uint8_t'),
+ ('uint64_t', 'uint8_t'),
+ ('int64_t', 'int32_t'),
+ ('uint16_t', 'uint16_t'),
+ ('uint32_t', 'uint16_t'),
+ ('uint64_t', 'uint16_t'),
+ ('int64_t', 'int16_t'),
+ ('int32_t', 'int16_t'),
+ ('uint32_t', 'uint32_t'),
+ ('uint64_t', 'uint32_t'),
+ ('int64_t', 'int8_t'),
+ ('int32_t', 'int8_t'),
+ ('int16_t', 'int8_t'),
+ ('uint64_t', 'uint64_t'),
+ )
+
+ storeTplArgs = (
+ ('uint8_t', 'uint8_t'),
+ ('uint16_t', 'uint8_t'),
+ ('uint32_t', 'uint8_t'),
+ ('uint64_t', 'uint8_t'),
+ ('uint16_t', 'uint16_t'),
+ ('uint32_t', 'uint16_t'),
+ ('uint64_t', 'uint16_t'),
+ ('uint32_t', 'uint32_t'),
+ ('uint64_t', 'uint32_t'),
+ ('uint64_t', 'uint64_t'),
+ )
+
+ # Generates definitions for SVE contiguous loads
+ def emitSveContigMemInsts(offsetIsImm):
+ global header_output, exec_output, decoders
+ tplHeader = 'template <class RegElemType, class MemElemType>'
+ tplArgs = '<RegElemType, MemElemType>'
+ eaCode = SPAlignmentCheckCode + '''
+ int memAccessSize = eCount * sizeof(MemElemType);
+ EA = XBase + '''
+ if offsetIsImm:
+ eaCode += '((int64_t) this->imm * eCount * sizeof(MemElemType))'
+ else:
+ eaCode += '(XOffset * sizeof(MemElemType));'
+ loadMemAccCode = '''
+ for (int i = 0; i < eCount; i++) {
+ if (GpOp_x[i]) {
+ AA64FpDest_x[i] = memDataView[i];
+ } else {
+ AA64FpDest_x[i] = 0;
+ }
+ }
+ '''
+ storeMemAccCode = '''
+ for (int i = 0; i < eCount; i++) {
+ if (GpOp_x[i]) {
+ memDataView[i] = AA64FpDest_x[i];
+ } else {
+ memDataView[i] = 0;
+ for (int j = 0; j < sizeof(MemElemType); j++) {
+ wrEn[sizeof(MemElemType) * i + j] = false;
+ }
+ }
+ }
+ '''
+ storeWrEnableCode = '''
+ auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true);
+ '''
+ loadIop = InstObjParams('ld1',
+ 'SveContigLoadSI' if offsetIsImm else 'SveContigLoadSS',
+ 'SveContigMemSI' if offsetIsImm else 'SveContigMemSS',
+ {'tpl_header': tplHeader,
+ 'tpl_args': tplArgs,
+ 'memacc_code': loadMemAccCode,
+ 'ea_code' : sveEnabledCheckCode + eaCode,
+ 'fa_code' : ''},
+ ['IsMemRef', 'IsLoad'])
+ storeIop = InstObjParams('st1',
+ 'SveContigStoreSI' if offsetIsImm else 'SveContigStoreSS',
+ 'SveContigMemSI' if offsetIsImm else 'SveContigMemSS',
+ {'tpl_header': tplHeader,
+ 'tpl_args': tplArgs,
+ 'wren_code': storeWrEnableCode,
+ 'memacc_code': storeMemAccCode,
+ 'ea_code' : sveEnabledCheckCode + eaCode,
+ 'fa_code' : ''},
+ ['IsMemRef', 'IsStore'])
+ if offsetIsImm:
+ header_output += SveContigMemSIOpDeclare.subst(loadIop)
+ header_output += SveContigMemSIOpDeclare.subst(storeIop)
+ else:
+ header_output += SveContigMemSSOpDeclare.subst(loadIop)
+ header_output += SveContigMemSSOpDeclare.subst(storeIop)
+ exec_output += (
+ SveContigLoadExecute.subst(loadIop) +
+ SveContigLoadInitiateAcc.subst(loadIop) +
+ SveContigLoadCompleteAcc.subst(loadIop) +
+ SveContigStoreExecute.subst(storeIop) +
+ SveContigStoreInitiateAcc.subst(storeIop) +
+ SveContigStoreCompleteAcc.subst(storeIop))
+ for args in loadTplArgs:
+ substDict = {'tpl_args': '<%s>' % ', '.join(args),
+ 'class_name': 'SveContigLoadSI' if offsetIsImm
+ else 'SveContigLoadSS'}
+ exec_output += SveContigMemExecDeclare.subst(substDict)
+ for args in storeTplArgs:
+ substDict = {'tpl_args': '<%s>' % ', '.join(args),
+ 'class_name': 'SveContigStoreSI' if offsetIsImm
+ else 'SveContigStoreSS'}
+ exec_output += SveContigMemExecDeclare.subst(substDict)
+
+ # Generates definitions for SVE load-and-replicate instructions
+ def emitSveLoadAndRepl():
+ global header_output, exec_output, decoders
+ tplHeader = 'template <class RegElemType, class MemElemType>'
+ tplArgs = '<RegElemType, MemElemType>'
+ eaCode = SPAlignmentCheckCode + '''
+ EA = XBase + imm * sizeof(MemElemType);'''
+ memAccCode = '''
+ for (int i = 0; i < eCount; i++) {
+ if (GpOp_x[i]) {
+ AA64FpDest_x[i] = memData;
+ } else {
+ AA64FpDest_x[i] = 0;
+ }
+ }
+ '''
+ iop = InstObjParams('ld1r',
+ 'SveLoadAndRepl',
+ 'SveContigMemSI',
+ {'tpl_header': tplHeader,
+ 'tpl_args': tplArgs,
+ 'memacc_code': memAccCode,
+ 'ea_code' : sveEnabledCheckCode + eaCode,
+ 'fa_code' : ''},
+ ['IsMemRef', 'IsLoad'])
+ header_output += SveContigMemSIOpDeclare.subst(iop)
+ exec_output += (
+ SveLoadAndReplExecute.subst(iop) +
+ SveLoadAndReplInitiateAcc.subst(iop) +
+ SveLoadAndReplCompleteAcc.subst(iop))
+ for args in loadTplArgs:
+ substDict = {'tpl_args': '<%s>' % ', '.join(args),
+ 'class_name': 'SveLoadAndRepl'}
+ exec_output += SveContigMemExecDeclare.subst(substDict)
+
+ # LD1[S]{B,H,W,D} (scalar plus immediate)
+ emitSveContigMemInsts(True)
+ # LD1[S]{B,H,W,D} (scalar plus scalar)
+ emitSveContigMemInsts(False)
+
+ # LD1R[S]{B,H,W,D}
+ emitSveLoadAndRepl()
+
+ # LDR (predicate), STR (predicate)
+ emitSveMemFillSpill(True)
+ # LDR (vector), STR (vector)
+ emitSveMemFillSpill(False)
+
+}};
diff --git a/src/arch/arm/isa/templates/sve.isa b/src/arch/arm/isa/templates/sve.isa
index d7682c447..6520a0c71 100644
--- a/src/arch/arm/isa/templates/sve.isa
+++ b/src/arch/arm/isa/templates/sve.isa
@@ -38,7 +38,7 @@
let {{
sveEnabledCheckCode = '''
if (FullSystem) {
- fault = checkSveEnabled(xc->tcBase(), Cpsr, Cpacr64);
+ fault = this->checkSveEnabled(xc->tcBase(), Cpsr, Cpacr64);
if (fault != NoFault) {
return fault;
}
diff --git a/src/arch/arm/isa/templates/sve_mem.isa b/src/arch/arm/isa/templates/sve_mem.isa
new file mode 100644
index 000000000..8471e44ba
--- /dev/null
+++ b/src/arch/arm/isa/templates/sve_mem.isa
@@ -0,0 +1,386 @@
+// Copyright (c) 2017 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: Giacomo Gabrielli
+
+def template SveMemFillSpillOpDeclare {{
+ class %(class_name)s : public %(base_class)s
+ {
+ protected:
+ typedef uint8_t TPElem;
+ typedef uint8_t RegElemType;
+ typedef uint8_t MemElemType;
+
+ public:
+ %(class_name)s(ExtMachInst machInst,
+ IntRegIndex _dest, IntRegIndex _base, uint64_t _imm)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ _dest, _base, _imm)
+ {
+ %(constructor)s;
+ }
+
+ Fault execute(ExecContext *, Trace::InstRecord *) const;
+ Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
+ Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
+
+ virtual void
+ annotateFault(ArmFault *fault) {
+ %(fa_code)s
+ }
+ };
+}};
+
+def template SveContigMemSSOpDeclare {{
+ %(tpl_header)s
+ class %(class_name)s : public %(base_class)s
+ {
+ protected:
+ typedef RegElemType TPElem;
+
+ public:
+ %(class_name)s(const char* mnem, ExtMachInst machInst,
+ IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
+ IntRegIndex _offset)
+ : %(base_class)s(mnem, machInst, %(op_class)s,
+ _dest, _gp, _base, _offset)
+ {
+ %(constructor)s;
+ }
+
+ Fault execute(ExecContext *, Trace::InstRecord *) const;
+ Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
+ Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
+
+ virtual void
+ annotateFault(ArmFault *fault) {
+ %(fa_code)s
+ }
+ };
+}};
+
+def template SveContigMemSIOpDeclare {{
+ %(tpl_header)s
+ class %(class_name)s : public %(base_class)s
+ {
+ protected:
+ typedef RegElemType TPElem;
+
+ public:
+ %(class_name)s(const char* mnem, ExtMachInst machInst,
+ IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
+ uint64_t _imm)
+ : %(base_class)s(mnem, machInst, %(op_class)s,
+ _dest, _gp, _base, _imm)
+ {
+ %(constructor)s;
+ }
+
+ Fault execute(ExecContext *, Trace::InstRecord *) const;
+ Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
+ Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
+
+ virtual void
+ annotateFault(ArmFault *fault) {
+ %(fa_code)s
+ }
+ };
+}};
+
+def template SveContigMemExecDeclare {{
+ template
+ Fault %(class_name)s%(tpl_args)s::execute(ExecContext *,
+ Trace::InstRecord *) const;
+
+ template
+ Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *,
+ Trace::InstRecord *) const;
+
+ template
+ Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr,
+ ExecContext *, Trace::InstRecord *) const;
+}};
+
+def template SveContigLoadExecute {{
+ %(tpl_header)s
+ Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ bool aarch64 M5_VAR_USED = true;
+ unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
+ xc->tcBase());
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ TheISA::VecRegContainer memData;
+ auto memDataView = memData.as<MemElemType>();
+
+ if (fault == NoFault) {
+ fault = xc->readMem(EA, memData.raw_ptr<uint8_t>(), memAccessSize,
+ this->memAccessFlags);
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template SveContigLoadInitiateAcc {{
+ %(tpl_header)s
+ Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ bool aarch64 M5_VAR_USED = true;
+ unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
+ xc->tcBase());
+
+ %(op_src_decl)s;
+ %(op_rd)s;
+
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->initiateMemRead(EA, memAccessSize,
+ this->memAccessFlags);
+ }
+
+ return fault;
+ }
+}};
+
+def template SveContigLoadCompleteAcc {{
+ %(tpl_header)s
+ Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
+ ExecContext *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ bool aarch64 M5_VAR_USED = true;
+ unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
+ xc->tcBase());
+
+ %(op_decl)s;
+ %(op_rd)s;
+
+ TheISA::VecRegContainer memData;
+ auto memDataView = memData.as<MemElemType>();
+
+ memcpy(memData.raw_ptr<uint8_t>(), pkt->getPtr<uint8_t>(),
+ pkt->getSize());
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template SveContigStoreExecute {{
+ %(tpl_header)s
+ Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ bool aarch64 M5_VAR_USED = true;
+ unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
+ xc->tcBase());
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ TheISA::VecRegContainer memData;
+ auto memDataView = memData.as<MemElemType>();
+
+ %(wren_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->writeMem(memData.raw_ptr<uint8_t>(), memAccessSize, EA,
+ this->memAccessFlags, NULL, wrEn);
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template SveContigStoreInitiateAcc {{
+ %(tpl_header)s
+ Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ bool aarch64 M5_VAR_USED = true;
+ unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
+ xc->tcBase());
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ TheISA::VecRegContainer memData;
+ auto memDataView = memData.as<MemElemType>();
+
+ %(wren_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->writeMem(memData.raw_ptr<uint8_t>(), memAccessSize, EA,
+ this->memAccessFlags, NULL, wrEn);
+ }
+
+ return fault;
+ }
+}};
+
+def template SveContigStoreCompleteAcc {{
+ %(tpl_header)s
+ Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
+ ExecContext *xc, Trace::InstRecord *traceData) const
+ {
+ return NoFault;
+ }
+}};
+
+def template SveLoadAndReplExecute {{
+ %(tpl_header)s
+ Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ bool aarch64 M5_VAR_USED = true;
+ unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
+ xc->tcBase());
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ MemElemType memData;
+
+ if (fault == NoFault) {
+ fault = readMemAtomic(xc, traceData, EA, memData,
+ this->memAccessFlags);
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template SveLoadAndReplInitiateAcc {{
+ %(tpl_header)s
+ Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ bool aarch64 M5_VAR_USED = true;
+
+ %(op_src_decl)s;
+ %(op_rd)s;
+
+ %(ea_code)s;
+
+ MemElemType memData;
+
+ if (fault == NoFault) {
+ fault = initiateMemRead(xc, traceData, EA, memData,
+ this->memAccessFlags);
+ }
+
+ return fault;
+ }
+}};
+
+def template SveLoadAndReplCompleteAcc {{
+ %(tpl_header)s
+ Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
+ ExecContext *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ bool aarch64 M5_VAR_USED = true;
+ unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
+ xc->tcBase());
+
+ %(op_decl)s;
+ %(op_rd)s;
+
+ MemElemType memData;
+ getMem(pkt, memData, traceData);
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
diff --git a/src/arch/arm/isa/templates/templates.isa b/src/arch/arm/isa/templates/templates.isa
index c0647b81f..0207599a2 100644
--- a/src/arch/arm/isa/templates/templates.isa
+++ b/src/arch/arm/isa/templates/templates.isa
@@ -83,3 +83,4 @@
//Templates for SVE instructions
##include "sve.isa"
+##include "sve_mem.isa"