summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/isa.cc23
-rw-r--r--src/arch/arm/isa/insts/mult.isa8
-rw-r--r--src/arch/arm/isa/insts/neon.isa28
-rw-r--r--src/arch/arm/miscregs.hh1
-rw-r--r--src/arch/arm/utility.hh7
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