diff options
author | Andreas Krebbel <krebbel1@de.ibm.com> | 2007-03-29 06:58:42 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@gcc.gnu.org> | 2007-03-29 06:58:42 +0000 |
commit | 833cd70a0c91517672ae309a95519bb2f409d304 (patch) | |
tree | 0eb02ea1d47ff33d3568fbef2b041a2c2dd70d61 | |
parent | 040f69ebaac3cb2fe8b26ff736d5885db4f16f6b (diff) | |
download | gcc-833cd70a0c91517672ae309a95519bb2f409d304.zip gcc-833cd70a0c91517672ae309a95519bb2f409d304.tar.gz gcc-833cd70a0c91517672ae309a95519bb2f409d304.tar.bz2 |
s390.c (s390_secondary_input_reload_class, [...]): Functions removed.
2007-03-29 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/s390.c (s390_secondary_input_reload_class,
s390_secondary_output_reload_class): Functions removed.
(s390_secondary_reload): New function.
(TARGET_SECONDARY_RELOAD): Target macro defined.
* config/s390/s390.h (SECONDARY_INPUT_RELOAD_CLASS,
SECONDARY_OUTPUT_RELOAD_CLASS): Macro definitions removed.
* config/s390/s390.md ("reload_outti", "reload_outdi",
"reload_indi", "reload_insi", "reload_out<mode>", "reload_in<mode>",
"reload_out<mode>"): Expanders removed.
("reload<mode>_plus", "reload<mode>_nonoffmem_in",
"reload<mode>_nonoffmem_out"): Expanders added.
From-SVN: r123324
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 103 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 10 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 118 |
4 files changed, 99 insertions, 146 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c06e792..8dacb71 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,19 @@ 2007-03-29 Andreas Krebbel <krebbel1@de.ibm.com> + * config/s390/s390.c (s390_secondary_input_reload_class, + s390_secondary_output_reload_class): Functions removed. + (s390_secondary_reload): New function. + (TARGET_SECONDARY_RELOAD): Target macro defined. + * config/s390/s390.h (SECONDARY_INPUT_RELOAD_CLASS, + SECONDARY_OUTPUT_RELOAD_CLASS): Macro definitions removed. + * config/s390/s390.md ("reload_outti", "reload_outdi", + "reload_indi", "reload_insi", "reload_out<mode>", "reload_in<mode>", + "reload_out<mode>"): Expanders removed. + ("reload<mode>_plus", "reload<mode>_nonoffmem_in", + "reload<mode>_nonoffmem_out"): Expanders added. + +2007-03-29 Andreas Krebbel <krebbel1@de.ibm.com> + * regmove.c (optimize_reg_copy_1): Don't perform DEST->SRC repair action if SRC->DEST replacement failed anyway. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index e72c34e..e0e3115 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2638,67 +2638,57 @@ s390_preferred_reload_class (rtx op, enum reg_class class) return class; } -/* Return the register class of a scratch register needed to - load IN into a register of class CLASS in MODE. - - We need a temporary when loading a PLUS expression which - is not a legitimate operand of the LOAD ADDRESS instruction. */ - -enum reg_class -s390_secondary_input_reload_class (enum reg_class class, - enum machine_mode mode, rtx in) -{ - if (s390_plus_operand (in, mode)) - return ADDR_REGS; - - if (reg_classes_intersect_p (FP_REGS, class) - && mode == TFmode - && GET_CODE (in) == MEM - && GET_CODE (XEXP (in, 0)) == PLUS - && GET_CODE (XEXP (XEXP (in, 0), 1)) == CONST_INT - && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (in, 0), 1)) - + GET_MODE_SIZE (mode) - 1)) - return ADDR_REGS; +/* Inform reload about cases where moving X with a mode MODE to a register in + CLASS requires an extra scratch or immediate register. Return the class + needed for the immediate register. */ +static enum reg_class +s390_secondary_reload (bool in_p, rtx x, enum reg_class class, + enum machine_mode mode, secondary_reload_info *sri) +{ + /* Intermediate register needed. */ if (reg_classes_intersect_p (CC_REGS, class)) return GENERAL_REGS; - return NO_REGS; -} - -/* Return the register class of a scratch register needed to - store a register of class CLASS in MODE into OUT: - - We need a temporary when storing a double-word to a - non-offsettable memory address. */ - -enum reg_class -s390_secondary_output_reload_class (enum reg_class class, - enum machine_mode mode, rtx out) -{ - if ((TARGET_64BIT ? (mode == TImode || mode == TFmode) - : (mode == DImode || mode == DFmode)) - && reg_classes_intersect_p (GENERAL_REGS, class) - && GET_CODE (out) == MEM - && GET_CODE (XEXP (out, 0)) == PLUS - && GET_CODE (XEXP (XEXP (out, 0), 0)) == PLUS - && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT - && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1)) + /* We need a scratch register when loading a PLUS expression which + is not a legitimate operand of the LOAD ADDRESS instruction. */ + if (in_p && s390_plus_operand (x, mode)) + sri->icode = (TARGET_64BIT ? + CODE_FOR_reloaddi_plus : CODE_FOR_reloadsi_plus); + + /* Peforming a multiword move from or to memory we have to make sure the + second chunk in memory is addressable without causing a displacement + overflow. If that would be the case we calculate the address in + a scratch register. */ + if (MEM_P (x) + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1)) + GET_MODE_SIZE (mode) - 1)) - return ADDR_REGS; - - if (reg_classes_intersect_p (FP_REGS, class) - && mode == TFmode - && GET_CODE (out) == MEM - && GET_CODE (XEXP (out, 0)) == PLUS - && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT - && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1)) - + GET_MODE_SIZE (mode) - 1)) - return ADDR_REGS; - - if (reg_classes_intersect_p (CC_REGS, class)) - return GENERAL_REGS; + { + /* For GENERAL_REGS a displacement overflow is no problem if occuring + in a s_operand address since we may fallback to lm/stm. So we only + have to care about overflows in the b+i+d case. */ + if ((reg_classes_intersect_p (GENERAL_REGS, class) + && s390_class_max_nregs (GENERAL_REGS, mode) > 1 + && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS) + /* For FP_REGS no lm/stm is available so this check is triggered + for displacement overflows in b+i+d and b+d like addresses. */ + || (reg_classes_intersect_p (FP_REGS, class) + && s390_class_max_nregs (FP_REGS, mode) > 1)) + { + if (in_p) + sri->icode = (TARGET_64BIT ? + CODE_FOR_reloaddi_nonoffmem_in : + CODE_FOR_reloadsi_nonoffmem_in); + else + sri->icode = (TARGET_64BIT ? + CODE_FOR_reloaddi_nonoffmem_out : + CODE_FOR_reloadsi_nonoffmem_out); + } + } + /* Either scratch or no register needed. */ return NO_REGS; } @@ -9364,6 +9354,9 @@ s390_reorg (void) #undef TARGET_SCALAR_MODE_SUPPORTED_P #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p +#undef TARGET_SECONDARY_RELOAD +#define TARGET_SECONDARY_RELOAD s390_secondary_reload + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-s390.h" diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index fc36baf..a495bc7 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -464,16 +464,6 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; #define PREFERRED_RELOAD_CLASS(X, CLASS) \ s390_preferred_reload_class ((X), (CLASS)) -/* We need a secondary reload when loading a PLUS which is - not a valid operand for LOAD ADDRESS. */ -#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ - s390_secondary_input_reload_class ((CLASS), (MODE), (IN)) - -/* We need a secondary reload when storing a double-word - to a non-offsettable memory address. */ -#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, OUT) \ - s390_secondary_output_reload_class ((CLASS), (MODE), (OUT)) - /* We need secondary memory to move data between GPRs and FPRs. */ #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ ((CLASS1) != (CLASS2) \ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 3fd6c31..bfbb598 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -893,11 +893,43 @@ operands[1] = replace_equiv_address (operands[1], addr); }) -(define_expand "reload_outti" - [(parallel [(match_operand:TI 0 "" "") - (match_operand:TI 1 "register_operand" "d") - (match_operand:DI 2 "register_operand" "=&a")])] - "TARGET_64BIT" + +; +; Patterns used for secondary reloads +; + +; Handles loading a PLUS (load address) expression + +(define_expand "reload<mode>_plus" + [(parallel [(match_operand:P 0 "register_operand" "=a") + (match_operand:P 1 "s390_plus_operand" "") + (match_operand:P 2 "register_operand" "=&a")])] + "" +{ + s390_expand_plus_operand (operands[0], operands[1], operands[2]); + DONE; +}) + +; Handles assessing a non-offsetable memory address + +(define_expand "reload<mode>_nonoffmem_in" + [(parallel [(match_operand 0 "register_operand" "") + (match_operand 1 "" "") + (match_operand:P 2 "register_operand" "=&a")])] + "" +{ + gcc_assert (MEM_P (operands[1])); + s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0))); + operands[1] = replace_equiv_address (operands[1], operands[2]); + emit_move_insn (operands[0], operands[1]); + DONE; +}) + +(define_expand "reload<mode>_nonoffmem_out" + [(parallel [(match_operand 0 "" "") + (match_operand 1 "register_operand" "") + (match_operand:P 2 "register_operand" "=&a")])] + "" { gcc_assert (MEM_P (operands[0])); s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0))); @@ -1130,19 +1162,6 @@ operands[1] = replace_equiv_address (operands[1], addr); }) -(define_expand "reload_outdi" - [(parallel [(match_operand:DI 0 "" "") - (match_operand:DI 1 "register_operand" "d") - (match_operand:SI 2 "register_operand" "=&a")])] - "!TARGET_64BIT" -{ - gcc_assert (MEM_P (operands[0])); - s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0))); - operands[0] = replace_equiv_address (operands[0], operands[2]); - emit_move_insn (operands[0], operands[1]); - DONE; -}) - (define_peephole2 [(set (match_operand:DI 0 "register_operand" "") (mem:DI (match_operand 1 "address_operand" "")))] @@ -1189,16 +1208,6 @@ [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] "") -(define_expand "reload_indi" - [(parallel [(match_operand:DI 0 "register_operand" "=a") - (match_operand:DI 1 "s390_plus_operand" "") - (match_operand:DI 2 "register_operand" "=&a")])] - "TARGET_64BIT" -{ - s390_expand_plus_operand (operands[0], operands[1], operands[2]); - DONE; -}) - ; ; movsi instruction pattern(s). ; @@ -1359,16 +1368,6 @@ [(set_attr "op_type" "RX") (set_attr "type" "la")]) -(define_expand "reload_insi" - [(parallel [(match_operand:SI 0 "register_operand" "=a") - (match_operand:SI 1 "s390_plus_operand" "") - (match_operand:SI 2 "register_operand" "=&a")])] - "!TARGET_64BIT" -{ - s390_expand_plus_operand (operands[0], operands[1], operands[2]); - DONE; -}) - ; ; movhi instruction pattern(s). ; @@ -1625,36 +1624,6 @@ <MODE>mode, 8); }) -(define_expand "reload_out<mode>" - [(parallel [(match_operand:TD_TF 0 "" "") - (match_operand:TD_TF 1 "register_operand" "f") - (match_operand:SI 2 "register_operand" "=&a")])] - "" -{ - rtx addr = gen_lowpart (Pmode, operands[2]); - - gcc_assert (MEM_P (operands[0])); - s390_load_address (addr, find_replacement (&XEXP (operands[0], 0))); - operands[0] = replace_equiv_address (operands[0], addr); - emit_move_insn (operands[0], operands[1]); - DONE; -}) - -(define_expand "reload_in<mode>" - [(parallel [(match_operand:TD_TF 0 "register_operand" "=f") - (match_operand:TD_TF 1 "" "") - (match_operand:SI 2 "register_operand" "=&a")])] - "" -{ - rtx addr = gen_lowpart (Pmode, operands[2]); - - gcc_assert (MEM_P (operands[1])); - s390_load_address (addr, find_replacement (&XEXP (operands[1], 0))); - operands[1] = replace_equiv_address (operands[1], addr); - emit_move_insn (operands[0], operands[1]); - DONE; -}) - ; ; mov(df|dd) instruction pattern(s). ; @@ -1772,19 +1741,6 @@ operands[1] = replace_equiv_address (operands[1], addr); }) -(define_expand "reload_out<mode>" - [(parallel [(match_operand:DD_DF 0 "" "") - (match_operand:DD_DF 1 "register_operand" "d") - (match_operand:SI 2 "register_operand" "=&a")])] - "!TARGET_64BIT" -{ - gcc_assert (MEM_P (operands[0])); - s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0))); - operands[0] = replace_equiv_address (operands[0], operands[2]); - emit_move_insn (operands[0], operands[1]); - DONE; -}) - ; ; mov(sf|sd) instruction pattern(s). ; |