llvm.org GIT mirror llvm / 01b0e94
ARM: provide diagnostics on more writeback LDM/STM instructions The set of circumstances where the writeback register is allowed to be in the list of registers is rather baroque, but I think this implements them all on the assembly parsing side. For disassembly, we still warn about an ARM-mode LDM even if the architecture revision is < v7 (the required architecture information isn't available). It's a silly instruction anyway, so hopefully no-one will mind. rdar://problem/15223374 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193185 91177308-0d34-0410-b5e6-96231b3b80d8 Tim Northover 7 years ago
5 changed file(s) with 80 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
54155415 "bitfield width must be in range [1,32-lsb]");
54165416 return false;
54175417 }
5418 // Notionally handles ARM::tLDMIA_UPD too.
54185419 case ARM::tLDMIA: {
54195420 // If we're parsing Thumb2, the .w variant is available and handles
54205421 // most cases that are normally illegal for a Thumb1 LDM instruction.
54435444
54445445 break;
54455446 }
5446 case ARM::t2LDMIA_UPD: {
5447 case ARM::LDMIA_UPD:
5448 case ARM::LDMDB_UPD:
5449 case ARM::LDMIB_UPD:
5450 case ARM::LDMDA_UPD:
5451 // ARM variants loading and updating the same register are only officially
5452 // UNPREDICTABLE on v7 upwards. Goodness knows what they did before.
5453 if (!hasV7Ops())
5454 break;
5455 // Fallthrough
5456 case ARM::t2LDMIA_UPD:
5457 case ARM::t2LDMDB_UPD:
5458 case ARM::t2STMIA_UPD:
5459 case ARM::t2STMDB_UPD: {
54475460 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
54485461 return Error(Operands[4]->getStartLoc(),
54495462 "writeback operator '!' not allowed when base register "
54895502 break;
54905503 }
54915504 case ARM::tSTMIA_UPD: {
5492 bool ListContainsBase;
5493 if (checkLowRegisterList(Inst, 4, 0, 0, ListContainsBase) && !isThumbTwo())
5505 bool ListContainsBase, InvalidLowList;
5506 InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(),
5507 0, ListContainsBase);
5508 if (InvalidLowList && !isThumbTwo())
54945509 return Error(Operands[4]->getStartLoc(),
54955510 "registers must be in range r0-r7");
5511
5512 // This would be converted to a 32-bit stm, but that's not valid if the
5513 // writeback register is in the list.
5514 if (InvalidLowList && ListContainsBase)
5515 return Error(Operands[4]->getStartLoc(),
5516 "writeback operator '!' not allowed when base register "
5517 "in register list");
54965518 break;
54975519 }
54985520 case ARM::tADDrSP: {
12021202 uint64_t Address, const void *Decoder) {
12031203 DecodeStatus S = MCDisassembler::Success;
12041204
1205 bool writebackLoad = false;
1206 unsigned writebackReg = 0;
1205 bool NeedDisjointWriteback = false;
1206 unsigned WritebackReg = 0;
12071207 switch (Inst.getOpcode()) {
1208 default:
1209 break;
1210 case ARM::LDMIA_UPD:
1211 case ARM::LDMDB_UPD:
1212 case ARM::LDMIB_UPD:
1213 case ARM::LDMDA_UPD:
1214 case ARM::t2LDMIA_UPD:
1215 case ARM::t2LDMDB_UPD:
1216 writebackLoad = true;
1217 writebackReg = Inst.getOperand(0).getReg();
1218 break;
1208 default:
1209 break;
1210 case ARM::LDMIA_UPD:
1211 case ARM::LDMDB_UPD:
1212 case ARM::LDMIB_UPD:
1213 case ARM::LDMDA_UPD:
1214 case ARM::t2LDMIA_UPD:
1215 case ARM::t2LDMDB_UPD:
1216 case ARM::t2STMIA_UPD:
1217 case ARM::t2STMDB_UPD:
1218 NeedDisjointWriteback = true;
1219 WritebackReg = Inst.getOperand(0).getReg();
1220 break;
12191221 }
12201222
12211223 // Empty register lists are not allowed.
12251227 if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
12261228 return MCDisassembler::Fail;
12271229 // Writeback not allowed if Rn is in the target list.
1228 if (writebackLoad && writebackReg == Inst.end()[-1].getReg())
1230 if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg())
12291231 Check(S, MCDisassembler::SoftFail);
12301232 }
12311233 }
428428
429429 bkpteq #7
430430 @ CHECK-ERRORS: error: instruction 'bkpt' is not predicable, but condition code specified
431
432 ldm r2!, {r2, r3}
433 ldmdb r2!, {r2, r3}
434 ldmda r2!, {r2, r3}
435 @ CHECK-ERRORS: error: writeback operator '!' not allowed when base register in register list
436 @ CHECK-ERRORS: error: writeback operator '!' not allowed when base register in register list
437 @ CHECK-ERRORS: error: writeback operator '!' not allowed when base register in register list
5656 ldm r2!, {r5, r8}
5757 ldm r2, {r5, r7}
5858 ldm r2!, {r2, r3, r4}
59 ldm r2!, {r2, r3, r4, r10}
60 ldmdb r2!, {r2, r3, r4}
5961 @ CHECK-ERRORS: error: registers must be in range r0-r7
6062 @ CHECK-ERRORS: ldm r2!, {r5, r8}
6163 @ CHECK-ERRORS: ^
6567 @ CHECK-ERRORS: error: writeback operator '!' not allowed when base register in register list
6668 @ CHECK-ERRORS: ldm r2!, {r2, r3, r4}
6769 @ CHECK-ERRORS: ^
70 @ CHECK-ERRORS-V8: error: writeback operator '!' not allowed when base register in register list
71 @ CHECK-ERRORS-V8: ldm r2!, {r2, r3, r4, r10}
72 @ CHECK-ERRORS-V8: ^
73 @ CHECK-ERRORS-V8: error: writeback operator '!' not allowed when base register in register list
74 @ CHECK-ERRORS-V8: ldmdb r2!, {r2, r3, r4}
75 @ CHECK-ERRORS-V8: ^
6876
6977 @ Invalid writeback and register lists for PUSH/POP
7078 pop {r1, r2, r10}
8088 @ Invalid writeback and register lists for STM
8189 stm r1, {r2, r6}
8290 stm r1!, {r2, r9}
91 stm r2!, {r2, r9}
92 stmdb r2!, {r0, r2}
8393 @ CHECK-ERRORS: error: instruction requires: thumb2
8494 @ CHECK-ERRORS: stm r1, {r2, r6}
8595 @ CHECK-ERRORS: ^
8696 @ CHECK-ERRORS: error: registers must be in range r0-r7
8797 @ CHECK-ERRORS: stm r1!, {r2, r9}
8898 @ CHECK-ERRORS: ^
99 @ CHECK-ERRORS-V8: error: writeback operator '!' not allowed when base register in register list
100 @ CHECK-ERRORS-V8: stm r2!, {r2, r9}
101 @ CHECK-ERRORS-V8: ^
102 @ CHECK-ERRORS-V8: error: writeback operator '!' not allowed when base register in register list
103 @ CHECK-ERRORS-V8: stmdb r2!, {r0, r2}
104 @ CHECK-ERRORS-V8: ^
89105
90106 @ Out of range immediates for LSL instruction.
91107 lsls r4, r5, #-1
388388 [0x80 0xf9 0x30 0x0b]
389389 # CHECK: invalid instruction encoding
390390 # CHECK-NEXT: [0x80 0xf9 0x30 0x0b]
391
392
393 #------------------------------------------------------------------------------
394 # Unpredictable STMs
395 #------------------------------------------------------------------------------
396
397 # 32-bit Thumb STM instructions cannot have a writeback register which appears
398 # in the list.
399
400 [0xa1,0xe8,0x07,0x04]
401 # CHECK: warning: potentially undefined instruction encoding
402 # CHECK-NEXT: [0xa1,0xe8,0x07,0x04]
403
404 [0x21,0xe9,0x07,0x04]
405 # CHECK: warning: potentially undefined instruction encoding
406 # CHECK-NEXT: [0x21,0xe9,0x07,0x04]