// 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];
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)
{
break;
case 0x1:
{
- if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
+ if (wrongVLdmStmRegs(vd, offset, single)) {
break;
}
switch (bits(opcode, 1, 0)) {
}
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: