diff options
Diffstat (limited to 'contrib/gcc/explow.c')
-rw-r--r-- | contrib/gcc/explow.c | 256 |
1 files changed, 74 insertions, 182 deletions
diff --git a/contrib/gcc/explow.c b/contrib/gcc/explow.c index 0d9139a..c1de4c8 100644 --- a/contrib/gcc/explow.c +++ b/contrib/gcc/explow.c @@ -1,6 +1,6 @@ /* Subroutines for manipulating rtx's in semantically interesting ways. Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "toplev.h" #include "rtl.h" #include "tree.h" @@ -36,16 +38,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "recog.h" #include "langhooks.h" -static rtx break_out_memory_refs PARAMS ((rtx)); -static void emit_stack_probe PARAMS ((rtx)); +static rtx break_out_memory_refs (rtx); +static void emit_stack_probe (rtx); /* Truncate and perhaps sign-extend C as appropriate for MODE. */ HOST_WIDE_INT -trunc_int_for_mode (c, mode) - HOST_WIDE_INT c; - enum machine_mode mode; +trunc_int_for_mode (HOST_WIDE_INT c, enum machine_mode mode) { int width = GET_MODE_BITSIZE (mode); @@ -76,9 +76,7 @@ trunc_int_for_mode (c, mode) This function should be used via the `plus_constant' macro. */ rtx -plus_constant_wide (x, c) - rtx x; - HOST_WIDE_INT c; +plus_constant_wide (rtx x, HOST_WIDE_INT c) { RTX_CODE code; rtx y; @@ -204,9 +202,7 @@ plus_constant_wide (x, c) it is not isomorphic to X. */ rtx -eliminate_constant_term (x, constptr) - rtx x; - rtx *constptr; +eliminate_constant_term (rtx x, rtx *constptr) { rtx x0, x1; rtx tem; @@ -239,61 +235,14 @@ eliminate_constant_term (x, constptr) return x; } -/* Returns the insn that next references REG after INSN, or 0 - if REG is clobbered before next referenced or we cannot find - an insn that references REG in a straight-line piece of code. */ - -rtx -find_next_ref (reg, insn) - rtx reg; - rtx insn; -{ - rtx next; - - for (insn = NEXT_INSN (insn); insn; insn = next) - { - next = NEXT_INSN (insn); - if (GET_CODE (insn) == NOTE) - continue; - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - return 0; - if (GET_CODE (insn) == INSN - || GET_CODE (insn) == JUMP_INSN - || GET_CODE (insn) == CALL_INSN) - { - if (reg_set_p (reg, insn)) - return 0; - if (reg_mentioned_p (reg, PATTERN (insn))) - return insn; - if (GET_CODE (insn) == JUMP_INSN) - { - if (any_uncondjump_p (insn)) - next = JUMP_LABEL (insn); - else - return 0; - } - if (GET_CODE (insn) == CALL_INSN - && REGNO (reg) < FIRST_PSEUDO_REGISTER - && call_used_regs[REGNO (reg)]) - return 0; - } - else - abort (); - } - return 0; -} - /* Return an rtx for the size in bytes of the value of EXP. */ rtx -expr_size (exp) - tree exp; +expr_size (tree exp) { tree size = (*lang_hooks.expr_size) (exp); - if (TREE_CODE (size) != INTEGER_CST - && contains_placeholder_p (size)) + if (CONTAINS_PLACEHOLDER_P (size)) size = build (WITH_RECORD_EXPR, sizetype, size, exp); return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0); @@ -303,8 +252,7 @@ expr_size (exp) if the size can vary or is larger than an integer. */ HOST_WIDE_INT -int_expr_size (exp) - tree exp; +int_expr_size (tree exp) { tree t = (*lang_hooks.expr_size) (exp); @@ -336,8 +284,7 @@ int_expr_size (exp) Values returned by expand_expr with 1 for sum_ok fit this constraint. */ static rtx -break_out_memory_refs (x) - rtx x; +break_out_memory_refs (rtx x) { if (GET_CODE (x) == MEM || (CONSTANT_P (x) && CONSTANT_ADDRESS_P (x) @@ -356,8 +303,6 @@ break_out_memory_refs (x) return x; } -#ifdef POINTERS_EXTEND_UNSIGNED - /* Given X, a memory address in ptr_mode, convert it to an address in Pmode, or vice versa (TO_MODE says which way). We take advantage of the fact that pointers are not allowed to overflow by commuting arithmetic @@ -365,14 +310,22 @@ break_out_memory_refs (x) used. */ rtx -convert_memory_address (to_mode, x) - enum machine_mode to_mode; - rtx x; +convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED, + rtx x) { - enum machine_mode from_mode = to_mode == ptr_mode ? Pmode : ptr_mode; +#ifndef POINTERS_EXTEND_UNSIGNED + return x; +#else /* defined(POINTERS_EXTEND_UNSIGNED) */ + enum machine_mode from_mode; rtx temp; enum rtx_code code; + /* If X already has the right mode, just return it. */ + if (GET_MODE (x) == to_mode) + return x; + + from_mode = to_mode == ptr_mode ? Pmode : ptr_mode; + /* Here we handle some special cases. If none of them apply, fall through to the default case. */ switch (GET_CODE (x)) @@ -436,8 +389,8 @@ convert_memory_address (to_mode, x) return convert_modes (to_mode, from_mode, x, POINTERS_EXTEND_UNSIGNED); +#endif /* defined(POINTERS_EXTEND_UNSIGNED) */ } -#endif /* Given a memory address or facsimile X, construct a new address, currently equivalent, that is stable: future stores won't change it. @@ -453,8 +406,7 @@ convert_memory_address (to_mode, x) but then you wouldn't get indexed addressing in the reference. */ rtx -copy_all_regs (x) - rtx x; +copy_all_regs (rtx x) { if (GET_CODE (x) == REG) { @@ -483,21 +435,16 @@ copy_all_regs (x) works by copying X or subexpressions of it into registers. */ rtx -memory_address (mode, x) - enum machine_mode mode; - rtx x; +memory_address (enum machine_mode mode, rtx x) { rtx oldx = x; if (GET_CODE (x) == ADDRESSOF) return x; -#ifdef POINTERS_EXTEND_UNSIGNED - if (GET_MODE (x) != Pmode) - x = convert_memory_address (Pmode, x); -#endif + x = convert_memory_address (Pmode, x); - /* By passing constant addresses thru registers + /* By passing constant addresses through registers we get a chance to cse them. */ if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x)) x = force_reg (Pmode, x); @@ -613,9 +560,7 @@ memory_address (mode, x) /* Like `memory_address' but pretend `flag_force_addr' is 0. */ rtx -memory_address_noforce (mode, x) - enum machine_mode mode; - rtx x; +memory_address_noforce (enum machine_mode mode, rtx x) { int ambient_force_addr = flag_force_addr; rtx val; @@ -630,8 +575,7 @@ memory_address_noforce (mode, x) Pass through anything else unchanged. */ rtx -validize_mem (ref) - rtx ref; +validize_mem (rtx ref) { if (GET_CODE (ref) != MEM) return ref; @@ -648,28 +592,17 @@ validize_mem (ref) appropriate. */ void -maybe_set_unchanging (ref, t) - rtx ref; - tree t; +maybe_set_unchanging (rtx ref, tree t) { /* We can set RTX_UNCHANGING_P from TREE_READONLY for decls whose initialization is only executed once, or whose initializer always has the same value. Currently we simplify this to PARM_DECLs in the - first case, and decls with TREE_CONSTANT initializers in the second. - - We cannot do this for non-static aggregates, because of the double - writes that can be generated by store_constructor, depending on the - contents of the initializer. Yes, this does eliminate a good fraction - of the number of uses of RTX_UNCHANGING_P for a language like Ada. - It also eliminates a good quantity of bugs. Let this be incentive to - eliminate RTX_UNCHANGING_P entirely in favour of a more reliable - solution, perhaps based on alias sets. */ + first case, and decls with TREE_CONSTANT initializers in the second. */ if ((TREE_READONLY (t) && DECL_P (t) - && (TREE_STATIC (t) || ! AGGREGATE_TYPE_P (TREE_TYPE (t))) - && (TREE_CODE (t) == PARM_DECL - || DECL_INITIAL (t) == NULL_TREE - || TREE_CONSTANT (DECL_INITIAL (t)))) + && (DECL_EXTERNAL (t) + || TREE_CODE (t) == PARM_DECL + || (DECL_INITIAL (t) && TREE_CONSTANT (DECL_INITIAL (t))))) || TREE_CODE_CLASS (TREE_CODE (t)) == 'c') RTX_UNCHANGING_P (ref) = 1; } @@ -680,10 +613,8 @@ maybe_set_unchanging (ref, t) Perhaps even if it is a MEM, if there is no need to change it. */ rtx -stabilize (x) - rtx x; +stabilize (rtx x) { - if (GET_CODE (x) != MEM || ! rtx_unstable_p (XEXP (x, 0))) return x; @@ -695,8 +626,7 @@ stabilize (x) /* Copy the value or contents of X to a new temp reg and return that reg. */ rtx -copy_to_reg (x) - rtx x; +copy_to_reg (rtx x) { rtx temp = gen_reg_rtx (GET_MODE (x)); @@ -715,8 +645,7 @@ copy_to_reg (x) in case X is a constant. */ rtx -copy_addr_to_reg (x) - rtx x; +copy_addr_to_reg (rtx x) { return copy_to_mode_reg (Pmode, x); } @@ -725,9 +654,7 @@ copy_addr_to_reg (x) in case X is a constant. */ rtx -copy_to_mode_reg (mode, x) - enum machine_mode mode; - rtx x; +copy_to_mode_reg (enum machine_mode mode, rtx x) { rtx temp = gen_reg_rtx (mode); @@ -752,9 +679,7 @@ copy_to_mode_reg (mode, x) since we mark it as a "constant" register. */ rtx -force_reg (mode, x) - enum machine_mode mode; - rtx x; +force_reg (enum machine_mode mode, rtx x) { rtx temp, insn, set; @@ -784,7 +709,8 @@ force_reg (mode, x) if INSN set something else (such as a SUBREG of TEMP). */ if (CONSTANT_P (x) && (set = single_set (insn)) != 0 - && SET_DEST (set) == temp) + && SET_DEST (set) == temp + && ! rtx_equal_p (x, SET_SRC (set))) set_unique_reg_note (insn, REG_EQUAL, x); return temp; @@ -794,8 +720,7 @@ force_reg (mode, x) that reg. Otherwise, return X. */ rtx -force_not_mem (x) - rtx x; +force_not_mem (rtx x) { rtx temp; @@ -812,9 +737,7 @@ force_not_mem (x) MODE is the mode to use for X in case it is a constant. */ rtx -copy_to_suggested_reg (x, target, mode) - rtx x, target; - enum machine_mode mode; +copy_to_suggested_reg (rtx x, rtx target, enum machine_mode mode) { rtx temp; @@ -834,11 +757,8 @@ copy_to_suggested_reg (x, target, mode) FOR_CALL is nonzero if this call is promoting args for a call. */ enum machine_mode -promote_mode (type, mode, punsignedp, for_call) - tree type; - enum machine_mode mode; - int *punsignedp; - int for_call ATTRIBUTE_UNUSED; +promote_mode (tree type, enum machine_mode mode, int *punsignedp, + int for_call ATTRIBUTE_UNUSED) { enum tree_code code = TREE_CODE (type); int unsignedp = *punsignedp; @@ -877,8 +797,7 @@ promote_mode (type, mode, punsignedp, for_call) This pops when ADJUST is positive. ADJUST need not be constant. */ void -adjust_stack (adjust) - rtx adjust; +adjust_stack (rtx adjust) { rtx temp; adjust = protect_from_queue (adjust, 0); @@ -908,8 +827,7 @@ adjust_stack (adjust) This pushes when ADJUST is positive. ADJUST need not be constant. */ void -anti_adjust_stack (adjust) - rtx adjust; +anti_adjust_stack (rtx adjust) { rtx temp; adjust = protect_from_queue (adjust, 0); @@ -939,15 +857,17 @@ anti_adjust_stack (adjust) by this machine. SIZE is the desired size, which need not be constant. */ rtx -round_push (size) - rtx size; +round_push (rtx size) { int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; + if (align == 1) return size; + if (GET_CODE (size) == CONST_INT) { - int new = (INTVAL (size) + align - 1) / align * align; + HOST_WIDE_INT new = (INTVAL (size) + align - 1) / align * align; + if (INTVAL (size) != new) size = GEN_INT (new); } @@ -962,6 +882,7 @@ round_push (size) NULL_RTX, 1); size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1); } + return size; } @@ -974,14 +895,11 @@ round_push (size) are emitted at the current position. */ void -emit_stack_save (save_level, psave, after) - enum save_level save_level; - rtx *psave; - rtx after; +emit_stack_save (enum save_level save_level, rtx *psave, rtx after) { rtx sa = *psave; /* The default is that we use a move insn and save in a Pmode object. */ - rtx (*fcn) PARAMS ((rtx, rtx)) = gen_move_insn; + rtx (*fcn) (rtx, rtx) = gen_move_insn; enum machine_mode mode = STACK_SAVEAREA_MODE (save_level); /* See if this machine has anything special to do for this kind of save. */ @@ -1057,13 +975,10 @@ emit_stack_save (save_level, psave, after) current position. */ void -emit_stack_restore (save_level, sa, after) - enum save_level save_level; - rtx after; - rtx sa; +emit_stack_restore (enum save_level save_level, rtx sa, rtx after) { /* The default is that we use a move insn. */ - rtx (*fcn) PARAMS ((rtx, rtx)) = gen_move_insn; + rtx (*fcn) (rtx, rtx) = gen_move_insn; /* See if this machine has anything special to do for this kind of save. */ switch (save_level) @@ -1097,7 +1012,7 @@ emit_stack_restore (save_level, sa, after) references to variable arrays below the code that deletes (pops) the arrays. */ emit_insn (gen_rtx_CLOBBER (VOIDmode, - gen_rtx_MEM (BLKmode, + gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)))); emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_MEM (BLKmode, stack_pointer_rtx))); @@ -1124,8 +1039,7 @@ emit_stack_restore (save_level, sa, after) frame, thus causing a crash if a longjmp unwinds to it. */ void -optimize_save_area_alloca (insns) - rtx insns; +optimize_save_area_alloca (rtx insns) { rtx insn; @@ -1209,10 +1123,7 @@ optimize_save_area_alloca (insns) KNOWN_ALIGN is the alignment (in bits) that we know SIZE has. */ rtx -allocate_dynamic_stack_space (size, target, known_align) - rtx size; - rtx target; - int known_align; +allocate_dynamic_stack_space (rtx size, rtx target, int known_align) { #ifdef SETJMP_VIA_SAVE_AREA rtx setjmpless_size = NULL_RTX; @@ -1373,7 +1284,7 @@ allocate_dynamic_stack_space (size, target, known_align) pred = insn_data[(int) CODE_FOR_allocate_stack].operand[1].predicate; if (pred && ! ((*pred) (size, mode))) - size = copy_to_mode_reg (mode, size); + size = copy_to_mode_reg (mode, convert_to_mode (mode, size, 1)); emit_insn (gen_allocate_stack (target, size)); } @@ -1443,13 +1354,6 @@ allocate_dynamic_stack_space (size, target, known_align) NULL_RTX, 1); } - /* Some systems require a particular insn to refer to the stack - to make the pages exist. */ -#ifdef HAVE_probe - if (HAVE_probe) - emit_insn (gen_probe ()); -#endif - /* Record the new stack level for nonlocal gotos. */ if (nonlocal_goto_handler_slots != 0) emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX); @@ -1464,8 +1368,7 @@ allocate_dynamic_stack_space (size, target, known_align) static GTY(()) rtx stack_check_libfunc; void -set_stack_check_libfunc (libfunc) - rtx libfunc; +set_stack_check_libfunc (rtx libfunc) { stack_check_libfunc = libfunc; } @@ -1473,8 +1376,7 @@ set_stack_check_libfunc (libfunc) /* Emit one stack probe at ADDRESS, an address within the stack. */ static void -emit_stack_probe (address) - rtx address; +emit_stack_probe (rtx address) { rtx memref = gen_rtx_MEM (word_mode, address); @@ -1499,9 +1401,7 @@ emit_stack_probe (address) #endif void -probe_stack_range (first, size) - HOST_WIDE_INT first; - rtx size; +probe_stack_range (HOST_WIDE_INT first, rtx size) { /* First ensure SIZE is Pmode. */ if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode) @@ -1516,11 +1416,7 @@ probe_stack_range (first, size) stack_pointer_rtx, plus_constant (size, first))); -#ifdef POINTERS_EXTEND_UNSIGNED - if (GET_MODE (addr) != ptr_mode) - addr = convert_memory_address (ptr_mode, addr); -#endif - + addr = convert_memory_address (ptr_mode, addr); emit_library_call (stack_check_libfunc, LCT_NORMAL, VOIDmode, 1, addr, ptr_mode); } @@ -1591,13 +1487,13 @@ probe_stack_range (first, size) || REGNO (test_addr) < FIRST_PSEUDO_REGISTER) test_addr = force_reg (Pmode, test_addr); - emit_note (NULL, NOTE_INSN_LOOP_BEG); + emit_note (NOTE_INSN_LOOP_BEG); emit_jump (test_lab); emit_label (loop_lab); emit_stack_probe (test_addr); - emit_note (NULL, NOTE_INSN_LOOP_CONT); + emit_note (NOTE_INSN_LOOP_CONT); #ifdef STACK_GROWS_DOWNWARD #define CMP_OPCODE GTU @@ -1616,7 +1512,7 @@ probe_stack_range (first, size) emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE, NULL_RTX, Pmode, 1, loop_lab); emit_jump (end_lab); - emit_note (NULL, NOTE_INSN_LOOP_END); + emit_note (NOTE_INSN_LOOP_END); emit_label (end_lab); emit_stack_probe (last_addr); @@ -1633,10 +1529,8 @@ probe_stack_range (first, size) and 0 otherwise. */ rtx -hard_function_value (valtype, func, outgoing) - tree valtype; - tree func ATTRIBUTE_UNUSED; - int outgoing ATTRIBUTE_UNUSED; +hard_function_value (tree valtype, tree func ATTRIBUTE_UNUSED, + int outgoing ATTRIBUTE_UNUSED) { rtx val; @@ -1679,8 +1573,7 @@ hard_function_value (valtype, func, outgoing) in which a scalar value of mode MODE was returned by a library call. */ rtx -hard_libcall_value (mode) - enum machine_mode mode; +hard_libcall_value (enum machine_mode mode) { return LIBCALL_VALUE (mode); } @@ -1691,8 +1584,7 @@ hard_libcall_value (mode) what `enum tree_code' means. */ int -rtx_to_tree_code (code) - enum rtx_code code; +rtx_to_tree_code (enum rtx_code code) { enum tree_code tcode; |