Patches from wilson; consider fp constants if -mrelocatable to be hard
authorMichael Meissner <meissner@gcc.gnu.org>
Thu, 20 Mar 1997 19:02:29 +0000 (19:02 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Thu, 20 Mar 1997 19:02:29 +0000 (19:02 +0000)
From-SVN: r13754

gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md

index d934cdf9c65fc604e0304c437dcd80d7ee11e2db..bf1f76c9d525ddddc2a532cd0ce323af068be0e4 100644 (file)
@@ -675,6 +675,12 @@ easy_fp_constant (op, mode)
   if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
     return 0;
 
+#ifdef TARGET_RELOCATABLE
+  /* Similarly if we are using -mrelocatable, consider all constants to be hard */
+  if (TARGET_RELOCATABLE)
+    return 0;
+#endif
+
   if (mode == DFmode)
     {
       long k[2];
@@ -744,22 +750,6 @@ offsettable_addr_operand (op, mode)
                                mode, op);
 }
 
-/* Return 1 if the operand is either a floating-point register, a pseudo
-   register, or memory.  */
-
-int
-fp_reg_or_mem_operand (op, mode)
-     register rtx op;
-     enum machine_mode mode;
-{
-  return (memory_operand (op, mode)
-         || volatile_mem_operand (op, mode)
-         || (register_operand (op, mode)
-             && (GET_CODE (op) != REG
-                 || REGNO (op) >= FIRST_PSEUDO_REGISTER
-                 || FP_REGNO_P (REGNO (op)))));
-}
-
 /* Return 1 if the operand is either an easy FP constant (see above) or
    memory.  */
 
index 6ca3aa4683ae5a633d32ebfa9b4797ef3cf4b269..eac6df393aeae1ceb714bd9999bf4786c53a6ef5 100644 (file)
@@ -3000,7 +3000,6 @@ do {                                                                      \
   {"lwa_operand", {SUBREG, MEM, REG}},                         \
   {"volatile_mem_operand", {MEM}},                             \
   {"offsettable_addr_operand", {REG, SUBREG, PLUS}},           \
-  {"fp_reg_or_mem_operand", {SUBREG, MEM, REG}},               \
   {"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}},  \
   {"add_operand", {SUBREG, REG, CONST_INT}},                   \
   {"non_add_cint_operand", {CONST_INT}},                       \
@@ -3060,7 +3059,6 @@ extern int num_insns_constant ();
 extern int easy_fp_constant ();
 extern int volatile_mem_operand ();
 extern int offsettable_addr_operand ();
-extern int fp_reg_or_mem_operand ();
 extern int mem_or_easy_const_operand ();
 extern int add_operand ();
 extern int non_add_cint_operand ();
index 61d16a11d1428c0063a0dfdc35060bd8e57da870..cdd419f656f3d104909572615b3bde5de2f03c5b 100644 (file)
 (define_split
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
        (match_operand:SF 1 "const_double_operand" ""))]
-  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) <= 1 && REGNO (operands[0]) <= 31"
+  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) <= 1
+   && ((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 3))]
   "
 {
   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
   REAL_VALUE_TO_TARGET_SINGLE (rv, l);
 
-  operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0);
+  operands[2] = operand_subword (operands[0], 0, 0, SFmode);
   operands[3] = GEN_INT(l);
 }")
 
 (define_split
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
        (match_operand:SF 1 "const_double_operand" ""))]
-  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) == 2 && REGNO (operands[0]) <= 31"
+  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) == 2
+   && ((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 3))
    (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 4)))]
   "
   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
   REAL_VALUE_TO_TARGET_SINGLE (rv, l);
 
-  operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0);
+  operands[2] = operand_subword (operands[0], 0, 0, SFmode);
   operands[3] = GEN_INT(l & 0xffff0000);
   operands[4] = GEN_INT(l & 0x0000ffff);
 }")
 
 (define_insn "*movsf_hardfloat"
-  [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m,!r,!r")
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,!r,!r")
        (match_operand:SF 1 "input_operand" "f,m,f,G,Fn"))]
   "(gpc_reg_operand (operands[0], SFmode)
    || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
 (define_split
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
        (match_operand:DF 1 "const_int_operand" ""))]
-  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 1 && REGNO (operands[0]) <= 31"
+  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 1
+   && ((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 1))]
   "
 {
-  operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
-  operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
+  int endian = (WORDS_BIG_ENDIAN == 0);
+  operands[2] = operand_subword (operands[0], endian, 0, DFmode);
+  operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
   operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
 }")
 
 (define_split
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
        (match_operand:DF 1 "const_int_operand" ""))]
-  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 2 && REGNO (operands[0]) <= 31"
+  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 2
+   && ((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 3) (match_dup 5))
    (set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 6)))]
   "
 {
   HOST_WIDE_INT value = INTVAL (operands[1]);
-  operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
-  operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
+  int endian = (WORDS_BIG_ENDIAN == 0);
+  operands[2] = operand_subword (operands[0], endian, 0, DFmode);
+  operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
   operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
   operands[5] = GEN_INT (value & 0xffff0000);
   operands[6] = GEN_INT (value & 0x0000ffff);
 (define_split
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
        (match_operand:DF 1 "const_double_operand" ""))]
-  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 2 && REGNO (operands[0]) <= 31"
+  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 2
+   && ((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))]
   "
 {
-  operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
-  operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
+  int endian = (WORDS_BIG_ENDIAN == 0);
+  operands[2] = operand_subword (operands[0], endian, 0, DFmode);
+  operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
 
 #ifdef HOST_WORDS_BIG_ENDIAN
   operands[4] = GEN_INT (CONST_DOUBLE_LOW  (operands[1]));
 (define_split
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
        (match_operand:DF 1 "const_double_operand" ""))]
-  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) == 3 && REGNO (operands[0]) <= 31"
+  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) == 3
+   && ((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))
    (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))]
 {
   HOST_WIDE_INT high;
   HOST_WIDE_INT low;
-  rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
-  rtx low_reg  = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
+  int endian = (WORDS_BIG_ENDIAN == 0);
+  rtx high_reg = operand_subword (operands[0], endian, 0, DFmode);
+  rtx low_reg  = operand_subword (operands[0], 1 - endian, 0, DFmode);
 
 #ifdef HOST_WORDS_BIG_ENDIAN
   high = CONST_DOUBLE_LOW  (operands[1]);
 (define_split
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
        (match_operand:DF 1 "const_double_operand" ""))]
-  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 4 && REGNO (operands[0]) <= 31"
+  "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 4
+   && ((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))
    (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))
 {
   HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
   HOST_WIDE_INT low  = CONST_DOUBLE_LOW  (operands[1]);
+  int endian = (WORDS_BIG_ENDIAN == 0);
 
-  operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
-  operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
+  operands[2] = operand_subword (operands[0], endian, 0, DFmode);
+  operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
   operands[4] = GEN_INT (high & 0xffff0000);
   operands[5] = GEN_INT (low  & 0xffff0000);
   operands[6] = GEN_INT (high & 0x0000ffff);
 (define_split
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
        (match_operand:DF 1 "easy_fp_constant" ""))]
-  "TARGET_64BIT && reload_completed && REGNO (operands[0]) <= 31"
-  [(set (subreg:DI (match_dup 0) 0) (subreg:DI (match_dup 1) 0))]
-  "")
+  "TARGET_64BIT && 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) (subreg:DI (match_dup 1) 0))]
+  "
+{ operands[2] = gen_lowpart (DImode, operands[0]); }")
 
 ;; Don't have reload use general registers to load a constant.  First,
 ;; it might not work if the output operand has is the equivalent of