Skip to content

Commit e27358c

Browse files
authored
[LoongArch][MC] Support %[ld_/gd_/desc_]pcrel_20
Reviewed By: SixWeining, MaskRay Pull Request: #100104
1 parent 63d088c commit e27358c

File tree

8 files changed

+92
-3
lines changed

8 files changed

+92
-3
lines changed

llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,24 @@ class LoongArchOperand : public MCParsedAsmOperand {
450450
IsValidKind;
451451
}
452452

453+
bool isSImm20pcaddi() const {
454+
if (!isImm())
455+
return false;
456+
457+
int64_t Imm;
458+
LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None;
459+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
460+
bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None ||
461+
VK == LoongArchMCExpr::VK_LoongArch_PCREL20_S2 ||
462+
VK == LoongArchMCExpr::VK_LoongArch_TLS_LD_PCREL20_S2 ||
463+
VK == LoongArchMCExpr::VK_LoongArch_TLS_GD_PCREL20_S2 ||
464+
VK == LoongArchMCExpr::VK_LoongArch_TLS_DESC_PCREL20_S2;
465+
return IsConstantImm
466+
? isInt<20>(Imm) && IsValidKind
467+
: LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
468+
IsValidKind;
469+
}
470+
453471
bool isSImm21lsl2() const {
454472
if (!isImm())
455473
return false;
@@ -1676,6 +1694,12 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
16761694
/*Upper=*/(1 << 19) - 1,
16771695
"operand must be a symbol with modifier (e.g. %call36) or an integer "
16781696
"in the range");
1697+
case Match_InvalidSImm20pcaddi:
1698+
return generateImmOutOfRangeError(
1699+
Operands, ErrorInfo, /*Lower=*/-(1 << 19),
1700+
/*Upper=*/(1 << 19) - 1,
1701+
"operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
1702+
"in the range");
16791703
case Match_InvalidSImm21lsl2:
16801704
return generateImmOutOfRangeError(
16811705
Operands, ErrorInfo, /*Lower=*/-(1 << 22), /*Upper=*/(1 << 22) - 4,

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,10 @@ def simm20_pcaddu18i : SImm20Operand {
397397
let ParserMatchClass = SImmAsmOperand<20, "pcaddu18i">;
398398
}
399399

400+
def simm20_pcaddi : SImm20Operand {
401+
let ParserMatchClass = SImmAsmOperand<20, "pcaddi">;
402+
}
403+
400404
def simm21_lsl2 : Operand<OtherVT> {
401405
let ParserMatchClass = SImmAsmOperand<21, "lsl2">;
402406
let EncoderMethod = "getImmOpValueAsr<2>";
@@ -754,7 +758,7 @@ def SLT : ALU_3R<0x00120000>;
754758
def SLTU : ALU_3R<0x00128000>;
755759
def SLTI : ALU_2RI12<0x02000000, simm12>;
756760
def SLTUI : ALU_2RI12<0x02400000, simm12>;
757-
def PCADDI : ALU_1RI20<0x18000000, simm20>;
761+
def PCADDI : ALU_1RI20<0x18000000, simm20_pcaddi>;
758762
def PCADDU12I : ALU_1RI20<0x1c000000, simm20>;
759763
def PCALAU12I : ALU_1RI20<0x1a000000, simm20_pcalau12i>;
760764
def AND : ALU_3R<0x00148000>;

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ enum Fixups {
111111
fixup_loongarch_relax = FirstLiteralRelocationKind + ELF::R_LARCH_RELAX,
112112
// Generate an R_LARCH_ALIGN which indicates the linker may fixup align here.
113113
fixup_loongarch_align = FirstLiteralRelocationKind + ELF::R_LARCH_ALIGN,
114+
// 20-bit fixup corresponding to %pcrel_20(foo) for instruction pcaddi.
115+
fixup_loongarch_pcrel20_s2,
114116
// 36-bit fixup corresponding to %call36(foo) for a pair instructions:
115117
// pcaddu18i+jirl.
116118
fixup_loongarch_call36 = FirstLiteralRelocationKind + ELF::R_LARCH_CALL36,
@@ -142,6 +144,12 @@ enum Fixups {
142144
fixup_loongarch_tls_le_add_r,
143145
// 12-bit fixup corresponding to %le_lo12_r(foo) for instruction addi.w/d.
144146
fixup_loongarch_tls_le_lo12_r,
147+
// 20-bit fixup corresponding to %ld_pcrel_20(foo) for instruction pcaddi.
148+
fixup_loongarch_tls_ld_pcrel20_s2,
149+
// 20-bit fixup corresponding to %gd_pcrel_20(foo) for instruction pcaddi.
150+
fixup_loongarch_tls_gd_pcrel20_s2,
151+
// 20-bit fixup corresponding to %desc_pcrel_20(foo) for instruction pcaddi.
152+
fixup_loongarch_tls_desc_pcrel20_s2,
145153
};
146154
} // end namespace LoongArch
147155
} // end namespace llvm

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,18 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
287287
case LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12_R:
288288
FixupKind = LoongArch::fixup_loongarch_tls_le_lo12_r;
289289
break;
290+
case LoongArchMCExpr::VK_LoongArch_PCREL20_S2:
291+
FixupKind = LoongArch::fixup_loongarch_pcrel20_s2;
292+
break;
293+
case LoongArchMCExpr::VK_LoongArch_TLS_LD_PCREL20_S2:
294+
FixupKind = LoongArch::fixup_loongarch_tls_ld_pcrel20_s2;
295+
break;
296+
case LoongArchMCExpr::VK_LoongArch_TLS_GD_PCREL20_S2:
297+
FixupKind = LoongArch::fixup_loongarch_tls_gd_pcrel20_s2;
298+
break;
299+
case LoongArchMCExpr::VK_LoongArch_TLS_DESC_PCREL20_S2:
300+
FixupKind = LoongArch::fixup_loongarch_tls_desc_pcrel20_s2;
301+
break;
290302
}
291303
} else if (Kind == MCExpr::SymbolRef &&
292304
cast<MCSymbolRefExpr>(Expr)->getKind() ==

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ StringRef LoongArchMCExpr::getVariantKindName(VariantKind Kind) {
166166
return "le_add_r";
167167
case VK_LoongArch_TLS_LE_LO12_R:
168168
return "le_lo12_r";
169+
case VK_LoongArch_PCREL20_S2:
170+
return "pcrel_20";
171+
case VK_LoongArch_TLS_LD_PCREL20_S2:
172+
return "ld_pcrel_20";
173+
case VK_LoongArch_TLS_GD_PCREL20_S2:
174+
return "gd_pcrel_20";
175+
case VK_LoongArch_TLS_DESC_PCREL20_S2:
176+
return "desc_pcrel_20";
169177
}
170178
}
171179

@@ -222,6 +230,10 @@ LoongArchMCExpr::getVariantKindForName(StringRef name) {
222230
.Case("le_hi20_r", VK_LoongArch_TLS_LE_HI20_R)
223231
.Case("le_add_r", VK_LoongArch_TLS_LE_ADD_R)
224232
.Case("le_lo12_r", VK_LoongArch_TLS_LE_LO12_R)
233+
.Case("pcrel_20", VK_LoongArch_PCREL20_S2)
234+
.Case("ld_pcrel_20", VK_LoongArch_TLS_LD_PCREL20_S2)
235+
.Case("gd_pcrel_20", VK_LoongArch_TLS_GD_PCREL20_S2)
236+
.Case("desc_pcrel_20", VK_LoongArch_TLS_DESC_PCREL20_S2)
225237
.Default(VK_LoongArch_Invalid);
226238
}
227239

@@ -264,6 +276,9 @@ void LoongArchMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
264276
case VK_LoongArch_TLS_GD_HI20:
265277
case VK_LoongArch_TLS_DESC_PC_HI20:
266278
case VK_LoongArch_TLS_DESC_HI20:
279+
case VK_LoongArch_TLS_LD_PCREL20_S2:
280+
case VK_LoongArch_TLS_GD_PCREL20_S2:
281+
case VK_LoongArch_TLS_DESC_PCREL20_S2:
267282
break;
268283
}
269284
fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ class LoongArchMCExpr : public MCTargetExpr {
7575
VK_LoongArch_TLS_LE_HI20_R,
7676
VK_LoongArch_TLS_LE_ADD_R,
7777
VK_LoongArch_TLS_LE_LO12_R,
78+
VK_LoongArch_PCREL20_S2,
79+
VK_LoongArch_TLS_LD_PCREL20_S2,
80+
VK_LoongArch_TLS_GD_PCREL20_S2,
81+
VK_LoongArch_TLS_DESC_PCREL20_S2,
7882
VK_LoongArch_Invalid // Must be the last item.
7983
};
8084

llvm/test/MC/LoongArch/Basic/Integer/invalid.s

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,13 @@ jirl $a0, $a0, 0x20000
9999
# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068]
100100

101101
## simm20
102-
pcaddi $a0, -0x80001
103-
# CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [-524288, 524287]
104102
pcaddu12i $a0, 0x80000
105103
# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-524288, 524287]
106104

105+
## simm20_pcaddi
106+
pcaddi $a0, -0x80001
107+
# CHECK: :[[#@LINE-1]]:13: error: operand must be a symbol with modifier (e.g. %pcrel_20) or an integer in the range [-524288, 524287]
108+
107109
## simm20_lu12iw
108110
lu12i.w $a0, -0x80001
109111
# CHECK: :[[#@LINE-1]]:14: error: operand must be a symbol with modifier (e.g. %abs_hi20) or an integer in the range [-524288, 524287]

llvm/test/MC/LoongArch/Relocations/relocations.s

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,23 @@ addi.d $t1, $a2, %le_lo12_r(foo)
288288
# RELOC: R_LARCH_TLS_LE_LO12_R foo 0x0
289289
# INSTR: addi.d $t1, $a2, %le_lo12_r(foo)
290290
# FIXUP: fixup A - offset: 0, value: %le_lo12_r(foo), kind: FK_NONE
291+
292+
pcaddi $t1, %pcrel_20(foo)
293+
# RELOC: R_LARCH_PCREL20_S2 foo 0x0
294+
# INSTR: pcaddi $t1, %pcrel_20(foo)
295+
# FIXUP: fixup A - offset: 0, value: %pcrel_20(foo), kind: FK_NONE
296+
297+
pcaddi $t1, %ld_pcrel_20(foo)
298+
# RELOC: R_LARCH_TLS_LD_PCREL20_S2 foo 0x0
299+
# INSTR: pcaddi $t1, %ld_pcrel_20(foo)
300+
# FIXUP: fixup A - offset: 0, value: %ld_pcrel_20(foo), kind: FK_NONE
301+
302+
pcaddi $t1, %gd_pcrel_20(foo)
303+
# RELOC: R_LARCH_TLS_GD_PCREL20_S2 foo 0x0
304+
# INSTR: pcaddi $t1, %gd_pcrel_20(foo)
305+
# FIXUP: fixup A - offset: 0, value: %gd_pcrel_20(foo), kind: FK_NONE
306+
307+
pcaddi $t1, %desc_pcrel_20(foo)
308+
# RELOC: R_LARCH_TLS_DESC_PCREL20_S2 foo 0x0
309+
# INSTR: pcaddi $t1, %desc_pcrel_20(foo)
310+
# FIXUP: fixup A - offset: 0, value: %desc_pcrel_20(foo), kind: FK_NONE

0 commit comments

Comments
 (0)