extern rtx riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y);
#endif
extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx);
-extern rtx riscv_legitimize_call_address (rtx);
+extern rtx riscv_legitimize_call_address (rtx, bool);
extern bool riscv_call_needs_lpad_p (rtx);
extern bool riscv_expand_zilsd_misaligned_move (rtx, rtx);
extern bool riscv_zilsd_valid_mem_p (rtx, machine_mode);
std_expand_builtin_va_start (valist, nextarg);
}
-/* Make ADDR suitable for use as a call or sibcall target. */
+/* Make ADDR a valid call target. */
rtx
-riscv_legitimize_call_address (rtx addr)
+riscv_legitimize_call_address (rtx addr, bool sibcall_p)
{
if (!call_insn_operand (addr, VOIDmode))
{
- rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode);
+ rtx reg = sibcall_p
+ ? gen_reg_rtx (Pmode)
+ : RISCV_CALL_ADDRESS_TEMP (Pmode);
riscv_emit_move (reg, addr);
if (is_zicfilp_p ())
(use (match_operand 2 ""))])]
""
{
- rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
+ rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0), true);
emit_call_insn (gen_sibcall_internal (target, operands[1]));
DONE;
})
(use (match_operand 3 ""))])]
""
{
- rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
+ rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0), true);
emit_call_insn (gen_sibcall_value_internal (operands[0], target,
operands[2]));
DONE;
""
{
rtx addr = XEXP (operands[0], 0);
- rtx target = riscv_legitimize_call_address (addr);
+ rtx target = riscv_legitimize_call_address (addr, false);
if (riscv_call_needs_lpad_p (addr))
emit_call_insn (gen_call_internal_cfi (target, operands[1]));
else
""
{
rtx addr = XEXP (operands[1], 0);
- rtx target = riscv_legitimize_call_address (addr);
+ rtx target = riscv_legitimize_call_address (addr, false);
if (riscv_call_needs_lpad_p (addr))
emit_call_insn (gen_call_value_internal_cfi (operands[0], target,
operands[2]));
--- /dev/null
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-options "-O2 -fPIC -fdump-rtl-expand" } */
+
+extern int callee_value (int) __attribute__ ((weak));
+extern void callee_void (int) __attribute__ ((weak));
+
+int
+caller_value (int x)
+{
+ return callee_value (x);
+}
+
+void
+caller_void (int x)
+{
+ callee_void (x);
+}
+
+/* { dg-final { scan-rtl-dump-times {call_insn/j} 2 "expand" } } */
+/* { dg-final { scan-rtl-dump-not {reg:DI 6 t1} "expand" } } */