Currently, gcc-13 will generate such assembly when `-mcmodel=medium`,
which is ostensibly a dirty hack to allow bigger offsets for extern
function calls without having to add more reloc types. This is not the
best way to accomplish the original goal, but such usages will appear
soon and we have to support it anyway.
Example:
```c
extern int foo(int);
int bar(int x) {
return foo(x + 123);
}
```
will produce the following (simplified) assembly when compiled with
`-O2 -mcmodel=medium`:
```
.globl bar
.type bar, @function
bar:
.cfi_startproc
addi.w $r4,$r4,123
pcalau12i $r12,%pc_hi20(foo)
jirl $r0,$r12,%pc_lo12(foo)
.cfi_endproc
```
Reviewed By: SixWeining, wangleiat, MaskRay, xry111
Differential Revision: https://reviews.llvm.org/D142278
LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None;
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None ||
- VK == LoongArchMCExpr::VK_LoongArch_B16;
+ VK == LoongArchMCExpr::VK_LoongArch_B16 ||
+ VK == LoongArchMCExpr::VK_LoongArch_PCALA_LO12;
return IsConstantImm
? isShiftedInt<16, 2>(Imm) && IsValidKind
: LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
# INSTR: addi.d $t1, $t1, %pc_lo12(foo+4)
# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo+4), kind: FK_NONE
+jirl $zero, $t1, %pc_lo12(foo)
+# RELOC: R_LARCH_PCALA_LO12 foo 0x0
+# INSTR: jirl $zero, $t1, %pc_lo12(foo)
+# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo), kind: FK_NONE
+
st.b $t1, $a2, %pc_lo12(foo)
# RELOC: R_LARCH_PCALA_LO12 foo 0x0
# INSTR: st.b $t1, $a2, %pc_lo12(foo)