llvm.org GIT mirror llvm / 8f59c35
[ARM] Add missing Thumb2 assembler diagnostics. Mostly just adding checks for Thumb2 instructions which correspond to ARM instructions which already had diagnostics. While I'm here, also fix ARM-mode strd to check the input registers correctly. Differential Revision: https://reviews.llvm.org/D48610 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335909 91177308-0d34-0410-b5e6-96231b3b80d8 Eli Friedman 2 years ago
5 changed file(s) with 231 addition(s) and 91 deletion(s). Raw diff Collapse all Expand all
560560 bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
561561 bool isITBlockTerminator(MCInst &Inst) const;
562562 void fixupGNULDRDAlias(StringRef Mnemonic, OperandVector &Operands);
563 bool validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands,
564 bool Load, bool ARMMode, bool Writeback);
563565
564566 public:
565567 enum ARMMatchResultTy {
63016303 return false;
63026304 }
63036305
6306 bool ARMAsmParser::validateLDRDSTRD(MCInst &Inst,
6307 const OperandVector &Operands,
6308 bool Load, bool ARMMode, bool Writeback) {
6309 unsigned RtIndex = Load || !Writeback ? 0 : 1;
6310 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(RtIndex).getReg());
6311 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(RtIndex + 1).getReg());
6312
6313 if (ARMMode) {
6314 // Rt can't be R14.
6315 if (Rt == 14)
6316 return Error(Operands[3]->getStartLoc(),
6317 "Rt can't be R14");
6318
6319 // Rt must be even-numbered.
6320 if ((Rt & 1) == 1)
6321 return Error(Operands[3]->getStartLoc(),
6322 "Rt must be even-numbered");
6323
6324 // Rt2 must be Rt + 1.
6325 if (Rt2 != Rt + 1) {
6326 if (Load)
6327 return Error(Operands[3]->getStartLoc(),
6328 "destination operands must be sequential");
6329 else
6330 return Error(Operands[3]->getStartLoc(),
6331 "source operands must be sequential");
6332 }
6333
6334 // FIXME: Diagnose m == 15
6335 // FIXME: Diagnose ldrd with m == t || m == t2.
6336 }
6337
6338 if (!ARMMode && Load) {
6339 if (Rt2 == Rt)
6340 return Error(Operands[3]->getStartLoc(),
6341 "destination operands can't be identical");
6342 }
6343
6344 if (Writeback) {
6345 unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg());
6346
6347 if (Rn == Rt || Rn == Rt2) {
6348 if (Load)
6349 return Error(Operands[3]->getStartLoc(),
6350 "base register needs to be different from destination "
6351 "registers");
6352 else
6353 return Error(Operands[3]->getStartLoc(),
6354 "source register and base register can't be identical");
6355 }
6356
6357 // FIXME: Diagnose ldrd/strd with writeback and n == 15.
6358 // (Except the immediate form of ldrd?)
6359 }
6360
6361 return false;
6362 }
6363
6364
63046365 // FIXME: We would really like to be able to tablegen'erate this.
63056366 bool ARMAsmParser::validateInstruction(MCInst &Inst,
63066367 const OperandVector &Operands) {
63636424 break;
63646425 }
63656426 case ARM::LDRD:
6427 if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/true,
6428 /*Writeback*/false))
6429 return true;
6430 break;
63666431 case ARM::LDRD_PRE:
6367 case ARM::LDRD_POST: {
6368 const unsigned RtReg = Inst.getOperand(0).getReg();
6369
6370 // Rt can't be R14.
6371 if (RtReg == ARM::LR)
6372 return Error(Operands[3]->getStartLoc(),
6373 "Rt can't be R14");
6374
6375 const unsigned Rt = MRI->getEncodingValue(RtReg);
6376 // Rt must be even-numbered.
6377 if ((Rt & 1) == 1)
6378 return Error(Operands[3]->getStartLoc(),
6379 "Rt must be even-numbered");
6380
6381 // Rt2 must be Rt + 1.
6382 const unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
6383 if (Rt2 != Rt + 1)
6384 return Error(Operands[3]->getStartLoc(),
6385 "destination operands must be sequential");
6386
6387 if (Opcode == ARM::LDRD_PRE || Opcode == ARM::LDRD_POST) {
6388 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg());
6389 // For addressing modes with writeback, the base register needs to be
6390 // different from the destination registers.
6391 if (Rn == Rt || Rn == Rt2)
6392 return Error(Operands[3]->getStartLoc(),
6393 "base register needs to be different from destination "
6394 "registers");
6395 }
6396
6397 return false;
6398 }
6432 case ARM::LDRD_POST:
6433 if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/true,
6434 /*Writeback*/true))
6435 return true;
6436 break;
63996437 case ARM::t2LDRDi8:
6438 if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/false,
6439 /*Writeback*/false))
6440 return true;
6441 break;
64006442 case ARM::t2LDRD_PRE:
6401 case ARM::t2LDRD_POST: {
6402 // Rt2 must be different from Rt.
6403 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
6404 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
6405 if (Rt2 == Rt)
6406 return Error(Operands[3]->getStartLoc(),
6407 "destination operands can't be identical");
6408 return false;
6409 }
6443 case ARM::t2LDRD_POST:
6444 if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/false,
6445 /*Writeback*/true))
6446 return true;
6447 break;
64106448 case ARM::t2BXJ: {
64116449 const unsigned RmReg = Inst.getOperand(0).getReg();
64126450 // Rm = SP is no longer unpredictable in v8-A
64156453 "r13 (SP) is an unpredictable operand to BXJ");
64166454 return false;
64176455 }
6418 case ARM::STRD: {
6419 // Rt2 must be Rt + 1.
6420 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
6421 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
6422 if (Rt2 != Rt + 1)
6423 return Error(Operands[3]->getStartLoc(),
6424 "source operands must be sequential");
6425 return false;
6426 }
6456 case ARM::STRD:
6457 if (validateLDRDSTRD(Inst, Operands, /*Load*/false, /*ARMMode*/true,
6458 /*Writeback*/false))
6459 return true;
6460 break;
64276461 case ARM::STRD_PRE:
6428 case ARM::STRD_POST: {
6429 // Rt2 must be Rt + 1.
6430 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
6431 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(2).getReg());
6432 if (Rt2 != Rt + 1)
6433 return Error(Operands[3]->getStartLoc(),
6434 "source operands must be sequential");
6435 return false;
6436 }
6462 case ARM::STRD_POST:
6463 if (validateLDRDSTRD(Inst, Operands, /*Load*/false, /*ARMMode*/true,
6464 /*Writeback*/true))
6465 return true;
6466 break;
6467 case ARM::t2STRD_PRE:
6468 case ARM::t2STRD_POST:
6469 if (validateLDRDSTRD(Inst, Operands, /*Load*/false, /*ARMMode*/false,
6470 /*Writeback*/true))
6471 return true;
6472 break;
64376473 case ARM::STR_PRE_IMM:
64386474 case ARM::STR_PRE_REG:
6475 case ARM::t2STR_PRE:
64396476 case ARM::STR_POST_IMM:
64406477 case ARM::STR_POST_REG:
6478 case ARM::t2STR_POST:
64416479 case ARM::STRH_PRE:
6480 case ARM::t2STRH_PRE:
64426481 case ARM::STRH_POST:
6482 case ARM::t2STRH_POST:
64436483 case ARM::STRB_PRE_IMM:
64446484 case ARM::STRB_PRE_REG:
6485 case ARM::t2STRB_PRE:
64456486 case ARM::STRB_POST_IMM:
6446 case ARM::STRB_POST_REG: {
6487 case ARM::STRB_POST_REG:
6488 case ARM::t2STRB_POST: {
64476489 // Rt must be different from Rn.
64486490 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
64496491 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
64556497 }
64566498 case ARM::LDR_PRE_IMM:
64576499 case ARM::LDR_PRE_REG:
6500 case ARM::t2LDR_PRE:
64586501 case ARM::LDR_POST_IMM:
64596502 case ARM::LDR_POST_REG:
6503 case ARM::t2LDR_POST:
64606504 case ARM::LDRH_PRE:
6505 case ARM::t2LDRH_PRE:
64616506 case ARM::LDRH_POST:
6507 case ARM::t2LDRH_POST:
64626508 case ARM::LDRSH_PRE:
6509 case ARM::t2LDRSH_PRE:
64636510 case ARM::LDRSH_POST:
6511 case ARM::t2LDRSH_POST:
64646512 case ARM::LDRB_PRE_IMM:
64656513 case ARM::LDRB_PRE_REG:
6514 case ARM::t2LDRB_PRE:
64666515 case ARM::LDRB_POST_IMM:
64676516 case ARM::LDRB_POST_REG:
6517 case ARM::t2LDRB_POST:
64686518 case ARM::LDRSB_PRE:
6469 case ARM::LDRSB_POST: {
6519 case ARM::t2LDRSB_PRE:
6520 case ARM::LDRSB_POST:
6521 case ARM::t2LDRSB_POST: {
64706522 // Rt must be different from Rn.
64716523 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
64726524 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
64776529 return false;
64786530 }
64796531 case ARM::SBFX:
6480 case ARM::UBFX: {
6532 case ARM::t2SBFX:
6533 case ARM::UBFX:
6534 case ARM::t2UBFX: {
64816535 // Width must be in range [1, 32-lsb].
64826536 unsigned LSB = Inst.getOperand(2).getImm();
64836537 unsigned Widthm1 = Inst.getOperand(3).getImm();
403403 @------------------------------------------------------------------------------
404404 @ STRD (immediate)
405405 @------------------------------------------------------------------------------
406 strd r1, r2, [r4]
406 strd r2, r3, [r4]
407407 strd r2, r3, [r6, #1]
408 strd r3, r4, [r7, #22]!
408 strd r0, r1, [r7, #22]!
409409 strd r4, r5, [r8], #7
410 strd r5, r6, [sp], #0
410 strd r4, r5, [sp], #0
411411 strd r6, r7, [lr], #+0
412 strd r7, r8, [r9], #-0
413
414 @ CHECK: strd r1, r2, [r4] @ encoding: [0xf0,0x10,0xc4,0xe1]
412 strd r10, r11, [r9], #-0
413
414 @ CHECK: strd r2, r3, [r4] @ encoding: [0xf0,0x20,0xc4,0xe1]
415415 @ CHECK: strd r2, r3, [r6, #1] @ encoding: [0xf1,0x20,0xc6,0xe1]
416 @ CHECK: strd r3, r4, [r7, #22]! @ encoding: [0xf6,0x31,0xe7,0xe1]
416 @ CHECK: strd r0, r1, [r7, #22]! @ encoding: [0xf6,0x01,0xe7,0xe1]
417417 @ CHECK: strd r4, r5, [r8], #7 @ encoding: [0xf7,0x40,0xc8,0xe0]
418 @ CHECK: strd r5, r6, [sp], #0 @ encoding: [0xf0,0x50,0xcd,0xe0]
418 @ CHECK: strd r4, r5, [sp], #0 @ encoding: [0xf0,0x40,0xcd,0xe0]
419419 @ CHECK: strd r6, r7, [lr], #0 @ encoding: [0xf0,0x60,0xce,0xe0]
420 @ CHECK: strd r7, r8, [r9], #-0 @ encoding: [0xf0,0x70,0x49,0xe0]
420 @ CHECK: strd r10, r11, [r9], #-0 @ encoding: [0xf0,0xa0,0x49,0xe0]
421421
422422
423423 @------------------------------------------------------------------------------
428428 @ STRD (register)
429429 @------------------------------------------------------------------------------
430430 strd r8, r9, [r4, r1]
431 strd r7, r8, [r3, r9]!
431 strd r6, r7, [r3, r9]!
432432 strd r6, r7, [r5], r8
433 strd r5, r6, [r12], -r10
433 strd r4, r5, [r12], -r10
434434
435435 @ CHECK: strd r8, r9, [r4, r1] @ encoding: [0xf1,0x80,0x84,0xe1]
436 @ CHECK: strd r7, r8, [r3, r9]! @ encoding: [0xf9,0x70,0xa3,0xe1]
436 @ CHECK: strd r6, r7, [r3, r9]! @ encoding: [0xf9,0x60,0xa3,0xe1]
437437 @ CHECK: strd r6, r7, [r5], r8 @ encoding: [0xf8,0x60,0x85,0xe0]
438 @ CHECK: strd r5, r6, [r12], -r10 @ encoding: [0xfa,0x50,0x0c,0xe0]
438 @ CHECK: strd r4, r5, [r12], -r10 @ encoding: [0xfa,0x40,0x0c,0xe0]
439439
440440
441441 @------------------------------------------------------------------------------
398398 @ CHECK-ERRORS: ubfx r14, pc, #1, #2
399399 @ CHECK-ERRORS: ^
400400
401 @ Out of order Rt/Rt2 operands for ldrd
401 @ Out of order Rt/Rt2 operands for ldrd/strd
402402 ldrd r4, r3, [r8]
403403 ldrd r4, r3, [r8, #8]!
404404 ldrd r4, r3, [r8], #8
405 strd r4, r3, [r8]
406 strd r4, r3, [r8, #8]!
407 strd r4, r3, [r8], #8
405408 @ CHECK-ERRORS: error: destination operands must be sequential
406409 @ CHECK-ERRORS: ldrd r4, r3, [r8]
407410 @ CHECK-ERRORS: ^
410413 @ CHECK-ERRORS: ^
411414 @ CHECK-ERRORS: error: destination operands must be sequential
412415 @ CHECK-ERRORS: ldrd r4, r3, [r8], #8
416 @ CHECK-ERRORS: ^
417 @ CHECK-ERRORS: error: source operands must be sequential
418 @ CHECK-ERRORS: strd r4, r3, [r8]
419 @ CHECK-ERRORS: ^
420 @ CHECK-ERRORS: error: source operands must be sequential
421 @ CHECK-ERRORS: strd r4, r3, [r8, #8]!
422 @ CHECK-ERRORS: ^
423 @ CHECK-ERRORS: error: source operands must be sequential
424 @ CHECK-ERRORS: strd r4, r3, [r8], #8
425 @ CHECK-ERRORS: ^
426
427 @ Odd first register for ldrd/strd
428 ldrd r5, r6, [r8]
429 strd r5, r6, [r8]
430 @ CHECK-ERRORS: error: Rt must be even-numbered
431 @ CHECK-ERRORS: ldrd r5, r6, [r8]
432 @ CHECK-ERRORS: ^
433 @ CHECK-ERRORS: error: Rt must be even-numbered
434 @ CHECK-ERRORS: strd r5, r6, [r8]
435 @ CHECK-ERRORS: ^
436
437 @ Post-increment with base equal to source
438 ldrd r6, r7, [r6]!
439 ldrd r6, r7, [r7]!
440 strd r6, r7, [r6]!
441 strd r6, r7, [r7]!
442 @ CHECK-ERRORS: error: base register needs to be different from destination registers
443 @ CHECK-ERRORS: ldrd r6, r7, [r6]!
444 @ CHECK-ERRORS: ^
445 @ CHECK-ERRORS: error: base register needs to be different from destination registers
446 @ CHECK-ERRORS: ldrd r6, r7, [r7]!
447 @ CHECK-ERRORS: ^
448 @ CHECK-ERRORS: error: source register and base register can't be identical
449 @ CHECK-ERRORS: strd r6, r7, [r6]!
450 @ CHECK-ERRORS: ^
451 @ CHECK-ERRORS: error: source register and base register can't be identical
452 @ CHECK-ERRORS: strd r6, r7, [r7]!
453 @ CHECK-ERRORS: ^
454
455 @ Paired load/store of pc
456 ldrd lr, pc, [r6]!
457 strd lr, pc, [r6]!
458 @ CHECK-ERRORS: error: Rt can't be R14
459 @ CHECK-ERRORS: ldrd lr, pc, [r6]!
460 @ CHECK-ERRORS: ^
461 @ CHECK-ERRORS: error: Rt can't be R14
462 @ CHECK-ERRORS: strd lr, pc, [r6]!
413463 @ CHECK-ERRORS: ^
414464
415465
359359 adds r0
360360 @ CHECK-ERRORS: error: too few operands for instruction
361361 @ CHECK-ERRORS: error: too few operands for instruction
362
363 @------------------------------------------------------------------------------
364 @ Out of range width for SBFX/UBFX
365 @------------------------------------------------------------------------------
366
367 sbfx r4, r5, #31, #2
368 ubfx r4, r5, #16, #17
369
370 @ CHECK-ERRORS-V8: error: bitfield width must be in range [1,32-lsb]
371 @ CHECK-ERRORS-V8: sbfx r4, r5, #31, #2
372 @ CHECK-ERRORS-V8: ^
373 @ CHECK-ERRORS-V8: error: bitfield width must be in range [1,32-lsb]
374 @ CHECK-ERRORS-V8: ubfx r4, r5, #16, #17
375 @ CHECK-ERRORS-V8: ^
376
377 @------------------------------------------------------------------------------
378 @ Writeback store writing to same register as value
379 @------------------------------------------------------------------------------
380
381 str r0, [r0, #4]!
382 str r0, [r0], #4
383 strh r0, [r0, #2]!
384 strh r0, [r0], #2
385 strb r0, [r0, #1]!
386 strb r0, [r0], #1
387 strd r0, r1, [r0], #1
388 strd r1, r0, [r0], #1
389 @ CHECK-ERRORS-V8: error: source register and base register can't be identical
390 @ CHECK-ERRORS-V8: str r0, [r0, #4]!
391 @ CHECK-ERRORS-V8: ^
392 @ CHECK-ERRORS-V8: error: source register and base register can't be identical
393 @ CHECK-ERRORS-V8: str r0, [r0], #4
394 @ CHECK-ERRORS-V8: ^
395 @ CHECK-ERRORS-V8: error: source register and base register can't be identical
396 @ CHECK-ERRORS-V8: strh r0, [r0, #2]!
397 @ CHECK-ERRORS-V8: ^
398 @ CHECK-ERRORS-V8: error: source register and base register can't be identical
399 @ CHECK-ERRORS-V8: strh r0, [r0], #2
400 @ CHECK-ERRORS-V8: ^
401 @ CHECK-ERRORS-V8: error: source register and base register can't be identical
402 @ CHECK-ERRORS-V8: strb r0, [r0, #1]!
403 @ CHECK-ERRORS-V8: ^
404 @ CHECK-ERRORS-V8: error: source register and base register can't be identical
405 @ CHECK-ERRORS-V8: strb r0, [r0], #1
406 @ CHECK-ERRORS-V8: ^
407 @ CHECK-ERRORS-V8: error: source register and base register can't be identical
408 @ CHECK-ERRORS-V8: strd r0, r1, [r0], #1
409 @ CHECK-ERRORS-V8: ^
410 @ CHECK-ERRORS-V8: error: source register and base register can't be identical
411 @ CHECK-ERRORS-V8: strd r1, r0, [r0], #1
412 @ CHECK-ERRORS-V8: ^
694694 strexge r0, r0, [pc]
695695 @ CHECK: [[@LINE+2]]:1: warning: deprecated instruction in IT block
696696 it ge
697 strdge r0, r0, [r0], #-0
698 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
699 it ge
700697 strdge r0, r0, [r1], #-0
701698 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
702699 it ge
742739 strdge r0, r0, [pc], #-0
743740 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
744741 it ge
745 strdge r0, r0, [r0], #0
746 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
747 it ge
748742 strdge r0, r0, [r1], #0
749743 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
750744 it ge
838832 strdge r0, r0, [pc, #-0]
839833 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
840834 it ge
841 strdge r0, r0, [r0, #-0]!
842 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
843 it ge
844835 strdge r0, r0, [r1, #-0]!
845836 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
846837 it ge
886877 strdge r0, r0, [pc, #-0]!
887878 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
888879 it ge
889 strdge r0, r0, [r0]
890 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
891 it ge
892880 strdge r0, r0, [r1]
893881 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
894882 it ge
934922 strdge r0, r0, [pc]
935923 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
936924 it ge
937 strdge r0, r0, [r0, #0]!
938 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
939 it ge
940925 strdge r0, r0, [r1, #0]!
941926 @ CHECK: :[[@LINE+2]]:1: warning: deprecated instruction in IT block
942927 it ge