sparc.c (sparc_emit_set_const64_quick2, [...]): Fix more bugs in 64-bit constant...
authorDavid S. Miller <davem@pierdol.cobaltmicro.com>
Fri, 14 Aug 1998 14:11:34 +0000 (14:11 +0000)
committerDavid S. Miller <davem@gcc.gnu.org>
Fri, 14 Aug 1998 14:11:34 +0000 (07:11 -0700)
* config/sparc/sparc.c (sparc_emit_set_const64_quick2,
sparc_emit_set_const64_longway, const64_is_2insns,
create_simple_focus_bits, sparc_emit_set_const64): Fix more bugs
in 64-bit constant formation.
* config/sparc/sparc.md (snesi_zero_extend split): Generate
rtl for addx not subx.
(define_insn movdi_const64_special): Make available even when
HOST_BITS_PER_WIDE_INT is not 64.
(movdi_lo_sum_sp64_cint, movdi_high_sp64_cint): Remove.
(losum_di_medlow, sethm, setlo): Make op2 symbolic_operand.
(cmp_siqi_trunc_set, cmp_diqi_trunc_set): Encapsulate both
instances of operand 1 inside a QI subreg.
(xordi3_sp64_dbl): Remove '%' constraint for op1.
(one_cmpldi2_sp64): Fix output string.
(one_cmplsi2_not_liveg0): Rewrite to remove unneeded extra
alternative case.
(unnamed arch64 ashift DI): Truncate shift count if greater than
63, not 31.

From-SVN: r21733

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md

index 11d6b7cd1e9aa85eeaa35bdfe6ae468161c85191..dd51f8da19e581c58615356644257f7a6463c4e2 100644 (file)
@@ -1,3 +1,24 @@
+Fri Aug 14 12:58:21 1998  David S. Miller  <davem@pierdol.cobaltmicro.com>
+
+       * config/sparc/sparc.c (sparc_emit_set_const64_quick2,
+       sparc_emit_set_const64_longway, const64_is_2insns,
+       create_simple_focus_bits, sparc_emit_set_const64): Fix more bugs
+       in 64-bit constant formation.
+       * config/sparc/sparc.md (snesi_zero_extend split): Generate
+       rtl for addx not subx.
+       (define_insn movdi_const64_special): Make available even when
+       HOST_BITS_PER_WIDE_INT is not 64.
+       (movdi_lo_sum_sp64_cint, movdi_high_sp64_cint): Remove.
+       (losum_di_medlow, sethm, setlo): Make op2 symbolic_operand.
+       (cmp_siqi_trunc_set, cmp_diqi_trunc_set): Encapsulate both
+       instances of operand 1 inside a QI subreg.
+       (xordi3_sp64_dbl): Remove '%' constraint for op1.
+       (one_cmpldi2_sp64): Fix output string.
+       (one_cmplsi2_not_liveg0): Rewrite to remove unneeded extra
+       alternative case.
+       (unnamed arch64 ashift DI): Truncate shift count if greater than
+       63, not 31.
+
 Fri Aug 14 21:52:53 1998  J"orn Rennecke <amylaar@cygnus.co.uk>
 
        * expr.c (store_expr): Don't optimize away load-store pair
index d6861b12f60daa82481d6a135e00f0fda7376dc9..6651ee3a75e0871b4393d8a20de8cfa0547c9af6 100644 (file)
@@ -1229,7 +1229,7 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
        {
          /* Getting this right wrt. reloading is really tricky.
             We _MUST_ have a seperate temporary at this point,
-            if we don't barf immediately instead of generating
+            so we barf immediately instead of generating
             incorrect code.  */
          if (temp1 == op0)
            abort ();
@@ -1369,7 +1369,7 @@ sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_immediate, shift_count)
     }
   else
     {
-      emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (high_bits)));
+      emit_insn (gen_safe_SET64 (temp, high_bits));
       temp2 = temp;
     }
 
@@ -1416,7 +1416,7 @@ sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits)
     }
   else
     {
-      emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (high_bits)));
+      emit_insn (gen_safe_SET64 (temp, high_bits));
       sub_temp = temp;
     }
 
@@ -1432,10 +1432,17 @@ sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits)
 
       sparc_emit_set_safe_HIGH64 (temp2, low_bits);
       if ((low_bits & ~0xfffffc00) != 0)
-       emit_insn (gen_rtx_SET (VOIDmode, temp3,
-                               gen_safe_OR64 (temp2, (low_bits & 0x3ff))));
-      emit_insn (gen_rtx_SET (VOIDmode, op0,
-                             gen_rtx_PLUS (DImode, temp4, temp3)));
+       {
+         emit_insn (gen_rtx_SET (VOIDmode, temp3,
+                                 gen_safe_OR64 (temp2, (low_bits & 0x3ff))));
+         emit_insn (gen_rtx_SET (VOIDmode, op0,
+                                 gen_rtx_PLUS (DImode, temp4, temp3)));
+       }
+      else
+       {
+         emit_insn (gen_rtx_SET (VOIDmode, op0,
+                                 gen_rtx_PLUS (DImode, temp4, temp2)));
+       }
     }
   else
     {
@@ -1572,17 +1579,14 @@ const64_is_2insns (high_bits, low_bits)
                          &highest_bit_set, &lowest_bit_set,
                          &all_bits_between_are_set);
 
-  if (highest_bit_set == 63
+  if ((highest_bit_set == 63
+       || lowest_bit_set == 0)
       && all_bits_between_are_set != 0)
     return 1;
 
   if ((highest_bit_set - lowest_bit_set) < 21)
     return 1;
 
-  if (high_bits == 0
-      || high_bits == 0xffffffff)
-    return 1;
-
   return 0;
 }
 
@@ -1595,7 +1599,7 @@ create_simple_focus_bits (high_bits, low_bits, highest_bit_set, lowest_bit_set,
      unsigned HOST_WIDE_INT high_bits, low_bits;
      int highest_bit_set, lowest_bit_set, shift;
 {
-  int hi, lo;
+  HOST_WIDE_INT hi, lo;
 
   if (lowest_bit_set < 32)
     {
@@ -1634,13 +1638,14 @@ sparc_emit_set_const64 (op0, op1)
          && REGNO (op0) <= SPARC_LAST_V9_FP_REG))
     abort ();
 
+  if (reload_in_progress || reload_completed)
+    temp = op0;
+  else
+    temp = gen_reg_rtx (DImode);
+
   if (GET_CODE (op1) != CONST_DOUBLE
       && GET_CODE (op1) != CONST_INT)
     {
-      if (reload_in_progress || reload_completed)
-       temp = op0;
-      else
-       temp = gen_reg_rtx (DImode);
       sparc_emit_set_symbolic_const64 (op0, op1, temp);
       return;
     }
@@ -1671,11 +1676,6 @@ sparc_emit_set_const64 (op0, op1)
   /* low_bits  bits 0  --> 31
      high_bits bits 32 --> 63  */
 
-  if (reload_in_progress || reload_completed)
-    temp = op0;
-  else
-    temp = gen_reg_rtx (DImode);
-
   analyze_64bit_constant (high_bits, low_bits,
                          &highest_bit_set, &lowest_bit_set,
                          &all_bits_between_are_set);
@@ -1699,15 +1699,9 @@ sparc_emit_set_const64 (op0, op1)
       HOST_WIDE_INT the_const = -1;
       int shift = lowest_bit_set;
 
-      if (highest_bit_set == lowest_bit_set)
-       {
-         /* There is no way to get here like this, because this case
-            can be done in one instruction.  */
-         if (lowest_bit_set < 32)
-           abort ();
-         the_const = 1;
-       }
-      else if (all_bits_between_are_set == 0)
+      if ((highest_bit_set != 63
+          && lowest_bit_set != 0)
+         || all_bits_between_are_set == 0)
        {
          the_const =
            create_simple_focus_bits (high_bits, low_bits,
@@ -1717,6 +1711,9 @@ sparc_emit_set_const64 (op0, op1)
       else if (lowest_bit_set == 0)
        shift = -(63 - highest_bit_set);
 
+      if (! SPARC_SIMM13_P (the_const))
+       abort ();
+
       emit_insn (gen_safe_SET64 (temp, the_const));
       if (shift > 0)
        emit_insn (gen_rtx_SET (VOIDmode,
@@ -1746,6 +1743,10 @@ sparc_emit_set_const64 (op0, op1)
       unsigned HOST_WIDE_INT focus_bits =
        create_simple_focus_bits (high_bits, low_bits,
                                  highest_bit_set, lowest_bit_set, 10);
+
+      if (! SPARC_SETHI_P (focus_bits))
+        abort ();
+
       sparc_emit_set_safe_HIGH64 (temp, focus_bits);
 
       /* If lowest_bit_set == 10 then a sethi alone could have done it.  */
@@ -1777,20 +1778,20 @@ sparc_emit_set_const64 (op0, op1)
       return;
     }
 
+  /* Now, try 3-insn sequences.  */
+
   /* 1) sethi  %hi(high_bits), %reg
    *    or     %reg, %lo(high_bits), %reg
    *    sllx   %reg, 32, %reg
    */
-  if (low_bits == 0
-      || (SPARC_SIMM13_P(low_bits)
-         && ((HOST_WIDE_INT)low_bits > 0)))
+  if (low_bits == 0)
     {
-      sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_bits, 32);
+      sparc_emit_set_const64_quick2 (op0, temp, high_bits, 0, 32);
       return;
     }
 
-  /* Now, try 3-insn sequences.  But first we may be able to do something
-     quick when the constant is negated, so try that.  */
+  /* We may be able to do something quick
+     when the constant is negated, so try that.  */
   if (const64_is_2insns ((~high_bits) & 0xffffffff,
                         (~low_bits) & 0xfffffc00))
     {
@@ -1832,10 +1833,15 @@ sparc_emit_set_const64 (op0, op1)
   /* 1) sethi  %hi(xxx), %reg
    *    or     %reg, %lo(xxx), %reg
    *   sllx    %reg, yyy, %reg
+   *
+   * ??? This is just a generalized version of the low_bits==0
+   * thing above, FIXME...
    */
   if ((highest_bit_set - lowest_bit_set) < 32)
     {
-      unsigned HOST_WIDE_INT hi, lo, focus_bits;
+      unsigned HOST_WIDE_INT focus_bits =
+       create_simple_focus_bits (high_bits, low_bits,
+                                 highest_bit_set, lowest_bit_set, 0);
 
       /* We can't get here in this state.  */
       if (highest_bit_set < 32
@@ -1844,17 +1850,24 @@ sparc_emit_set_const64 (op0, op1)
 
       /* So what we know is that the set bits straddle the
         middle of the 64-bit word.  */
-      hi = (low_bits >> lowest_bit_set);
-      lo = (high_bits << (32 - lowest_bit_set));
-      if (hi & lo)
-       abort ();
-      focus_bits = (hi | lo);
       sparc_emit_set_const64_quick2 (op0, temp,
                                     focus_bits, 0,
                                     lowest_bit_set);
       return;
     }
 
+  /* 1) sethi  %hi(high_bits), %reg
+   *    or     %reg, %lo(high_bits), %reg
+   *    sllx   %reg, 32, %reg
+   *   or      %reg, low_bits, %reg
+   */
+  if (SPARC_SIMM13_P(low_bits)
+      && ((int)low_bits > 0))
+    {
+      sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_bits, 32);
+      return;
+    }
+
   /* The easiest way when all else fails, is full decomposition. */
 #if 0
   printf ("sparc_emit_set_const64: Hard constant [%08lx%08lx] neg[%08lx%08lx]\n",
index 47b10ac9ee92fb4c91a20643aa8c4219df29af8a..72795121ec0236fd65ebe5ea45c794dfddd501bc 100644 (file)
    && reload_completed"
   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
                                            (const_int 0)))
-   (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
-                                                          (const_int 0))
-                                                (ltu:SI (reg:CC_NOOV 100)
-                                                        (const_int 0)))))]
+   (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
+                                                        (const_int 0))
+                                               (ltu:SI (reg:CC_NOOV 100)
+                                                       (const_int 0)))))]
   "")
 
 (define_insn "*snedi_zero"
   [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
    (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
 
+;; The following are generated by sparc_emit_set_const64
 (define_insn "*movdi_sp64_dbl"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (match_operand:DI 1 "const64_operand" ""))]
   [(set_attr "type" "move")
    (set_attr "length" "1")])
 
+;; This is needed to show CSE exactly which bits are set
+;; in a 64-bit register by sethi instructions.
 (define_insn "*movdi_const64_special"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (match_operand:DI 1 "const64_high_operand" ""))]
-  "(TARGET_ARCH64
-    && HOST_BITS_PER_WIDE_INT != 64)"
+  "TARGET_ARCH64"
   "sethi\\t%%hi(%a1), %0"
   [(set_attr "type" "move")
    (set_attr "length" "1")])
   [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore")
    (set_attr "length" "1")])
 
-;; The following are generated by sparc_emit_set_const64
-(define_insn "*movdi_lo_sum_sp64_cint"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
-                   (match_operand:DI 2 "const_int_operand" "in")))]
-  "TARGET_ARCH64"
-  "or\\t%1, %%lo(%a2), %0"
-  [(set_attr "type" "ialu")
-   (set_attr "length" "1")])
-
-(define_insn "*movdi_high_sp64_cint"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (high:DI (match_operand:DI 1 "const_int_operand" "in")))]
-  "TARGET_ARCH64"
-  "sethi\\t%%hi(%a1), %0"
-  [(set_attr "type" "move")
-   (set_attr "length" "1")])
-
 ;; ??? revisit this...
 (define_insn "move_label_di"
   [(set (match_operand:DI 0 "register_operand" "=r")
 (define_insn "*losum_di_medlow"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
-                   (match_operand:DI 2 "" "")))]
+                   (match_operand:DI 2 "symbolic_operand" "")))]
   "TARGET_CM_MEDLOW"
   "or\\t%1, %%lo(%a2), %0"
   [(set_attr "length" "1")])
 (define_insn "sethm"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
-                   (unspec:DI [(match_operand:DI 2 "" "")] 18)))]
+                   (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
   "TARGET_CM_MEDANY"
   "or\\t%1, %%hm(%a2), %0"
   [(set_attr "length" "1")])
 (define_insn "setlo"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
-                   (match_operand:DI 2 "" "")))]
+                   (match_operand:DI 2 "symbolic_operand" "")))]
   "TARGET_CM_MEDANY"
   "or\\t%1, %%lo(%a2), %0"
   [(set_attr "length" "1")])
        (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
                    (const_int 0)))
    (set (match_operand:QI 0 "register_operand" "=r")
-       (match_dup 1))]
+       (subreg:QI (match_dup 1) 0))]
   ""
   "andcc\\t%1, 0xff, %0"
   [(set_attr "type" "compare")
        (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
                    (const_int 0)))
    (set (match_operand:QI 0 "register_operand" "=r")
-       (match_dup 1))]
+       (subreg:QI (match_dup 1) 0))]
   "TARGET_ARCH64"
   "andcc\\t%1, 0xff, %0"
   [(set_attr "type" "compare")
             (GET_CODE (operands[2]) == CONST_INT
              ? INTVAL (operands[2])
              : CONST_DOUBLE_LOW (operands[2])) - len;
-  unsigned mask = ((1 << len) - 1) << pos;
+  HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
 
   operands[1] = GEN_INT (mask);
   return \"andcc\\t%0, %1, %%g0\";
             (GET_CODE (operands[2]) == CONST_INT
              ? INTVAL (operands[2])
              : CONST_DOUBLE_LOW (operands[2])) - len;
-  unsigned HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
+  HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
 
   operands[1] = GEN_INT (mask);
   return \"andcc\\t%0, %1, %%g0\";
 
 (define_insn "*xordi3_sp64_dbl"
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (xor:DI (match_operand:DI 1 "register_operand" "%r")
+       (xor:DI (match_operand:DI 1 "register_operand" "r")
                (match_operand:DI 2 "const64_operand" "")))]
   "(TARGET_ARCH64
     && HOST_BITS_PER_WIDE_INT != 64)"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
   "TARGET_ARCH64"
-  "xnor\\t%1, 0, %0"
+  "xnor\\t%%g0, %1, %0"
   [(set_attr "type" "unary")
    (set_attr "length" "1")])
 
 }")
 
 (define_insn "*one_cmplsi2_not_liveg0"
-  [(set (match_operand:SI 0 "register_operand" "=r,r,d")
-       (not:SI (match_operand:SI 1 "arith_operand" "r,I,d")))]
+  [(set (match_operand:SI 0 "register_operand" "=r,d")
+       (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
   "! TARGET_LIVE_G0"
   "@
-  xnor\\t%1, 0, %0
   xnor\\t%%g0, %1, %0
   fnot1s\\t%1, %0"
-  [(set_attr "type" "unary,unary,fp")
-   (set_attr "length" "1,1,1")])
+  [(set_attr "type" "unary,fp")
+   (set_attr "length" "1,1")])
 
 (define_insn "*one_cmplsi2_liveg0"
   [(set (match_operand:SI 0 "register_operand" "=r,d")
   "*
 {
   if (GET_CODE (operands[2]) == CONST_INT
-      && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
+      && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
 
   return \"sllx\\t%1, %2, %0\";