diff options
-rw-r--r-- | src/arch/arm/insts/macromem.cc | 50 | ||||
-rw-r--r-- | src/arch/arm/insts/pred_inst.hh | 8 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/fp.isa | 10 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/misc.isa | 5 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/neon.isa | 79 | ||||
-rw-r--r-- | src/arch/arm/miscregs.cc | 2 |
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; } |