[llvm-branch-commits] [llvm] release/19.x: [LoongArch][MC] Support %[ld_/gd_/desc_]pcrel_20 (PR #100704)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jul 25 23:53:22 PDT 2024
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/100704
Backport e27358c8ed7abac200546e808ea30a86aa9aa580
Requested by: @wangleiat
>From 77642a3646e1cd86f51198f715b2ff68bf92c4c3 Mon Sep 17 00:00:00 2001
From: wanglei <wanglei at loongson.cn>
Date: Fri, 26 Jul 2024 14:36:54 +0800
Subject: [PATCH] [LoongArch][MC] Support %[ld_/gd_/desc_]pcrel_20
Reviewed By: SixWeining, MaskRay
Pull Request: https://github.com/llvm/llvm-project/pull/100104
(cherry picked from commit e27358c8ed7abac200546e808ea30a86aa9aa580)
---
.../AsmParser/LoongArchAsmParser.cpp | 24 +++++++++++++++++++
.../Target/LoongArch/LoongArchInstrInfo.td | 6 ++++-
.../MCTargetDesc/LoongArchFixupKinds.h | 8 +++++++
.../MCTargetDesc/LoongArchMCCodeEmitter.cpp | 12 ++++++++++
.../MCTargetDesc/LoongArchMCExpr.cpp | 15 ++++++++++++
.../LoongArch/MCTargetDesc/LoongArchMCExpr.h | 4 ++++
.../test/MC/LoongArch/Basic/Integer/invalid.s | 6 +++--
.../MC/LoongArch/Relocations/relocations.s | 20 ++++++++++++++++
8 files changed, 92 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
index 208bd3db8f14e..f52e188f87792 100644
--- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
+++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
@@ -450,6 +450,24 @@ class LoongArchOperand : public MCParsedAsmOperand {
IsValidKind;
}
+ bool isSImm20pcaddi() const {
+ if (!isImm())
+ return false;
+
+ int64_t Imm;
+ LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None ||
+ VK == LoongArchMCExpr::VK_LoongArch_PCREL20_S2 ||
+ VK == LoongArchMCExpr::VK_LoongArch_TLS_LD_PCREL20_S2 ||
+ VK == LoongArchMCExpr::VK_LoongArch_TLS_GD_PCREL20_S2 ||
+ VK == LoongArchMCExpr::VK_LoongArch_TLS_DESC_PCREL20_S2;
+ return IsConstantImm
+ ? isInt<20>(Imm) && IsValidKind
+ : LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
+ IsValidKind;
+ }
+
bool isSImm21lsl2() const {
if (!isImm())
return false;
@@ -1676,6 +1694,12 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
/*Upper=*/(1 << 19) - 1,
"operand must be a symbol with modifier (e.g. %call36) or an integer "
"in the range");
+ case Match_InvalidSImm20pcaddi:
+ return generateImmOutOfRangeError(
+ Operands, ErrorInfo, /*Lower=*/-(1 << 19),
+ /*Upper=*/(1 << 19) - 1,
+ "operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
+ "in the range");
case Match_InvalidSImm21lsl2:
return generateImmOutOfRangeError(
Operands, ErrorInfo, /*Lower=*/-(1 << 22), /*Upper=*/(1 << 22) - 4,
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index ec0d071453c3f..ef647a4277873 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -397,6 +397,10 @@ def simm20_pcaddu18i : SImm20Operand {
let ParserMatchClass = SImmAsmOperand<20, "pcaddu18i">;
}
+def simm20_pcaddi : SImm20Operand {
+ let ParserMatchClass = SImmAsmOperand<20, "pcaddi">;
+}
+
def simm21_lsl2 : Operand<OtherVT> {
let ParserMatchClass = SImmAsmOperand<21, "lsl2">;
let EncoderMethod = "getImmOpValueAsr<2>";
@@ -754,7 +758,7 @@ def SLT : ALU_3R<0x00120000>;
def SLTU : ALU_3R<0x00128000>;
def SLTI : ALU_2RI12<0x02000000, simm12>;
def SLTUI : ALU_2RI12<0x02400000, simm12>;
-def PCADDI : ALU_1RI20<0x18000000, simm20>;
+def PCADDI : ALU_1RI20<0x18000000, simm20_pcaddi>;
def PCADDU12I : ALU_1RI20<0x1c000000, simm20>;
def PCALAU12I : ALU_1RI20<0x1a000000, simm20_pcalau12i>;
def AND : ALU_3R<0x00148000>;
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h
index 29ed14f6e4d62..370f5b0189b51 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h
@@ -111,6 +111,8 @@ enum Fixups {
fixup_loongarch_relax = FirstLiteralRelocationKind + ELF::R_LARCH_RELAX,
// Generate an R_LARCH_ALIGN which indicates the linker may fixup align here.
fixup_loongarch_align = FirstLiteralRelocationKind + ELF::R_LARCH_ALIGN,
+ // 20-bit fixup corresponding to %pcrel_20(foo) for instruction pcaddi.
+ fixup_loongarch_pcrel20_s2,
// 36-bit fixup corresponding to %call36(foo) for a pair instructions:
// pcaddu18i+jirl.
fixup_loongarch_call36 = FirstLiteralRelocationKind + ELF::R_LARCH_CALL36,
@@ -142,6 +144,12 @@ enum Fixups {
fixup_loongarch_tls_le_add_r,
// 12-bit fixup corresponding to %le_lo12_r(foo) for instruction addi.w/d.
fixup_loongarch_tls_le_lo12_r,
+ // 20-bit fixup corresponding to %ld_pcrel_20(foo) for instruction pcaddi.
+ fixup_loongarch_tls_ld_pcrel20_s2,
+ // 20-bit fixup corresponding to %gd_pcrel_20(foo) for instruction pcaddi.
+ fixup_loongarch_tls_gd_pcrel20_s2,
+ // 20-bit fixup corresponding to %desc_pcrel_20(foo) for instruction pcaddi.
+ fixup_loongarch_tls_desc_pcrel20_s2,
};
} // end namespace LoongArch
} // end namespace llvm
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
index efbfce35dbfca..4f7f93fa4783e 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
@@ -287,6 +287,18 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
case LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12_R:
FixupKind = LoongArch::fixup_loongarch_tls_le_lo12_r;
break;
+ case LoongArchMCExpr::VK_LoongArch_PCREL20_S2:
+ FixupKind = LoongArch::fixup_loongarch_pcrel20_s2;
+ break;
+ case LoongArchMCExpr::VK_LoongArch_TLS_LD_PCREL20_S2:
+ FixupKind = LoongArch::fixup_loongarch_tls_ld_pcrel20_s2;
+ break;
+ case LoongArchMCExpr::VK_LoongArch_TLS_GD_PCREL20_S2:
+ FixupKind = LoongArch::fixup_loongarch_tls_gd_pcrel20_s2;
+ break;
+ case LoongArchMCExpr::VK_LoongArch_TLS_DESC_PCREL20_S2:
+ FixupKind = LoongArch::fixup_loongarch_tls_desc_pcrel20_s2;
+ break;
}
} else if (Kind == MCExpr::SymbolRef &&
cast<MCSymbolRefExpr>(Expr)->getKind() ==
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp
index 98b9b1ab6d3f4..53d46cca913e5 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp
@@ -166,6 +166,14 @@ StringRef LoongArchMCExpr::getVariantKindName(VariantKind Kind) {
return "le_add_r";
case VK_LoongArch_TLS_LE_LO12_R:
return "le_lo12_r";
+ case VK_LoongArch_PCREL20_S2:
+ return "pcrel_20";
+ case VK_LoongArch_TLS_LD_PCREL20_S2:
+ return "ld_pcrel_20";
+ case VK_LoongArch_TLS_GD_PCREL20_S2:
+ return "gd_pcrel_20";
+ case VK_LoongArch_TLS_DESC_PCREL20_S2:
+ return "desc_pcrel_20";
}
}
@@ -222,6 +230,10 @@ LoongArchMCExpr::getVariantKindForName(StringRef name) {
.Case("le_hi20_r", VK_LoongArch_TLS_LE_HI20_R)
.Case("le_add_r", VK_LoongArch_TLS_LE_ADD_R)
.Case("le_lo12_r", VK_LoongArch_TLS_LE_LO12_R)
+ .Case("pcrel_20", VK_LoongArch_PCREL20_S2)
+ .Case("ld_pcrel_20", VK_LoongArch_TLS_LD_PCREL20_S2)
+ .Case("gd_pcrel_20", VK_LoongArch_TLS_GD_PCREL20_S2)
+ .Case("desc_pcrel_20", VK_LoongArch_TLS_DESC_PCREL20_S2)
.Default(VK_LoongArch_Invalid);
}
@@ -264,6 +276,9 @@ void LoongArchMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
case VK_LoongArch_TLS_GD_HI20:
case VK_LoongArch_TLS_DESC_PC_HI20:
case VK_LoongArch_TLS_DESC_HI20:
+ case VK_LoongArch_TLS_LD_PCREL20_S2:
+ case VK_LoongArch_TLS_GD_PCREL20_S2:
+ case VK_LoongArch_TLS_DESC_PCREL20_S2:
break;
}
fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h
index 1546d894d56ab..91215b863ccc2 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h
@@ -75,6 +75,10 @@ class LoongArchMCExpr : public MCTargetExpr {
VK_LoongArch_TLS_LE_HI20_R,
VK_LoongArch_TLS_LE_ADD_R,
VK_LoongArch_TLS_LE_LO12_R,
+ VK_LoongArch_PCREL20_S2,
+ VK_LoongArch_TLS_LD_PCREL20_S2,
+ VK_LoongArch_TLS_GD_PCREL20_S2,
+ VK_LoongArch_TLS_DESC_PCREL20_S2,
VK_LoongArch_Invalid // Must be the last item.
};
diff --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid.s
index 958d5cab6f2f3..08a131d4d43f9 100644
--- a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s
+++ b/llvm/test/MC/LoongArch/Basic/Integer/invalid.s
@@ -99,11 +99,13 @@ jirl $a0, $a0, 0x20000
# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068]
## simm20
-pcaddi $a0, -0x80001
-# CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [-524288, 524287]
pcaddu12i $a0, 0x80000
# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-524288, 524287]
+## simm20_pcaddi
+pcaddi $a0, -0x80001
+# CHECK: :[[#@LINE-1]]:13: error: operand must be a symbol with modifier (e.g. %pcrel_20) or an integer in the range [-524288, 524287]
+
## simm20_lu12iw
lu12i.w $a0, -0x80001
# CHECK: :[[#@LINE-1]]:14: error: operand must be a symbol with modifier (e.g. %abs_hi20) or an integer in the range [-524288, 524287]
diff --git a/llvm/test/MC/LoongArch/Relocations/relocations.s b/llvm/test/MC/LoongArch/Relocations/relocations.s
index e83b67199e656..091dce200b7de 100644
--- a/llvm/test/MC/LoongArch/Relocations/relocations.s
+++ b/llvm/test/MC/LoongArch/Relocations/relocations.s
@@ -288,3 +288,23 @@ addi.d $t1, $a2, %le_lo12_r(foo)
# RELOC: R_LARCH_TLS_LE_LO12_R foo 0x0
# INSTR: addi.d $t1, $a2, %le_lo12_r(foo)
# FIXUP: fixup A - offset: 0, value: %le_lo12_r(foo), kind: FK_NONE
+
+pcaddi $t1, %pcrel_20(foo)
+# RELOC: R_LARCH_PCREL20_S2 foo 0x0
+# INSTR: pcaddi $t1, %pcrel_20(foo)
+# FIXUP: fixup A - offset: 0, value: %pcrel_20(foo), kind: FK_NONE
+
+pcaddi $t1, %ld_pcrel_20(foo)
+# RELOC: R_LARCH_TLS_LD_PCREL20_S2 foo 0x0
+# INSTR: pcaddi $t1, %ld_pcrel_20(foo)
+# FIXUP: fixup A - offset: 0, value: %ld_pcrel_20(foo), kind: FK_NONE
+
+pcaddi $t1, %gd_pcrel_20(foo)
+# RELOC: R_LARCH_TLS_GD_PCREL20_S2 foo 0x0
+# INSTR: pcaddi $t1, %gd_pcrel_20(foo)
+# FIXUP: fixup A - offset: 0, value: %gd_pcrel_20(foo), kind: FK_NONE
+
+pcaddi $t1, %desc_pcrel_20(foo)
+# RELOC: R_LARCH_TLS_DESC_PCREL20_S2 foo 0x0
+# INSTR: pcaddi $t1, %desc_pcrel_20(foo)
+# FIXUP: fixup A - offset: 0, value: %desc_pcrel_20(foo), kind: FK_NONE
More information about the llvm-branch-commits
mailing list