diff options
Diffstat (limited to 'src/arch/arm/isa')
-rw-r--r-- | src/arch/arm/isa/formats/fp.isa | 84 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/fp.isa | 148 |
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 = "" |