[llvm-branch-commits] [llvm] [llvm][LoongArch] Add call30 and tail30 macro instruction support (PR #175356)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Jan 10 08:57:22 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: hev (heiher)
<details>
<summary>Changes</summary>
Link: https://sourceware.org/pipermail/binutils/2025-December/146091.html
---
Full diff: https://github.com/llvm/llvm-project/pull/175356.diff
8 Files Affected:
- (modified) llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp (+30-12)
- (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp (+1)
- (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.td (+10)
- (modified) llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp (+3)
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h (+1)
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp (+3)
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp (+1)
- (modified) llvm/test/MC/LoongArch/Macros/macros-call.s (+14-1)
``````````diff
diff --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
index 9b11201d0312d..ef787a9352a9b 100644
--- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
+++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
@@ -171,9 +171,9 @@ class LoongArchAsmParser : public MCTargetAsmParser {
// Helper to emit pseudo instruction "li.w/d $rd, $imm".
void emitLoadImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
- // Helper to emit pseudo instruction "call36 sym" or "tail36 $rj, sym".
- void emitFuncCall36(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
- bool IsTailCall);
+ // Helper to emit pseudo instruction "call{3x} sym" or "tail{3x} $rj, sym".
+ void emitFuncCall(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, bool IsTailCall,
+ bool IsCall36);
public:
enum LoongArchMatchResultTy {
@@ -1465,8 +1465,19 @@ void LoongArchAsmParser::emitLoadImm(MCInst &Inst, SMLoc IDLoc,
}
}
-void LoongArchAsmParser::emitFuncCall36(MCInst &Inst, SMLoc IDLoc,
- MCStreamer &Out, bool IsTailCall) {
+void LoongArchAsmParser::emitFuncCall(MCInst &Inst, SMLoc IDLoc,
+ MCStreamer &Out, bool IsTailCall,
+ bool IsCall36) {
+ // call30 sym
+ // expands to:
+ // pcaddu12i $ra, %call30(sym)
+ // jirl $ra, $ra, 0
+ //
+ // tail30 $rj, sym
+ // expands to:
+ // pcaddu12i $rj, %call30(sym)
+ // jirl $r0, $rj, 0
+ //
// call36 sym
// expands to:
// pcaddu18i $ra, %call36(sym)
@@ -1478,14 +1489,15 @@ void LoongArchAsmParser::emitFuncCall36(MCInst &Inst, SMLoc IDLoc,
// jirl $r0, $rj, 0
MCRegister ScratchReg =
IsTailCall ? Inst.getOperand(0).getReg() : MCRegister(LoongArch::R1);
+ unsigned PCAI = IsCall36 ? LoongArch::PCADDU18I : LoongArch::PCADDU12I;
+ unsigned Rel = IsCall36 ? ELF::R_LARCH_CALL36 : ELF::R_LARCH_CALL30;
const MCExpr *Sym =
IsTailCall ? Inst.getOperand(1).getExpr() : Inst.getOperand(0).getExpr();
- const LoongArchMCExpr *LE = LoongArchMCExpr::create(
- Sym, ELF::R_LARCH_CALL36, getContext(), /*RelaxHint=*/true);
+ const LoongArchMCExpr *LE =
+ LoongArchMCExpr::create(Sym, Rel, getContext(), /*RelaxHint=*/true);
- Out.emitInstruction(
- MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE),
- getSTI());
+ Out.emitInstruction(MCInstBuilder(PCAI).addReg(ScratchReg).addExpr(LE),
+ getSTI());
Out.emitInstruction(
MCInstBuilder(LoongArch::JIRL)
.addReg(IsTailCall ? MCRegister(LoongArch::R0) : ScratchReg)
@@ -1548,11 +1560,17 @@ bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
case LoongArch::PseudoLI_D:
emitLoadImm(Inst, IDLoc, Out);
return false;
+ case LoongArch::PseudoCALL30:
+ emitFuncCall(Inst, IDLoc, Out, /*IsTailCall=*/false, /*IsCall36=*/false);
+ return false;
case LoongArch::PseudoCALL36:
- emitFuncCall36(Inst, IDLoc, Out, /*IsTailCall=*/false);
+ emitFuncCall(Inst, IDLoc, Out, /*IsTailCall=*/false, /*IsCall36=*/true);
+ return false;
+ case LoongArch::PseudoTAIL30:
+ emitFuncCall(Inst, IDLoc, Out, /*IsTailCall=*/true, /*IsCall36=*/false);
return false;
case LoongArch::PseudoTAIL36:
- emitFuncCall36(Inst, IDLoc, Out, /*IsTailCall=*/true);
+ emitFuncCall(Inst, IDLoc, Out, /*IsTailCall=*/true, /*IsCall36=*/true);
return false;
}
Out.emitInstruction(Inst, getSTI());
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
index 9fc862af7ea24..39e105b5db4ce 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
@@ -744,6 +744,7 @@ LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
{MO_IE_PC64_HI, "loongarch-ie-pc64-hi"},
{MO_LD_PC_HI, "loongarch-ld-pc-hi"},
{MO_GD_PC_HI, "loongarch-gd-pc-hi"},
+ {MO_CALL30, "loongarch-call30"},
{MO_CALL36, "loongarch-call36"},
{MO_DESC_PC_HI, "loongarch-desc-pc-hi"},
{MO_DESC_PC_LO, "loongarch-desc-pc-lo"},
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index d971f8bc1986b..26315b13876c8 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -1718,6 +1718,16 @@ def PseudoJIRL_TAIL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>,
PseudoInstExpansion<(JIRL R0, GPR:$rj,
simm16_lsl2:$imm16)>;
+/// call30/tail30 macro instructions
+let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, isAsmParserOnly = 1,
+ Defs = [R1], hasSideEffects = 0, mayStore = 0, mayLoad = 0 in
+def PseudoCALL30 : Pseudo<(outs), (ins bare_symbol:$dst), [], "call30", "$dst">;
+let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3],
+ isCodeGenOnly = 0, isAsmParserOnly = 1, hasSideEffects = 0,
+ mayStore = 0, mayLoad = 0 in
+def PseudoTAIL30 : Pseudo<(outs), (ins GPR:$tmp, bare_symbol:$dst), [],
+ "tail30", "$tmp, $dst">;
+
/// call36/taill36 macro instructions
let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, isAsmParserOnly = 1,
Defs = [R1], hasSideEffects = 0, mayStore = 0, mayLoad = 0 in
diff --git a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
index 455e6ad7c3ac5..ae4090784a9f2 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
@@ -92,6 +92,9 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
case LoongArchII::MO_GD_PC_HI:
Kind = ELF::R_LARCH_TLS_GD_PC_HI20;
break;
+ case LoongArchII::MO_CALL30:
+ Kind = ELF::R_LARCH_CALL30;
+ break;
case LoongArchII::MO_CALL36:
Kind = ELF::R_LARCH_CALL36;
break;
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
index 833cd06261624..99d7df63fce04 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
@@ -48,6 +48,7 @@ enum {
MO_IE_PC64_HI,
MO_LD_PC_HI,
MO_GD_PC_HI,
+ MO_CALL30,
MO_CALL36,
MO_DESC_PC_HI,
MO_DESC_PC_LO,
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
index 8ecb62d0ea7bb..3f9bea5d69bf9 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
@@ -97,6 +97,8 @@ static StringRef getLoongArchSpecifierName(uint16_t S) {
return "gd_pc_hi20";
case ELF::R_LARCH_TLS_GD_HI20:
return "gd_hi20";
+ case ELF::R_LARCH_CALL30:
+ return "call30";
case ELF::R_LARCH_CALL36:
return "call36";
case ELF::R_LARCH_TLS_DESC_PC_HI20:
@@ -174,6 +176,7 @@ LoongArchMCExpr::Specifier LoongArch::parseSpecifier(StringRef name) {
.Case("ld_hi20", ELF::R_LARCH_TLS_LD_HI20)
.Case("gd_pc_hi20", ELF::R_LARCH_TLS_GD_PC_HI20)
.Case("gd_hi20", ELF::R_LARCH_TLS_GD_HI20)
+ .Case("call30", ELF::R_LARCH_CALL30)
.Case("call36", ELF::R_LARCH_CALL36)
.Case("desc_pc_hi20", ELF::R_LARCH_TLS_DESC_PC_HI20)
.Case("desc_pc_lo12", ELF::R_LARCH_TLS_DESC_PC_LO12)
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
index 08fa51d333346..661cf8aae99e4 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
@@ -180,6 +180,7 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
case ELF::R_LARCH_ABS64_HI12:
FixupKind = LoongArch::fixup_loongarch_abs64_hi12;
break;
+ case ELF::R_LARCH_CALL30:
case ELF::R_LARCH_CALL36:
case ELF::R_LARCH_TLS_LE_HI20_R:
case ELF::R_LARCH_TLS_LE_LO12_R:
diff --git a/llvm/test/MC/LoongArch/Macros/macros-call.s b/llvm/test/MC/LoongArch/Macros/macros-call.s
index df7715050a0f9..0fbc2160c14f5 100644
--- a/llvm/test/MC/LoongArch/Macros/macros-call.s
+++ b/llvm/test/MC/LoongArch/Macros/macros-call.s
@@ -7,6 +7,20 @@
# RELOC: Relocations [
# RELOC-NEXT: Section ({{.*}}) .rela.text {
+call30 sym_call
+# CHECK: pcaddu12i $ra, %call30(sym_call)
+# CHECK-NEXT: jirl $ra, $ra, 0
+
+# RELOC-NEXT: R_LARCH_CALL30 sym_call 0x0
+# RELAX-NEXT: R_LARCH_RELAX - 0x0
+
+tail30 $t0, sym_tail
+# CHECK: pcaddu12i $t0, %call30(sym_tail)
+# CHECK-NEXT: jr $t0
+
+# RELOC-NEXT: R_LARCH_CALL30 sym_tail 0x0
+# RELAX-NEXT: R_LARCH_RELAX - 0x0
+
call36 sym_call
# CHECK: pcaddu18i $ra, %call36(sym_call)
# CHECK-NEXT: jirl $ra, $ra, 0
@@ -21,6 +35,5 @@ tail36 $t0, sym_tail
# RELOC-NEXT: R_LARCH_CALL36 sym_tail 0x0
# RELAX-NEXT: R_LARCH_RELAX - 0x0
-
# RELOC-NEXT: }
# RELOC-NEXT: ]
``````````
</details>
https://github.com/llvm/llvm-project/pull/175356
More information about the llvm-branch-commits
mailing list