Skip to content

Commit a65557d

Browse files
wangleiatSixWeining
authored andcommitted
[LoongArch] Fixup value adjustment in applyFixup
A complete implementation of `applyFixup` for D132323. Makes `LoongArchAsmBackend::shouldForceRelocation` to determine if the relocation types must be forced. This patch also adds range and alignment checks for `b*` instructions' operands, at which point the offset to a label is known. Differential Revision: https://reviews.llvm.org/D132818
1 parent 3ce7d25 commit a65557d

File tree

5 files changed

+167
-4
lines changed

5 files changed

+167
-4
lines changed

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "LoongArchAsmBackend.h"
14+
#include "LoongArchFixupKinds.h"
1415
#include "llvm/MC/MCAsmLayout.h"
1516
#include "llvm/MC/MCAssembler.h"
1617
#include "llvm/MC/MCContext.h"
1718
#include "llvm/MC/MCELFObjectWriter.h"
19+
#include "llvm/MC/MCValue.h"
1820
#include "llvm/Support/Endian.h"
1921
#include "llvm/Support/EndianStream.h"
2022

@@ -75,6 +77,52 @@ LoongArchAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
7577
return Infos[Kind - FirstTargetFixupKind];
7678
}
7779

80+
static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
81+
MCContext &Ctx) {
82+
switch (Fixup.getTargetKind()) {
83+
default:
84+
llvm_unreachable("Unknown fixup kind");
85+
case FK_Data_1:
86+
case FK_Data_2:
87+
case FK_Data_4:
88+
case FK_Data_8:
89+
return Value;
90+
case LoongArch::fixup_loongarch_b16: {
91+
if (!isInt<18>(Value))
92+
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
93+
if (Value % 4)
94+
Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
95+
return (Value >> 2) & 0xffff;
96+
}
97+
case LoongArch::fixup_loongarch_b21: {
98+
if (!isInt<23>(Value))
99+
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
100+
if (Value % 4)
101+
Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
102+
return ((Value & 0x3fffc) << 8) | ((Value >> 18) & 0x1f);
103+
}
104+
case LoongArch::fixup_loongarch_b26: {
105+
if (!isInt<28>(Value))
106+
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
107+
if (Value % 4)
108+
Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
109+
return ((Value & 0x3fffc) << 8) | ((Value >> 18) & 0x3ff);
110+
}
111+
case LoongArch::fixup_loongarch_abs_hi20:
112+
case LoongArch::fixup_loongarch_tls_le_hi20:
113+
return (Value >> 12) & 0xfffff;
114+
case LoongArch::fixup_loongarch_abs_lo12:
115+
case LoongArch::fixup_loongarch_tls_le_lo12:
116+
return Value & 0xfff;
117+
case LoongArch::fixup_loongarch_abs64_lo20:
118+
case LoongArch::fixup_loongarch_tls_le64_lo20:
119+
return (Value >> 32) & 0xfffff;
120+
case LoongArch::fixup_loongarch_abs64_hi12:
121+
case LoongArch::fixup_loongarch_tls_le64_hi12:
122+
return (Value >> 52) & 0xfff;
123+
}
124+
}
125+
78126
void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm,
79127
const MCFixup &Fixup,
80128
const MCValue &Target,
@@ -88,7 +136,10 @@ void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm,
88136
if (Kind >= FirstLiteralRelocationKind)
89137
return;
90138
MCFixupKindInfo Info = getFixupKindInfo(Kind);
91-
// TODO: Apply any target-specific value adjustments.
139+
MCContext &Ctx = Asm.getContext();
140+
141+
// Apply any target-specific value adjustments.
142+
Value = adjustFixupValue(Fixup, Value, Ctx);
92143

93144
// Shift the value into position.
94145
Value <<= Info.TargetOffset;
@@ -109,9 +160,15 @@ bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
109160
const MCValue &Target) {
110161
if (Fixup.getKind() >= FirstLiteralRelocationKind)
111162
return true;
112-
// TODO: Determine which relocation require special processing at linking
113-
// time.
114-
return false;
163+
switch (Fixup.getTargetKind()) {
164+
default:
165+
return false;
166+
case FK_Data_1:
167+
case FK_Data_2:
168+
case FK_Data_4:
169+
case FK_Data_8:
170+
return !Target.isAbsolute();
171+
}
115172
}
116173

117174
bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
263263
case LoongArch::BCNEZ:
264264
FixupKind = LoongArch::fixup_loongarch_b21;
265265
break;
266+
case LoongArch::B:
267+
FixupKind = LoongArch::fixup_loongarch_b26;
268+
break;
266269
}
267270
}
268271

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# RUN: not llvm-mc --triple=loongarch64 --filetype=obj %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
beq $a0, $a1, far_distant # CHECK: :[[#@LINE]]:3: error: fixup value out of range
4+
bne $a0, $a1, unaligned # CHECK: :[[#@LINE]]:3: error: fixup value must be 4-byte aligned
5+
6+
bnez $a0, unaligned # CHECK: :[[#@LINE]]:3: error: fixup value must be 4-byte aligned
7+
beqz $a0, far_distant_bz # CHECK: :[[#@LINE]]:3: error: fixup value out of range
8+
9+
b unaligned # CHECK: :[[#@LINE]]:3: error: fixup value must be 4-byte aligned
10+
11+
.byte 0
12+
unaligned:
13+
.byte 0
14+
.byte 0
15+
.byte 0
16+
17+
.space 1<<16
18+
distant:
19+
.space 1<<18
20+
far_distant:
21+
22+
.byte 0
23+
unaligned_bz:
24+
.byte 0
25+
.byte 0
26+
.byte 0
27+
distant_bz:
28+
.space 1<<23
29+
far_distant_bz:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# RUN: not llvm-mc --filetype=obj %s --triple=loongarch32 -o /dev/null 2>&1 \
2+
# RUN: | FileCheck %s
3+
# RUN: not llvm-mc --filetype=obj %s --triple=loongarch64 -o /dev/null 2>&1 \
4+
# RUN: | FileCheck %s
5+
6+
.byte foo # CHECK: [[#@LINE]]:7: error: 1-byte data relocations not supported
7+
.2byte foo # CHECK: [[#@LINE]]:8: error: 2-byte data relocations not supported
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# RUN: llvm-mc --triple=loongarch64 %s --show-encoding \
2+
# RUN: | FileCheck --check-prefix=CHECK-FIXUP %s
3+
# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \
4+
# RUN: | llvm-objdump -d - | FileCheck --check-prefix=CHECK-INSTR %s
5+
# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \
6+
# RUN: | llvm-readobj -r - | FileCheck --check-prefix=CHECK-REL %s
7+
8+
## Checks that fixups that can be resolved within the same object file are
9+
## applied correctly.
10+
11+
.LBB0:
12+
lu12i.w $t1, %abs_hi20(val)
13+
# CHECK-FIXUP: fixup A - offset: 0, value: %abs_hi20(val), kind: fixup_loongarch_abs_hi20
14+
# CHECK-INSTR: lu12i.w $t1, 74565
15+
16+
ori $t1, $t1, %abs_lo12(val)
17+
# CHECK-FIXUP: fixup A - offset: 0, value: %abs_lo12(val), kind: fixup_loongarch_abs_lo12
18+
# CHECK-INSTR: ori $t1, $t1, 1656
19+
20+
b .LBB0
21+
# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_loongarch_b26
22+
# CHECK-INSTR: b -8
23+
b .LBB2
24+
# CHECK-FIXUP: fixup A - offset: 0, value: .LBB2, kind: fixup_loongarch_b26
25+
# CHECK-INSTR: b 331004
26+
beq $a0, $a1, .LBB0
27+
# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_loongarch_b16
28+
# CHECK-INSTR: beq $a0, $a1, -16
29+
blt $a0, $a1, .LBB1
30+
# CHECK-FIXUP: fixup A - offset: 0, value: .LBB1, kind: fixup_loongarch_b16
31+
# CHECK-INSTR: blt $a0, $a1, 1116
32+
beqz $a0, .LBB0
33+
# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_loongarch_b21
34+
# CHECK-INSTR: beqz $a0, -24
35+
bnez $a0, .LBB1
36+
# CHECK-FIXUP: fixup A - offset: 0, value: .LBB1, kind: fixup_loongarch_b21
37+
# CHECK-INSTR: bnez $a0, 1108
38+
39+
.fill 1104
40+
41+
.LBB1:
42+
43+
.fill 329876
44+
nop
45+
.LBB2:
46+
47+
.set val, 0x12345678
48+
49+
# CHECK-REL-NOT: R_LARCH
50+
51+
## Testing the function call offset could resolved by assembler
52+
## when the function and the callsite within the same compile unit.
53+
func:
54+
.fill 100
55+
bl func
56+
# CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_loongarch_b26
57+
# CHECK-INSTR: bl -100
58+
59+
.fill 10000
60+
bl func
61+
# CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_loongarch_b26
62+
# CHECK-INSTR: bl -10104
63+
64+
.fill 20888
65+
bl func
66+
# CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_loongarch_b26
67+
# CHECK-INSTR: bl -30996

0 commit comments

Comments
 (0)