From fb4d43485acbe15bc3cfeed48f0dae1d9556f9e5 Mon Sep 17 00:00:00 2001 From: Geoff Keating Date: Mon, 3 Jul 2000 20:00:44 +0000 Subject: [PATCH] rs6000.c (rs6000_emit_move): New function. * config/rs6000/rs6000.c (rs6000_emit_move): New function. * config/rs6000/rs6000-proto.h: Prototype rs6000_emit_move. * config/rs6000/rs6000.md (movsi): Use rs6000_emit_move. (movhi): Likewise. (movqi): Likewise. (movdf): Likewise. (movsf): Likewise. (movdi): Likewise. (movti): Likewise. From-SVN: r34852 --- gcc/ChangeLog | 10 ++ gcc/config/rs6000/rs6000-protos.h | 1 + gcc/config/rs6000/rs6000.c | 269 +++++++++++++++++++++++++++++++++ gcc/config/rs6000/rs6000.md | 309 +------------------------------------- 4 files changed, 287 insertions(+), 302 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a14e763..85c2e08 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2000-07-03 Geoff Keating + * config/rs6000/rs6000.c (rs6000_emit_move): New function. + * config/rs6000/rs6000-proto.h: Prototype rs6000_emit_move. + * config/rs6000/rs6000.md (movsi): Use rs6000_emit_move. + (movhi): Likewise. + (movqi): Likewise. + (movdf): Likewise. + (movsf): Likewise. + (movdi): Likewise. + (movti): Likewise. + * expmed.c (expand_mult_highpart): Use op1 instead of wide_op1 when mode instead of wider_mode is being used. diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 691dfa9..2237b7e 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -97,6 +97,7 @@ extern int mtcrf_operation PARAMS ((rtx, enum machine_mode)); extern int lmw_operation PARAMS ((rtx, enum machine_mode)); extern struct rtx_def *create_TOC_reference PARAMS ((rtx)); extern void rs6000_emit_eh_toc_restore PARAMS ((rtx)); +extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode)); extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode)); extern void rs6000_select_rtx_section PARAMS ((enum machine_mode, rtx)); #endif /* RTX_CODE */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 66cb911..73b46df 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1458,8 +1458,277 @@ rs6000_legitimize_address (x, oldx, mode) else return NULL_RTX; } + +/* Emit a move from SOURCE to DEST in mode MODE. */ +void +rs6000_emit_move (dest, source, mode) + rtx dest; + rtx source; + enum machine_mode mode; +{ + rtx operands[2]; + operands[0] = dest; + operands[1] = source; + + /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */ + if (GET_CODE (operands[1]) == CONST_DOUBLE + && ! FLOAT_MODE_P (mode) + && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) + { + /* FIXME. This should never happen. */ + /* Since it seems that it does, do the safe thing and convert + to a CONST_INT. */ + operands[1] = + GEN_INT (trunc_int_for_mode (CONST_DOUBLE_LOW (operands[1]), mode)); + } + if (GET_CODE (operands[1]) == CONST_DOUBLE + && ! FLOAT_MODE_P (mode) + && ((CONST_DOUBLE_HIGH (operands[1]) == 0 + && CONST_DOUBLE_LOW (operands[1]) >= 0) + || (CONST_DOUBLE_HIGH (operands[1]) == -1 + && CONST_DOUBLE_LOW (operands[1]) < 0))) + abort (); + + if (! no_new_pseudos && GET_CODE (operands[0]) != REG) + operands[1] = force_reg (mode, operands[1]); + + if (mode == SFmode && ! TARGET_POWERPC && TARGET_HARD_FLOAT) + { + int regnum = true_regnum (operands[1]); + /* regnum may be -1 in which case the test below will fail. */ + + /* If operands[1] is a register, on POWER it may have + double-precision data in it, so truncate it to single + precision. */ + if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER) + { + rtx newreg; + newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode)); + emit_insn (gen_aux_truncdfsf2 (newreg, operands[1])); + operands[1] = newreg; + } + } + + /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */ + if (GET_CODE (operands[1]) == CONSTANT_P_RTX) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); + 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. */ + switch (mode) + { + case HImode: + case QImode: + if (CONSTANT_P (operands[1]) + && GET_CODE (operands[1]) != CONST_INT) + { + operands[1] = force_const_mem (mode, operands[1]); + if (! memory_address_p (mode, XEXP (operands[1], 0)) + && ! reload_in_progress) + operands[1] = change_address (operands[1], mode, + XEXP (operands[1], 0)); + } + break; + case DFmode: + case SFmode: + if (CONSTANT_P (operands[1]) + && ! easy_fp_constant (operands[1], mode)) + { + operands[1] = force_const_mem (mode, operands[1]); + if (! memory_address_p (mode, XEXP (operands[1], 0)) + && ! reload_in_progress) + operands[1] = change_address (operands[1], mode, + XEXP (operands[1], 0)); + } + break; + + case SImode: + /* Use default pattern for address of ELF small data */ + if (TARGET_ELF + && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) + && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) + && small_data_operand (operands[1], SImode)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); + return; + } + + if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) + && flag_pic == 1 && got_operand (operands[1], SImode)) + { + emit_insn (gen_movsi_got (operands[0], operands[1])); + return; + } + if (TARGET_ELF && TARGET_NO_TOC && ! TARGET_64BIT + && ! flag_pic + && CONSTANT_P (operands[1]) + && GET_CODE (operands[1]) != HIGH + && GET_CODE (operands[1]) != CONST_INT) + { + rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (SImode)); + + /* If this is a function address on -mcall-aixdesc, + convert it to the address of the descriptor. */ + if (DEFAULT_ABI == ABI_AIX + && GET_CODE (operands[1]) == SYMBOL_REF + && XSTR (operands[1], 0)[0] == '.') + { + const char *name = XSTR (operands[1], 0); + rtx new_ref; + while (*name == '.') + name++; + new_ref = gen_rtx_SYMBOL_REF (Pmode, name); + CONSTANT_POOL_ADDRESS_P (new_ref) + = CONSTANT_POOL_ADDRESS_P (operands[1]); + SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]); + SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]); + operands[1] = new_ref; + } + + emit_insn (gen_elf_high (target, operands[1])); + emit_insn (gen_elf_low (operands[0], target, operands[1])); + return; + } + + if (CONSTANT_P (operands[1]) + && GET_CODE (operands[1]) != CONST_INT + && GET_CODE (operands[1]) != HIGH + && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]) + && ! TOC_RELATIVE_EXPR_P (operands[1])) + { + /* Emit a USE operation so that the constant isn't deleted if + expensive optimizations are turned on because nobody + references it. This should only be done for operands that + contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set. + This should not be done for operands that contain LABEL_REFs. + For now, we just handle the obvious case. */ + if (GET_CODE (operands[1]) != LABEL_REF) + emit_insn (gen_rtx_USE (VOIDmode, operands[1])); + + /* If we are to limit the number of things we put in the TOC and + this is a symbol plus a constant we can add in one insn, + just put the symbol in the TOC and add the constant. Don't do + this if reload is in progress. */ + if (GET_CODE (operands[1]) == CONST + && TARGET_NO_SUM_IN_TOC && ! reload_in_progress + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode) + && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF + || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF) + && ! side_effects_p (operands[0])) + { + rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0)); + rtx other = XEXP (XEXP (operands[1], 0), 1); + + emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other)); + return; + } + + operands[1] = force_const_mem (SImode, operands[1]); + + if (TARGET_TOC + && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0)) + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant ( + XEXP (operands[1], 0)))) + { + operands[1] = gen_rtx_MEM (SImode, + create_TOC_reference (XEXP (operands[1], 0))); + MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set (); + RTX_UNCHANGING_P (operands[1]) = 1; + } + + if (! memory_address_p (SImode, XEXP (operands[1], 0)) + && ! reload_in_progress) + operands[1] = change_address (operands[1], SImode, + XEXP (operands[1], 0)); + } + break; + + case DImode: + if (TARGET_64BIT + && CONSTANT_P (operands[1]) +#if HOST_BITS_PER_WIDE_INT == 32 + && GET_CODE (operands[1]) != CONST_INT +#endif + && ! easy_fp_constant (operands[1], DImode) + && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]) + && ! TOC_RELATIVE_EXPR_P (operands[1])) + { + /* Emit a USE operation so that the constant isn't deleted if + expensive optimizations are turned on because nobody + references it. This should only be done for operands that + contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set. + This should not be done for operands that contain LABEL_REFs. + For now, we just handle the obvious case. */ + if (GET_CODE (operands[1]) != LABEL_REF) + emit_insn (gen_rtx_USE (VOIDmode, operands[1])); + + /* If we are to limit the number of things we put in the TOC and + this is a symbol plus a constant we can add in one insn, + just put the symbol in the TOC and add the constant. Don't do + this if reload is in progress. */ + if (GET_CODE (operands[1]) == CONST + && TARGET_NO_SUM_IN_TOC && ! reload_in_progress + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && add_operand (XEXP (XEXP (operands[1], 0), 1), DImode) + && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF + || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF) + && ! side_effects_p (operands[0])) + { + rtx sym = force_const_mem (DImode, XEXP (XEXP (operands[1], 0), 0)); + rtx other = XEXP (XEXP (operands[1], 0), 1); + + emit_insn (gen_adddi3 (operands[0], force_reg (DImode, sym), other)); + return; + } + + operands[1] = force_const_mem (DImode, operands[1]); + + if (TARGET_TOC + && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0)) + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant ( + XEXP (operands[1], 0)))) + { + operands[1] = gen_rtx_MEM (DImode, + create_TOC_reference (XEXP (operands[1], 0))); + + MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set (); + RTX_UNCHANGING_P (operands[1]) = 1; + } + + if (! memory_address_p (DImode, XEXP (operands[1], 0)) + && ! reload_in_progress) + operands[1] = change_address (operands[1], DImode, + XEXP (operands[1], 0)); + } + break; + + case TImode: + if (GET_CODE (operands[0]) == MEM + && GET_CODE (XEXP (operands[0], 0)) != REG + && ! reload_in_progress) + operands[0] = change_address (operands[0], TImode, + copy_addr_to_reg (XEXP (operands[0], 0))); + + if (GET_CODE (operands[1]) == MEM + && GET_CODE (XEXP (operands[1], 0)) != REG + && ! reload_in_progress) + operands[1] = change_address (operands[1], TImode, + copy_addr_to_reg (XEXP (operands[1], 0))); + break; + + default: + abort (); + } + + emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); +} /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a839971..4dfe6ba 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -7434,123 +7434,7 @@ [(set (match_operand:SI 0 "general_operand" "") (match_operand:SI 1 "any_operand" ""))] "" - " -{ - if (! no_new_pseudos && GET_CODE (operands[0]) != REG) - operands[1] = force_reg (SImode, operands[1]); - - /* Convert a move of a CONST_DOUBLE into a CONST_INT */ - if (GET_CODE (operands[1]) == CONST_DOUBLE) - operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - - /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */ - if (GET_CODE (operands[1]) == CONSTANT_P_RTX) - { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; - } - - /* Use default pattern for address of ELF small data */ - if (TARGET_ELF - && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) - && small_data_operand (operands[1], SImode)) - { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; - } - - if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && flag_pic == 1 && got_operand (operands[1], SImode)) - { - emit_insn (gen_movsi_got (operands[0], operands[1])); - DONE; - } - - if (TARGET_ELF && TARGET_NO_TOC && ! TARGET_64BIT - && ! flag_pic - && CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != HIGH - && GET_CODE (operands[1]) != CONST_INT) - { - rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (SImode)); - - /* If this is a function address on -mcall-aixdesc, - convert it to the address of the descriptor. */ - if (DEFAULT_ABI == ABI_AIX - && GET_CODE (operands[1]) == SYMBOL_REF - && XSTR (operands[1], 0)[0] == '.') - { - const char *name = XSTR (operands[1], 0); - rtx new_ref; - while (*name == '.') - name++; - new_ref = gen_rtx_SYMBOL_REF (Pmode, name); - CONSTANT_POOL_ADDRESS_P (new_ref) - = CONSTANT_POOL_ADDRESS_P (operands[1]); - SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]); - SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]); - operands[1] = new_ref; - } - - emit_insn (gen_elf_high (target, operands[1])); - emit_insn (gen_elf_low (operands[0], target, operands[1])); - DONE; - } - - if (CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != CONST_INT - && GET_CODE (operands[1]) != HIGH - && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]) - && ! TOC_RELATIVE_EXPR_P (operands[1])) - { - /* Emit a USE operation so that the constant isn't deleted if - expensive optimizations are turned on because nobody - references it. This should only be done for operands that - contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set. - This should not be done for operands that contain LABEL_REFs. - For now, we just handle the obvious case. */ - if (GET_CODE (operands[1]) != LABEL_REF) - emit_insn (gen_rtx_USE (VOIDmode, operands[1])); - - /* If we are to limit the number of things we put in the TOC and - this is a symbol plus a constant we can add in one insn, - just put the symbol in the TOC and add the constant. Don't do - this if reload is in progress. */ - if (GET_CODE (operands[1]) == CONST - && TARGET_NO_SUM_IN_TOC && ! reload_in_progress - && GET_CODE (XEXP (operands[1], 0)) == PLUS - && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode) - && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF - || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF) - && ! side_effects_p (operands[0])) - { - rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0)); - rtx other = XEXP (XEXP (operands[1], 0), 1); - - emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other)); - DONE; - } - - operands[1] = force_const_mem (SImode, operands[1]); - - if (TARGET_TOC - && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0)) - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant ( - XEXP (operands[1], 0)))) - { - operands[1] = gen_rtx_MEM (SImode, - create_TOC_reference (XEXP (operands[1], 0))); - MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set (); - RTX_UNCHANGING_P (operands[1]) = 1; - } - - if (! memory_address_p (SImode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], SImode, - XEXP (operands[1], 0)); - } -}") + "{ rs6000_emit_move (operands[0], operands[1], SImode); DONE; }") (define_insn "*movsi_internal1" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h") @@ -7620,21 +7504,7 @@ [(set (match_operand:HI 0 "general_operand" "") (match_operand:HI 1 "any_operand" ""))] "" - " -{ - if (! no_new_pseudos && GET_CODE (operands[0]) != REG) - operands[1] = force_reg (HImode, operands[1]); - - if (CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != CONST_INT) - { - operands[1] = force_const_mem (HImode, operands[1]); - if (! memory_address_p (HImode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], HImode, - XEXP (operands[1], 0)); - } -}") + "{ rs6000_emit_move (operands[0], operands[1], HImode); DONE; }") (define_insn "" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h") @@ -7656,21 +7526,7 @@ [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "any_operand" ""))] "" - " -{ - if (! no_new_pseudos && GET_CODE (operands[0]) != REG) - operands[1] = force_reg (QImode, operands[1]); - - if (CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != CONST_INT) - { - operands[1] = force_const_mem (QImode, operands[1]); - if (! memory_address_p (QImode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], QImode, - XEXP (operands[1], 0)); - } -}") + "{ rs6000_emit_move (operands[0], operands[1], QImode); DONE; }") (define_insn "" [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h") @@ -7723,49 +7579,7 @@ [(set (match_operand:SF 0 "nonimmediate_operand" "") (match_operand:SF 1 "any_operand" ""))] "" - " -{ - /* If we are called from reload, we might be getting a SUBREG of a hard - reg. So expand it. */ - if (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER - && (! REG_FUNCTION_VALUE_P (SUBREG_REG (operands[0])) - || ! rtx_equal_function_value_matters)) - operands[0] = alter_subreg (operands[0]); - if (GET_CODE (operands[1]) == SUBREG - && GET_CODE (SUBREG_REG (operands[1])) == REG - && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER) - operands[1] = alter_subreg (operands[1]); - - if (GET_CODE (operands[0]) == MEM) - { - /* If operands[1] is a register, it may have double-precision data - in it, so truncate it to single precision. We need not do - this for POWERPC. */ - if (! TARGET_POWERPC && TARGET_HARD_FLOAT - && GET_CODE (operands[1]) == REG - && (FP_REGNO_P (REGNO (operands[1])) - || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)) - { - rtx newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (SFmode)); - emit_insn (gen_aux_truncdfsf2 (newreg, operands[1])); - operands[1] = newreg; - } - - operands[1] = force_reg (SFmode, operands[1]); - } - - if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT - && ! easy_fp_constant (operands[1], SFmode)) - { - operands[1] = force_const_mem (SFmode, operands[1]); - if (! memory_address_p (SFmode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], SFmode, - XEXP (operands[1], 0)); - } -}") + "{ rs6000_emit_move (operands[0], operands[1], SFmode); DONE; }") (define_split [(set (match_operand:SF 0 "gpc_reg_operand" "") @@ -7831,20 +7645,7 @@ [(set (match_operand:DF 0 "nonimmediate_operand" "") (match_operand:DF 1 "any_operand" ""))] "" - " -{ - if (GET_CODE (operands[0]) != REG) - operands[1] = force_reg (DFmode, operands[1]); - - if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode)) - { - operands[1] = force_const_mem (DFmode, operands[1]); - if (! memory_address_p (DFmode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], DFmode, - XEXP (operands[1], 0)); - } -}") + "{ rs6000_emit_move (operands[0], operands[1], DFmode); DONE; }") (define_split [(set (match_operand:DF 0 "gpc_reg_operand" "") @@ -8100,87 +7901,7 @@ [(set (match_operand:DI 0 "general_operand" "") (match_operand:DI 1 "any_operand" ""))] "" - " -{ - if (! no_new_pseudos && GET_CODE (operands[0]) != REG) - operands[1] = force_reg (DImode, operands[1]); - - /* Convert a move of a CONST_DOUBLE into a CONST_INT - only if sign-extended lower-half for 32-bit host. */ - if (GET_CODE (operands[1]) == CONST_DOUBLE -#if HOST_BITS_PER_WIDE_INT == 32 - && ((CONST_DOUBLE_HIGH (operands[1]) == 0 - && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0) - || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff - && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0)) -#endif - ) - operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - - /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */ - if (GET_CODE (operands[1]) == CONSTANT_P_RTX) - { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; - } - - if (TARGET_64BIT - && CONSTANT_P (operands[1]) -#if HOST_BITS_PER_WIDE_INT == 32 - && GET_CODE (operands[1]) != CONST_INT -#endif - && ! easy_fp_constant (operands[1], DImode) - && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]) - && ! TOC_RELATIVE_EXPR_P (operands[1])) - { - /* Emit a USE operation so that the constant isn't deleted if - expensive optimizations are turned on because nobody - references it. This should only be done for operands that - contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set. - This should not be done for operands that contain LABEL_REFs. - For now, we just handle the obvious case. */ - if (GET_CODE (operands[1]) != LABEL_REF) - emit_insn (gen_rtx_USE (VOIDmode, operands[1])); - - /* If we are to limit the number of things we put in the TOC and - this is a symbol plus a constant we can add in one insn, - just put the symbol in the TOC and add the constant. Don't do - this if reload is in progress. */ - if (GET_CODE (operands[1]) == CONST - && TARGET_NO_SUM_IN_TOC && ! reload_in_progress - && GET_CODE (XEXP (operands[1], 0)) == PLUS - && add_operand (XEXP (XEXP (operands[1], 0), 1), DImode) - && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF - || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF) - && ! side_effects_p (operands[0])) - { - rtx sym = force_const_mem (DImode, XEXP (XEXP (operands[1], 0), 0)); - rtx other = XEXP (XEXP (operands[1], 0), 1); - - emit_insn (gen_adddi3 (operands[0], force_reg (DImode, sym), other)); - DONE; - } - - operands[1] = force_const_mem (DImode, operands[1]); - - if (TARGET_TOC - && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0)) - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant ( - XEXP (operands[1], 0)))) - { - operands[1] = gen_rtx_MEM (DImode, - create_TOC_reference (XEXP (operands[1], 0))); - - MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set (); - RTX_UNCHANGING_P (operands[1]) = 1; - } - - if (! memory_address_p (DImode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], DImode, - XEXP (operands[1], 0)); - } -}") + "{ rs6000_emit_move (operands[0], operands[1], DImode); DONE; }") (define_insn "*movdi_internal32" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r") @@ -8526,23 +8247,7 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32); (match_operand:TI 1 "general_operand" "")) (clobber (scratch:SI))])] "TARGET_STRING || TARGET_POWERPC64" - " -{ - if (GET_CODE (operands[0]) == MEM) - operands[1] = force_reg (TImode, operands[1]); - - if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) != REG - && ! reload_in_progress) - operands[0] = change_address (operands[0], TImode, - copy_addr_to_reg (XEXP (operands[0], 0))); - - if (GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) != REG - && ! reload_in_progress) - operands[1] = change_address (operands[1], TImode, - copy_addr_to_reg (XEXP (operands[1], 0))); -}") + "{ rs6000_emit_move (operands[0], operands[1], TImode); DONE; }") ;; We say that MQ is clobbered in the last alternative because the first ;; alternative would never get used otherwise since it would need a reload -- 2.7.4