Hello! A small cleanup, no functional change. This allows us to assert that generated code length is less than TRAMPOLINE_SIZE also for 32bit targets.
2011-07-11 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.c (ix86_trampoline_init): Switch arms of if expr. Use offset everywhere. Always assert that offset <= TRAMPOLINE_SIZE. Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline. Uros.
Index: i386.c =================================================================== --- i386.c (revision 176159) +++ i386.c (working copy) @@ -22683,54 +22683,14 @@ static void ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) { rtx mem, fnaddr; + int opcode; + int offset = 0; fnaddr = XEXP (DECL_RTL (fndecl), 0); - if (!TARGET_64BIT) - { - rtx disp, chain; - int opcode; - - /* Depending on the static chain location, either load a register - with a constant, or push the constant to the stack. All of the - instructions are the same size. */ - chain = ix86_static_chain (fndecl, true); - if (REG_P (chain)) - { - if (REGNO (chain) == CX_REG) - opcode = 0xb9; - else if (REGNO (chain) == AX_REG) - opcode = 0xb8; - else - gcc_unreachable (); - } - else - opcode = 0x68; - - mem = adjust_address (m_tramp, QImode, 0); - emit_move_insn (mem, gen_int_mode (opcode, QImode)); - - mem = adjust_address (m_tramp, SImode, 1); - emit_move_insn (mem, chain_value); - - /* Compute offset from the end of the jmp to the target function. - In the case in which the trampoline stores the static chain on - the stack, we need to skip the first insn which pushes the - (call-saved) register static chain; this push is 1 byte. */ - disp = expand_binop (SImode, sub_optab, fnaddr, - plus_constant (XEXP (m_tramp, 0), - MEM_P (chain) ? 9 : 10), - NULL_RTX, 1, OPTAB_DIRECT); - - mem = adjust_address (m_tramp, QImode, 5); - emit_move_insn (mem, gen_int_mode (0xe9, QImode)); - - mem = adjust_address (m_tramp, SImode, 6); - emit_move_insn (mem, disp); - } - else + if (TARGET_64BIT) { - int offset = 0, size; + int size; /* Load the function address to r11. Try to load address using the shorter movl instead of movabs. We may want to support @@ -22757,20 +22717,22 @@ ix86_trampoline_init (rtx m_tramp, tree offset += 10; } - /* Load static chain using movabs to r10. */ - mem = adjust_address (m_tramp, HImode, offset); - /* Use the shorter movl instead of movabs for x32. */ + /* Load static chain using movabs to r10. Use the + shorter movl instead of movabs for x32. */ if (TARGET_X32) { + opcode = 0xba41; size = 6; - emit_move_insn (mem, gen_int_mode (0xba41, HImode)); } else { + opcode = 0xba49; size = 10; - emit_move_insn (mem, gen_int_mode (0xba49, HImode)); } + mem = adjust_address (m_tramp, HImode, offset); + emit_move_insn (mem, gen_int_mode (opcode, HImode)); + mem = adjust_address (m_tramp, ptr_mode, offset + 2); emit_move_insn (mem, chain_value); offset += size; @@ -22780,10 +22742,56 @@ ix86_trampoline_init (rtx m_tramp, tree mem = adjust_address (m_tramp, SImode, offset); emit_move_insn (mem, gen_int_mode (0x90e3ff49, SImode)); offset += 4; + } + else + { + rtx disp, chain; - gcc_assert (offset <= TRAMPOLINE_SIZE); + /* Depending on the static chain location, either load a register + with a constant, or push the constant to the stack. All of the + instructions are the same size. */ + chain = ix86_static_chain (fndecl, true); + if (REG_P (chain)) + { + switch (REGNO (chain)) + { + case AX_REG: + opcode = 0xb8; break; + case CX_REG: + opcode = 0xb9; break; + default: + gcc_unreachable (); + } + } + else + opcode = 0x68; + + mem = adjust_address (m_tramp, QImode, offset); + emit_move_insn (mem, gen_int_mode (opcode, QImode)); + + mem = adjust_address (m_tramp, SImode, offset + 1); + emit_move_insn (mem, chain_value); + offset += 5; + + mem = adjust_address (m_tramp, QImode, offset); + emit_move_insn (mem, gen_int_mode (0xe9, QImode)); + + mem = adjust_address (m_tramp, SImode, offset + 1); + + /* Compute offset from the end of the jmp to the target function. + In the case in which the trampoline stores the static chain on + the stack, we need to skip the first insn which pushes the + (call-saved) register static chain; this push is 1 byte. */ + offset += 5; + disp = expand_binop (SImode, sub_optab, fnaddr, + plus_constant (XEXP (m_tramp, 0), + offset - (MEM_P (chain) ? 1 : 0)), + NULL_RTX, 1, OPTAB_DIRECT); + emit_move_insn (mem, disp); } + gcc_assert (offset <= TRAMPOLINE_SIZE); + #ifdef HAVE_ENABLE_EXECUTE_STACK #ifdef CHECK_EXECUTE_STACK_ENABLED if (CHECK_EXECUTE_STACK_ENABLED)