@@ -3110,7 +3110,7 @@ riscv_legitimize_call_address (rtx addr)
{
if (!call_insn_operand (addr, VOIDmode))
{
- rtx reg = RISCV_PROLOGUE_TEMP (Pmode);
+ rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode);
riscv_emit_move (reg, addr);
return reg;
}
@@ -3707,18 +3707,18 @@ riscv_compute_frame_info (void)
{
struct riscv_frame_info *frame;
HOST_WIDE_INT offset;
- bool interrupt_save_t1 = false;
+ bool interrupt_save_prologue_temp = false;
unsigned int regno, i, num_x_saved = 0, num_f_saved = 0;
frame = &cfun->machine->frame;
/* In an interrupt function, if we have a large frame, then we need to
- save/restore t1. We check for this before clearing the frame struct. */
+ save/restore t0. We check for this before clearing the frame struct. */
if (cfun->machine->interrupt_handler_p)
{
HOST_WIDE_INT step1 = riscv_first_stack_step (frame);
if (! SMALL_OPERAND (frame->total_size - step1))
- interrupt_save_t1 = true;
+ interrupt_save_prologue_temp = true;
}
memset (frame, 0, sizeof (*frame));
@@ -3728,7 +3728,8 @@ riscv_compute_frame_info (void)
/* Find out which GPRs we need to save. */
for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
if (riscv_save_reg_p (regno)
- || (interrupt_save_t1 && (regno == T1_REGNUM)))
+ || (interrupt_save_prologue_temp
+ && (regno == RISCV_PROLOGUE_TEMP_REGNUM)))
frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
/* If this function calls eh_return, we must also save and restore the
@@ -4902,9 +4903,9 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
rtx target_function = force_reg (Pmode, XEXP (DECL_RTL (fndecl), 0));
/* lui t2, hi(chain)
- lui t1, hi(func)
+ lui t0, hi(func)
addi t2, t2, lo(chain)
- jr r1, lo(func)
+ jr t0, lo(func)
*/
unsigned HOST_WIDE_INT lui_hi_chain_code, lui_hi_func_code;
unsigned HOST_WIDE_INT lo_chain_code, lo_func_code;
@@ -4929,7 +4930,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
mem = adjust_address (m_tramp, SImode, 0);
riscv_emit_move (mem, lui_hi_chain);
- /* Gen lui t1, hi(func). */
+ /* Gen lui t0, hi(func). */
rtx hi_func = riscv_force_binary (SImode, PLUS, target_function,
fixup_value);
hi_func = riscv_force_binary (SImode, AND, hi_func,
@@ -4956,7 +4957,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode));
riscv_emit_move (mem, addi_lo_chain);
- /* Gen jr r1, lo(func). */
+ /* Gen jr t0, lo(func). */
rtx lo_func = riscv_force_binary (SImode, AND, target_function,
imm12_mask);
lo_func = riscv_force_binary (SImode, ASHIFT, lo_func, GEN_INT (20));
@@ -4975,9 +4976,9 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
/* auipc t2, 0
- l[wd] t1, target_function_offset(t2)
+ l[wd] t0, target_function_offset(t2)
l[wd] t2, static_chain_offset(t2)
- jr t1
+ jr t0
*/
trampoline[0] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD);
trampoline[1] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
@@ -342,9 +342,13 @@ extern const char *riscv_default_mtune (int argc, const char **argv);
The epilogue temporary mustn't conflict with the return registers,
the frame pointer, the EH stack adjustment, or the EH data registers. */
-#define RISCV_PROLOGUE_TEMP_REGNUM (GP_TEMP_FIRST + 1)
+#define RISCV_PROLOGUE_TEMP_REGNUM (GP_TEMP_FIRST)
#define RISCV_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, RISCV_PROLOGUE_TEMP_REGNUM)
+#define RISCV_CALL_ADDRESS_TEMP_REGNUM (GP_TEMP_FIRST + 1)
+#define RISCV_CALL_ADDRESS_TEMP(MODE) \
+ gen_rtx_REG (MODE, RISCV_CALL_ADDRESS_TEMP_REGNUM)
+
#define MCOUNT_NAME "_mcount"
#define NO_PROFILE_COUNTERS 1
new file mode 100644
@@ -0,0 +1,160 @@
+/* PR target/97682 */
+/* { dg-do compile } */
+/* { dg-options "-fPIC -O2 -march=rv64g -mabi=lp64" } */
+
+template <typename ab, int ac> struct g { ab b[ac]; };
+long i, m;
+
+namespace std
+{
+ template <typename c> struct t
+ {
+ int a;
+ c h;
+ };
+
+ struct ad
+ {
+ enum { j };
+ };
+
+ template <typename k> k l(k);
+ struct al {};
+ template <typename k> k aa(k);
+
+ struct v
+ {
+ template <typename n, typename q> static q o(n, n, q);
+ };
+
+ template <int, typename n, typename q> void p(n z, n ao, q ap)
+ {
+ v::o(z, ao, ap);
+ }
+
+ template <int ae, typename n, typename q> void r(n z, n ao, q ap)
+ {
+ p<ae>(z, ao, ap);
+ }
+
+ template <int ae, typename n, typename q> void af(n z, n ao, q)
+ {
+ r<ae>(aa(z), aa(ao), 0);
+ }
+
+ template <typename n, typename q> void ag(n z, n ao, q ap)
+ {
+ af<ad::j>(l(z), l(ao), ap);
+ }
+
+ template <typename> class allocator;
+ template <typename ah, typename ai, typename aj> void ak(ah, ai, aj);
+
+ template <typename s> class aq
+ {
+ template <typename am> struct ar { using f = am *; };
+ public:
+ using an = typename ar<s>::f;
+ };
+
+ template <typename s> class as
+ {
+ public:
+ using an = typename aq<s>::an;
+ an operator->();
+ };
+
+ struct ay
+ {
+ int at();
+ };
+
+ template <typename s, typename = allocator<s>> class vector : ay
+ {
+ public:
+ long au();
+ long x;
+ void av() { _M_default_append(x); }
+ void _M_default_append(unsigned long);
+ void aw();
+ long ax(int);
+ };
+
+ template <typename s, typename y>
+ void vector<s, y>::_M_default_append(unsigned long z)
+ {
+ long az = au();
+ int w = at(), bc = at();
+ i = ax(w);
+ m = ax(w);
+ if (i || m)
+ aw();
+ ak(az, z, bc);
+ }
+}
+
+namespace llvm
+{
+ template <int bd> class bh
+ {
+ enum { bf = bd } * bg[bf];
+ };
+
+ template <class> class bi;
+
+ class bm
+ {
+ using bj = bi<int>;
+ std::as<bj> bk;
+ void bl();
+ };
+
+ template <class> struct bn;
+
+ class br
+ {
+ bh<8> bo;
+ };
+
+ class ca
+ {
+ int *d;
+ int e;
+ };
+
+ template <class bp> class bv : std::al, br
+ {
+ g<std::t<ca>, 8> b;
+ };
+
+ template <class ab> bv<ab> bt(ab);
+
+ class BlockFrequencyInfoImplBase
+ {
+ public:
+ struct FrequencyData;
+ std::vector<FrequencyData> bu;
+ };
+
+ template <class> struct cb { using bw = int; };
+ template <class bx> class bi : BlockFrequencyInfoImplBase
+ {
+ using bw = typename cb<bx>::bw;
+ public:
+ void bl();
+ };
+
+ template <class bx> void bi<bx>::bl()
+ {
+ const bw *by;
+ bv<const int *> bz;
+ ag(bz, bt(by), 0);
+ bu.av();
+ }
+
+ template <> struct bn<const int *> { using u = ca; };
+ void bm::bl() { bk->bl(); }
+}
+
+/* The t1 register is to initial symbol reference for call instruction. */
+/* { dg-final { scan-assembler "la\tt1,.*FrequencyData.*_M_default_append.*" } } */
@@ -1,4 +1,4 @@
-/* Verify t1 is saved before use. */
+/* Verify t0 is saved before use. */
/* { dg-do compile } */
/* { dg-options "-O0 -fomit-frame-pointer" } */
void __attribute__ ((interrupt))
@@ -6,4 +6,4 @@ foo (void)
{
char array[4096];
}
-/* { dg-final { scan-assembler "s\[wd\]\tt1" } } */
+/* { dg-final { scan-assembler "s\[wd\]\tt0" } } */
@@ -1,4 +1,4 @@
-/* Verify t1 is saved before use. */
+/* Verify t0 is saved before use. */
/* { dg-do compile } */
/* { dg-options "-O0 -fomit-frame-pointer" } */
void __attribute__ ((interrupt))
@@ -15,4 +15,4 @@ foo2 (void)
COUNTER++;
#endif
}
-/* { dg-final { scan-assembler "s\[wd\]\tt1" } } */
+/* { dg-final { scan-assembler "s\[wd\]\tt0" } } */