From: Marcus Comstedt Date: Fri, 19 Mar 2021 19:49:06 +0000 (+0100) Subject: RISC-V: Fix trampoline generation on big endian X-Git-Tag: basepoints/gcc-12~477 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=28bddf0e322a5fdc33d3dcc3b9928d559ad7f124;p=thirdparty%2Fgcc.git RISC-V: Fix trampoline generation on big endian gcc/ * config/riscv/riscv.c (riscv_swap_instruction): New function to byteswap an SImode rtx containing an instruction. (riscv_trampoline_init): Byteswap the generated instructions when needed. --- diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 99b843867b5b..fe48db7a2798 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -1073,6 +1073,15 @@ riscv_force_binary (machine_mode mode, enum rtx_code code, rtx x, rtx y) return riscv_emit_binary (code, gen_reg_rtx (mode), x, y); } +static rtx +riscv_swap_instruction (rtx inst) +{ + gcc_assert (GET_MODE (inst) == SImode); + if (BYTES_BIG_ENDIAN) + inst = expand_unop (SImode, bswap_optab, inst, gen_reg_rtx (SImode), 1); + return inst; +} + /* Copy VALUE to a register and return that register. If new pseudos are allowed, copy it into a new register, otherwise use DEST. */ @@ -4955,7 +4964,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) gen_int_mode (lui_hi_chain_code, SImode)); mem = adjust_address (m_tramp, SImode, 0); - riscv_emit_move (mem, lui_hi_chain); + riscv_emit_move (mem, riscv_swap_instruction (lui_hi_chain)); /* Gen lui t0, hi(func). */ rtx hi_func = riscv_force_binary (SImode, PLUS, target_function, @@ -4967,7 +4976,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) gen_int_mode (lui_hi_func_code, SImode)); mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode)); - riscv_emit_move (mem, lui_hi_func); + riscv_emit_move (mem, riscv_swap_instruction (lui_hi_func)); /* Gen addi t2, t2, lo(chain). */ rtx lo_chain = riscv_force_binary (SImode, AND, chain_value, @@ -4982,7 +4991,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) force_reg (SImode, GEN_INT (lo_chain_code))); mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode)); - riscv_emit_move (mem, addi_lo_chain); + riscv_emit_move (mem, riscv_swap_instruction (addi_lo_chain)); /* Gen jr t0, lo(func). */ rtx lo_func = riscv_force_binary (SImode, AND, target_function, @@ -4995,7 +5004,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) force_reg (SImode, GEN_INT (lo_func_code))); mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode)); - riscv_emit_move (mem, jr_lo_func); + riscv_emit_move (mem, riscv_swap_instruction (jr_lo_func)); } else { @@ -5021,6 +5030,8 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) /* Copy the trampoline code. */ for (i = 0; i < ARRAY_SIZE (trampoline); i++) { + if (BYTES_BIG_ENDIAN) + trampoline[i] = __builtin_bswap32(trampoline[i]); mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode)); riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode)); }