diff options
Diffstat (limited to 'src/arch/arm')
-rw-r--r-- | src/arch/arm/isa.cc | 23 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/mult.isa | 8 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/neon.isa | 28 | ||||
-rw-r--r-- | src/arch/arm/miscregs.hh | 1 | ||||
-rw-r--r-- | 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 |