summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:14 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:14 -0500
commitc1f7bf7f0e97f8470eb4280870244b6b673dbff4 (patch)
treec89128e4dff36de237bf7601936f6bb935621e00 /src/arch/arm/isa
parentf245f4937b2f48df17795887bdde9aeaf4476e39 (diff)
downloadgem5-c1f7bf7f0e97f8470eb4280870244b6b673dbff4.tar.xz
ARM: Add support for VFP vector mode.
Diffstat (limited to 'src/arch/arm/isa')
-rw-r--r--src/arch/arm/isa/formats/fp.isa84
-rw-r--r--src/arch/arm/isa/insts/fp.isa148
2 files changed, 204 insertions, 28 deletions
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
index e92757096..d15412825 100644
--- a/src/arch/arm/isa/formats/fp.isa
+++ b/src/arch/arm/isa/formats/fp.isa
@@ -504,65 +504,83 @@ let {{
case 0x0:
if (bits(machInst, 6) == 0) {
if (single) {
- return new VmlaS(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VmlaS>(
+ machInst, vd, vn, vm, false);
} else {
- return new VmlaD(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VmlaD>(
+ machInst, vd, vn, vm, true);
}
} else {
if (single) {
- return new VmlsS(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VmlsS>(
+ machInst, vd, vn, vm, false);
} else {
- return new VmlsD(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VmlsD>(
+ machInst, vd, vn, vm, true);
}
}
case 0x1:
if (bits(machInst, 6) == 1) {
if (single) {
- return new VnmlaS(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VnmlaS>(
+ machInst, vd, vn, vm, false);
} else {
- return new VnmlaD(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VnmlaD>(
+ machInst, vd, vn, vm, true);
}
} else {
if (single) {
- return new VnmlsS(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VnmlsS>(
+ machInst, vd, vn, vm, false);
} else {
- return new VnmlsD(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VnmlsD>(
+ machInst, vd, vn, vm, true);
}
}
case 0x2:
if ((opc3 & 0x1) == 0) {
if (single) {
- return new VmulS(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VmulS>(
+ machInst, vd, vn, vm, false);
} else {
- return new VmulD(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VmulD>(
+ machInst, vd, vn, vm, true);
}
} else {
if (single) {
- return new VnmulS(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VnmulS>(
+ machInst, vd, vn, vm, false);
} else {
- return new VnmulD(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VnmulD>(
+ machInst, vd, vn, vm, true);
}
}
case 0x3:
if ((opc3 & 0x1) == 0) {
if (single) {
- return new VaddS(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VaddS>(
+ machInst, vd, vn, vm, false);
} else {
- return new VaddD(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VaddD>(
+ machInst, vd, vn, vm, true);
}
} else {
if (single) {
- return new VsubS(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VsubS>(
+ machInst, vd, vn, vm, false);
} else {
- return new VsubD(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VsubD>(
+ machInst, vd, vn, vm, true);
}
}
case 0x8:
if ((opc3 & 0x1) == 0) {
if (single) {
- return new VdivS(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VdivS>(
+ machInst, vd, vn, vm, false);
} else {
- return new VdivD(machInst, vd, vn, vm);
+ return decodeVfpRegRegRegOp<VdivD>(
+ machInst, vd, vn, vm, true);
}
}
break;
@@ -572,39 +590,49 @@ let {{
bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
if (single) {
uint32_t imm = vfp_modified_imm(baseImm, false);
- return new VmovImmS(machInst, vd, imm);
+ return decodeVfpRegImmOp<VmovImmS>(
+ machInst, vd, imm, false);
} else {
uint64_t imm = vfp_modified_imm(baseImm, true);
- return new VmovImmD(machInst, vd, imm);
+ return decodeVfpRegImmOp<VmovImmD>(
+ machInst, vd, imm, true);
}
}
switch (opc2) {
case 0x0:
if (opc3 == 1) {
if (single) {
- return new VmovRegS(machInst, vd, vm);
+ return decodeVfpRegRegOp<VmovRegS>(
+ machInst, vd, vm, false);
} else {
- return new VmovRegD(machInst, vd, vm);
+ return decodeVfpRegRegOp<VmovRegD>(
+ machInst, vd, vm, true);
}
} else {
if (single) {
- return new VabsS(machInst, vd, vm);
+ return decodeVfpRegRegOp<VabsS>(
+ machInst, vd, vm, false);
} else {
- return new VabsD(machInst, vd, vm);
+ return decodeVfpRegRegOp<VabsD>(
+ machInst, vd, vm, true);
}
}
case 0x1:
if (opc3 == 1) {
if (single) {
- return new VnegS(machInst, vd, vm);
+ return decodeVfpRegRegOp<VnegS>(
+ machInst, vd, vm, false);
} else {
- return new VnegD(machInst, vd, vm);
+ return decodeVfpRegRegOp<VnegD>(
+ machInst, vd, vm, true);
}
} else {
if (single) {
- return new VsqrtS(machInst, vd, vm);
+ return decodeVfpRegRegOp<VsqrtS>(
+ machInst, vd, vm, false);
} else {
- return new VsqrtD(machInst, vd, vm);
+ return decodeVfpRegRegOp<VsqrtD>(
+ machInst, vd, vm, true);
}
}
case 0x2:
diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa
index 1402da61a..e2c7dd79b 100644
--- a/src/arch/arm/isa/insts/fp.isa
+++ b/src/arch/arm/isa/insts/fp.isa
@@ -37,6 +37,154 @@
//
// Authors: Gabe Black
+output header {{
+
+template <class Micro>
+class VfpMacroRegRegOp : public VfpMacroOp
+{
+ public:
+ VfpMacroRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
+ IntRegIndex _op1, bool _wide) :
+ VfpMacroOp("VfpMacroRegRegOp", _machInst, No_OpClass, _wide)
+ {
+ numMicroops = machInst.fpscrLen + 1;
+ assert(numMicroops > 1);
+ microOps = new StaticInstPtr[numMicroops];
+ for (unsigned i = 0; i < numMicroops; i++) {
+ VfpMicroMode mode = VfpMicroop;
+ if (i == 0)
+ mode = VfpFirstMicroop;
+ else if (i == numMicroops - 1)
+ mode = VfpLastMicroop;
+ microOps[i] = new Micro(_machInst, _dest, _op1, mode);
+ nextIdxs(_dest, _op1);
+ }
+ }
+
+ %(BasicExecPanic)s
+};
+
+template <class VfpOp>
+static StaticInstPtr
+decodeVfpRegRegOp(ExtMachInst machInst,
+ IntRegIndex dest, IntRegIndex op1, bool wide)
+{
+ if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
+ return new VfpOp(machInst, dest, op1);
+ } else {
+ return new VfpMacroRegRegOp<VfpOp>(machInst, dest, op1, wide);
+ }
+}
+
+template <class Micro>
+class VfpMacroRegImmOp : public VfpMacroOp
+{
+ public:
+ VfpMacroRegImmOp(ExtMachInst _machInst, IntRegIndex _dest, uint64_t _imm,
+ bool _wide) :
+ VfpMacroOp("VfpMacroRegImmOp", _machInst, No_OpClass, _wide)
+ {
+ numMicroops = machInst.fpscrLen + 1;
+ microOps = new StaticInstPtr[numMicroops];
+ for (unsigned i = 0; i < numMicroops; i++) {
+ VfpMicroMode mode = VfpMicroop;
+ if (i == 0)
+ mode = VfpFirstMicroop;
+ else if (i == numMicroops - 1)
+ mode = VfpLastMicroop;
+ microOps[i] = new Micro(_machInst, _dest, _imm, mode);
+ nextIdxs(_dest);
+ }
+ }
+
+ %(BasicExecPanic)s
+};
+
+template <class VfpOp>
+static StaticInstPtr
+decodeVfpRegImmOp(ExtMachInst machInst,
+ IntRegIndex dest, uint64_t imm, bool wide)
+{
+ if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
+ return new VfpOp(machInst, dest, imm);
+ } else {
+ return new VfpMacroRegImmOp<VfpOp>(machInst, dest, imm, wide);
+ }
+}
+
+template <class Micro>
+class VfpMacroRegRegImmOp : public VfpMacroOp
+{
+ public:
+ VfpMacroRegRegImmOp(ExtMachInst _machInst, IntRegIndex _dest,
+ IntRegIndex _op1, uint64_t _imm, bool _wide) :
+ VfpMacroOp("VfpMacroRegRegImmOp", _machInst, No_OpClass, _wide)
+ {
+ numMicroops = machInst.fpscrLen + 1;
+ microOps = new StaticInstPtr[numMicroops];
+ for (unsigned i = 0; i < numMicroops; i++) {
+ VfpMicroMode mode = VfpMicroop;
+ if (i == 0)
+ mode = VfpFirstMicroop;
+ else if (i == numMicroops - 1)
+ mode = VfpLastMicroop;
+ microOps[i] = new Micro(_machInst, _dest, _op1, _imm, mode);
+ nextIdxs(_dest, _op1);
+ }
+ }
+
+ %(BasicExecPanic)s
+};
+
+template <class VfpOp>
+static StaticInstPtr
+decodeVfpRegRegImmOp(ExtMachInst machInst, IntRegIndex dest,
+ IntRegIndex op1, uint64_t imm, bool wide)
+{
+ if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
+ return new VfpOp(machInst, dest, op1, imm);
+ } else {
+ return new VfpMacroRegRegImmOp<VfpOp>(machInst, dest, op1, imm, wide);
+ }
+}
+
+template <class Micro>
+class VfpMacroRegRegRegOp : public VfpMacroOp
+{
+ public:
+ VfpMacroRegRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
+ IntRegIndex _op1, IntRegIndex _op2, bool _wide) :
+ VfpMacroOp("VfpMacroRegRegRegOp", _machInst, No_OpClass, _wide)
+ {
+ numMicroops = machInst.fpscrLen + 1;
+ microOps = new StaticInstPtr[numMicroops];
+ for (unsigned i = 0; i < numMicroops; i++) {
+ VfpMicroMode mode = VfpMicroop;
+ if (i == 0)
+ mode = VfpFirstMicroop;
+ else if (i == numMicroops - 1)
+ mode = VfpLastMicroop;
+ microOps[i] = new Micro(_machInst, _dest, _op1, _op2, mode);
+ nextIdxs(_dest, _op1, _op2);
+ }
+ }
+
+ %(BasicExecPanic)s
+};
+
+template <class VfpOp>
+static StaticInstPtr
+decodeVfpRegRegRegOp(ExtMachInst machInst, IntRegIndex dest,
+ IntRegIndex op1, IntRegIndex op2, bool wide)
+{
+ if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
+ return new VfpOp(machInst, dest, op1, op2);
+ } else {
+ return new VfpMacroRegRegRegOp<VfpOp>(machInst, dest, op1, op2, wide);
+ }
+}
+}};
+
let {{
header_output = ""