diff options
author | Geoffrey Keating <geoffk@apple.com> | 2003-12-09 01:57:45 +0000 |
---|---|---|
committer | Geoffrey Keating <geoffk@gcc.gnu.org> | 2003-12-09 01:57:45 +0000 |
commit | a9baceb10b8db929dbf87c0670b041aaa9171b42 (patch) | |
tree | a42d7b7b99c57a76ad67255b112d715ef171c90e | |
parent | 86b40947201d0457c50072eb6443ce09b68d5acc (diff) | |
download | gcc-a9baceb10b8db929dbf87c0670b041aaa9171b42.zip gcc-a9baceb10b8db929dbf87c0670b041aaa9171b42.tar.gz gcc-a9baceb10b8db929dbf87c0670b041aaa9171b42.tar.bz2 |
re PR target/11848 ([darwin] [no support for 128 doubles] internal compiler error for -mlong-double-128)
PR target/11848
* rs6000.h (CANNOT_CHANGE_MODE_CLASS): Allow change of mode
in floating-point registers between TFmode and DImode.
* rs6000.c (rs6000_emit_move): Split moves early.
(secondary_reload_class): Random Whitespace Change.
(rs6000_split_multireg_move): Support moves involving FP registers.
Emit instructions directly.
* rs6000-protos.h (rs6000_split_multireg_move): Update prototype.
* altivec.md: Update for changes to rs6000_split_multireg_move.
* rs6000.md: Update for changes to rs6000_split_multireg_move.
(movtf_internal): Support moves to/from GPRs.
From-SVN: r74454
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/config/rs6000/altivec.md | 88 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 181 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 11 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 158 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20031208-1.c | 6 |
7 files changed, 156 insertions, 304 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 984fa45..113bdcb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2003-12-08 Geoffrey Keating <geoffk@apple.com> + + PR target/11848 + * rs6000.h (CANNOT_CHANGE_MODE_CLASS): Allow change of mode + in floating-point registers between TFmode and DImode. + * rs6000.c (rs6000_emit_move): Split moves early. + (secondary_reload_class): Random Whitespace Change. + (rs6000_split_multireg_move): Support moves involving FP registers. + Emit instructions directly. + * rs6000-protos.h (rs6000_split_multireg_move): Update prototype. + * altivec.md: Update for changes to rs6000_split_multireg_move. + * rs6000.md: Update for changes to rs6000_split_multireg_move. + (movtf_internal): Support moves to/from GPRs. + 2003-12-08 Stuart Hastings <stuart@apple.com> * config/i386/i386.md: Typo in split of fp-valued if_then_else. diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 5fccb98..73d0417 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -113,26 +113,10 @@ (define_split [(set (match_operand:V4SI 0 "nonimmediate_operand" "") (match_operand:V4SI 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64 + "TARGET_ALTIVEC && reload_completed && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] -"{ - rs6000_split_multireg_move (operands); -}") - -(define_split - [(set (match_operand:V4SI 0 "nonimmediate_operand" "") - (match_operand:V4SI 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64 - && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 6)) - (set (match_dup 3) (match_dup 7)) - (set (match_dup 4) (match_dup 8)) - (set (match_dup 5) (match_dup 9))] -"{ - rs6000_split_multireg_move (operands); -}") + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_split [(set (match_operand:V4SI 0 "altivec_register_operand" "") @@ -175,26 +159,10 @@ (define_split [(set (match_operand:V8HI 0 "nonimmediate_operand" "") (match_operand:V8HI 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64 + "TARGET_ALTIVEC && reload_completed && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] -"{ - rs6000_split_multireg_move (operands); -}") - -(define_split - [(set (match_operand:V8HI 0 "nonimmediate_operand" "") - (match_operand:V8HI 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64 - && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 6)) - (set (match_dup 3) (match_dup 7)) - (set (match_dup 4) (match_dup 8)) - (set (match_dup 5) (match_dup 9))] -"{ - rs6000_split_multireg_move (operands); -}") + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_split [(set (match_operand:V8HI 0 "altivec_register_operand" "") @@ -237,26 +205,10 @@ (define_split [(set (match_operand:V16QI 0 "nonimmediate_operand" "") (match_operand:V16QI 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64 + "TARGET_ALTIVEC && reload_completed && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] -"{ - rs6000_split_multireg_move (operands); -}") - -(define_split - [(set (match_operand:V16QI 0 "nonimmediate_operand" "") - (match_operand:V16QI 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64 - && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 6)) - (set (match_dup 3) (match_dup 7)) - (set (match_dup 4) (match_dup 8)) - (set (match_dup 5) (match_dup 9))] -"{ - rs6000_split_multireg_move (operands); -}") + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_split [(set (match_operand:V16QI 0 "altivec_register_operand" "") @@ -299,26 +251,10 @@ (define_split [(set (match_operand:V4SF 0 "nonimmediate_operand" "") (match_operand:V4SF 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64 + "TARGET_ALTIVEC && reload_completed && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] -"{ - rs6000_split_multireg_move (operands); -}") - -(define_split - [(set (match_operand:V4SF 0 "nonimmediate_operand" "") - (match_operand:V4SF 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64 - && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 6)) - (set (match_dup 3) (match_dup 7)) - (set (match_dup 4) (match_dup 8)) - (set (match_dup 5) (match_dup 9))] -"{ - rs6000_split_multireg_move (operands); -}") + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_insn "get_vrsave_internal" [(set (match_operand:SI 0 "register_operand" "=r") diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 57fca19..79679f4 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -125,7 +125,7 @@ extern int mfcr_operation (rtx, enum machine_mode); extern int mtcrf_operation (rtx, enum machine_mode); extern int lmw_operation (rtx, enum machine_mode); extern struct rtx_def *create_TOC_reference (rtx); -extern void rs6000_split_multireg_move (rtx *); +extern void rs6000_split_multireg_move (rtx, rtx); extern void rs6000_emit_move (rtx, rtx, enum machine_mode); extern rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode); extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4f91e80..647469f 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3457,7 +3457,26 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) /* Handle the case of CONSTANT_P_RTX. */ if (GET_CODE (operands[1]) == CONSTANT_P_RTX) goto emit_set; - + + /* 128-bit constant floating-point values on Darwin should really be + loaded as two parts. */ + if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128 + && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE) + { + /* DImode is used, not DFmode, because simplify_gen_subreg doesn't + know how to get a DFmode SUBREG of a TFmode. */ + rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0), + simplify_gen_subreg (DImode, operands[1], mode, 0), + DImode); + rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, + GET_MODE_SIZE (DImode)), + simplify_gen_subreg (DImode, operands[1], mode, + GET_MODE_SIZE (DImode)), + DImode); + return; + } + /* FIXME: In the long term, this switch statement should go away and be replaced by a sequence of tests based on things like mode == Pmode. */ @@ -8302,7 +8321,8 @@ addrs_ok_for_quad_peep (rtx addr1, rtx addr2) enum reg_class secondary_reload_class (enum reg_class class, - enum machine_mode mode ATTRIBUTE_UNUSED, rtx in) + enum machine_mode mode ATTRIBUTE_UNUSED, + rtx in) { int regno; @@ -10007,73 +10027,72 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1) emit_move_insn (dest, target); } -/* Called by splitter for multireg moves. - Input: - operands[0] : Destination of move - operands[1] : Source of move - - Output: - operands[2-n] : Destination slots - operands[n-m] : Source slots - where n = 2 + HARD_REGNO_NREGS (reg, GET_MODE (operands[0])) - m = 2 + 2 * HARD_REGNO_NREGS (reg, GET_MODE (operands[0])) - 1 +/* Emit instructions to move SRC to DST. Called by splitters for + multi-register moves. It will emit at most one instruction for + each register that is accessed; that is, it won't emit li/lis pairs + (or equivalent for 64-bit code). One of SRC or DST must be a hard + register. */ - Splits the move of operands[1] to operands[0]. - This is done, if GPRs are one of the operands. In this case - a sequence of simple move insns has to be issued. The sequence of these - move insns has to be done in correct order to avoid early clobber of the - base register or destructive overlap of registers. -*/ - void -rs6000_split_multireg_move (rtx *operands) +rs6000_split_multireg_move (rtx dst, rtx src) { - int nregs, reg, i, j, used_update = 0; - enum machine_mode mode; - rtx dst = operands[0]; - rtx src = operands[1]; - rtx insn = 0; - - /* Calculate number to move (2/4 for 32/64 bit mode). */ - - reg = REG_P (operands[0]) ? REGNO (operands[0]) : REGNO (operands[1]); - mode = GET_MODE (operands[0]); - nregs = HARD_REGNO_NREGS (reg, mode); + /* The register number of the first register being moved. */ + int reg; + /* The mode that is to be moved. */ + enum machine_mode mode; + /* The mode that the move is being done in, and its size. */ + enum machine_mode reg_mode; + int reg_mode_size; + /* The number of registers that will be moved. */ + int nregs; + + reg = REG_P (dst) ? REGNO (dst) : REGNO (src); + mode = GET_MODE (dst); + nregs = HARD_REGNO_NREGS (reg, mode); + if (FP_REGNO_P (reg)) + reg_mode = DFmode; + else if (ALTIVEC_REGNO_P (reg)) + reg_mode = V16QImode; + else + reg_mode = word_mode; + reg_mode_size = GET_MODE_SIZE (reg_mode); - if (REG_P (operands[1]) - && REG_P (operands[0]) - && (REGNO (operands[1]) < REGNO (operands[0]))) - { - /* Move register range backwards, if we have destructive overlap. */ - - j = nregs; - for (i = 0; i < nregs; i++) - { - j--; - operands[i+2] = operand_subword (operands[0], j, 0, mode); - operands[i+2+nregs] = - operand_subword (operands[1], j, 0, mode); - } - } + if (reg_mode_size * nregs != GET_MODE_SIZE (mode)) + abort (); + + if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst))) + { + /* Move register range backwards, if we might have destructive + overlap. */ + int i; + for (i = nregs - 1; i >= 0; i--) + emit_insn (gen_rtx_SET (VOIDmode, + simplify_gen_subreg (reg_mode, dst, mode, + i * reg_mode_size), + simplify_gen_subreg (reg_mode, src, mode, + i * reg_mode_size))); + } else { - j = -1; + int i; + int j = -1; + bool used_update = false; - if (GET_CODE (operands[1]) == MEM) + if (GET_CODE (src) == MEM && INT_REGNO_P (reg)) { rtx breg; - if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC - || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) + if (GET_CODE (XEXP (src, 0)) == PRE_INC + || GET_CODE (XEXP (src, 0)) == PRE_DEC) { rtx delta_rtx; - breg = XEXP (XEXP (operands[1], 0), 0); - delta_rtx = GET_CODE (XEXP (operands[1], 0)) == PRE_INC - ? GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))) - : GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[1]))); - insn = emit_insn (TARGET_32BIT - ? gen_addsi3 (breg, breg, delta_rtx) - : gen_adddi3 (breg, breg, delta_rtx)); + breg = XEXP (XEXP (src, 0), 0); + delta_rtx = GET_CODE (XEXP (src, 0)) == PRE_INC + ? GEN_INT (GET_MODE_SIZE (GET_MODE (src))) + : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))); + emit_insn (TARGET_32BIT + ? gen_addsi3 (breg, breg, delta_rtx) + : gen_adddi3 (breg, breg, delta_rtx)); src = gen_rtx_MEM (mode, breg); } @@ -10093,35 +10112,34 @@ rs6000_split_multireg_move (rtx *operands) j = REGNO (breg) - REGNO (dst); } - if (GET_CODE (operands[0]) == MEM) + if (GET_CODE (dst) == MEM && INT_REGNO_P (reg)) { rtx breg; - if (GET_CODE (XEXP (operands[0], 0)) == PRE_INC - || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) + if (GET_CODE (XEXP (dst, 0)) == PRE_INC + || GET_CODE (XEXP (dst, 0)) == PRE_DEC) { rtx delta_rtx; - breg = XEXP (XEXP (operands[0], 0), 0); - delta_rtx = GET_CODE (XEXP (operands[0], 0)) == PRE_INC - ? GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))) - : GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0]))); + breg = XEXP (XEXP (dst, 0), 0); + delta_rtx = GET_CODE (XEXP (dst, 0)) == PRE_INC + ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst))) + : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))); /* We have to update the breg before doing the store. Use store with update, if available. */ if (TARGET_UPDATE) { - insn = emit_insn (TARGET_32BIT - ? gen_movsi_update (breg, breg, delta_rtx, - operand_subword (src, 0, 0, mode)) - : gen_movdi_update (breg, breg, delta_rtx, - operand_subword (src, 0, 0, mode))); - used_update = 1; + rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0); + emit_insn (TARGET_32BIT + ? gen_movsi_update (breg, breg, delta_rtx, nsrc) + : gen_movdi_update (breg, breg, delta_rtx, nsrc)); + used_update = true; } else - insn = emit_insn (TARGET_32BIT - ? gen_addsi3 (breg, breg, delta_rtx) - : gen_adddi3 (breg, breg, delta_rtx)); + emit_insn (TARGET_32BIT + ? gen_addsi3 (breg, breg, delta_rtx) + : gen_adddi3 (breg, breg, delta_rtx)); dst = gen_rtx_MEM (mode, breg); } } @@ -10133,15 +10151,16 @@ rs6000_split_multireg_move (rtx *operands) if (j == nregs) j = 0; - operands[i+2] = operand_subword (dst, j, 0, mode); - operands[i+2+nregs] = operand_subword (src, j, 0, mode); - + /* If compiler already emited move of first word by + store with update, no need to do anything. */ if (j == 0 && used_update) - { - /* Already emited move of first word by - store with update -> emit dead insn instead (r := r). */ - operands[i+2] = operands[i+2+nregs]; - } + continue; + + emit_insn (gen_rtx_SET (VOIDmode, + simplify_gen_subreg (reg_mode, dst, mode, + j * reg_mode_size), + simplify_gen_subreg (reg_mode, src, mode, + j * reg_mode_size))); } } } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index f0f351e..761873d 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1480,11 +1480,14 @@ enum reg_class /* Return a class of registers that cannot change FROM mode to TO mode. */ -#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ - (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ - ? reg_classes_intersect_p (FLOAT_REGS, CLASS) \ +#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ + (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) \ + && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8) \ + ? 0 \ + : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ + ? reg_classes_intersect_p (FLOAT_REGS, CLASS) \ : (TARGET_SPE && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1) \ - ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \ + ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \ : 0) /* Stack layout; function entry, exit and calling. */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 19b263a..50c3595 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -8206,110 +8206,21 @@ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }") -(define_insn "*movtf_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,m,!r,!r,!r") - (match_operand:TF 1 "input_operand" "f,m,f,G,H,F"))] +; It's important to list the o->f and f->o moves before f->f because +; otherwise reload, given m->f, will try to pick f->f and reload it, +; which doesn't make progress. +(define_insn_and_split "*movtf_internal" + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,rm,r") + (match_operand:TF 1 "input_operand" "f,o,f,r,mGHF"))] "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128 && (gpc_reg_operand (operands[0], TFmode) || gpc_reg_operand (operands[1], TFmode))" - "* -{ - switch (which_alternative) - { - default: - abort (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"fmr %L0,%L1\;fmr %0,%1\"; - else - return \"fmr %0,%1\;fmr %L0,%L1\"; - case 1: - return \"lfd %0,%1\;lfd %L0,%Y1\"; - case 2: - return \"stfd %1,%0\;stfd %L1,%Y0\"; - case 3: - case 4: - case 5: - return \"#\"; - } -}" - [(set_attr "type" "fp,fpload,fpstore,*,*,*") - (set_attr "length" "8,8,8,12,16,20")]) - -(define_split - [(set (match_operand:TF 0 "gpc_reg_operand" "") - (match_operand:TF 1 "easy_fp_constant" ""))] - "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) - && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64 - && TARGET_LONG_DOUBLE_128 && reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 6)) - (set (match_dup 3) (match_dup 7)) - (set (match_dup 4) (match_dup 8)) - (set (match_dup 5) (match_dup 9))] - " -{ - long l[4]; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l); - - operands[2] = operand_subword (operands[0], 0, 0, TFmode); - operands[3] = operand_subword (operands[0], 1, 0, TFmode); - operands[4] = operand_subword (operands[0], 2, 0, TFmode); - operands[5] = operand_subword (operands[0], 3, 0, TFmode); - operands[6] = gen_int_mode (l[0], SImode); - operands[7] = gen_int_mode (l[1], SImode); - operands[8] = gen_int_mode (l[2], SImode); - operands[9] = gen_int_mode (l[3], SImode); -}") - -(define_split - [(set (match_operand:TF 0 "gpc_reg_operand" "") - (match_operand:TF 1 "easy_fp_constant" ""))] - "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 - && TARGET_LONG_DOUBLE_128 && reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] - " -{ - long l[4]; - REAL_VALUE_TYPE rv; -#if HOST_BITS_PER_WIDE_INT >= 64 - HOST_WIDE_INT val; -#endif - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l); - - operands[2] = gen_lowpart (DImode, operands[0]); - operands[3] = gen_highpart (DImode, operands[0]); -#if HOST_BITS_PER_WIDE_INT >= 64 - val = ((HOST_WIDE_INT)(unsigned long)l[0] << 32 - | ((HOST_WIDE_INT)(unsigned long)l[1])); - operands[4] = gen_int_mode (val, DImode); - - val = ((HOST_WIDE_INT)(unsigned long)l[2] << 32 - | ((HOST_WIDE_INT)(unsigned long)l[3])); - operands[5] = gen_int_mode (val, DImode); -#else - operands[4] = immed_double_const (l[1], l[0], DImode); - operands[5] = immed_double_const (l[3], l[2], DImode); -#endif -}") + "#" + "reload_completed" + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } + [(set_attr "length" "8,8,8,20,20")]) (define_insn "extenddftf2" [(set (match_operand:TF 0 "gpc_reg_operand" "=f") @@ -8527,31 +8438,12 @@ }") (define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_double_operand" ""))] - "HOST_BITS_PER_WIDE_INT == 32 && ! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] - " -{ - operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, - DImode); - operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, - DImode); - operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); - operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); -}") - -(define_split [(set (match_operand:DI 0 "nonimmediate_operand" "") (match_operand:DI 1 "input_operand" ""))] "reload_completed && !TARGET_POWERPC64 && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] -"{ - rs6000_split_multireg_move (operands); -}") + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_split [(set (match_operand:TI 0 "gpc_reg_operand" "") @@ -8780,28 +8672,10 @@ (define_split [(set (match_operand:TI 0 "nonimmediate_operand" "") (match_operand:TI 1 "input_operand" ""))] - "reload_completed && TARGET_POWERPC64 - && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] -"{ - rs6000_split_multireg_move (operands); -}") - -(define_split - [(set (match_operand:TI 0 "nonimmediate_operand" "") - (match_operand:TI 1 "input_operand" ""))] - "reload_completed && !TARGET_POWERPC64 + "reload_completed && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 6)) - (set (match_dup 3) (match_dup 7)) - (set (match_dup 4) (match_dup 8)) - (set (match_dup 5) (match_dup 9))] -"{ - rs6000_split_multireg_move (operands); -}") - - + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_expand "load_multiple" [(match_par_dup 3 [(set (match_operand:SI 0 "" "") diff --git a/gcc/testsuite/gcc.c-torture/compile/20031208-1.c b/gcc/testsuite/gcc.c-torture/compile/20031208-1.c new file mode 100644 index 0000000..02586df --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20031208-1.c @@ -0,0 +1,6 @@ +extern int foo(int, ...); +int bar(void) { + long double l = 1.2345E6; + foo(0, l); + return 0; +} |