extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
extern int ix86_expand_int_movcc PARAMS ((rtx[]));
extern int ix86_expand_fp_movcc PARAMS ((rtx[]));
+extern void x86_initialize_trampoline PARAMS ((rtx, rtx, rtx));
extern void ix86_split_long_move PARAMS ((rtx[]));
extern void ix86_split_ashldi PARAMS ((rtx *, rtx));
extern void ix86_split_ashrdi PARAMS ((rtx *, rtx));
/* Length in units of the trampoline for entering a nested function. */
-#define TRAMPOLINE_SIZE 10
+#define TRAMPOLINE_SIZE (TARGET_64BIT ? 23 : 10)
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function. */
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-{ \
- /* Compute offset from the end of the jmp to the target function. */ \
- rtx disp = expand_binop (SImode, sub_optab, FNADDR, \
- plus_constant (TRAMP, 10), \
- NULL_RTX, 1, OPTAB_DIRECT); \
- emit_move_insn (gen_rtx_MEM (QImode, TRAMP), GEN_INT (0xb9)); \
- emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 1)), CXT); \
- emit_move_insn (gen_rtx_MEM (QImode, plus_constant (TRAMP, 5)), GEN_INT (0xe9));\
- emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 6)), disp); \
-}
+ x86_initialize_trampoline (TRAMP, FNADDR, CXT)
\f
/* Definitions for register eliminations.
(define_expand "call"
[(call (match_operand:QI 0 "" "")
- (match_operand 2 "" ""))]
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))]
;; Operand 1 not used on the i386.
""
"
{
+ rtx insn;
/* Static functions and indirect calls don't need
current_function_uses_pic_offset_table. */
if (flag_pic
XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
{
- rtx insn;
rtx reg = gen_rtx_REG (QImode, 0);
emit_move_insn (reg, operands[2]);
- insn = emit_call_insn (gen_call_exp (operands[0], operands[2]));
+ insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
DONE;
}
+ insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
+ DONE;
}")
(define_expand "call_exp"
(define_expand "call_value"
[(set (match_operand 0 "" "")
(call (match_operand:QI 1 "" "")
- (match_operand:SI 3 "" "")))]
+ (match_operand:SI 2 "" "")))
+ (use (match_operand:SI 3 "" ""))]
;; Operand 2 not used on the i386.
""
"
{
+ rtx insn;
/* Static functions and indirect calls don't need
current_function_uses_pic_offset_table. */
if (flag_pic
XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
{
- rtx insn;
rtx reg = gen_rtx_REG (QImode, 0);
emit_move_insn (reg, operands[3]);
insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
- operands[3]));
+ operands[2]));
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
DONE;
}
+ insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
+ operands[2]));
+ DONE;
}")
(define_expand "call_value_exp"