llvm.org GIT mirror llvm / 1fb27ec
Fix #13241, a bug around shift immediate operand for ARM instruction ADR. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161159 91177308-0d34-0410-b5e6-96231b3b80d8 Jiangning Liu 8 years ago
10 changed file(s) with 82 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
415415 }
416416
417417 // ADR instruction labels.
418 def AdrLabelAsmOperand : AsmOperandClass { let Name = "AdrLabel"; }
418419 def adrlabel : Operand {
419420 let EncoderMethod = "getAdrLabelOpValue";
421 let ParserMatchClass = AdrLabelAsmOperand;
422 let PrintMethod = "printAdrLabelOperand";
420423 }
421424
422425 def neon_vcvt_imm32 : Operand {
171171 // ADR instruction labels.
172172 def t2adrlabel : Operand {
173173 let EncoderMethod = "getT2AdrLabelOpValue";
174 let PrintMethod = "printAdrLabelOperand";
174175 }
175176
176177
795795 int64_t Value = CE->getValue();
796796 return Value > 0 && Value <= 32;
797797 }
798 bool isAdrLabel() const {
799 // If we have an immediate that's not a constant, treat it as a label
800 // reference needing a fixup. If it is a constant, but it can't fit
801 // into shift immediate encoding, we reject it.
802 if (isImm() && !isa(getImm())) return true;
803 else return (isARMSOImm() || isARMSOImmNeg());
804 }
798805 bool isARMSOImm() const {
799806 if (!isImm()) return false;
800807 const MCConstantExpr *CE = dyn_cast(getImm());
16411648 // FIXME: Handle #-0
16421649 if (Imm == INT32_MIN) Imm = 0;
16431650 Inst.addOperand(MCOperand::CreateImm(Imm));
1651 }
1652
1653 void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
1654 assert(N == 1 && "Invalid number of operands!");
1655 assert(isImm() && "Not an immediate!");
1656
1657 // If we have an immediate that's not a constant, treat it as a label
1658 // reference needing a fixup.
1659 if (!isa(getImm())) {
1660 Inst.addOperand(MCOperand::CreateExpr(getImm()));
1661 return;
1662 }
1663
1664 const MCConstantExpr *CE = dyn_cast(getImm());
1665 int Val = CE->getValue();
1666 Inst.addOperand(MCOperand::CreateImm(Val));
16441667 }
16451668
16461669 void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
791791 llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
792792 }
793793
794 void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
795 raw_ostream &O) {
796 const MCOperand &MO = MI->getOperand(OpNum);
797
798 if (MO.isExpr()) {
799 O << *MO.getExpr();
800 return;
801 }
802
803 int32_t OffImm = (int32_t)MO.getImm();
804
805 if (OffImm == INT32_MIN)
806 O << "#-0";
807 else if (OffImm < 0)
808 O << "#-" << -OffImm;
809 else
810 O << "#" << OffImm;
811 }
812
794813 void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
795814 raw_ostream &O) {
796815 O << "#" << MI->getOperand(OpNum).getImm() * 4;
7272 void printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, raw_ostream &O);
7373 void printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, raw_ostream &O);
7474
75 void printAdrLabelOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
7576 void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
7677 void printThumbSRImm(const MCInst *MI, unsigned OpNum, raw_ostream &O);
7778 void printThumbITMask(const MCInst *MI, unsigned OpNum, raw_ostream &O);
640640 return Val;
641641 }
642642
643 /// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
644 /// target.
643 /// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate
644 /// ADR label target.
645645 uint32_t ARMMCCodeEmitter::
646646 getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
647647 SmallVectorImpl &Fixups) const {
651651 Fixups);
652652 int32_t offset = MO.getImm();
653653 uint32_t Val = 0x2000;
654 if (offset < 0) {
654
655 if (offset == INT32_MIN) {
656 Val = 0x1000;
657 offset = 0;
658 } else if (offset < 0) {
655659 Val = 0x1000;
656660 offset *= -1;
657661 }
658 Val |= offset;
662
663 int SoImmVal = ARM_AM::getSOImmVal(offset);
664 assert(SoImmVal != -1 && "Not a valid so_imm value!");
665
666 Val |= SoImmVal;
659667 return Val;
660668 }
661669
662 /// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
670 /// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
663671 /// target.
664672 uint32_t ARMMCCodeEmitter::
665673 getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
669677 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
670678 Fixups);
671679 int32_t Val = MO.getImm();
672 if (Val < 0) {
680 if (Val == INT32_MIN)
681 Val = 0x1000;
682 else if (Val < 0) {
673683 Val *= -1;
674684 Val |= 0x1000;
675685 }
676686 return Val;
677687 }
678688
679 /// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
689 /// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
680690 /// target.
681691 uint32_t ARMMCCodeEmitter::
682692 getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
140140 @ CHECK: adr r2, #3 @ encoding: [0x03,0x20,0x8f,0xe2]
141141 @ CHECK: adr r2, #-3 @ encoding: [0x03,0x20,0x4f,0xe2]
142142
143 adr r1, #-0x0
144 adr r1, #-0x12000000
145 adr r1, #0x12000000
146
147 @ CHECK: adr r1, #-0 @ encoding: [0x00,0x10,0x4f,0xe2]
148 @ CHECK: adr r1, #-301989888 @ encoding: [0x12,0x14,0x4f,0xe2]
149 @ CHECK: adr r1, #301989888 @ encoding: [0x12,0x14,0x8f,0xe2]
150
143151
144152 @------------------------------------------------------------------------------
145153 @ ADD
134134
135135 subw r11, pc, #3270
136136 adr.w r11, #-826
137 adr.w r1, #-0x0
137138
138139 @ CHECK: subw r11, pc, #3270 @ encoding: [0xaf,0xf6,0xc6,0x4b]
139140 @ CHECK: adr.w r11, #-826 @ encoding: [0xaf,0xf2,0x3a,0x3b]
141 @ CHECK: adr.w r1, #-0 @ encoding: [0xaf,0xf2,0x00,0x01]
140142
141143 @------------------------------------------------------------------------------
142144 @ AND (immediate)
168168 #------------------------------------------------------------------------------
169169 # CHECK: add r2, pc, #3
170170 # CHECK: sub r2, pc, #3
171 # CHECK: sub r1, pc, #0
172 # CHECK: sub r1, pc, #301989888
173 # CHECK: add r1, pc, #301989888
171174
172175 0x03 0x20 0x8f 0xe2
173176 0x03 0x20 0x4f 0xe2
177 0x00 0x10 0x4f 0xe2
178 0x12 0x14 0x4f 0xe2
179 0x12 0x14 0x8f 0xe2
174180
175181 #------------------------------------------------------------------------------
176182 # AND
9191 #------------------------------------------------------------------------------
9292 # CHECK: subw r11, pc, #3270
9393 # CHECK: subw r11, pc, #826
94 # CHECK: subw r1, pc, #0
9495
9596 0xaf 0xf6 0xc6 0x4b
9697 0xaf 0xf2 0x3a 0x3b
98 0xaf 0xf2 0x00 0x01
9799
98100 #------------------------------------------------------------------------------
99101 # AND (immediate)