llvm.org GIT mirror llvm / e4e5e2a
Add support to the ARM MC infrastructure to support mcr and friends. This requires supporting the symbolic immediate names used for these instructions, fixing their pretty-printers, and adding proper encoding information for them. With this, we can properly pretty-print and encode assembly like: mrc p15, #0, r3, c13, c0, #3 Fixes <rdar://problem/8857858>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123404 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 9 years ago
5 changed file(s) with 241 addition(s) and 43 deletion(s). Raw diff Collapse all Expand all
558558
559559 def nohash_imm : Operand {
560560 let PrintMethod = "printNoHashImmediate";
561 }
562
563 def p_imm : Operand {
564 let PrintMethod = "printPImmediate";
565 }
566
567 def c_imm : Operand {
568 let PrintMethod = "printCImmediate";
561569 }
562570
563571 //===----------------------------------------------------------------------===//
35973605 defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
35983606 defm STC2 : LdStCop<0b1111, 0, "stc2">;
35993607
3600 def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3601 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3602 NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3608 def MCR : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3609 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3610 NoItinerary, "mcr", "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
36033611 [/* For disassembly only; pattern left blank */]> {
36043612 let Inst{20} = 0;
36053613 let Inst{4} = 1;
3606 }
3607
3608 def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3609 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3610 NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3614
3615 bits<4> Rt;
3616 bits<4> cop;
3617 bits<3> opc1;
3618 bits<3> opc2;
3619 bits<4> CRm;
3620 bits<4> CRn;
3621
3622 let Inst{15-12} = Rt;
3623 let Inst{11-8} = cop;
3624 let Inst{23-21} = opc1;
3625 let Inst{7-5} = opc2;
3626 let Inst{3-0} = CRm;
3627 let Inst{19-16} = CRn;
3628 }
3629
3630 def MCR2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3631 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3632 NoItinerary, "mcr2\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
36113633 [/* For disassembly only; pattern left blank */]> {
36123634 let Inst{31-28} = 0b1111;
36133635 let Inst{20} = 0;
36143636 let Inst{4} = 1;
3615 }
3616
3617 def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3618 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3619 NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3637
3638 bits<4> Rt;
3639 bits<4> cop;
3640 bits<3> opc1;
3641 bits<3> opc2;
3642 bits<4> CRm;
3643 bits<4> CRn;
3644
3645 let Inst{15-12} = Rt;
3646 let Inst{11-8} = cop;
3647 let Inst{23-21} = opc1;
3648 let Inst{7-5} = opc2;
3649 let Inst{3-0} = CRm;
3650 let Inst{19-16} = CRn;
3651 }
3652
3653 def MRC : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3654 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3655 NoItinerary, "mrc", "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
36203656 [/* For disassembly only; pattern left blank */]> {
36213657 let Inst{20} = 1;
36223658 let Inst{4} = 1;
3623 }
3624
3625 def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
3626 GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
3627 NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
3659
3660 bits<4> Rt;
3661 bits<4> cop;
3662 bits<3> opc1;
3663 bits<3> opc2;
3664 bits<4> CRm;
3665 bits<4> CRn;
3666
3667 let Inst{15-12} = Rt;
3668 let Inst{11-8} = cop;
3669 let Inst{23-21} = opc1;
3670 let Inst{7-5} = opc2;
3671 let Inst{3-0} = CRm;
3672 let Inst{19-16} = CRn;
3673 }
3674
3675 def MRC2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
3676 GPR:$Rt, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
3677 NoItinerary, "mrc2\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
36283678 [/* For disassembly only; pattern left blank */]> {
36293679 let Inst{31-28} = 0b1111;
36303680 let Inst{20} = 1;
36313681 let Inst{4} = 1;
3632 }
3633
3634 def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3635 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3636 NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3682
3683 bits<4> Rt;
3684 bits<4> cop;
3685 bits<3> opc1;
3686 bits<3> opc2;
3687 bits<4> CRm;
3688 bits<4> CRn;
3689
3690 let Inst{15-12} = Rt;
3691 let Inst{11-8} = cop;
3692 let Inst{23-21} = opc1;
3693 let Inst{7-5} = opc2;
3694 let Inst{3-0} = CRm;
3695 let Inst{19-16} = CRn;
3696 }
3697
3698 def MCRR : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3699 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3700 NoItinerary, "mcrr", "\t$cop, $opc, $Rt, $Rt2, $CRm",
36373701 [/* For disassembly only; pattern left blank */]> {
36383702 let Inst{23-20} = 0b0100;
3639 }
3640
3641 def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3642 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3643 NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3703
3704 bits<4> Rt;
3705 bits<4> Rt2;
3706 bits<4> cop;
3707 bits<3> opc1;
3708 bits<4> CRm;
3709
3710 let Inst{15-12} = Rt;
3711 let Inst{19-16} = Rt2;
3712 let Inst{11-8} = cop;
3713 let Inst{7-5} = opc1;
3714 let Inst{3-0} = CRm;
3715 }
3716
3717 def MCRR2 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3718 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3719 NoItinerary, "mcrr2\t$cop, $opc, $Rt, $Rt2, $CRm",
36443720 [/* For disassembly only; pattern left blank */]> {
36453721 let Inst{31-28} = 0b1111;
36463722 let Inst{23-20} = 0b0100;
3647 }
3648
3649 def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3650 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3651 NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3723
3724 bits<4> Rt;
3725 bits<4> Rt2;
3726 bits<4> cop;
3727 bits<3> opc1;
3728 bits<4> CRm;
3729
3730 let Inst{15-12} = Rt;
3731 let Inst{19-16} = Rt2;
3732 let Inst{11-8} = cop;
3733 let Inst{7-5} = opc1;
3734 let Inst{3-0} = CRm;
3735 }
3736
3737 def MRRC : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3738 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3739 NoItinerary, "mrrc", "\t$cop, $opc, $Rt, $Rt2, $CRm",
36523740 [/* For disassembly only; pattern left blank */]> {
36533741 let Inst{23-20} = 0b0101;
3654 }
3655
3656 def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
3657 GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
3658 NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
3742
3743 bits<4> Rt;
3744 bits<4> Rt2;
3745 bits<4> cop;
3746 bits<3> opc1;
3747 bits<4> CRm;
3748
3749 let Inst{15-12} = Rt;
3750 let Inst{19-16} = Rt2;
3751 let Inst{11-8} = cop;
3752 let Inst{7-5} = opc1;
3753 let Inst{3-0} = CRm;
3754 }
3755
3756 def MRRC2 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc,
3757 GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
3758 NoItinerary, "mrrc2\t$cop, $opc, $Rt, $Rt2, $CRm",
36593759 [/* For disassembly only; pattern left blank */]> {
36603760 let Inst{31-28} = 0b1111;
36613761 let Inst{23-20} = 0b0101;
3762
3763 bits<4> Rt;
3764 bits<4> Rt2;
3765 bits<4> cop;
3766 bits<3> opc1;
3767 bits<4> CRm;
3768
3769 let Inst{15-12} = Rt;
3770 let Inst{19-16} = Rt2;
3771 let Inst{11-8} = cop;
3772 let Inst{7-5} = opc1;
3773 let Inst{3-0} = CRm;
36623774 }
36633775
36643776 //===----------------------------------------------------------------------===//
5151 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
5252
5353 int TryParseRegister();
54 bool TryParseMCRName(SmallVectorImpl&);
5455 bool TryParseRegisterWithWriteBack(SmallVectorImpl &);
5556 bool ParseRegisterList(SmallVectorImpl &);
5657 bool ParseMemory(SmallVectorImpl &);
57 bool ParseOperand(SmallVectorImpl &);
58 bool ParseOperand(SmallVectorImpl &, bool isMCR);
5859 bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
5960 const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
6061 MCSymbolRefExpr::VariantKind Variant);
526527 return false;
527528 }
528529
530 static int MatchMCRName(StringRef Name) {
531 // Use the same layout as the tablegen'erated register name matcher. Ugly,
532 // but efficient.
533 switch (Name.size()) {
534 default: break;
535 case 2:
536 if (Name[0] != 'p' && Name[0] != 'c')
537 return -1;
538 switch (Name[1]) {
539 default: return -1;
540 case '0': return 0;
541 case '1': return 1;
542 case '2': return 2;
543 case '3': return 3;
544 case '4': return 4;
545 case '5': return 5;
546 case '6': return 6;
547 case '7': return 7;
548 case '8': return 8;
549 case '9': return 9;
550 }
551 break;
552 case 3:
553 if ((Name[0] != 'p' && Name[0] != 'c') || Name[1] != '1')
554 return -1;
555 switch (Name[2]) {
556 default: return -1;
557 case '0': return 10;
558 case '1': return 11;
559 case '2': return 12;
560 case '3': return 13;
561 case '4': return 14;
562 case '5': return 15;
563 }
564 break;
565 }
566
567 llvm_unreachable("Unhandled coprocessor operand string!");
568 return -1;
569 }
570
571 /// TryParseMCRName - Try to parse an MCR/MRC symbolic operand
572 /// name. The token must be an Identifier when called, and if it is a MCR
573 /// operand name, the token is eaten and the operand is added to the
574 /// operand list.
575 bool ARMAsmParser::
576 TryParseMCRName(SmallVectorImpl &Operands) {
577 SMLoc S = Parser.getTok().getLoc();
578 const AsmToken &Tok = Parser.getTok();
579 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
580
581 int Num = MatchMCRName(Tok.getString());
582 if (Num == -1)
583 return true;
584
585 Parser.Lex(); // Eat identifier token.
586 Operands.push_back(ARMOperand::CreateImm(
587 MCConstantExpr::Create(Num, getContext()), S, Parser.getTok().getLoc()));
588 return false;
589 }
590
529591 /// Parse a register list, return it if successful else return null. The first
530592 /// token must be a '{' when called.
531593 bool ARMAsmParser::
833895
834896 /// Parse a arm instruction operand. For now this parses the operand regardless
835897 /// of the mnemonic.
836 bool ARMAsmParser::ParseOperand(SmallVectorImpl &Operands){
898 bool ARMAsmParser::ParseOperand(SmallVectorImpl &Operands,
899 bool isMCR){
837900 SMLoc S, E;
838901 switch (getLexer().getKind()) {
839902 default:
842905 case AsmToken::Identifier:
843906 if (!TryParseRegisterWithWriteBack(Operands))
844907 return false;
845 // Fall though for the Identifier case that is not a register
908 if (isMCR && !TryParseMCRName(Operands))
909 return false;
910
911 // Fall though for the Identifier case that is not a register or a
912 // special name.
846913 case AsmToken::Integer: // things like 1f and 2b as a branch targets
847914 case AsmToken::Dot: { // . as a branch target
848915 // This was not a register so parse other operands that start with an
11191186 Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
11201187 }
11211188
1189 bool isMCR = (Head == "mcr" || Head == "mcr2" ||
1190 Head == "mcrr" || Head == "mcrr2" ||
1191 Head == "mrc" || Head == "mrc2" ||
1192 Head == "mrrc" || Head == "mrrc2");
1193
11221194 // Read the remaining operands.
11231195 if (getLexer().isNot(AsmToken::EndOfStatement)) {
11241196 // Read the first operand.
1125 if (ParseOperand(Operands)) {
1197 if (ParseOperand(Operands, isMCR)) {
11261198 Parser.EatToEndOfStatement();
11271199 return true;
11281200 }
11311203 Parser.Lex(); // Eat the comma.
11321204
11331205 // Parse and remember the operand.
1134 if (ParseOperand(Operands)) {
1206 if (ParseOperand(Operands, isMCR)) {
11351207 Parser.EatToEndOfStatement();
11361208 return true;
11371209 }
452452 O << MI->getOperand(OpNum).getImm();
453453 }
454454
455 void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
456 raw_ostream &O) {
457 O << "p" << MI->getOperand(OpNum).getImm();
458 }
459
460 void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
461 raw_ostream &O) {
462 O << "c" << MI->getOperand(OpNum).getImm();
463 }
464
455465 void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
456466 raw_ostream &O) {
457467 llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
9494 raw_ostream &O);
9595 void printRegisterList(const MCInst *MI, unsigned OpNum, raw_ostream &O);
9696 void printNoHashImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O);
97 void printPImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O);
98 void printCImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O);
9799 void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
98100 void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
99101 void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
567567 IMM("bf_inv_mask_imm");
568568 IMM("jtblock_operand");
569569 IMM("nohash_imm");
570 IMM("p_imm");
571 IMM("c_imm");
570572 IMM("cpinst_operand");
571573 IMM("setend_op");
572574 IMM("cps_opt");