summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2000-07-03 20:00:44 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2000-07-03 20:00:44 +0000
commit5b6c6a8e26f3bbaed5b61eb21fbad79ce4d0e464 (patch)
tree75e6dae798241201d77df3dd22054dddc824c663 /gcc
parent2182a646d158b2e9c44f007594d253793a23756f (diff)
downloadgcc-5b6c6a8e26f3bbaed5b61eb21fbad79ce4d0e464.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34852 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c269
-rw-r--r--gcc/config/rs6000/rs6000.md309
4 files changed, 287 insertions, 302 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a14e7638a8a..85c2e0855f1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,15 @@
2000-07-03 Geoff Keating <geoffk@cygnus.com>
+ * 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 691dfa935a8..2237b7e1c8f 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 66cb91145ac..73b46df7ce0 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 a839971a196..4dfe6ba4a23 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