From: Bob Wilson Date: Fri, 22 Nov 2002 00:23:31 +0000 (+0000) Subject: xtensa-protos.h (xtensa_copy_incoming_a7): Declare. X-Git-Tag: releases/gcc-3.3.0~1681 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=58db834b27756ef397b96597ce0a541d8ae89dec;p=thirdparty%2Fgcc.git xtensa-protos.h (xtensa_copy_incoming_a7): Declare. * config/xtensa/xtensa-protos.h (xtensa_copy_incoming_a7): Declare. * config/xtensa/xtensa.c (struct machine_function): Add incoming_a7_copied flag. (xtensa_copy_incoming_a7): Define. (xtensa_emit_move_sequence): Use xtensa_copy_incoming_a7. * config/xtensa/xtensa.md (movdi, movsf, movdf): Ditto. From-SVN: r59364 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3672f9bd4f7..ab62b5063aa0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2002-11-21 Bob Wilson + + * config/xtensa/xtensa-protos.h (xtensa_copy_incoming_a7): Declare. + * config/xtensa/xtensa.c (struct machine_function): Add + incoming_a7_copied flag. + (xtensa_copy_incoming_a7): Define. + (xtensa_emit_move_sequence): Use xtensa_copy_incoming_a7. + * config/xtensa/xtensa.md (movdi, movsf, movdf): Ditto. + Thu Nov 21 23:52:04 CET 2002 Jan Hubicka * i386-protos.h (x86_64_sign_extended_value): Fix prototype. diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index 051c81e6939d..195d71da6426 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -70,6 +70,7 @@ extern int xtensa_expand_conditional_move PARAMS ((rtx *, int)); extern int xtensa_expand_scc PARAMS ((rtx *)); extern int xtensa_expand_block_move PARAMS ((rtx *)); extern int xtensa_emit_move_sequence PARAMS ((rtx *, enum machine_mode)); +extern bool xtensa_copy_incoming_a7 PARAMS ((rtx *, enum machine_mode)); extern void xtensa_emit_block_move PARAMS ((rtx *, rtx *, int)); extern void xtensa_expand_nonlocal_goto PARAMS ((rtx *)); extern void xtensa_emit_loop_end PARAMS ((rtx, rtx *)); diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index ae7c994d9a85..babb5b06a515 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -90,6 +90,7 @@ const char *xtensa_st_opcodes[(int) MAX_MACHINE_MODE]; struct machine_function GTY(()) { int accesses_prev_frame; + bool incoming_a7_copied; }; /* Vector, indexed by hard register number, which contains 1 for a @@ -1275,45 +1276,8 @@ xtensa_emit_move_sequence (operands, mode) if (!xtensa_valid_move (mode, operands)) operands[1] = force_reg (mode, operands[1]); - /* Check if this move is copying an incoming argument in a7. If - so, emit the move, followed by the special "set_frame_ptr" - unspec_volatile insn, at the very beginning of the function. - This is necessary because the register allocator will ignore - conflicts with a7 and may assign some other pseudo to a7. If - that pseudo was assigned prior to this move, it would clobber - the incoming argument in a7. By copying the argument out of - a7 as the very first thing, and then immediately following - that with an unspec_volatile to keep the scheduler away, we - should avoid any problems. */ - - if (a7_overlap_mentioned_p (operands[1])) - { - rtx mov; - switch (mode) - { - case SImode: - mov = gen_movsi_internal (operands[0], operands[1]); - break; - case HImode: - mov = gen_movhi_internal (operands[0], operands[1]); - break; - case QImode: - mov = gen_movqi_internal (operands[0], operands[1]); - break; - default: - abort (); - } - - /* Insert the instructions before any other argument copies. - (The set_frame_ptr insn comes _after_ the move, so push it - out first.) */ - push_topmost_sequence (); - emit_insn_after (gen_set_frame_ptr (), get_insns ()); - emit_insn_after (mov, get_insns ()); - pop_topmost_sequence (); - - return 1; - } + if (xtensa_copy_incoming_a7 (operands, mode)) + return 1; } /* During reload we don't want to emit (subreg:X (mem:Y)) since that @@ -1345,6 +1309,74 @@ fixup_subreg_mem (x) } +/* Check if this move is copying an incoming argument in a7. If so, + emit the move, followed by the special "set_frame_ptr" + unspec_volatile insn, at the very beginning of the function. This + is necessary because the register allocator will ignore conflicts + with a7 and may assign some other pseudo to a7. If that pseudo was + assigned prior to this move, it would clobber the incoming argument + in a7. By copying the argument out of a7 as the very first thing, + and then immediately following that with an unspec_volatile to keep + the scheduler away, we should avoid any problems. */ + +bool +xtensa_copy_incoming_a7 (operands, mode) + rtx *operands; + enum machine_mode mode; +{ + if (a7_overlap_mentioned_p (operands[1]) + && !cfun->machine->incoming_a7_copied) + { + rtx mov; + switch (mode) + { + case DFmode: + mov = gen_movdf_internal (operands[0], operands[1]); + break; + case SFmode: + mov = gen_movsf_internal (operands[0], operands[1]); + break; + case DImode: + mov = gen_movdi_internal (operands[0], operands[1]); + break; + case SImode: + mov = gen_movsi_internal (operands[0], operands[1]); + break; + case HImode: + mov = gen_movhi_internal (operands[0], operands[1]); + break; + case QImode: + mov = gen_movqi_internal (operands[0], operands[1]); + break; + default: + abort (); + } + + /* Insert the instructions before any other argument copies. + (The set_frame_ptr insn comes _after_ the move, so push it + out first.) */ + push_topmost_sequence (); + emit_insn_after (gen_set_frame_ptr (), get_insns ()); + emit_insn_after (mov, get_insns ()); + pop_topmost_sequence (); + + /* Ideally the incoming argument in a7 would only be copied + once, since propagating a7 into the body of a function + will almost certainly lead to errors. However, there is + at least one harmless case (in GCSE) where the original + copy from a7 is changed to copy into a new pseudo. Thus, + we use a flag to only do this special treatment for the + first copy of a7. */ + + cfun->machine->incoming_a7_copied = true; + + return 1; + } + + return 0; +} + + /* Try to expand a block move operation to an RTL block move instruction. If not optimizing or if the block size is not a constant or if the block is small, the expansion fails and GCC falls back to calling diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index d4f8c84852e0..5db5c0ca487d 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -929,12 +929,8 @@ && !register_operand (operands[1], DImode)) operands[1] = force_reg (DImode, operands[1]); - if (a7_overlap_mentioned_p (operands[1])) - { - emit_insn (gen_movdi_internal (operands[0], operands[1])); - emit_insn (gen_set_frame_ptr ()); - DONE; - } + if (xtensa_copy_incoming_a7 (operands, DImode)) + DONE; } }") @@ -1107,12 +1103,8 @@ && constantpool_mem_p (operands[1])))) operands[1] = force_reg (SFmode, operands[1]); - if (a7_overlap_mentioned_p (operands[1])) - { - emit_insn (gen_movsf_internal (operands[0], operands[1])); - emit_insn (gen_set_frame_ptr ()); - DONE; - } + if (xtensa_copy_incoming_a7 (operands, SFmode)) + DONE; } }") @@ -1193,12 +1185,8 @@ && !register_operand (operands[1], DFmode)) operands[1] = force_reg (DFmode, operands[1]); - if (a7_overlap_mentioned_p (operands[1])) - { - emit_insn (gen_movdf_internal (operands[0], operands[1])); - emit_insn (gen_set_frame_ptr ()); - DONE; - } + if (xtensa_copy_incoming_a7 (operands, DFmode)) + DONE; } }")