From 16fcad3907f439b8cdbaad638a8618ee7ad6a9da Mon Sep 17 00:00:00 2001 From: William Wang Date: Mon, 4 Apr 2011 11:42:28 -0500 Subject: [PATCH] ARM: Cleanup and small fixes to some NEON ops to match the spec. Only certain bits of the cpacr can be written, some must be equal. Mult instructions that write the same register should do something sane --- src/arch/arm/isa.cc | 23 ++++++++++++++--------- src/arch/arm/isa/insts/mult.isa | 8 ++++---- src/arch/arm/isa/insts/neon.isa | 28 ++++++++++++++-------------- src/arch/arm/miscregs.hh | 1 + src/arch/arm/utility.hh | 7 ++++++- 5 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index f3f730896..216ae04e7 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -268,19 +268,22 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) switch (misc_reg) { case MISCREG_CPACR: { - CPACR newCpacr = 0; - CPACR valCpacr = val; - newCpacr.cp10 = valCpacr.cp10; - newCpacr.cp11 = valCpacr.cp11; - //XXX d32dis isn't implemented. The manual says whether or not - //it works is implementation defined. - newCpacr.asedis = valCpacr.asedis; - newVal = newCpacr; + + const uint32_t ones = (uint32_t)(-1); + CPACR cpacrMask = 0; + // Only cp10, cp11, and ase are implemented, nothing else should + // be writable + cpacrMask.cp10 = ones; + cpacrMask.cp11 = ones; + cpacrMask.asedis = ones; + newVal &= cpacrMask; + DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n", + miscRegName[misc_reg], newVal); } break; case MISCREG_CSSELR: warn_once("The csselr register isn't implemented.\n"); - break; + return; case MISCREG_FPSCR: { const uint32_t ones = (uint32_t)(-1); @@ -320,6 +323,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) break; case MISCREG_FPEXC: { + // vfpv3 architecture, section B.6.1 of DDI04068 + // bit 29 - valid only if fpexc[31] is 0 const uint32_t fpexcMask = 0x60000000; newVal = (newVal & fpexcMask) | (miscRegs[MISCREG_FPEXC] & ~fpexcMask); diff --git a/src/arch/arm/isa/insts/mult.isa b/src/arch/arm/isa/insts/mult.isa index ae8f04a81..b3a9fca5f 100644 --- a/src/arch/arm/isa/insts/mult.isa +++ b/src/arch/arm/isa/insts/mult.isa @@ -349,8 +349,8 @@ let {{ ''') buildMult4Inst ("smull", '''resTemp = (int64_t)Reg2.sw * (int64_t)Reg3.sw; - Reg0 = (int32_t)resTemp; Reg1 = (int32_t)(resTemp >> 32); + Reg0 = (int32_t)resTemp; ''', "llbit") buildMult3InstUnCc("smulwb", '''Reg0 = resTemp = (Reg1.sw * @@ -374,16 +374,16 @@ let {{ ''') buildMult4InstUnCc("umaal", '''resTemp = Reg2.ud * Reg3.ud + Reg0.ud + Reg1.ud; - Reg0.ud = (uint32_t)resTemp; Reg1.ud = (uint32_t)(resTemp >> 32); + Reg0.ud = (uint32_t)resTemp; ''') buildMult4Inst ("umlal", '''resTemp = Reg2.ud * Reg3.ud + Reg0.ud + (Reg1.ud << 32); - Reg0.ud = (uint32_t)resTemp; Reg1.ud = (uint32_t)(resTemp >> 32); + Reg0.ud = (uint32_t)resTemp; ''', "llbit") buildMult4Inst ("umull", '''resTemp = Reg2.ud * Reg3.ud; - Reg0 = (uint32_t)resTemp; Reg1 = (uint32_t)(resTemp >> 32); + Reg0 = (uint32_t)resTemp; ''', "llbit") }}; diff --git a/src/arch/arm/isa/insts/neon.isa b/src/arch/arm/isa/insts/neon.isa index 5aca525a4..083d1ebaf 100644 --- a/src/arch/arm/isa/insts/neon.isa +++ b/src/arch/arm/isa/insts/neon.isa @@ -1761,8 +1761,8 @@ let {{ } } ''' - threeEqualRegInst("vshl", "VshlD", "SimdAluOp", allTypes, 2, vshlCode) - threeEqualRegInst("vshl", "VshlQ", "SimdAluOp", allTypes, 4, vshlCode) + threeEqualRegInst("vshl", "VshlD", "SimdShiftOp", allTypes, 2, vshlCode) + threeEqualRegInst("vshl", "VshlQ", "SimdShiftOp", allTypes, 4, vshlCode) vrshlCode = ''' int16_t shiftAmt = (int8_t)srcElem2; @@ -3204,8 +3204,8 @@ let {{ substDict = { "targs" : type, "class_name" : Name } exec_output += NeonExecDeclare.subst(substDict) - vdupGprInst("vdup", "NVdupDGpr", "SimdAluOp", smallUnsignedTypes, 2) - vdupGprInst("vdup", "NVdupQGpr", "SimdAluOp", smallUnsignedTypes, 4) + vdupGprInst("vdup", "NVdupDGpr", "SimdMiscOp", smallUnsignedTypes, 2) + vdupGprInst("vdup", "NVdupQGpr", "SimdMiscOp", smallUnsignedTypes, 4) vmovCode = 'destElem = imm;' oneRegImmInst("vmov", "NVmoviD", "SimdMiscOp", ("uint64_t",), 2, vmovCode) @@ -3309,8 +3309,8 @@ let {{ } } ''' - buildVext("vext", "NVextD", "SimdAluOp", ("uint8_t",), 2, vextCode) - buildVext("vext", "NVextQ", "SimdAluOp", ("uint8_t",), 4, vextCode) + buildVext("vext", "NVextD", "SimdMiscOp", ("uint8_t",), 2, vextCode) + buildVext("vext", "NVextQ", "SimdMiscOp", ("uint8_t",), 4, vextCode) def buildVtbxl(name, Name, opClass, length, isVtbl): global header_output, decoder_output, exec_output @@ -3366,13 +3366,13 @@ let {{ decoder_output += RegRegRegOpConstructor.subst(iop) exec_output += PredOpExecute.subst(iop) - buildVtbxl("vtbl", "NVtbl1", "SimdAluOp", 1, "true") - buildVtbxl("vtbl", "NVtbl2", "SimdAluOp", 2, "true") - buildVtbxl("vtbl", "NVtbl3", "SimdAluOp", 3, "true") - buildVtbxl("vtbl", "NVtbl4", "SimdAluOp", 4, "true") + buildVtbxl("vtbl", "NVtbl1", "SimdMiscOp", 1, "true") + buildVtbxl("vtbl", "NVtbl2", "SimdMiscOp", 2, "true") + buildVtbxl("vtbl", "NVtbl3", "SimdMiscOp", 3, "true") + buildVtbxl("vtbl", "NVtbl4", "SimdMiscOp", 4, "true") - buildVtbxl("vtbx", "NVtbx1", "SimdAluOp", 1, "false") - buildVtbxl("vtbx", "NVtbx2", "SimdAluOp", 2, "false") - buildVtbxl("vtbx", "NVtbx3", "SimdAluOp", 3, "false") - buildVtbxl("vtbx", "NVtbx4", "SimdAluOp", 4, "false") + buildVtbxl("vtbx", "NVtbx1", "SimdMiscOp", 1, "false") + buildVtbxl("vtbx", "NVtbx2", "SimdMiscOp", 2, "false") + buildVtbxl("vtbx", "NVtbx3", "SimdMiscOp", 3, "false") + buildVtbxl("vtbx", "NVtbx4", "SimdMiscOp", 4, "false") }}; diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 1e105799f..fc18fa114 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -310,6 +310,7 @@ namespace ArmISA Bitfield<23, 22> cp11; Bitfield<25, 24> cp12; Bitfield<27, 26> cp13; + Bitfield<29, 28> rsvd; Bitfield<30> d32dis; Bitfield<31> asedis; EndBitUnion(CPACR) diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 0fea44695..20cb9b426 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -146,7 +146,12 @@ vfpEnabled(CPACR cpacr, CPSR cpsr) static inline bool vfpEnabled(CPACR cpacr, CPSR cpsr, FPEXC fpexc) { - return fpexc.en && vfpEnabled(cpacr, cpsr); + if ((cpacr.cp11 == 0x3) || + ((cpacr.cp11 == 0x1) && inPrivilegedMode(cpsr))) + return fpexc.en && vfpEnabled(cpacr, cpsr); + else + return fpexc.en && vfpEnabled(cpacr, cpsr) && + (cpacr.cp11 == cpacr.cp10); } static inline bool -- 2.30.2