summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/insts/macromem.cc50
-rw-r--r--src/arch/arm/insts/pred_inst.hh8
-rw-r--r--src/arch/arm/isa/formats/fp.isa10
-rw-r--r--src/arch/arm/isa/formats/misc.isa5
-rw-r--r--src/arch/arm/isa/insts/neon.isa79
-rw-r--r--src/arch/arm/miscregs.cc2
6 files changed, 105 insertions, 49 deletions
diff --git a/src/arch/arm/insts/macromem.cc b/src/arch/arm/insts/macromem.cc
index f64fbeff9..2a45cf2e6 100644
--- a/src/arch/arm/insts/macromem.cc
+++ b/src/arch/arm/insts/macromem.cc
@@ -42,7 +42,9 @@
#include "arch/arm/insts/macromem.hh"
#include "arch/arm/decoder.hh"
+#include <sstream>
+using namespace std;
using namespace ArmISAInst;
namespace ArmISA
@@ -180,7 +182,8 @@ VldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
size, machInst, rMid, rn, 0, align);
break;
default:
- panic("Unrecognized number of registers %d.\n", regs);
+ // Unknown number of registers
+ microOps[uopIdx++] = new Unknown(machInst);
}
if (wb) {
if (rm != 15 && rm != 13) {
@@ -216,7 +219,8 @@ VldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
}
break;
default:
- panic("Bad number of elements to deinterleave %d.\n", elems);
+ // Bad number of elements to deinterleave
+ microOps[uopIdx++] = new Unknown(machInst);
}
}
assert(uopIdx == numMicroops);
@@ -315,7 +319,8 @@ VldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst,
machInst, ufp0, rn, 0, align);
break;
default:
- panic("Unrecognized load size %d.\n", regs);
+ // Unrecognized load size
+ microOps[uopIdx++] = new Unknown(machInst);
}
if (wb) {
if (rm != 15 && rm != 13) {
@@ -358,7 +363,8 @@ VldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst,
}
break;
default:
- panic("Bad size %d.\n", size);
+ // Bad size
+ microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
@@ -393,7 +399,8 @@ VldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst,
}
break;
default:
- panic("Bad size %d.\n", size);
+ // Bad size
+ microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
@@ -429,7 +436,8 @@ VldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst,
}
break;
default:
- panic("Bad size %d.\n", size);
+ // Bad size
+ microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
@@ -472,13 +480,15 @@ VldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst,
}
break;
default:
- panic("Bad size %d.\n", size);
+ // Bad size
+ microOps[uopIdx++] = new Unknown(machInst);
break;
}
}
break;
default:
- panic("Bad number of elements to unpack %d.\n", elems);
+ // Bad number of elements to unpack
+ microOps[uopIdx++] = new Unknown(machInst);
}
assert(uopIdx == numMicroops);
@@ -536,7 +546,8 @@ VstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
}
break;
default:
- panic("Bad number of elements to interleave %d.\n", elems);
+ // Bad number of elements to interleave
+ microOps[uopIdx++] = new Unknown(machInst);
}
}
switch (regs) {
@@ -561,7 +572,8 @@ VstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
size, machInst, rMid, rn, 0, align);
break;
default:
- panic("Unrecognized number of registers %d.\n", regs);
+ // Unknown number of registers
+ microOps[uopIdx++] = new Unknown(machInst);
}
if (wb) {
if (rm != 15 && rm != 13) {
@@ -627,7 +639,8 @@ VstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst,
machInst, ufp0, vd * 2, inc * 2, lane);
break;
default:
- panic("Bad size %d.\n", size);
+ // Bad size
+ microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
@@ -647,7 +660,8 @@ VstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst,
machInst, ufp0, vd * 2, inc * 2, lane);
break;
default:
- panic("Bad size %d.\n", size);
+ // Bad size
+ microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
@@ -668,7 +682,8 @@ VstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst,
machInst, ufp0, vd * 2, inc * 2, lane);
break;
default:
- panic("Bad size %d.\n", size);
+ // Bad size
+ microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
@@ -690,13 +705,15 @@ VstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst,
machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
break;
default:
- panic("Bad size %d.\n", size);
+ // Bad size
+ microOps[uopIdx++] = new Unknown(machInst);
break;
}
}
break;
default:
- panic("Bad number of elements to pack %d.\n", elems);
+ // Bad number of elements to unpack
+ microOps[uopIdx++] = new Unknown(machInst);
}
switch (storeSize) {
case 1:
@@ -757,7 +774,8 @@ VstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst,
machInst, ufp0, rn, 0, align);
break;
default:
- panic("Unrecognized store size %d.\n", regs);
+ // Bad store size
+ microOps[uopIdx++] = new Unknown(machInst);
}
if (wb) {
if (rm != 15 && rm != 13) {
diff --git a/src/arch/arm/insts/pred_inst.hh b/src/arch/arm/insts/pred_inst.hh
index f779b46f5..c441d1f32 100644
--- a/src/arch/arm/insts/pred_inst.hh
+++ b/src/arch/arm/insts/pred_inst.hh
@@ -78,9 +78,10 @@ modified_imm(uint8_t ctrlImm, uint8_t dataImm)
}
static inline uint64_t
-simd_modified_imm(bool op, uint8_t cmode, uint8_t data)
+simd_modified_imm(bool op, uint8_t cmode, uint8_t data, bool &immValid)
{
uint64_t bigData = data;
+ immValid = true;
switch (cmode) {
case 0x0:
case 0x1:
@@ -139,9 +140,10 @@ simd_modified_imm(bool op, uint8_t cmode, uint8_t data)
bigData |= (bigData << 32);
break;
}
- // Fall through
+ // Fall through, immediate encoding is invalid.
default:
- panic("Illegal modified SIMD immediate parameters.\n");
+ immValid = false;
+ break;
}
return bigData;
}
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
index 9d40a4a43..3a0cad1c5 100644
--- a/src/arch/arm/isa/formats/fp.isa
+++ b/src/arch/arm/isa/formats/fp.isa
@@ -758,7 +758,15 @@ let {{
bits(machInst, 24)) << 7) |
(bits(machInst, 18, 16) << 4) |
(bits(machInst, 3, 0) << 0);
- const uint64_t bigImm = simd_modified_imm(op, cmode, imm);
+
+ // Check for invalid immediate encodings and return an unknown op
+ // if it happens
+ bool immValid = true;
+ const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid);
+ if (!immValid) {
+ return new Unknown(machInst);
+ }
+
if (op) {
if (bits(cmode, 3) == 0) {
if (bits(cmode, 0) == 0) {
diff --git a/src/arch/arm/isa/formats/misc.isa b/src/arch/arm/isa/formats/misc.isa
index c2003fe6d..6a734a582 100644
--- a/src/arch/arm/isa/formats/misc.isa
+++ b/src/arch/arm/isa/formats/misc.isa
@@ -100,7 +100,10 @@ let {{
case MISCREG_NOP:
return new NopInst(machInst);
case NUM_MISCREGS:
- return new Unknown(machInst);
+ return new FailUnimplemented(
+ csprintf("miscreg crn:%d opc1:%d crm:%d opc2:%d %s unknown",
+ crn, opc1, crm, opc2, isRead ? "read" : "write").c_str(),
+ machInst);
case MISCREG_DCCISW:
return new WarnUnimplemented(
isRead ? "mrc dccisw" : "mcr dcisw", machInst);
diff --git a/src/arch/arm/isa/insts/neon.isa b/src/arch/arm/isa/insts/neon.isa
index a2948b90a..5aca525a4 100644
--- a/src/arch/arm/isa/insts/neon.isa
+++ b/src/arch/arm/isa/insts/neon.isa
@@ -871,14 +871,21 @@ let {{
if readDest:
readDestCode = 'destElem = gtoh(destReg.elements[i]);'
eWalkCode += '''
- assert(imm >= 0 && imm < eCount);
- for (unsigned i = 0; i < eCount; i++) {
- Element srcElem1 = gtoh(srcReg1.elements[i]);
- Element srcElem2 = gtoh(srcReg2.elements[imm]);
- Element destElem;
- %(readDest)s
- %(op)s
- destReg.elements[i] = htog(destElem);
+ if (imm < 0 && imm >= eCount) {
+#if FULL_SYSTEM
+ fault = new UndefinedInstruction;
+#else
+ fault = new UndefinedInstruction(false, mnemonic);
+#endif
+ } else {
+ for (unsigned i = 0; i < eCount; i++) {
+ Element srcElem1 = gtoh(srcReg1.elements[i]);
+ Element srcElem2 = gtoh(srcReg2.elements[imm]);
+ Element destElem;
+ %(readDest)s
+ %(op)s
+ destReg.elements[i] = htog(destElem);
+ }
}
''' % { "op" : op, "readDest" : readDestCode }
for reg in range(rCount):
@@ -919,14 +926,21 @@ let {{
if readDest:
readDestCode = 'destElem = gtoh(destReg.elements[i]);'
eWalkCode += '''
- assert(imm >= 0 && imm < eCount);
- for (unsigned i = 0; i < eCount; i++) {
- Element srcElem1 = gtoh(srcReg1.elements[i]);
- Element srcElem2 = gtoh(srcReg2.elements[imm]);
- BigElement destElem;
- %(readDest)s
- %(op)s
- destReg.elements[i] = htog(destElem);
+ if (imm < 0 && imm >= eCount) {
+#if FULL_SYSTEM
+ fault = new UndefinedInstruction;
+#else
+ fault = new UndefinedInstruction(false, mnemonic);
+#endif
+ } else {
+ for (unsigned i = 0; i < eCount; i++) {
+ Element srcElem1 = gtoh(srcReg1.elements[i]);
+ Element srcElem2 = gtoh(srcReg2.elements[imm]);
+ BigElement destElem;
+ %(readDest)s
+ %(op)s
+ destReg.elements[i] = htog(destElem);
+ }
}
''' % { "op" : op, "readDest" : readDestCode }
for reg in range(2 * rCount):
@@ -965,14 +979,21 @@ let {{
if readDest:
readDestCode = 'destReg = destRegs[i];'
eWalkCode += '''
- assert(imm >= 0 && imm < rCount);
- for (unsigned i = 0; i < rCount; i++) {
- FloatReg srcReg1 = srcRegs1[i];
- FloatReg srcReg2 = srcRegs2[imm];
- FloatReg destReg;
- %(readDest)s
- %(op)s
- destRegs[i] = destReg;
+ if (imm < 0 && imm >= eCount) {
+#if FULL_SYSTEM
+ fault = new UndefinedInstruction;
+#else
+ fault = new UndefinedInstruction(false, mnemonic);
+#endif
+ } else {
+ for (unsigned i = 0; i < rCount; i++) {
+ FloatReg srcReg1 = srcRegs1[i];
+ FloatReg srcReg2 = srcRegs2[imm];
+ FloatReg destReg;
+ %(readDest)s
+ %(op)s
+ destRegs[i] = destReg;
+ }
}
''' % { "op" : op, "readDest" : readDestCode }
for reg in range(rCount):
@@ -3277,8 +3298,14 @@ let {{
destReg.elements[i] = srcReg1.elements[index];
} else {
index -= eCount;
- assert(index < eCount);
- destReg.elements[i] = srcReg2.elements[index];
+ if (index >= eCount)
+#if FULL_SYSTEM
+ fault = new UndefinedInstruction;
+#else
+ fault = new UndefinedInstruction(false, mnemonic);
+#endif
+ else
+ destReg.elements[i] = srcReg2.elements[index];
}
}
'''
diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc
index fd861befc..13dec0add 100644
--- a/src/arch/arm/miscregs.cc
+++ b/src/arch/arm/miscregs.cc
@@ -451,8 +451,6 @@ decodeCP15Reg(unsigned crn, unsigned opc1, unsigned crm, unsigned opc2)
// Implementation defined
break;
}
- warn("Unknown miscreg: CRn: %d Opc1: %d CRm: %d opc2: %d\n",
- crn, opc1, crm, opc2);
// Unrecognized register
return NUM_MISCREGS;
}