gas/
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 6 Aug 2011 10:02:03 +0000 (10:02 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Sat, 6 Aug 2011 10:02:03 +0000 (10:02 +0000)
* config/tc-mips.c (delayed_branch_p, compact_branch_p)
(uncond_branch_p, branch_likely_p): New functions.
(insns_between, nops_for_insn_or_target, append_insn)
(macro_start): Use them.
(get_append_method): Likewise.  Remove redundant test.

gas/ChangeLog
gas/config/tc-mips.c

index 287b6bed48bf309c6dc949fc25ae08d8d20b0094..7b2f9e7caeb8c34c4447f3a4e7722863c4852a6f 100644 (file)
@@ -1,3 +1,11 @@
+2011-08-06  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * config/tc-mips.c (delayed_branch_p, compact_branch_p)
+       (uncond_branch_p, branch_likely_p): New functions.
+       (insns_between, nops_for_insn_or_target, append_insn)
+       (macro_start): Use them.
+       (get_append_method): Likewise.  Remove redundant test.
+
 2011-08-05  David S. Miller  <davem@davemloft.net>
 
        * config/tc-sparc.c (v9a_asr_table): Add "cps".
index 66f0f467c98f2bc9d83fa7e2b7ae9280e0bf0ae9..783127a768a610b6db8ced8398acb5e9b4c4746e 100644 (file)
@@ -2888,6 +2888,48 @@ relax_end (void)
   mips_relax.sequence = 0;
 }
 
+/* Return true if IP is a delayed branch or jump.  */
+
+static inline bfd_boolean
+delayed_branch_p (const struct mips_cl_insn *ip)
+{
+  return (ip->insn_mo->pinfo & (INSN_UNCOND_BRANCH_DELAY
+                               | INSN_COND_BRANCH_DELAY
+                               | INSN_COND_BRANCH_LIKELY)) != 0;
+}
+
+/* Return true if IP is a compact branch or jump.  */
+
+static inline bfd_boolean
+compact_branch_p (const struct mips_cl_insn *ip)
+{
+  if (mips_opts.mips16)
+    return (ip->insn_mo->pinfo & (MIPS16_INSN_UNCOND_BRANCH
+                                 | MIPS16_INSN_COND_BRANCH)) != 0;
+  else
+    return (ip->insn_mo->pinfo2 & (INSN2_UNCOND_BRANCH
+                                  | INSN2_COND_BRANCH)) != 0;
+}
+
+/* Return true if IP is an unconditional branch or jump.  */
+
+static inline bfd_boolean
+uncond_branch_p (const struct mips_cl_insn *ip)
+{
+  return ((ip->insn_mo->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
+         || (mips_opts.mips16
+             ? (ip->insn_mo->pinfo & MIPS16_INSN_UNCOND_BRANCH) != 0
+             : (ip->insn_mo->pinfo2 & INSN2_UNCOND_BRANCH) != 0));
+}
+
+/* Return true if IP is a branch-likely instruction.  */
+
+static inline bfd_boolean
+branch_likely_p (const struct mips_cl_insn *ip)
+{
+  return (ip->insn_mo->pinfo & INSN_COND_BRANCH_LIKELY) != 0;
+}
+
 /* Return the mask of core registers that IP reads or writes.  */
 
 static unsigned int
@@ -3160,10 +3202,7 @@ insns_between (const struct mips_cl_insn *insn1,
          if (insn2 == NULL
              || insn2->insn_opcode == INSN_ERET
              || insn2->insn_opcode == INSN_DERET
-             || (insn2->insn_mo->pinfo
-                 & (INSN_UNCOND_BRANCH_DELAY
-                    | INSN_COND_BRANCH_DELAY
-                    | INSN_COND_BRANCH_LIKELY)) != 0)
+             || delayed_branch_p (insn2))
            return 1;
        }
     }
@@ -3554,18 +3593,14 @@ nops_for_insn_or_target (int ignore, const struct mips_cl_insn *hist,
   int nops, tmp_nops;
 
   nops = nops_for_insn (ignore, hist, insn);
-  if (insn->insn_mo->pinfo & (INSN_UNCOND_BRANCH_DELAY
-                             | INSN_COND_BRANCH_DELAY
-                             | INSN_COND_BRANCH_LIKELY))
+  if (delayed_branch_p (insn))
     {
       tmp_nops = nops_for_sequence (2, ignore ? ignore + 2 : 0,
                                    hist, insn, NOP_INSN);
       if (tmp_nops > nops)
        nops = tmp_nops;
     }
-  else if (mips_opts.mips16
-          && (insn->insn_mo->pinfo & (MIPS16_INSN_UNCOND_BRANCH
-                                      | MIPS16_INSN_COND_BRANCH)))
+  else if (compact_branch_p (insn))
     {
       tmp_nops = nops_for_sequence (1, ignore ? ignore + 1 : 0, hist, insn);
       if (tmp_nops > nops)
@@ -3771,27 +3806,20 @@ get_append_method (struct mips_cl_insn *ip)
     return APPEND_ADD;
 
   /* Otherwise, it's our responsibility to fill branch delay slots.  */
-  pinfo = ip->insn_mo->pinfo;
-  if ((pinfo & INSN_UNCOND_BRANCH_DELAY)
-      || (pinfo & INSN_COND_BRANCH_DELAY))
+  if (delayed_branch_p (ip))
     {
-      if (can_swap_branch_p (ip))
+      if (!branch_likely_p (ip) && can_swap_branch_p (ip))
        return APPEND_SWAP;
 
+      pinfo = ip->insn_mo->pinfo;
       if (mips_opts.mips16
          && ISA_SUPPORTS_MIPS16E
-         && (pinfo & INSN_UNCOND_BRANCH_DELAY)
          && (pinfo & (MIPS16_INSN_READ_X | MIPS16_INSN_READ_31)))
        return APPEND_ADD_COMPACT;
 
       return APPEND_ADD_WITH_NOP;
     }
 
-  /* We don't bother trying to track the target of branches, so there's
-     nothing we can use to fill a branch-likely slot.  */
-  if (pinfo & INSN_COND_BRANCH_LIKELY)
-    return APPEND_ADD_WITH_NOP;
-
   return APPEND_ADD;
 }
 
@@ -3941,7 +3969,7 @@ static void
 append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
             bfd_reloc_code_real_type *reloc_type, bfd_boolean expansionp)
 {
-  unsigned long prev_pinfo, prev_pinfo2, pinfo, pinfo2;
+  unsigned long prev_pinfo2, pinfo, pinfo2;
   bfd_boolean relaxed_branch = FALSE;
   enum append_method method;
   bfd_boolean relax32;
@@ -3954,7 +3982,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
   file_ase_mips16 |= mips_opts.mips16;
   file_ase_micromips |= mips_opts.micromips;
 
-  prev_pinfo = history[0].insn_mo->pinfo;
   prev_pinfo2 = history[0].insn_mo->pinfo2;
   pinfo = ip->insn_mo->pinfo;
   pinfo2 = ip->insn_mo->pinfo2;
@@ -4175,19 +4202,18 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
       && address_expr
       && relax32
       && *reloc_type == BFD_RELOC_16_PCREL_S2
-      && (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY
-         || pinfo & INSN_COND_BRANCH_LIKELY))
+      && delayed_branch_p (ip))
     {
       relaxed_branch = TRUE;
       add_relaxed_insn (ip, (relaxed_branch_length
                             (NULL, NULL,
-                             (pinfo & INSN_UNCOND_BRANCH_DELAY) ? -1
-                             : (pinfo & INSN_COND_BRANCH_LIKELY) ? 1
+                             uncond_branch_p (ip) ? -1
+                             : branch_likely_p (ip) ? 1
                              : 0)), 4,
                        RELAX_BRANCH_ENCODE
                        (AT,
-                        pinfo & INSN_UNCOND_BRANCH_DELAY,
-                        pinfo & INSN_COND_BRANCH_LIKELY,
+                        uncond_branch_p (ip),
+                        branch_likely_p (ip),
                         pinfo & INSN_WRITE_GPR_31,
                         0),
                        address_expr->X_add_symbol,
@@ -4198,16 +4224,12 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
           && address_expr
           && ((relax32 && *reloc_type == BFD_RELOC_16_PCREL_S2)
               || *reloc_type > BFD_RELOC_UNUSED)
-          && (pinfo & INSN_UNCOND_BRANCH_DELAY
-              || pinfo & INSN_COND_BRANCH_DELAY
-              || (pinfo2 & ~INSN2_ALIAS) == INSN2_UNCOND_BRANCH
-              || pinfo2 & INSN2_COND_BRANCH))
+          && (delayed_branch_p (ip) || compact_branch_p (ip)))
     {
       bfd_boolean relax16 = *reloc_type > BFD_RELOC_UNUSED;
       int type = relax16 ? *reloc_type - BFD_RELOC_UNUSED : 0;
-      int uncond = (pinfo & INSN_UNCOND_BRANCH_DELAY
-                   || pinfo2 & INSN2_UNCOND_BRANCH) ? -1 : 0;
-      int compact = pinfo2 & (INSN2_COND_BRANCH | INSN2_UNCOND_BRANCH);
+      int uncond = uncond_branch_p (ip) ? -1 : 0;
+      int compact = compact_branch_p (ip);
       int al = pinfo & INSN_WRITE_GPR_31;
       int length32;
 
@@ -4232,7 +4254,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                        RELAX_MIPS16_ENCODE
                        (*reloc_type - BFD_RELOC_UNUSED,
                         forced_insn_length == 2, forced_insn_length == 4,
-                        prev_pinfo & INSN_UNCOND_BRANCH_DELAY,
+                        delayed_branch_p (&history[0]),
                         history[0].mips16_absolute_jump_p),
                        make_expr_symbol (address_expr), 0);
     }
@@ -4240,7 +4262,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
           && ! ip->use_extend
           && *reloc_type != BFD_RELOC_MIPS16_JMP)
     {
-      if ((pinfo & INSN_UNCOND_BRANCH_DELAY) == 0)
+      if (!delayed_branch_p (ip))
        /* Make sure there is enough room to swap this instruction with
           a following jump instruction.  */
        frag_grow (6);
@@ -4250,7 +4272,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
     {
       if (mips_opts.mips16
          && mips_opts.noreorder
-         && (prev_pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
+         && delayed_branch_p (&history[0]))
        as_warn (_("extended instruction in delay slot"));
 
       if (mips_relax.sequence)
@@ -4464,9 +4486,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
     }
 
   /* If we have just completed an unconditional branch, clear the history.  */
-  if ((history[1].insn_mo->pinfo & INSN_UNCOND_BRANCH_DELAY)
-      || (mips_opts.mips16
-         && (history[0].insn_mo->pinfo & MIPS16_INSN_UNCOND_BRANCH)))
+  if ((delayed_branch_p (&history[1]) && uncond_branch_p (&history[1]))
+      || (compact_branch_p (&history[0]) && uncond_branch_p (&history[0])))
     mips_no_prev_insn ();
 
   /* We need to emit a label at the end of branch-likely macros.  */
@@ -4586,10 +4607,7 @@ macro_start (void)
          sizeof (mips_macro_warning.first_insn_sizes));
   memset (&mips_macro_warning.insns, 0, sizeof (mips_macro_warning.insns));
   mips_macro_warning.delay_slot_p = (mips_opts.noreorder
-                                    && (history[0].insn_mo->pinfo
-                                        & (INSN_UNCOND_BRANCH_DELAY
-                                           | INSN_COND_BRANCH_DELAY
-                                           | INSN_COND_BRANCH_LIKELY)) != 0);
+                                    && delayed_branch_p (&history[0]));
   switch (history[0].insn_mo->pinfo2
          & (INSN2_BRANCH_DELAY_32BIT | INSN2_BRANCH_DELAY_16BIT))
     {