diff options
Diffstat (limited to 'src/arch/arm')
-rw-r--r-- | src/arch/arm/insts/macromem.cc | 9 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/fp.isa | 39 |
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: |