ARM: Fix VFP enabled checks for mem instructions
This commit is contained in:
parent
63464d950e
commit
99fafb72b8
9 changed files with 60 additions and 25 deletions
|
@ -139,6 +139,8 @@ ISA::clear()
|
||||||
(0 << 2) | // 3:2
|
(0 << 2) | // 3:2
|
||||||
0; // 1:0
|
0; // 1:0
|
||||||
|
|
||||||
|
miscRegs[MISCREG_CPACR] = 0;
|
||||||
|
miscRegs[MISCREG_FPSID] = 0x410430A0;
|
||||||
//XXX We need to initialize the rest of the state.
|
//XXX We need to initialize the rest of the state.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,14 +192,14 @@ let {{
|
||||||
exec_output = ""
|
exec_output = ""
|
||||||
|
|
||||||
vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegOp",
|
vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegOp",
|
||||||
{ "code": vmsrrsEnabledCheckCode + \
|
{ "code": vmsrEnabledCheckCode + \
|
||||||
"MiscDest = Op1;",
|
"MiscDest = Op1;",
|
||||||
"predicate_test": predicateTest }, [])
|
"predicate_test": predicateTest }, [])
|
||||||
header_output += FpRegRegOpDeclare.subst(vmsrIop);
|
header_output += FpRegRegOpDeclare.subst(vmsrIop);
|
||||||
decoder_output += FpRegRegOpConstructor.subst(vmsrIop);
|
decoder_output += FpRegRegOpConstructor.subst(vmsrIop);
|
||||||
exec_output += PredOpExecute.subst(vmsrIop);
|
exec_output += PredOpExecute.subst(vmsrIop);
|
||||||
|
|
||||||
vmsrFpscrCode = vmsrrsEnabledCheckCode + '''
|
vmsrFpscrCode = vmsrEnabledCheckCode + '''
|
||||||
Fpscr = Op1 & ~FpCondCodesMask;
|
Fpscr = Op1 & ~FpCondCodesMask;
|
||||||
FpCondCodes = Op1 & FpCondCodesMask;
|
FpCondCodes = Op1 & FpCondCodesMask;
|
||||||
'''
|
'''
|
||||||
|
@ -211,7 +211,7 @@ let {{
|
||||||
exec_output += PredOpExecute.subst(vmsrFpscrIop);
|
exec_output += PredOpExecute.subst(vmsrFpscrIop);
|
||||||
|
|
||||||
vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegOp",
|
vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegOp",
|
||||||
{ "code": vmsrrsEnabledCheckCode + \
|
{ "code": vmrsEnabledCheckCode + \
|
||||||
"Dest = MiscOp1;",
|
"Dest = MiscOp1;",
|
||||||
"predicate_test": predicateTest }, [])
|
"predicate_test": predicateTest }, [])
|
||||||
header_output += FpRegRegOpDeclare.subst(vmrsIop);
|
header_output += FpRegRegOpDeclare.subst(vmrsIop);
|
||||||
|
@ -219,14 +219,14 @@ let {{
|
||||||
exec_output += PredOpExecute.subst(vmrsIop);
|
exec_output += PredOpExecute.subst(vmrsIop);
|
||||||
|
|
||||||
vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp",
|
vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp",
|
||||||
{ "code": vmsrrsEnabledCheckCode + \
|
{ "code": vmrsEnabledCheckCode + \
|
||||||
"Dest = Fpscr | FpCondCodes;",
|
"Dest = Fpscr | FpCondCodes;",
|
||||||
"predicate_test": predicateTest }, [])
|
"predicate_test": predicateTest }, [])
|
||||||
header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop);
|
header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop);
|
||||||
decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
|
decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
|
||||||
exec_output += PredOpExecute.subst(vmrsFpscrIop);
|
exec_output += PredOpExecute.subst(vmrsFpscrIop);
|
||||||
|
|
||||||
vmrsApsrCode = vmsrrsEnabledCheckCode + '''
|
vmrsApsrCode = vmrsEnabledCheckCode + '''
|
||||||
Dest = (MiscOp1 & imm) | (Dest & ~imm);
|
Dest = (MiscOp1 & imm) | (Dest & ~imm);
|
||||||
'''
|
'''
|
||||||
vmrsApsrIop = InstObjParams("vmrs", "VmrsApsr", "FpRegRegImmOp",
|
vmrsApsrIop = InstObjParams("vmrs", "VmrsApsr", "FpRegRegImmOp",
|
||||||
|
@ -236,7 +236,7 @@ let {{
|
||||||
decoder_output += FpRegRegImmOpConstructor.subst(vmrsApsrIop);
|
decoder_output += FpRegRegImmOpConstructor.subst(vmrsApsrIop);
|
||||||
exec_output += PredOpExecute.subst(vmrsApsrIop);
|
exec_output += PredOpExecute.subst(vmrsApsrIop);
|
||||||
|
|
||||||
vmrsApsrFpscrCode = vmsrrsEnabledCheckCode + '''
|
vmrsApsrFpscrCode = vmrsEnabledCheckCode + '''
|
||||||
assert((imm & ~FpCondCodesMask) == 0);
|
assert((imm & ~FpCondCodesMask) == 0);
|
||||||
Dest = (FpCondCodes & imm) | (Dest & ~imm);
|
Dest = (FpCondCodes & imm) | (Dest & ~imm);
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -160,6 +160,10 @@ let {{
|
||||||
if not self.post:
|
if not self.post:
|
||||||
eaCode += self.offset
|
eaCode += self.offset
|
||||||
eaCode += ";"
|
eaCode += ";"
|
||||||
|
|
||||||
|
if self.flavor == "fp":
|
||||||
|
eaCode += vfpEnabledCheckCode
|
||||||
|
|
||||||
self.codeBlobs["ea_code"] = eaCode
|
self.codeBlobs["ea_code"] = eaCode
|
||||||
|
|
||||||
# Code that actually handles the access
|
# Code that actually handles the access
|
||||||
|
@ -220,6 +224,10 @@ let {{
|
||||||
if not self.post:
|
if not self.post:
|
||||||
eaCode += self.offset
|
eaCode += self.offset
|
||||||
eaCode += ";"
|
eaCode += ";"
|
||||||
|
|
||||||
|
if self.flavor == "fp":
|
||||||
|
eaCode += vfpEnabledCheckCode
|
||||||
|
|
||||||
self.codeBlobs["ea_code"] = eaCode
|
self.codeBlobs["ea_code"] = eaCode
|
||||||
|
|
||||||
# Code that actually handles the access
|
# Code that actually handles the access
|
||||||
|
|
|
@ -59,7 +59,7 @@ let {{
|
||||||
microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop',
|
microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop',
|
||||||
'MicroMemOp',
|
'MicroMemOp',
|
||||||
{'memacc_code': microLdrFpUopCode,
|
{'memacc_code': microLdrFpUopCode,
|
||||||
'ea_code':
|
'ea_code': vfpEnabledCheckCode +
|
||||||
'EA = Rb + (up ? imm : -imm);',
|
'EA = Rb + (up ? imm : -imm);',
|
||||||
'predicate_test': predicateTest},
|
'predicate_test': predicateTest},
|
||||||
['IsMicroop'])
|
['IsMicroop'])
|
||||||
|
@ -68,7 +68,7 @@ let {{
|
||||||
microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop',
|
microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop',
|
||||||
'MicroMemOp',
|
'MicroMemOp',
|
||||||
{'memacc_code': microLdrFpUopCode,
|
{'memacc_code': microLdrFpUopCode,
|
||||||
'ea_code': '''
|
'ea_code': vfpEnabledCheckCode + '''
|
||||||
EA = Rb + (up ? imm : -imm) +
|
EA = Rb + (up ? imm : -imm) +
|
||||||
(((CPSR)Cpsr).e ? 4 : 0);
|
(((CPSR)Cpsr).e ? 4 : 0);
|
||||||
''',
|
''',
|
||||||
|
@ -79,7 +79,7 @@ let {{
|
||||||
microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop',
|
microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop',
|
||||||
'MicroMemOp',
|
'MicroMemOp',
|
||||||
{'memacc_code': microLdrFpUopCode,
|
{'memacc_code': microLdrFpUopCode,
|
||||||
'ea_code': '''
|
'ea_code': vfpEnabledCheckCode + '''
|
||||||
EA = Rb + (up ? imm : -imm) -
|
EA = Rb + (up ? imm : -imm) -
|
||||||
(((CPSR)Cpsr).e ? 4 : 0);
|
(((CPSR)Cpsr).e ? 4 : 0);
|
||||||
''',
|
''',
|
||||||
|
@ -117,7 +117,8 @@ let {{
|
||||||
'MicroMemOp',
|
'MicroMemOp',
|
||||||
{'memacc_code': microStrFpUopCode,
|
{'memacc_code': microStrFpUopCode,
|
||||||
'postacc_code': "",
|
'postacc_code': "",
|
||||||
'ea_code': 'EA = Rb + (up ? imm : -imm);',
|
'ea_code': vfpEnabledCheckCode +
|
||||||
|
'EA = Rb + (up ? imm : -imm);',
|
||||||
'predicate_test': predicateTest},
|
'predicate_test': predicateTest},
|
||||||
['IsMicroop'])
|
['IsMicroop'])
|
||||||
|
|
||||||
|
@ -126,7 +127,7 @@ let {{
|
||||||
'MicroMemOp',
|
'MicroMemOp',
|
||||||
{'memacc_code': microStrFpUopCode,
|
{'memacc_code': microStrFpUopCode,
|
||||||
'postacc_code': "",
|
'postacc_code': "",
|
||||||
'ea_code': '''
|
'ea_code': vfpEnabledCheckCode + '''
|
||||||
EA = Rb + (up ? imm : -imm) +
|
EA = Rb + (up ? imm : -imm) +
|
||||||
(((CPSR)Cpsr).e ? 4 : 0);
|
(((CPSR)Cpsr).e ? 4 : 0);
|
||||||
''',
|
''',
|
||||||
|
@ -138,7 +139,7 @@ let {{
|
||||||
'MicroMemOp',
|
'MicroMemOp',
|
||||||
{'memacc_code': microStrFpUopCode,
|
{'memacc_code': microStrFpUopCode,
|
||||||
'postacc_code': "",
|
'postacc_code': "",
|
||||||
'ea_code': '''
|
'ea_code': vfpEnabledCheckCode + '''
|
||||||
EA = Rb + (up ? imm : -imm) -
|
EA = Rb + (up ? imm : -imm) -
|
||||||
(((CPSR)Cpsr).e ? 4 : 0);
|
(((CPSR)Cpsr).e ? 4 : 0);
|
||||||
''',
|
''',
|
||||||
|
@ -222,7 +223,7 @@ let {{
|
||||||
{ 'mem_decl' : memDecl,
|
{ 'mem_decl' : memDecl,
|
||||||
'size' : size,
|
'size' : size,
|
||||||
'memacc_code' : loadMemAccCode,
|
'memacc_code' : loadMemAccCode,
|
||||||
'ea_code' : eaCode,
|
'ea_code' : simdEnabledCheckCode + eaCode,
|
||||||
'predicate_test' : predicateTest },
|
'predicate_test' : predicateTest },
|
||||||
[ 'IsMicroop', 'IsMemRef', 'IsLoad' ])
|
[ 'IsMicroop', 'IsMemRef', 'IsLoad' ])
|
||||||
storeIop = InstObjParams('strneon%(size)d_uop' % subst,
|
storeIop = InstObjParams('strneon%(size)d_uop' % subst,
|
||||||
|
@ -231,7 +232,7 @@ let {{
|
||||||
{ 'mem_decl' : memDecl,
|
{ 'mem_decl' : memDecl,
|
||||||
'size' : size,
|
'size' : size,
|
||||||
'memacc_code' : storeMemAccCode,
|
'memacc_code' : storeMemAccCode,
|
||||||
'ea_code' : eaCode,
|
'ea_code' : simdEnabledCheckCode + eaCode,
|
||||||
'predicate_test' : predicateTest },
|
'predicate_test' : predicateTest },
|
||||||
[ 'IsMicroop', 'IsMemRef', 'IsStore' ])
|
[ 'IsMicroop', 'IsMemRef', 'IsStore' ])
|
||||||
|
|
||||||
|
|
|
@ -619,13 +619,6 @@ output exec {{
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
let {{
|
|
||||||
simdEnabledCheckCode = '''
|
|
||||||
if (!neonEnabled(Cpacr, Cpsr, Fpexc))
|
|
||||||
return disabledFault();
|
|
||||||
'''
|
|
||||||
}};
|
|
||||||
|
|
||||||
let {{
|
let {{
|
||||||
|
|
||||||
header_output = ""
|
header_output = ""
|
||||||
|
@ -3235,7 +3228,7 @@ let {{
|
||||||
RegVect srcReg1, srcReg2, destReg;
|
RegVect srcReg1, srcReg2, destReg;
|
||||||
'''
|
'''
|
||||||
for reg in range(rCount):
|
for reg in range(rCount):
|
||||||
eWalkCode += '''
|
eWalkCode += simdEnabledCheckCode + '''
|
||||||
srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
|
srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
|
||||||
srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d.uw);
|
srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d.uw);
|
||||||
''' % { "reg" : reg }
|
''' % { "reg" : reg }
|
||||||
|
|
|
@ -171,6 +171,10 @@ let {{
|
||||||
if not self.post:
|
if not self.post:
|
||||||
eaCode += self.offset
|
eaCode += self.offset
|
||||||
eaCode += ";"
|
eaCode += ";"
|
||||||
|
|
||||||
|
if self.flavor == "fp":
|
||||||
|
eaCode += vfpEnabledCheckCode
|
||||||
|
|
||||||
self.codeBlobs["ea_code"] = eaCode
|
self.codeBlobs["ea_code"] = eaCode
|
||||||
|
|
||||||
# Code that actually handles the access
|
# Code that actually handles the access
|
||||||
|
@ -241,6 +245,10 @@ let {{
|
||||||
if not self.post:
|
if not self.post:
|
||||||
eaCode += self.offset
|
eaCode += self.offset
|
||||||
eaCode += ";"
|
eaCode += ";"
|
||||||
|
|
||||||
|
if self.flavor == "fp":
|
||||||
|
eaCode += vfpEnabledCheckCode
|
||||||
|
|
||||||
self.codeBlobs["ea_code"] = eaCode
|
self.codeBlobs["ea_code"] = eaCode
|
||||||
|
|
||||||
# Code that actually handles the access
|
# Code that actually handles the access
|
||||||
|
|
|
@ -37,6 +37,14 @@
|
||||||
//
|
//
|
||||||
// Authors: Gabe Black
|
// Authors: Gabe Black
|
||||||
|
|
||||||
|
let {{
|
||||||
|
simdEnabledCheckCode = '''
|
||||||
|
if (!neonEnabled(Cpacr, Cpsr, Fpexc))
|
||||||
|
return disabledFault();
|
||||||
|
'''
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
def template NeonRegRegRegOpDeclare {{
|
def template NeonRegRegRegOpDeclare {{
|
||||||
template <class _Element>
|
template <class _Element>
|
||||||
class %(class_name)s : public %(base_class)s
|
class %(class_name)s : public %(base_class)s
|
||||||
|
|
|
@ -43,8 +43,23 @@ let {{
|
||||||
return disabledFault();
|
return disabledFault();
|
||||||
'''
|
'''
|
||||||
|
|
||||||
vmsrrsEnabledCheckCode = '''
|
vmsrEnabledCheckCode = '''
|
||||||
if (!vfpEnabled(Cpacr, Cpsr))
|
if (!vfpEnabled(Cpacr, Cpsr))
|
||||||
|
if (dest != (int)MISCREG_FPEXC && dest != (int)MISCREG_FPSID)
|
||||||
|
return disabledFault();
|
||||||
|
if (!inPrivilegedMode(Cpsr))
|
||||||
|
if (dest != (int)MISCREG_FPSCR)
|
||||||
|
return disabledFault();
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
vmrsEnabledCheckCode = '''
|
||||||
|
if (!vfpEnabled(Cpacr, Cpsr))
|
||||||
|
if (op1 != (int)MISCREG_FPEXC && op1 != (int)MISCREG_FPSID &&
|
||||||
|
op1 != (int)MISCREG_MVFR0 && op1 != (int)MISCREG_MVFR1)
|
||||||
|
return disabledFault();
|
||||||
|
if (!inPrivilegedMode(Cpsr))
|
||||||
|
if (op1 != (int)MISCREG_FPSCR)
|
||||||
return disabledFault();
|
return disabledFault();
|
||||||
'''
|
'''
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -150,7 +150,7 @@ namespace ArmISA {
|
||||||
vfpEnabled(CPACR cpacr, CPSR cpsr)
|
vfpEnabled(CPACR cpacr, CPSR cpsr)
|
||||||
{
|
{
|
||||||
return cpacr.cp10 == 0x3 ||
|
return cpacr.cp10 == 0x3 ||
|
||||||
(cpacr.cp10 == 0x2 && inPrivilegedMode(cpsr));
|
(cpacr.cp10 == 0x1 && inPrivilegedMode(cpsr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
|
|
Loading…
Reference in a new issue