From 6107a46e07d2968c5b2f0c0274cfd871766b3a13 Mon Sep 17 00:00:00 2001 From: rsandifo Date: Fri, 10 Aug 2007 15:40:26 +0000 Subject: [PATCH] gcc/ * config/mips/mips-protos.h (mips_address_insns): Add a boolean argument. (mips_fetch_insns): Delete in favor of... (mips_load_store_insns): ...this new function. * config/mips/mips.c (mips_address_insns): Add a boolean argument to say whether multiword moves _might_ be split. (mips_fetch_insns): Delete in favor of... (mips_load_store_insns): ...this new function. (mips_rtx_costs): Update the call to mips_address_insns. (mips_address_cost): Likewise. * config/mips/mips.md (length): Use mips_load_store_insns instead of mips_fetch_insns. * config/mips/constraints.md (R): Use mips_address_insns rather than mips_fetch_insns. Assume that the move never needs to be split. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127338 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 17 +++++++++++++++ gcc/config/mips/constraints.md | 2 +- gcc/config/mips/mips-protos.h | 4 ++-- gcc/config/mips/mips.c | 48 ++++++++++++++++++++++++++++++------------ gcc/config/mips/mips.md | 4 ++-- 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a62a76c..d514d48 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2007-08-10 Richard Sandiford + + * config/mips/mips-protos.h (mips_address_insns): Add a boolean + argument. + (mips_fetch_insns): Delete in favor of... + (mips_load_store_insns): ...this new function. + * config/mips/mips.c (mips_address_insns): Add a boolean argument + to say whether multiword moves _might_ be split. + (mips_fetch_insns): Delete in favor of... + (mips_load_store_insns): ...this new function. + (mips_rtx_costs): Update the call to mips_address_insns. + (mips_address_cost): Likewise. + * config/mips/mips.md (length): Use mips_load_store_insns instead + of mips_fetch_insns. + * config/mips/constraints.md (R): Use mips_address_insns rather + than mips_fetch_insns. Assume that the move never needs to be split. + 2007-08-09 Sandra Loosemore * config/mips/mips.opt (mhard-float, msoft-float): Make these diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md index 3a28425..47b3966 100644 --- a/gcc/config/mips/constraints.md +++ b/gcc/config/mips/constraints.md @@ -151,7 +151,7 @@ (define_memory_constraint "R" "An address that can be used in a non-macro load or store." (and (match_code "mem") - (match_test "mips_fetch_insns (op) == 1"))) + (match_test "mips_address_insns (XEXP (op, 0), mode, false) == 1"))) (define_constraint "S" "@internal diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 2fec3ed..0a42ce1 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -168,9 +168,9 @@ extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_context, enum mips_symbol_type *); extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, int); extern bool mips_stack_address_p (rtx, enum machine_mode); -extern int mips_address_insns (rtx, enum machine_mode); +extern int mips_address_insns (rtx, enum machine_mode, bool); extern int mips_const_insns (rtx); -extern int mips_fetch_insns (rtx); +extern int mips_load_store_insns (rtx, rtx); extern int mips_idiv_insns (void); extern int fp_register_operand (rtx, enum machine_mode); extern int lo_operand (rtx, enum machine_mode); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index ccd93fb..dce8042 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -1945,22 +1945,26 @@ mips16_unextended_reference_p (enum machine_mode mode, rtx base, rtx offset) /* Return the number of instructions needed to load or store a value - of mode MODE at X. Return 0 if X isn't valid for MODE. + of mode MODE at X. Return 0 if X isn't valid for MODE. Assume that + multiword moves may need to be split into word moves if MIGHT_SPLIT_P, + otherwise assume that a single load or store is enough. For mips16 code, count extended instructions as two instructions. */ int -mips_address_insns (rtx x, enum machine_mode mode) +mips_address_insns (rtx x, enum machine_mode mode, bool might_split_p) { struct mips_address_info addr; int factor; - if (mode == BLKmode) - /* BLKmode is used for single unaligned loads and stores. */ - factor = 1; - else - /* Each word of a multi-word value will be accessed individually. */ + /* BLKmode is used for single unaligned loads and stores and should + not count as a multiword mode. (GET_MODE_SIZE (BLKmode) is pretty + meaningless, so we have to single it out as a special case one way + or the other.) */ + if (mode != BLKmode && might_split_p) factor = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + else + factor = 1; if (mips_classify_address (&addr, x, mode, false)) switch (addr.type) @@ -2059,14 +2063,30 @@ mips_const_insns (rtx x) } -/* Return the number of instructions needed for memory reference X. - Count extended mips16 instructions as two instructions. */ +/* Return the number of instructions needed to implement INSN, + given that it loads from or stores to MEM. Count extended + mips16 instructions as two instructions. */ int -mips_fetch_insns (rtx x) +mips_load_store_insns (rtx mem, rtx insn) { - gcc_assert (MEM_P (x)); - return mips_address_insns (XEXP (x, 0), GET_MODE (x)); + enum machine_mode mode; + bool might_split_p; + rtx set; + + gcc_assert (MEM_P (mem)); + mode = GET_MODE (mem); + + /* Try to prove that INSN does not need to be split. */ + might_split_p = true; + if (GET_MODE_BITSIZE (mode) == 64) + { + set = single_set (insn); + if (set && !mips_split_64bit_move_p (SET_DEST (set), SET_SRC (set))) + might_split_p = false; + } + + return mips_address_insns (XEXP (mem, 0), mode, might_split_p); } @@ -2857,7 +2877,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total) /* If the address is legitimate, return the number of instructions it needs. */ rtx addr = XEXP (x, 0); - int n = mips_address_insns (addr, GET_MODE (x)); + int n = mips_address_insns (addr, GET_MODE (x), true); if (n > 0) { *total = COSTS_N_INSNS (n + 1); @@ -3012,7 +3032,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total) static int mips_address_cost (rtx addr) { - return mips_address_insns (addr, SImode); + return mips_address_insns (addr, SImode, false); } /* Return one word of double-word value OP, taking into account the fixed diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 6ec2235..bac479f 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -360,9 +360,9 @@ (eq_attr "type" "const") (symbol_ref "mips_const_insns (operands[1]) * 4") (eq_attr "type" "load,fpload") - (symbol_ref "mips_fetch_insns (operands[1]) * 4") + (symbol_ref "mips_load_store_insns (operands[1], insn) * 4") (eq_attr "type" "store,fpstore") - (symbol_ref "mips_fetch_insns (operands[0]) * 4") + (symbol_ref "mips_load_store_insns (operands[0], insn) * 4") ;; In the worst case, a call macro will take 8 instructions: ;; -- 2.7.4