summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Saidi <ali.saidi@arm.com>2010-08-25 19:10:42 -0500
committerAli Saidi <ali.saidi@arm.com>2010-08-25 19:10:42 -0500
commit99fafb72b87f3b63f205bee7b20b8c19724d6305 (patch)
tree305127cadcae96140871d128525bc89c5a1486ec
parent63464d950ec4e8b8f3aa86802ca9fbf1e8c662b6 (diff)
downloadgem5-99fafb72b87f3b63f205bee7b20b8c19724d6305.tar.xz
ARM: Fix VFP enabled checks for mem instructions
-rw-r--r--src/arch/arm/isa.cc2
-rw-r--r--src/arch/arm/isa/insts/fp.isa12
-rw-r--r--src/arch/arm/isa/insts/ldr.isa8
-rw-r--r--src/arch/arm/isa/insts/macromem.isa17
-rw-r--r--src/arch/arm/isa/insts/neon.isa9
-rw-r--r--src/arch/arm/isa/insts/str.isa8
-rw-r--r--src/arch/arm/isa/templates/neon.isa8
-rw-r--r--src/arch/arm/isa/templates/vfp.isa19
-rw-r--r--src/arch/arm/utility.hh2
9 files changed, 60 insertions, 25 deletions
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 7991dbfb7..f5bbc3610 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -139,6 +139,8 @@ ISA::clear()
(0 << 2) | // 3:2
0; // 1:0
+ miscRegs[MISCREG_CPACR] = 0;
+ miscRegs[MISCREG_FPSID] = 0x410430A0;
//XXX We need to initialize the rest of the state.
}
diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa
index 849ce1299..6ba4ac3bf 100644
--- a/src/arch/arm/isa/insts/fp.isa
+++ b/src/arch/arm/isa/insts/fp.isa
@@ -192,14 +192,14 @@ let {{
exec_output = ""
vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegOp",
- { "code": vmsrrsEnabledCheckCode + \
+ { "code": vmsrEnabledCheckCode + \
"MiscDest = Op1;",
"predicate_test": predicateTest }, [])
header_output += FpRegRegOpDeclare.subst(vmsrIop);
decoder_output += FpRegRegOpConstructor.subst(vmsrIop);
exec_output += PredOpExecute.subst(vmsrIop);
- vmsrFpscrCode = vmsrrsEnabledCheckCode + '''
+ vmsrFpscrCode = vmsrEnabledCheckCode + '''
Fpscr = Op1 & ~FpCondCodesMask;
FpCondCodes = Op1 & FpCondCodesMask;
'''
@@ -211,7 +211,7 @@ let {{
exec_output += PredOpExecute.subst(vmsrFpscrIop);
vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegOp",
- { "code": vmsrrsEnabledCheckCode + \
+ { "code": vmrsEnabledCheckCode + \
"Dest = MiscOp1;",
"predicate_test": predicateTest }, [])
header_output += FpRegRegOpDeclare.subst(vmrsIop);
@@ -219,14 +219,14 @@ let {{
exec_output += PredOpExecute.subst(vmrsIop);
vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp",
- { "code": vmsrrsEnabledCheckCode + \
+ { "code": vmrsEnabledCheckCode + \
"Dest = Fpscr | FpCondCodes;",
"predicate_test": predicateTest }, [])
header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop);
decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
exec_output += PredOpExecute.subst(vmrsFpscrIop);
- vmrsApsrCode = vmsrrsEnabledCheckCode + '''
+ vmrsApsrCode = vmrsEnabledCheckCode + '''
Dest = (MiscOp1 & imm) | (Dest & ~imm);
'''
vmrsApsrIop = InstObjParams("vmrs", "VmrsApsr", "FpRegRegImmOp",
@@ -236,7 +236,7 @@ let {{
decoder_output += FpRegRegImmOpConstructor.subst(vmrsApsrIop);
exec_output += PredOpExecute.subst(vmrsApsrIop);
- vmrsApsrFpscrCode = vmsrrsEnabledCheckCode + '''
+ vmrsApsrFpscrCode = vmrsEnabledCheckCode + '''
assert((imm & ~FpCondCodesMask) == 0);
Dest = (FpCondCodes & imm) | (Dest & ~imm);
'''
diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa
index 6919bbca4..a936ffaaf 100644
--- a/src/arch/arm/isa/insts/ldr.isa
+++ b/src/arch/arm/isa/insts/ldr.isa
@@ -160,6 +160,10 @@ let {{
if not self.post:
eaCode += self.offset
eaCode += ";"
+
+ if self.flavor == "fp":
+ eaCode += vfpEnabledCheckCode
+
self.codeBlobs["ea_code"] = eaCode
# Code that actually handles the access
@@ -220,6 +224,10 @@ let {{
if not self.post:
eaCode += self.offset
eaCode += ";"
+
+ if self.flavor == "fp":
+ eaCode += vfpEnabledCheckCode
+
self.codeBlobs["ea_code"] = eaCode
# Code that actually handles the access
diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa
index 652a929f1..bcb1e26b8 100644
--- a/src/arch/arm/isa/insts/macromem.isa
+++ b/src/arch/arm/isa/insts/macromem.isa
@@ -59,7 +59,7 @@ let {{
microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop',
'MicroMemOp',
{'memacc_code': microLdrFpUopCode,
- 'ea_code':
+ 'ea_code': vfpEnabledCheckCode +
'EA = Rb + (up ? imm : -imm);',
'predicate_test': predicateTest},
['IsMicroop'])
@@ -68,7 +68,7 @@ let {{
microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop',
'MicroMemOp',
{'memacc_code': microLdrFpUopCode,
- 'ea_code': '''
+ 'ea_code': vfpEnabledCheckCode + '''
EA = Rb + (up ? imm : -imm) +
(((CPSR)Cpsr).e ? 4 : 0);
''',
@@ -79,7 +79,7 @@ let {{
microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop',
'MicroMemOp',
{'memacc_code': microLdrFpUopCode,
- 'ea_code': '''
+ 'ea_code': vfpEnabledCheckCode + '''
EA = Rb + (up ? imm : -imm) -
(((CPSR)Cpsr).e ? 4 : 0);
''',
@@ -117,7 +117,8 @@ let {{
'MicroMemOp',
{'memacc_code': microStrFpUopCode,
'postacc_code': "",
- 'ea_code': 'EA = Rb + (up ? imm : -imm);',
+ 'ea_code': vfpEnabledCheckCode +
+ 'EA = Rb + (up ? imm : -imm);',
'predicate_test': predicateTest},
['IsMicroop'])
@@ -126,7 +127,7 @@ let {{
'MicroMemOp',
{'memacc_code': microStrFpUopCode,
'postacc_code': "",
- 'ea_code': '''
+ 'ea_code': vfpEnabledCheckCode + '''
EA = Rb + (up ? imm : -imm) +
(((CPSR)Cpsr).e ? 4 : 0);
''',
@@ -138,7 +139,7 @@ let {{
'MicroMemOp',
{'memacc_code': microStrFpUopCode,
'postacc_code': "",
- 'ea_code': '''
+ 'ea_code': vfpEnabledCheckCode + '''
EA = Rb + (up ? imm : -imm) -
(((CPSR)Cpsr).e ? 4 : 0);
''',
@@ -222,7 +223,7 @@ let {{
{ 'mem_decl' : memDecl,
'size' : size,
'memacc_code' : loadMemAccCode,
- 'ea_code' : eaCode,
+ 'ea_code' : simdEnabledCheckCode + eaCode,
'predicate_test' : predicateTest },
[ 'IsMicroop', 'IsMemRef', 'IsLoad' ])
storeIop = InstObjParams('strneon%(size)d_uop' % subst,
@@ -231,7 +232,7 @@ let {{
{ 'mem_decl' : memDecl,
'size' : size,
'memacc_code' : storeMemAccCode,
- 'ea_code' : eaCode,
+ 'ea_code' : simdEnabledCheckCode + eaCode,
'predicate_test' : predicateTest },
[ 'IsMicroop', 'IsMemRef', 'IsStore' ])
diff --git a/src/arch/arm/isa/insts/neon.isa b/src/arch/arm/isa/insts/neon.isa
index 790c9c3a1..0a3285490 100644
--- a/src/arch/arm/isa/insts/neon.isa
+++ b/src/arch/arm/isa/insts/neon.isa
@@ -620,13 +620,6 @@ output exec {{
}};
let {{
- simdEnabledCheckCode = '''
- if (!neonEnabled(Cpacr, Cpsr, Fpexc))
- return disabledFault();
- '''
-}};
-
-let {{
header_output = ""
exec_output = ""
@@ -3235,7 +3228,7 @@ let {{
RegVect srcReg1, srcReg2, destReg;
'''
for reg in range(rCount):
- eWalkCode += '''
+ eWalkCode += simdEnabledCheckCode + '''
srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw);
srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d.uw);
''' % { "reg" : reg }
diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa
index 5b0e5b132..66a486ecf 100644
--- a/src/arch/arm/isa/insts/str.isa
+++ b/src/arch/arm/isa/insts/str.isa
@@ -171,6 +171,10 @@ let {{
if not self.post:
eaCode += self.offset
eaCode += ";"
+
+ if self.flavor == "fp":
+ eaCode += vfpEnabledCheckCode
+
self.codeBlobs["ea_code"] = eaCode
# Code that actually handles the access
@@ -241,6 +245,10 @@ let {{
if not self.post:
eaCode += self.offset
eaCode += ";"
+
+ if self.flavor == "fp":
+ eaCode += vfpEnabledCheckCode
+
self.codeBlobs["ea_code"] = eaCode
# Code that actually handles the access
diff --git a/src/arch/arm/isa/templates/neon.isa b/src/arch/arm/isa/templates/neon.isa
index 20c1d26b8..0e592c6e4 100644
--- a/src/arch/arm/isa/templates/neon.isa
+++ b/src/arch/arm/isa/templates/neon.isa
@@ -37,6 +37,14 @@
//
// Authors: Gabe Black
+let {{
+ simdEnabledCheckCode = '''
+ if (!neonEnabled(Cpacr, Cpsr, Fpexc))
+ return disabledFault();
+ '''
+}};
+
+
def template NeonRegRegRegOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
diff --git a/src/arch/arm/isa/templates/vfp.isa b/src/arch/arm/isa/templates/vfp.isa
index 5de52738c..8ccfedd0d 100644
--- a/src/arch/arm/isa/templates/vfp.isa
+++ b/src/arch/arm/isa/templates/vfp.isa
@@ -43,9 +43,24 @@ let {{
return disabledFault();
'''
- vmsrrsEnabledCheckCode = '''
+ vmsrEnabledCheckCode = '''
if (!vfpEnabled(Cpacr, Cpsr))
- return disabledFault();
+ 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();
'''
}};
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
index 4256aa047..c2daff99f 100644
--- a/src/arch/arm/utility.hh
+++ b/src/arch/arm/utility.hh
@@ -150,7 +150,7 @@ namespace ArmISA {
vfpEnabled(CPACR cpacr, CPSR cpsr)
{
return cpacr.cp10 == 0x3 ||
- (cpacr.cp10 == 0x2 && inPrivilegedMode(cpsr));
+ (cpacr.cp10 == 0x1 && inPrivilegedMode(cpsr));
}
static inline bool