]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
*** empty log message ***
authorRichard Kenner <kenner@gcc.gnu.org>
Sun, 8 Mar 1992 21:45:38 +0000 (16:45 -0500)
committerRichard Kenner <kenner@gcc.gnu.org>
Sun, 8 Mar 1992 21:45:38 +0000 (16:45 -0500)
From-SVN: r422

gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/integrate.c
gcc/reload1.c

index 47e9342a63a669e53cd1e1a55b9d0563ee3ef576..3d4683b1275c831f4a837c8e0a6b35b1843d4989 100644 (file)
@@ -1018,6 +1018,17 @@ print_operand (file, x, code)
       RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
       return;
 
+    case 'A':
+      /* If X is a constant integer whose low-order 5 bits are zero,
+        write 'l'.  Otherwise, write 'r'.  This is a kludge to fix a bug
+        in the RS/6000 assembler where "sri" with a zero shift count
+        write a trash instruction.  */
+      if (GET_CODE (x) != CONST_INT && (INTVAL (x) & 31) == 0)
+       fprintf (file, "l");
+      else
+       fprintf (file, "r");
+      return;
+
     case 0:
       if (GET_CODE (x) == REG)
        fprintf (file, "%s", reg_names[REGNO (x)]);
index 14c3edd0aeca3911b51e049dc0881f9e46e27b8d..167363bdd2fc754e9739b126b5dfee2549e9a9ee 100644 (file)
@@ -22,7 +22,7 @@
 \f
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations.
-(define_attr "type" "load,integer,fp,compare,delayed_compare,fpcompare"
+(define_attr "type" "load,integer,fp,compare,delayed_compare,fpcompare,mtlr"
   (const_string "integer"))
 
 ;; Memory delivers its result in two cycles.
@@ -40,6 +40,9 @@
 
 ;; Floating-point comparisons take eight cycles.
 (define_function_unit "compare" 1 0 (eq_attr "type" "fpcompare") 8 0)
+
+;; Branches on LR cannot be done until five cycles after LR is set.
+(define_function_unit "branch" 1 0 (eq_attr "type" "mtlr") 5 0)
 \f
 ;; Start with fixed-point load and store insns.  Here we put only the more
 ;; complex forms.  Basic data transfer is done later.
 (define_insn ""
   [(set (match_operand:SI 0 "gen_reg_operand" "=r")
        (if_then_else:SI (gt (match_operand:SI 1 "gen_reg_operand" "r")
-                            (match_operand:SI 2 "reg_or_short_operand" "r"))
+                            (match_operand:SI 2 "reg_or_short_operand" "rI"))
                         (const_int 0)
                         (minus:SI (match_dup 2) (match_dup 1))))]
   ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
        (compare:CC
         (if_then_else:SI (gt (match_operand:SI 1 "gen_reg_operand" "r")
-                             (match_operand:SI 2 "reg_or_short_operand" "r"))
+                             (match_operand:SI 2 "reg_or_short_operand" "rI"))
                          (const_int 0)
                          (minus:SI (match_dup 2) (match_dup 1)))
         (const_int 0)))
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
        (compare:CC
         (if_then_else:SI (gt (match_operand:SI 1 "gen_reg_operand" "r")
-                             (match_operand:SI 2 "reg_or_short_operand" "r"))
+                             (match_operand:SI 2 "reg_or_short_operand" "rI"))
                          (const_int 0)
                          (minus:SI (match_dup 2) (match_dup 1)))
         (const_int 0)))
   "rlinm. %0,%h1,%h2,%m3,%M3"
   [(set_attr "type" "delayed_compare")])
 
+;; The RS/6000 assembler mis-handles "sri x,x,0", so write that case as
+;; "sli x,x,0".
 (define_insn "lshrsi3"
   [(set (match_operand:SI 0 "gen_reg_operand" "=r,r")
        (lshiftrt:SI (match_operand:SI 1 "gen_reg_operand" "r,r")
   ""
   "@
   sre %0,%1,%2
-  sri %0,%1,%h2")
+  s%A2i %0,%1,%h2")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
   ""
   "@
   sre. %3,%1,%2
-  sri. %3,%1,%h2"
+  s%A2i. %3,%1,%h2"
   [(set_attr "type" "delayed_compare")])
 
 (define_insn ""
   ""
   "@
   sre. %0,%1,%2
-  sri. %0,%1,%h2"
+  s%A2i. %0,%1,%h2"
   [(set_attr "type" "delayed_compare")])
 
 (define_insn ""
    sli %0,%L1,%h2\;cal %L0,0(0)
    sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
    sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
-   sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 ")
+   sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2")
 
 (define_insn "lshrdi3"
-  [(set (match_operand:DI 0 "gen_reg_operand" "=r,r,r,&r")
+  [(set (match_operand:DI 0 "gen_reg_operand" "=&r,r,r,&r")
        (lshiftrt:DI (match_operand:DI 1 "gen_reg_operand" "r,r,0,r")
                     (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
    (clobber (match_scratch:SI 3 "=X,q,q,q"))]
   ""
   "@
-   cal %0,0(0)\;sri %L0,%1,%h2
-   sr%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2
-   sr%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2
-   sr%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2 ")
+   cal %0,0(0)\;s%A2i %L0,%1,%h2
+   s%A2%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2
+   s%A2%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2
+   s%A2%I2q %L0,%L1,%2\;srl%I2q %0,%1,%2")
 
 ;; Shift by a variable amount is too complex to be worth open-coding.  We
 ;; just handle shifts by constants.
 }")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*h")
-       (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*c*q,*l")
+       (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r,r"))]
   "gen_reg_operand (operands[0], SImode)
    || gen_reg_operand (operands[1], SImode)"
   "@
    cal %0,%1(0)
    cau %0,0,%u1
    mf%1 %0
+   mt%0 %1
    mt%0 %1"
-  [(set_attr "type" "*,load,*,*,*,*,*")])
+  [(set_attr "type" "*,load,*,*,*,*,*,mtlr")])
 
 (define_insn ""
   [(set (match_operand:CC 2 "cc_reg_operand" "=x")
index 3026203d61620f1481d45f038e95ef935bd12a72..05b114335c088c6d98f4c001b308d242f2d76913 100644 (file)
@@ -1775,14 +1775,14 @@ copy_rtx_and_substitute (orig, map)
              rounded = CEIL_ROUND (size, BIGGEST_ALIGNMENT / BITS_PER_UNIT);
              loc = plus_constant (loc, rounded);
 #endif
-             map->reg_map[regno] = force_operand (loc, 0);
-             map->const_equiv_map[regno] = loc;
-             map->const_age_map[regno] = CONST_AGE_PARM;
+             map->reg_map[regno] = temp = force_operand (loc, 0);
+             map->const_equiv_map[REGNO (temp)] = loc;
+             map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
 
              seq = gen_sequence ();
              end_sequence ();
              emit_insn_after (seq, map->insns_at_start);
-             return map->reg_map[regno];
+             return temp;
            }
          else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
            {
@@ -1794,14 +1794,14 @@ copy_rtx_and_substitute (orig, map)
              start_sequence ();
              loc = assign_stack_temp (BLKmode, size, 1);
              loc = XEXP (loc, 0);
-             map->reg_map[regno] = force_operand (loc, 0);
-             map->const_equiv_map[regno] = loc;
-             map->const_age_map[regno] = CONST_AGE_PARM;
+             map->reg_map[regno] = temp = force_operand (loc, 0);
+             map->const_equiv_map[REGNO (temp)] = loc;
+             map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
 
              seq = gen_sequence ();
              end_sequence ();
              emit_insn_after (seq, map->insns_at_start);
-             return map->reg_map[regno];
+             return temp;
            }
          else if (REG_FUNCTION_VALUE_P (orig))
            {
index e26cefeae281bca2b366f92f7276c6278d9ba97c..c6f46b176d4f71cbd7a0a104522c533ebcfa4d14 100644 (file)
@@ -1367,6 +1367,20 @@ reload (first, global, dumpfile)
            }
        }
 
+      /* See if anything that happened changes which eliminations are valid.
+        For example, on the Sparc, whether or not the frame pointer can
+        be eliminated can depend on what registers have been used.  We need
+        not check some conditions again (such as flag_omit_frame_pointer)
+        since they can't have changed.  */
+
+      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+       if ((ep->from == FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED)
+#ifdef ELIMINABLE_REGS
+           || ! CAN_ELIMINATE (ep->from, ep->to)
+#endif
+           )
+         ep->can_eliminate = 0;
+
       /* Look for the case where we have discovered that we can't replace
         register A with register B and that means that we will now be
         trying to replace register A with register C.  This means we can