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
This commit is contained in:
parent
a679cd917a
commit
16fcad3907
5 changed files with 39 additions and 28 deletions
|
@ -268,19 +268,22 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
|
||||||
switch (misc_reg) {
|
switch (misc_reg) {
|
||||||
case MISCREG_CPACR:
|
case MISCREG_CPACR:
|
||||||
{
|
{
|
||||||
CPACR newCpacr = 0;
|
|
||||||
CPACR valCpacr = val;
|
const uint32_t ones = (uint32_t)(-1);
|
||||||
newCpacr.cp10 = valCpacr.cp10;
|
CPACR cpacrMask = 0;
|
||||||
newCpacr.cp11 = valCpacr.cp11;
|
// Only cp10, cp11, and ase are implemented, nothing else should
|
||||||
//XXX d32dis isn't implemented. The manual says whether or not
|
// be writable
|
||||||
//it works is implementation defined.
|
cpacrMask.cp10 = ones;
|
||||||
newCpacr.asedis = valCpacr.asedis;
|
cpacrMask.cp11 = ones;
|
||||||
newVal = newCpacr;
|
cpacrMask.asedis = ones;
|
||||||
|
newVal &= cpacrMask;
|
||||||
|
DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
|
||||||
|
miscRegName[misc_reg], newVal);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MISCREG_CSSELR:
|
case MISCREG_CSSELR:
|
||||||
warn_once("The csselr register isn't implemented.\n");
|
warn_once("The csselr register isn't implemented.\n");
|
||||||
break;
|
return;
|
||||||
case MISCREG_FPSCR:
|
case MISCREG_FPSCR:
|
||||||
{
|
{
|
||||||
const uint32_t ones = (uint32_t)(-1);
|
const uint32_t ones = (uint32_t)(-1);
|
||||||
|
@ -320,6 +323,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
|
||||||
break;
|
break;
|
||||||
case MISCREG_FPEXC:
|
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;
|
const uint32_t fpexcMask = 0x60000000;
|
||||||
newVal = (newVal & fpexcMask) |
|
newVal = (newVal & fpexcMask) |
|
||||||
(miscRegs[MISCREG_FPEXC] & ~fpexcMask);
|
(miscRegs[MISCREG_FPEXC] & ~fpexcMask);
|
||||||
|
|
|
@ -349,8 +349,8 @@ let {{
|
||||||
''')
|
''')
|
||||||
buildMult4Inst ("smull", '''resTemp = (int64_t)Reg2.sw *
|
buildMult4Inst ("smull", '''resTemp = (int64_t)Reg2.sw *
|
||||||
(int64_t)Reg3.sw;
|
(int64_t)Reg3.sw;
|
||||||
Reg0 = (int32_t)resTemp;
|
|
||||||
Reg1 = (int32_t)(resTemp >> 32);
|
Reg1 = (int32_t)(resTemp >> 32);
|
||||||
|
Reg0 = (int32_t)resTemp;
|
||||||
''', "llbit")
|
''', "llbit")
|
||||||
buildMult3InstUnCc("smulwb", '''Reg0 = resTemp =
|
buildMult3InstUnCc("smulwb", '''Reg0 = resTemp =
|
||||||
(Reg1.sw *
|
(Reg1.sw *
|
||||||
|
@ -374,16 +374,16 @@ let {{
|
||||||
''')
|
''')
|
||||||
buildMult4InstUnCc("umaal", '''resTemp = Reg2.ud * Reg3.ud +
|
buildMult4InstUnCc("umaal", '''resTemp = Reg2.ud * Reg3.ud +
|
||||||
Reg0.ud + Reg1.ud;
|
Reg0.ud + Reg1.ud;
|
||||||
Reg0.ud = (uint32_t)resTemp;
|
|
||||||
Reg1.ud = (uint32_t)(resTemp >> 32);
|
Reg1.ud = (uint32_t)(resTemp >> 32);
|
||||||
|
Reg0.ud = (uint32_t)resTemp;
|
||||||
''')
|
''')
|
||||||
buildMult4Inst ("umlal", '''resTemp = Reg2.ud * Reg3.ud + Reg0.ud +
|
buildMult4Inst ("umlal", '''resTemp = Reg2.ud * Reg3.ud + Reg0.ud +
|
||||||
(Reg1.ud << 32);
|
(Reg1.ud << 32);
|
||||||
Reg0.ud = (uint32_t)resTemp;
|
|
||||||
Reg1.ud = (uint32_t)(resTemp >> 32);
|
Reg1.ud = (uint32_t)(resTemp >> 32);
|
||||||
|
Reg0.ud = (uint32_t)resTemp;
|
||||||
''', "llbit")
|
''', "llbit")
|
||||||
buildMult4Inst ("umull", '''resTemp = Reg2.ud * Reg3.ud;
|
buildMult4Inst ("umull", '''resTemp = Reg2.ud * Reg3.ud;
|
||||||
Reg0 = (uint32_t)resTemp;
|
|
||||||
Reg1 = (uint32_t)(resTemp >> 32);
|
Reg1 = (uint32_t)(resTemp >> 32);
|
||||||
|
Reg0 = (uint32_t)resTemp;
|
||||||
''', "llbit")
|
''', "llbit")
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -1761,8 +1761,8 @@ let {{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
threeEqualRegInst("vshl", "VshlD", "SimdAluOp", allTypes, 2, vshlCode)
|
threeEqualRegInst("vshl", "VshlD", "SimdShiftOp", allTypes, 2, vshlCode)
|
||||||
threeEqualRegInst("vshl", "VshlQ", "SimdAluOp", allTypes, 4, vshlCode)
|
threeEqualRegInst("vshl", "VshlQ", "SimdShiftOp", allTypes, 4, vshlCode)
|
||||||
|
|
||||||
vrshlCode = '''
|
vrshlCode = '''
|
||||||
int16_t shiftAmt = (int8_t)srcElem2;
|
int16_t shiftAmt = (int8_t)srcElem2;
|
||||||
|
@ -3204,8 +3204,8 @@ let {{
|
||||||
substDict = { "targs" : type,
|
substDict = { "targs" : type,
|
||||||
"class_name" : Name }
|
"class_name" : Name }
|
||||||
exec_output += NeonExecDeclare.subst(substDict)
|
exec_output += NeonExecDeclare.subst(substDict)
|
||||||
vdupGprInst("vdup", "NVdupDGpr", "SimdAluOp", smallUnsignedTypes, 2)
|
vdupGprInst("vdup", "NVdupDGpr", "SimdMiscOp", smallUnsignedTypes, 2)
|
||||||
vdupGprInst("vdup", "NVdupQGpr", "SimdAluOp", smallUnsignedTypes, 4)
|
vdupGprInst("vdup", "NVdupQGpr", "SimdMiscOp", smallUnsignedTypes, 4)
|
||||||
|
|
||||||
vmovCode = 'destElem = imm;'
|
vmovCode = 'destElem = imm;'
|
||||||
oneRegImmInst("vmov", "NVmoviD", "SimdMiscOp", ("uint64_t",), 2, vmovCode)
|
oneRegImmInst("vmov", "NVmoviD", "SimdMiscOp", ("uint64_t",), 2, vmovCode)
|
||||||
|
@ -3309,8 +3309,8 @@ let {{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
buildVext("vext", "NVextD", "SimdAluOp", ("uint8_t",), 2, vextCode)
|
buildVext("vext", "NVextD", "SimdMiscOp", ("uint8_t",), 2, vextCode)
|
||||||
buildVext("vext", "NVextQ", "SimdAluOp", ("uint8_t",), 4, vextCode)
|
buildVext("vext", "NVextQ", "SimdMiscOp", ("uint8_t",), 4, vextCode)
|
||||||
|
|
||||||
def buildVtbxl(name, Name, opClass, length, isVtbl):
|
def buildVtbxl(name, Name, opClass, length, isVtbl):
|
||||||
global header_output, decoder_output, exec_output
|
global header_output, decoder_output, exec_output
|
||||||
|
@ -3366,13 +3366,13 @@ let {{
|
||||||
decoder_output += RegRegRegOpConstructor.subst(iop)
|
decoder_output += RegRegRegOpConstructor.subst(iop)
|
||||||
exec_output += PredOpExecute.subst(iop)
|
exec_output += PredOpExecute.subst(iop)
|
||||||
|
|
||||||
buildVtbxl("vtbl", "NVtbl1", "SimdAluOp", 1, "true")
|
buildVtbxl("vtbl", "NVtbl1", "SimdMiscOp", 1, "true")
|
||||||
buildVtbxl("vtbl", "NVtbl2", "SimdAluOp", 2, "true")
|
buildVtbxl("vtbl", "NVtbl2", "SimdMiscOp", 2, "true")
|
||||||
buildVtbxl("vtbl", "NVtbl3", "SimdAluOp", 3, "true")
|
buildVtbxl("vtbl", "NVtbl3", "SimdMiscOp", 3, "true")
|
||||||
buildVtbxl("vtbl", "NVtbl4", "SimdAluOp", 4, "true")
|
buildVtbxl("vtbl", "NVtbl4", "SimdMiscOp", 4, "true")
|
||||||
|
|
||||||
buildVtbxl("vtbx", "NVtbx1", "SimdAluOp", 1, "false")
|
buildVtbxl("vtbx", "NVtbx1", "SimdMiscOp", 1, "false")
|
||||||
buildVtbxl("vtbx", "NVtbx2", "SimdAluOp", 2, "false")
|
buildVtbxl("vtbx", "NVtbx2", "SimdMiscOp", 2, "false")
|
||||||
buildVtbxl("vtbx", "NVtbx3", "SimdAluOp", 3, "false")
|
buildVtbxl("vtbx", "NVtbx3", "SimdMiscOp", 3, "false")
|
||||||
buildVtbxl("vtbx", "NVtbx4", "SimdAluOp", 4, "false")
|
buildVtbxl("vtbx", "NVtbx4", "SimdMiscOp", 4, "false")
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -310,6 +310,7 @@ namespace ArmISA
|
||||||
Bitfield<23, 22> cp11;
|
Bitfield<23, 22> cp11;
|
||||||
Bitfield<25, 24> cp12;
|
Bitfield<25, 24> cp12;
|
||||||
Bitfield<27, 26> cp13;
|
Bitfield<27, 26> cp13;
|
||||||
|
Bitfield<29, 28> rsvd;
|
||||||
Bitfield<30> d32dis;
|
Bitfield<30> d32dis;
|
||||||
Bitfield<31> asedis;
|
Bitfield<31> asedis;
|
||||||
EndBitUnion(CPACR)
|
EndBitUnion(CPACR)
|
||||||
|
|
|
@ -146,7 +146,12 @@ vfpEnabled(CPACR cpacr, CPSR cpsr)
|
||||||
static inline bool
|
static inline bool
|
||||||
vfpEnabled(CPACR cpacr, CPSR cpsr, FPEXC fpexc)
|
vfpEnabled(CPACR cpacr, CPSR cpsr, FPEXC fpexc)
|
||||||
{
|
{
|
||||||
|
if ((cpacr.cp11 == 0x3) ||
|
||||||
|
((cpacr.cp11 == 0x1) && inPrivilegedMode(cpsr)))
|
||||||
return fpexc.en && vfpEnabled(cpacr, cpsr);
|
return fpexc.en && vfpEnabled(cpacr, cpsr);
|
||||||
|
else
|
||||||
|
return fpexc.en && vfpEnabled(cpacr, cpsr) &&
|
||||||
|
(cpacr.cp11 == cpacr.cp10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
|
|
Loading…
Reference in a new issue