From 9b901d50bbf94b33f4bade9c2a093b76bef2afd7 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Thu, 7 Apr 2005 11:24:11 +0000 Subject: [PATCH] arm.c (arm_const_double_inline_cost): Handle any constant by using gen_lowpart and gen_highpart_mode. * arm.c (arm_const_double_inline_cost): Handle any constant by using gen_lowpart and gen_highpart_mode. (note_invalid_constants): All constants in an RTX with a constraint that permits memory are now pushed to the constant pool. (output_move_double): Delete code to handle reg to reg and constant to reg moves. (const_double_needs_minipool, output_mov_immediate): Delete. * arm.h (EXTRA_CONSTRAINT_STR_ARM): All 'D' variants now handle CONST_INT and CONST_VECTOR. * arm.md (ANY64): New mode macro. (arm_movdi): Split reg-reg and const-reg moves. Simplify constraints. (movdf_soft_insn): Split reg-reg and const-reg moves. (split patterns for 64-bit constant and register moves): New. * cirrus.md (cirrus_arm_movdi): Split reg-reg and const-reg moves. (cirrus_movdf_hard_insn): Likewise. * fpa.md (movdf_fpa): Likewise. * iwmmxt.md (iwmmxt_arm_movdi): Likewise. (movv8qi_internal, movv4hi_internal, movv2si_internal): Fix constraints. (movv2si_internal_2): Likewise. * vfp.md (arm_movdi_vfp): Split reg-reg and const-reg moves. (movdf_vfp): Likewise. * arm-protos.h (output_mov_immediate): Delete prototype. From-SVN: r97778 --- gcc/ChangeLog | 26 ++++ gcc/config/arm/arm-protos.h | 1 - gcc/config/arm/arm.c | 270 +++--------------------------------- gcc/config/arm/arm.h | 4 +- gcc/config/arm/arm.md | 85 +++++++++++- gcc/config/arm/cirrus.md | 6 +- gcc/config/arm/fpa.md | 3 +- gcc/config/arm/iwmmxt.md | 10 +- gcc/config/arm/vfp.md | 11 +- 9 files changed, 152 insertions(+), 264 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0b30d17bce3..f2591678a32 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2005-04-07 Richard Earnshaw + + * arm.c (arm_const_double_inline_cost): Handle any constant by + using gen_lowpart and gen_highpart_mode. + (note_invalid_constants): All constants in an RTX with a constraint + that permits memory are now pushed to the constant pool. + (output_move_double): Delete code to handle reg to reg and + constant to reg moves. + (const_double_needs_minipool, output_mov_immediate): Delete. + * arm.h (EXTRA_CONSTRAINT_STR_ARM): All 'D' variants now handle + CONST_INT and CONST_VECTOR. + * arm.md (ANY64): New mode macro. + (arm_movdi): Split reg-reg and const-reg moves. Simplify constraints. + (movdf_soft_insn): Split reg-reg and const-reg moves. + (split patterns for 64-bit constant and register moves): New. + * cirrus.md (cirrus_arm_movdi): Split reg-reg and const-reg moves. + (cirrus_movdf_hard_insn): Likewise. + * fpa.md (movdf_fpa): Likewise. + * iwmmxt.md (iwmmxt_arm_movdi): Likewise. + (movv8qi_internal, movv4hi_internal, movv2si_internal): Fix + constraints. + (movv2si_internal_2): Likewise. + * vfp.md (arm_movdi_vfp): Split reg-reg and const-reg moves. + (movdf_vfp): Likewise. + * arm-protos.h (output_mov_immediate): Delete prototype. + 2005-04-07 Joseph S. Myers PR target/20093 diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index f609b3907dc..0baca5783ff 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -100,7 +100,6 @@ extern const char *output_mov_long_double_arm_from_arm (rtx *); extern const char *output_mov_double_fpa_from_arm (rtx *); extern const char *output_mov_double_arm_from_fpa (rtx *); extern const char *output_move_double (rtx *); -extern const char *output_mov_immediate (rtx *); extern const char *output_add_immediate (rtx *); extern const char *arithmetic_instr (rtx, int); extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 817185673da..27c6f75a5e5 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -7390,57 +7390,37 @@ push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx *loc, minipool_fix_tail = fix; } -/* Return the cost of synthesizing the const_double VAL inline. +/* Return the cost of synthesizing a 64-bit constant VAL inline. Returns the number of insns needed, or 99 if we don't know how to do it. */ int arm_const_double_inline_cost (rtx val) { - long parts[2]; + rtx lowpart, highpart; + enum machine_mode mode; - if (GET_MODE (val) == DFmode) - { - REAL_VALUE_TYPE r; - if (!TARGET_SOFT_FLOAT) - return 99; - REAL_VALUE_FROM_CONST_DOUBLE (r, val); - REAL_VALUE_TO_TARGET_DOUBLE (r, parts); - } - else if (GET_MODE (val) != VOIDmode) - return 99; - else - { - parts[0] = CONST_DOUBLE_LOW (val); - parts[1] = CONST_DOUBLE_HIGH (val); - } + mode = GET_MODE (val); - return (arm_gen_constant (SET, SImode, NULL_RTX, parts[0], - NULL_RTX, NULL_RTX, 0, 0) - + arm_gen_constant (SET, SImode, NULL_RTX, parts[1], - NULL_RTX, NULL_RTX, 0, 0)); -} + if (mode == VOIDmode) + mode = DImode; -/* Determine if a CONST_DOUBLE should be pushed to the minipool */ -static bool -const_double_needs_minipool (rtx val) -{ - /* thumb only knows to load a CONST_DOUBLE from memory at the moment */ - if (TARGET_THUMB) - return true; + gcc_assert (GET_MODE_SIZE (mode) == 8); + + lowpart = gen_lowpart (SImode, val); + highpart = gen_highpart_mode (SImode, mode, val); + + gcc_assert (GET_CODE (lowpart) == CONST_INT); + gcc_assert (GET_CODE (highpart) == CONST_INT); - /* Don't push anything to the minipool if a CONST_DOUBLE can be built with - a few ALU insns directly. On balance, the optimum is likely to be around - 3 insns, except when there are no load delay slots where it should be 4. - When optimizing for size, a limit of 3 allows saving at least one word - except for cases where a single minipool entry could be shared more than - 2 times which is rather unlikely to outweight the overall savings. */ - return (arm_const_double_inline_cost (val) - > ((optimize_size || arm_ld_sched) ? 3 : 4)); + return (arm_gen_constant (SET, SImode, NULL_RTX, INTVAL (lowpart), + NULL_RTX, NULL_RTX, 0, 0) + + arm_gen_constant (SET, SImode, NULL_RTX, INTVAL (highpart), + NULL_RTX, NULL_RTX, 0, 0)); } /* Scan INSN and note any of its operands that need fixing. If DO_PUSHES is false we do not actually push any of the fixups - needed. The function returns TRUE is any fixups were needed/pushed. + needed. The function returns TRUE if any fixups were needed/pushed. This is used by arm_memory_load_p() which needs to know about loads of constants that will be converted into minipool loads. */ static bool @@ -7457,7 +7437,8 @@ note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes) if (recog_data.n_alternatives == 0) return false; - /* Fill in recog_op_alt with information about the constraints of this insn. */ + /* Fill in recog_op_alt with information about the constraints of + this insn. */ preprocess_constraints (); for (opno = 0; opno < recog_data.n_operands; opno++) @@ -7474,9 +7455,7 @@ note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes) { rtx op = recog_data.operand[opno]; - if (CONSTANT_P (op) - && (GET_CODE (op) != CONST_DOUBLE - || const_double_needs_minipool (op))) + if (CONSTANT_P (op)) { if (do_pushes) push_minipool_fix (insn, address, recog_data.operand_loc[opno], @@ -8072,175 +8051,7 @@ output_move_double (rtx *operands) otherops[0] = gen_rtx_REG (SImode, 1 + reg0); - if (code1 == REG) - { - int reg1 = REGNO (operands[1]); - if (reg1 == IP_REGNUM) - abort (); - - /* Ensure the second source is not overwritten. */ - if (reg1 == reg0 + (WORDS_BIG_ENDIAN ? -1 : 1)) - output_asm_insn ("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands); - else - output_asm_insn ("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands); - } - else if (code1 == CONST_VECTOR) - { - HOST_WIDE_INT hint = 0; - - switch (GET_MODE (operands[1])) - { - case V2SImode: - otherops[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 1))); - operands[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0))); - break; - - case V4HImode: - if (BYTES_BIG_ENDIAN) - { - hint = INTVAL (CONST_VECTOR_ELT (operands[1], 2)); - hint <<= 16; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3)); - } - else - { - hint = INTVAL (CONST_VECTOR_ELT (operands[1], 3)); - hint <<= 16; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2)); - } - - otherops[1] = GEN_INT (hint); - hint = 0; - - if (BYTES_BIG_ENDIAN) - { - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0)); - hint <<= 16; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1)); - } - else - { - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1)); - hint <<= 16; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0)); - } - - operands[1] = GEN_INT (hint); - break; - - case V8QImode: - if (BYTES_BIG_ENDIAN) - { - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7)); - } - else - { - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4)); - } - - otherops[1] = GEN_INT (hint); - hint = 0; - - if (BYTES_BIG_ENDIAN) - { - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3)); - } - else - { - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1)); - hint <<= 8; - hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0)); - } - - operands[1] = GEN_INT (hint); - break; - - default: - abort (); - } - output_mov_immediate (operands); - output_mov_immediate (otherops); - } - else if (code1 == CONST_DOUBLE) - { - if (GET_MODE (operands[1]) == DFmode) - { - REAL_VALUE_TYPE r; - long l[2]; - - REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); - REAL_VALUE_TO_TARGET_DOUBLE (r, l); - otherops[1] = GEN_INT (l[1]); - operands[1] = GEN_INT (l[0]); - } - else if (GET_MODE (operands[1]) != VOIDmode) - abort (); - else if (WORDS_BIG_ENDIAN) - { - otherops[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - operands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); - } - else - { - otherops[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); - operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - } - - output_mov_immediate (operands); - output_mov_immediate (otherops); - } - else if (code1 == CONST_INT) - { -#if HOST_BITS_PER_WIDE_INT > 32 - /* If HOST_WIDE_INT is more than 32 bits, the intval tells us - what the upper word is. */ - if (WORDS_BIG_ENDIAN) - { - otherops[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1]))); - operands[1] = GEN_INT (INTVAL (operands[1]) >> 32); - } - else - { - otherops[1] = GEN_INT (INTVAL (operands[1]) >> 32); - operands[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1]))); - } -#else - /* Sign extend the intval into the high-order word. */ - if (WORDS_BIG_ENDIAN) - { - otherops[1] = operands[1]; - operands[1] = (INTVAL (operands[1]) < 0 - ? constm1_rtx : const0_rtx); - } - else - otherops[1] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx; -#endif - output_mov_immediate (otherops); - output_mov_immediate (operands); - } - else if (code1 == MEM) + if (code1 == MEM) { switch (GET_CODE (XEXP (operands[1], 0))) { @@ -8479,43 +8290,6 @@ output_move_double (rtx *operands) return ""; } - -/* Output an arbitrary MOV reg, #n. - OPERANDS[0] is a register. OPERANDS[1] is a const_int. */ -const char * -output_mov_immediate (rtx *operands) -{ - HOST_WIDE_INT n = INTVAL (operands[1]); - - /* Try to use one MOV. */ - if (const_ok_for_arm (n)) - output_asm_insn ("mov%?\t%0, %1", operands); - - /* Try to use one MVN. */ - else if (const_ok_for_arm (~n)) - { - operands[1] = GEN_INT (~n); - output_asm_insn ("mvn%?\t%0, %1", operands); - } - else - { - int n_ones = 0; - int i; - - /* If all else fails, make it out of ORRs or BICs as appropriate. */ - for (i = 0; i < 32; i++) - if (n & 1 << i) - n_ones++; - - if (n_ones > 16) /* Shorter to use MVN with BIC in this case. */ - output_multi_immediate (operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1, ~ n); - else - output_multi_immediate (operands, "mov%?\t%0, %1", "orr%?\t%0, %0, %1", 1, n); - } - - return ""; -} - /* Output an ADD r, s, #n where n may be too big for one instruction. If adding zero to one register, output nothing. */ const char * diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 6e223c875b3..088c003f524 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1323,7 +1323,9 @@ enum reg_class 'Uq' is an address valid for ldrsb. */ #define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR) \ - (((C) == 'D') ? (GET_CODE (OP) == CONST_DOUBLE \ + (((C) == 'D') ? ((GET_CODE (OP) == CONST_DOUBLE \ + || GET_CODE (OP) == CONST_INT \ + || GET_CODE (OP) == CONST_VECTOR) \ && (((STR)[1] == 'a' \ && arm_const_double_inline_cost (OP) == 2) \ || ((STR)[1] == 'b' \ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index a4f914aa4c7..9474c0db55a 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -289,6 +289,18 @@ ;; distant label. Only applicable to Thumb code. (define_attr "far_jump" "yes,no" (const_string "no")) + +;;--------------------------------------------------------------------------- +;; Mode macros + +; A list of modes that are exactly 64 bits in size. We use this to expand +; some splits that are the same for all modes when operating on ARM +; registers. +(define_mode_macro ANY64 [DI DF V8QI V4HI V2SI V2SF]) + +;;--------------------------------------------------------------------------- +;; Predicates + (include "predicates.md") ;;--------------------------------------------------------------------------- @@ -4137,13 +4149,21 @@ ) (define_insn "*arm_movdi" - [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m") - (match_operand:DI 1 "di_operand" "rIKDa,Db,Dc,mi,r"))] + [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m") + (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))] "TARGET_ARM && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP)) && !TARGET_IWMMXT" "* - return (output_move_double (operands)); + switch (which_alternative) + { + case 0: + case 1: + case 2: + return \"#\"; + default: + return output_move_double (operands); + } " [(set_attr "length" "8,12,16,8,8") (set_attr "type" "*,*,*,load2,store2") @@ -4151,6 +4171,53 @@ (set_attr "neg_pool_range" "*,*,*,1008,*")] ) +(define_split + [(set (match_operand:ANY64 0 "arm_general_register_operand" "") + (match_operand:ANY64 1 "const_double_operand" ""))] + "TARGET_ARM + && reload_completed + && (arm_const_double_inline_cost (operands[1]) + <= ((optimize_size || arm_ld_sched) ? 3 : 4))" + [(const_int 0)] + " + arm_split_constant (SET, SImode, curr_insn, + INTVAL (gen_lowpart (SImode, operands[1])), + gen_lowpart (SImode, operands[0]), NULL_RTX, 0); + arm_split_constant (SET, SImode, curr_insn, + INTVAL (gen_highpart_mode (SImode, + GET_MODE (operands[0]), + operands[1])), + gen_highpart (SImode, operands[0]), NULL_RTX, 0); + DONE; + " +) + +(define_split + [(set (match_operand:ANY64 0 "arm_general_register_operand" "") + (match_operand:ANY64 1 "arm_general_register_operand" ""))] + "TARGET_EITHER && reload_completed" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))] + " + operands[2] = gen_highpart (SImode, operands[0]); + operands[3] = gen_highpart (SImode, operands[1]); + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); + + /* Handle a partial overlap. */ + if (rtx_equal_p (operands[0], operands[3])) + { + rtx tmp0 = operands[0]; + rtx tmp1 = operands[1]; + + operands[0] = operands[2]; + operands[1] = operands[3]; + operands[2] = tmp0; + operands[3] = tmp1; + } + " +) + ;; We can't actually do base+index doubleword loads if the index and ;; destination overlap. Split here so that we at least have chance to ;; schedule. @@ -5150,7 +5217,17 @@ (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))] "TARGET_ARM && TARGET_SOFT_FLOAT " - "* return output_move_double (operands);" + "* + switch (which_alternative) + { + case 0: + case 1: + case 2: + return \"#\"; + default: + return output_move_double (operands); + } + " [(set_attr "length" "8,12,16,8,8") (set_attr "type" "*,*,*,load2,store2") (set_attr "pool_range" "1020") diff --git a/gcc/config/arm/cirrus.md b/gcc/config/arm/cirrus.md index 5a30eb5fa71..ece341e4155 100644 --- a/gcc/config/arm/cirrus.md +++ b/gcc/config/arm/cirrus.md @@ -377,9 +377,10 @@ switch (which_alternative) { case 0: + return \"#\"; case 1: case 2: - return (output_move_double (operands)); + return output_move_double (operands); case 3: return \"cfmv64lr%?\\t%V0, %Q1\;cfmv64hr%?\\t%V0, %R1\"; case 4: return \"cfmvr64l%?\\t%Q0, %V1\;cfmvr64h%?\\t%R0, %V1\"; @@ -460,7 +461,8 @@ { case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\"; case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\"; - case 2: case 3: case 4: return output_move_double (operands); + case 2: return \"#\"; + case 3: case 4: return output_move_double (operands); case 5: return \"cfcpyd%?\\t%V0, %V1\"; case 6: return \"cfldrd%?\\t%V0, %1\"; case 7: return \"cfmvdlr\\t%V0, %Q1\;cfmvdhr%?\\t%V0, %R1\"; diff --git a/gcc/config/arm/fpa.md b/gcc/config/arm/fpa.md index 02d0804b5f0..cbcfc13cd8a 100644 --- a/gcc/config/arm/fpa.md +++ b/gcc/config/arm/fpa.md @@ -563,7 +563,8 @@ default: case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\"; case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\"; - case 2: case 3: case 4: return output_move_double (operands); + case 2: return \"#\"; + case 3: case 4: return output_move_double (operands); case 5: return \"mvf%?d\\t%0, %1\"; case 6: return \"mnf%?d\\t%0, #%N1\"; case 7: return \"ldf%?d\\t%0, %1\"; diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md index c2adfce07c6..a87d78ffce4 100644 --- a/gcc/config/arm/iwmmxt.md +++ b/gcc/config/arm/iwmmxt.md @@ -73,6 +73,8 @@ { default: return output_move_double (operands); + case 0: + return \"#\"; case 3: return \"wmov%?\\t%0,%1\"; case 4: @@ -155,7 +157,7 @@ (define_insn "movv8qi_internal" [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r") - (match_operand:V8QI 1 "general_operand" "y,y,m,y,r,i"))] + (match_operand:V8QI 1 "general_operand" "y,y,mi,y,r,mi"))] "TARGET_REALLY_IWMMXT" "* switch (which_alternative) @@ -175,7 +177,7 @@ (define_insn "movv4hi_internal" [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r") - (match_operand:V4HI 1 "general_operand" "y,y,m,y,r,i"))] + (match_operand:V4HI 1 "general_operand" "y,y,mi,y,r,mi"))] "TARGET_REALLY_IWMMXT" "* switch (which_alternative) @@ -195,7 +197,7 @@ (define_insn "movv2si_internal" [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r") - (match_operand:V2SI 1 "general_operand" "y,y,m,y,r,i"))] + (match_operand:V2SI 1 "general_operand" "y,y,mi,y,r,mi"))] "TARGET_REALLY_IWMMXT" "* switch (which_alternative) @@ -220,7 +222,7 @@ ;; deliberately omitted. (define_insn "movv2si_internal_2" [(set (match_operand:V2SI 0 "nonimmediate_operand" "=?r") - (match_operand 1 "immediate_operand" "i"))] + (match_operand 1 "immediate_operand" "mi"))] "TARGET_REALLY_IWMMXT" "* return output_move_double (operands);" [(set_attr "predicable" "yes") diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index fb20dd19760..4086a5c6643 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -142,8 +142,11 @@ "* switch (which_alternative) { - case 0: case 1: case 2: - return (output_move_double (operands)); + case 0: + return \"#\"; + case 1: + case 2: + return output_move_double (operands); case 3: return \"fmdrr%?\\t%P0, %1\\t%@ int\"; case 4: @@ -203,7 +206,7 @@ return \"fmdrr%?\\t%P0, %Q1, %R1\"; case 1: return \"fmrrd%?\\t%Q0, %R0, %P1\"; - case 2: case 3: case 7: + case 2: case 3: return output_move_double (operands); case 4: return \"fldd%?\\t%P0, %1\"; @@ -211,6 +214,8 @@ return \"fstd%?\\t%P1, %0\"; case 6: return \"fcpyd%?\\t%P0, %P1\"; + case 7: + return \"#\"; default: abort (); } -- 2.30.2