summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/insts/macromem.cc9
-rw-r--r--src/arch/arm/isa/formats/fp.isa39
2 files changed, 33 insertions, 15 deletions
diff --git a/src/arch/arm/insts/macromem.cc b/src/arch/arm/insts/macromem.cc
index 7ed62f283..e6de8321d 100644
--- a/src/arch/arm/insts/macromem.cc
+++ b/src/arch/arm/insts/macromem.cc
@@ -1446,15 +1446,6 @@ MacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst,
// to be functionally identical except that fldmx is deprecated. For now
// we'll assume they're otherwise interchangable.
int count = (single ? offset : (offset / 2));
- if (count == 0 || count > NumFloatV7ArchRegs)
- warn_once("Bad offset field for VFP load/store multiple.\n");
- if (count == 0) {
- // Force there to be at least one microop so the macroop makes sense.
- writeback = true;
- }
- if (count > NumFloatV7ArchRegs)
- count = NumFloatV7ArchRegs;
-
numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0);
microOps = new StaticInstPtr[numMicroops];
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
index a87988f14..133f918d9 100644
--- a/src/arch/arm/isa/formats/fp.isa
+++ b/src/arch/arm/isa/formats/fp.isa
@@ -1873,10 +1873,29 @@ def format ThumbNeonData() {{
let {{
header_output = '''
+ bool
+ wrongVLdmStmRegs(IntRegIndex start_reg, uint8_t count, bool single);
+
StaticInstPtr
decodeExtensionRegLoadStore(ExtMachInst machInst);
'''
decoder_output = '''
+ bool
+ wrongVLdmStmRegs(RegIndex start_reg, uint8_t count, bool single)
+ {
+ if (single) {
+ const auto regs = count;
+ if (regs == 0 || start_reg + regs > NumFloatV7ArchRegs)
+ return true;
+ } else {
+ const auto regs = count/2;
+ if (regs == 0 || start_reg + regs > NumFloatV7ArchRegs ||
+ regs > 16)
+ return true;
+ }
+ return false;
+ }
+
StaticInstPtr
decodeExtensionRegLoadStore(ExtMachInst machInst)
{
@@ -1923,7 +1942,7 @@ let {{
break;
case 0x1:
{
- if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
+ if (wrongVLdmStmRegs(vd, offset, single)) {
break;
}
switch (bits(opcode, 1, 0)) {
@@ -1946,12 +1965,20 @@ let {{
}
case 0x2:
if (bits(opcode, 1, 0) == 0x2) {
- // If rn == sp, then this is called vpush.
- return new VLdmStm(machInst, rn, vd, single,
- false, true, false, offset);
+ if (wrongVLdmStmRegs(vd, offset, single)) {
+ break;
+ } else {
+ // If rn == sp, then this is called vpush.
+ return new VLdmStm(machInst, rn, vd, single,
+ false, true, false, offset);
+ }
} else if (bits(opcode, 1, 0) == 0x3) {
- return new VLdmStm(machInst, rn, vd, single,
- false, true, true, offset);
+ if (wrongVLdmStmRegs(vd, offset, single)) {
+ break;
+ } else {
+ return new VLdmStm(machInst, rn, vd, single,
+ false, true, true, offset);
+ }
}
M5_FALLTHROUGH;
case 0x3: