llvm.org GIT mirror llvm / b36a459
Fix for pr24346: arm asm label calculation error in sub Some ARM instructions encode 32-bit immediates as a 8-bit integer (0-255) and a 4-bit rotation (0-30, even) in its least significant 12 bits. The original fixup, FK_Data_4, patches the instruction by the value bit-to-bit, regardless of the encoding. For example, assuming the label L1 and L2 are 0x0 and 0x104 respectively, the following instruction: add r0, r0, #(L2 - L1) ; expects 0x104, i.e., 260 would be assembled to the following, which adds 1 to r0, instead of 260: e2800104 add r0, r0, #4, 2 ; equivalently 1 The new fixup kind fixup_arm_mod_imm takes care of the encoding: e2800f41 add r0, r0, #260 Patch by Ting-Yuan Huang! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265122 91177308-0d34-0410-b5e6-96231b3b80d8 James Molloy 4 years ago
6 changed file(s) with 52 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
9494 {"fixup_arm_movw_lo16", 0, 20, 0},
9595 {"fixup_t2_movt_hi16", 0, 20, 0},
9696 {"fixup_t2_movw_lo16", 0, 20, 0},
97 {"fixup_arm_mod_imm", 0, 12, 0},
9798 };
9899 const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = {
99100 // This table *must* be in the order that the fixup_* kinds are defined in
141142 {"fixup_arm_movw_lo16", 12, 20, 0},
142143 {"fixup_t2_movt_hi16", 12, 20, 0},
143144 {"fixup_t2_movw_lo16", 12, 20, 0},
145 {"fixup_arm_mod_imm", 20, 12, 0},
144146 };
145147
146148 if (Kind < FirstTargetFixupKind)
664666
665667 return Value;
666668 }
669 case ARM::fixup_arm_mod_imm:
670 Value = ARM_AM::getSOImmVal(Value);
671 if (Ctx && Value >> 12) {
672 Ctx->reportError(Fixup.getLoc(), "out of range immediate fixup value");
673 return 0;
674 }
675 return Value;
667676 }
668677 }
669678
730739 case FK_Data_2:
731740 case ARM::fixup_arm_thumb_br:
732741 case ARM::fixup_arm_thumb_cb:
742 case ARM::fixup_arm_mod_imm:
733743 return 2;
734744
735745 case ARM::fixup_arm_pcrel_10_unscaled:
808818 case ARM::fixup_arm_movw_lo16:
809819 case ARM::fixup_t2_movt_hi16:
810820 case ARM::fixup_t2_movw_lo16:
821 case ARM::fixup_arm_mod_imm:
811822 // Instruction size is 4 bytes.
812823 return 4;
813824 }
106106 fixup_t2_movt_hi16, // :upper16:
107107 fixup_t2_movw_lo16, // :lower16:
108108
109 // fixup_arm_mod_imm - Fixup for mod_imm
110 fixup_arm_mod_imm,
111
109112 // Marker
110113 LastTargetFixupKind,
111114 NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
316316 // Support for fixups (MCFixup)
317317 if (MO.isExpr()) {
318318 const MCExpr *Expr = MO.getExpr();
319 // In instruction code this value always encoded as lowest 12 bits,
320 // so we don't have to perform any specific adjustments.
321 // Due to requirements of relocatable records we have to use FK_Data_4.
322 // See ARMELFObjectWriter::ExplicitRelSym and
323 // ARMELFObjectWriter::GetRelocTypeInner for more details.
324 MCFixupKind Kind = MCFixupKind(FK_Data_4);
319 // Fixups resolve to plain values that need to be encoded.
320 MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_mod_imm);
325321 Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
326322 return 0;
327323 }
3131 @ CHECK: @ fixup A - offset: 0, value: fred, kind: fixup_arm_movw_lo16
3232 @ CHECK-BE: movw r2, :lower16:fred @ encoding: [0xe3,0b0000AAAA,0x20'A',A]
3333 @ CHECK-BE: @ fixup A - offset: 0, value: fred, kind: fixup_arm_movw_lo16
34
35 add r0, r0, #(L1 - L2)
36
37 @ CHECK: add r0, r0, #L1-L2 @ encoding: [A,0b0000AAAA,0x80,0xe2]
38 @ CHECK: @ fixup A - offset: 0, value: L1-L2, kind: fixup_arm_mod_imm
39 @ CHECK-BE: add r0, r0, #L1-L2 @ encoding: [0xe2,0x80,0b0000AAAA,A]
40 @ CHECK-BE: @ fixup A - offset: 0, value: L1-L2, kind: fixup_arm_mod_imm
0 @ PR24346
1 @ RUN: not llvm-mc -triple=arm-linux-gnueabi -filetype=obj < %s 2>&1 | FileCheck %s
2
3 .data
4 .align 8
5 L2:
6 .word 0
7 .align 8
8 .byte 0
9 L1:
10
11 .text
12 @ CHECK: error: out of range immediate fixup value
13 add r0, r0, #(L1 - L2)
0 @ PR24346
1 @ RUN: llvm-mc < %s -triple=arm-linux-gnueabi -filetype=obj -o - \
2 @ RUN: | llvm-objdump --disassemble -arch=arm - | FileCheck %s
3
4 .data
5 .align 8
6 L2:
7 .word 0
8 .align 8
9 .word 0
10 L1:
11
12 .text
13 @ CHECK: add r0, r0, #260
14 add r0, r0, #(L1 - L2)