* config/tc-mips.c (mips_optimize): New static variable.
authorIan Lance Taylor <ian@airs.com>
Tue, 27 Jul 1993 15:55:35 +0000 (15:55 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 27 Jul 1993 15:55:35 +0000 (15:55 +0000)
(append_insn): If ! mips_optimize, don't swap branches.
(md_parse_option): If -Ox, set mips_optimize accordingly.

gas/config/tc-mips.c

index db0671e568cbebec1070dc39d85d657e8a9daf37..bb4c48e7cc4c1159aa7cd6847caadffa9de654ba 100644 (file)
@@ -102,6 +102,11 @@ static symbolS *insn_label;
 /* To output NOP instructions correctly, we need to keep information
    about the previous two instructions.  */
 
+/* Whether we are optimizing.  We always optimize unless -O0 is given.
+   For the very simple optimizations we do, this is compatible with
+   the MIPS assembler.  */
+static int mips_optimize = 1;
+
 /* The previous instruction.  */
 static struct mips_cl_insn prev_insn;
 
@@ -126,6 +131,13 @@ static fixS *prev_insn_fixp;
 
 /* Non-zero if the previous instruction was in a delay slot.  */
 static int prev_insn_is_delay_slot;
+
+/* Non-zero if the previous instruction was in a .set noreorder.  */
+static int prev_insn_unreordered;
+
+/* Non-zero if the previous previous instruction was in a .set
+   noreorder.  */
+static int prev_prev_insn_unreordered;
 \f
 /* Prototypes for static functions.  */
 
@@ -613,15 +625,33 @@ append_insn (ip, address_expr, reloc_type)
       if ((ip->insn_mo->pinfo & INSN_UNCOND_BRANCH_DELAY)
          || (ip->insn_mo->pinfo & INSN_COND_BRANCH_DELAY))
        {
-         /* If we had to emit any NOP instructions, then we already
-            know we can not swap.  */
-         if (nops != 0
+         if (! mips_optimize
+             /* If we had to emit any NOP instructions, then we
+                already know we can not swap.  */
+             || nops != 0
              /* If we don't even know the previous insn, we can not
                 swap. */
              || ! prev_insn_valid
              /* If the previous insn is already in a branch delay
                 slot, then we can not swap.  */
              || prev_insn_is_delay_slot
+             /* If the previous previous insn was in a .set
+                noreorder, we can't swap.  Actually, the MIPS
+                assembler will swap in this situation.  However, gcc
+                configured -with-gnu-as will generate code like
+                  .set noreorder
+                  lw   $4,XXX
+                  .set reorder
+                  INSN
+                  bne  $4,$0,foo
+                in which we can not swap the bne and INSN.  If gcc is
+                not configured -with-gnu-as, it does not output the
+                .set pseudo-ops.  We don't have to check
+                prev_insn_unreordered, because prev_insn_valid will
+                be 0 in that case.  We don't want to use
+                prev_prev_insn_valid, because we do want to be able
+                to swap at the start of a function.  */
+             || prev_prev_insn_unreordered
              /* If the branch is itself the target of a branch, we
                 can not swap.  We cheat on this; all we check for is
                 whether there is a label on this instruction.  If
@@ -738,6 +768,8 @@ append_insn (ip, address_expr, reloc_type)
          prev_insn_is_delay_slot = 0;
        }
 
+      prev_prev_insn_unreordered = prev_insn_unreordered;
+      prev_insn_unreordered = 0;
       prev_insn_frag = frag_now;
       prev_insn_where = f - frag_now->fr_literal;
       prev_insn_fixp = fixp;
@@ -758,6 +790,8 @@ mips_no_prev_insn ()
   prev_prev_insn.insn_mo = &dummy_opcode;
   prev_insn_valid = 0;
   prev_insn_is_delay_slot = 0;
+  prev_insn_unreordered = 0;
+  prev_prev_insn_unreordered = 0;
   insn_label = NULL;
 }
 
@@ -2965,6 +2999,12 @@ md_parse_option (argP, cntP, vecP)
       return 1;
     }
 
+  if (**argP == 'O')
+    {
+      mips_optimize = (*argP)[1] != '0';
+      return 1;
+    }
+
 #ifdef OBJ_ECOFF
   if (**argP == 'G')
     {
@@ -2983,6 +3023,7 @@ md_parse_option (argP, cntP, vecP)
       return 1;
     }
 #endif
+
   return 1;                    /* pretend you parsed the character */
 }
 
@@ -3356,6 +3397,11 @@ s_mipsset (x)
 
   if (strcmp (name, "reorder") == 0)
     {
+      if (mips_noreorder)
+       {
+         prev_insn_unreordered = 1;
+         prev_prev_insn_unreordered = 1;
+       }
       mips_noreorder = 0;
     }
   else if (strcmp (name, "noreorder") == 0)