From c1f7bf7f0e97f8470eb4280870244b6b673dbff4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Jun 2010 12:58:14 -0500 Subject: ARM: Add support for VFP vector mode. --- src/arch/arm/isa/formats/fp.isa | 84 +++++++++++++++-------- src/arch/arm/isa/insts/fp.isa | 148 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+), 28 deletions(-) (limited to 'src/arch/arm/isa') 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( + machInst, vd, vn, vm, false); } else { - return new VmlaD(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, true); } } else { if (single) { - return new VmlsS(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, false); } else { - return new VmlsD(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, true); } } case 0x1: if (bits(machInst, 6) == 1) { if (single) { - return new VnmlaS(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, false); } else { - return new VnmlaD(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, true); } } else { if (single) { - return new VnmlsS(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, false); } else { - return new VnmlsD(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, true); } } case 0x2: if ((opc3 & 0x1) == 0) { if (single) { - return new VmulS(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, false); } else { - return new VmulD(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, true); } } else { if (single) { - return new VnmulS(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, false); } else { - return new VnmulD(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, true); } } case 0x3: if ((opc3 & 0x1) == 0) { if (single) { - return new VaddS(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, false); } else { - return new VaddD(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, true); } } else { if (single) { - return new VsubS(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, false); } else { - return new VsubD(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, true); } } case 0x8: if ((opc3 & 0x1) == 0) { if (single) { - return new VdivS(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + machInst, vd, vn, vm, false); } else { - return new VdivD(machInst, vd, vn, vm); + return decodeVfpRegRegRegOp( + 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( + machInst, vd, imm, false); } else { uint64_t imm = vfp_modified_imm(baseImm, true); - return new VmovImmD(machInst, vd, imm); + return decodeVfpRegImmOp( + machInst, vd, imm, true); } } switch (opc2) { case 0x0: if (opc3 == 1) { if (single) { - return new VmovRegS(machInst, vd, vm); + return decodeVfpRegRegOp( + machInst, vd, vm, false); } else { - return new VmovRegD(machInst, vd, vm); + return decodeVfpRegRegOp( + machInst, vd, vm, true); } } else { if (single) { - return new VabsS(machInst, vd, vm); + return decodeVfpRegRegOp( + machInst, vd, vm, false); } else { - return new VabsD(machInst, vd, vm); + return decodeVfpRegRegOp( + machInst, vd, vm, true); } } case 0x1: if (opc3 == 1) { if (single) { - return new VnegS(machInst, vd, vm); + return decodeVfpRegRegOp( + machInst, vd, vm, false); } else { - return new VnegD(machInst, vd, vm); + return decodeVfpRegRegOp( + machInst, vd, vm, true); } } else { if (single) { - return new VsqrtS(machInst, vd, vm); + return decodeVfpRegRegOp( + machInst, vd, vm, false); } else { - return new VsqrtD(machInst, vd, vm); + return decodeVfpRegRegOp( + 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 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 +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(machInst, dest, op1, wide); + } +} + +template +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 +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(machInst, dest, imm, wide); + } +} + +template +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 +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(machInst, dest, op1, imm, wide); + } +} + +template +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 +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(machInst, dest, op1, op2, wide); + } +} +}}; + let {{ header_output = "" -- cgit v1.2.3