* config/tc-mips.h (mips_cl_insn): Move definition to...
authorRichard Sandiford <rdsandiford@googlemail.com>
Wed, 9 Mar 2005 09:41:01 +0000 (09:41 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Wed, 9 Mar 2005 09:41:01 +0000 (09:41 +0000)
* config/tc-mips.c (mips_cl_insn): ...here.  Add new fields:
frag, where, fixp, reloc_type, valid_p, noreorder_p, delay_slot_p
and extended_p.
(history): New variable.
(prev_insn, prev_prev_insn, prev_insn_valid, prev_insn_frag)
(prev_insn_where, prev_insn_reloc_type, prev_insn_fixp)
(prev_insn_is_delay_slot, prev_insn_unreordered, prev_insn_extended)
(prev_prev_insn_unreordered): Delete.
(reg_needs_delay, append_insn, mips_no_prev_insn, mips_emit_delays)
(macro_start): Replace uses of prev_insn* with the equivalent history[]
field.

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

index d5602a9..222eea6 100644 (file)
@@ -1,3 +1,18 @@
+2005-03-09  Richard Sandiford  <rsandifo@redhat.com>
+
+       * config/tc-mips.h (mips_cl_insn): Move definition to...
+       * config/tc-mips.c (mips_cl_insn): ...here.  Add new fields:
+       frag, where, fixp, reloc_type, valid_p, noreorder_p, delay_slot_p
+       and extended_p.
+       (history): New variable.
+       (prev_insn, prev_prev_insn, prev_insn_valid, prev_insn_frag)
+       (prev_insn_where, prev_insn_reloc_type, prev_insn_fixp)
+       (prev_insn_is_delay_slot, prev_insn_unreordered, prev_insn_extended)
+       (prev_prev_insn_unreordered): Delete.
+       (reg_needs_delay, append_insn, mips_no_prev_insn, mips_emit_delays)
+       (macro_start): Replace uses of prev_insn* with the equivalent history[]
+       field.
+
 2005-03-08  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * doc/Makefile.am: Update as.info dependencies.
index 284d09c..a0c7944 100644 (file)
@@ -119,6 +119,50 @@ extern int target_big_endian;
                            ? ".rodata" \
                            : (abort (), ""))
 
+/* Information about an instruction, including its format, operands
+   and fixups.  */
+struct mips_cl_insn
+{
+  /* The opcode's entry in mips_opcodes or mips16_opcodes.  */
+  const struct mips_opcode *insn_mo;
+
+  /* True if this is a mips16 instruction and if we want the extended
+     form of INSN_MO.  */
+  bfd_boolean use_extend;
+
+  /* The 16-bit extension instruction to use when USE_EXTEND is true.  */
+  unsigned short extend;
+
+  /* The 16-bit or 32-bit bitstring of the instruction itself.  This is
+     a copy of INSN_MO->match with the operands filled in.  */
+  unsigned long insn_opcode;
+
+  /* The frag that contains the instruction.  */
+  struct frag *frag;
+
+  /* The offset into FRAG of the first instruction byte.  */
+  long where;
+
+  /* The relocs associated with the instruction, if any.  */
+  fixS *fixp[3];
+
+  /* The reloc types associated with the instruction.  */
+  bfd_reloc_code_real_type reloc_type[3];
+
+  /* True if this entry describes a real instruction.  */
+  unsigned int valid_p : 1;
+
+  /* True if this instruction occured in a .set noreorder block.  */
+  unsigned int noreorder_p : 1;
+
+  /* True if this instruction corresponds to an assembler-filled
+     delay slot.  Always false if noreorder_p.  */
+  unsigned int delay_slot_p : 1;
+
+  /* True for extended mips16 instructions.  */
+  unsigned int extended_p : 1;
+};
+
 /* The ABI to use.  */
 enum mips_abi_level
 {
@@ -520,45 +564,13 @@ static int mips_optimize = 2;
    equivalent to seeing no -g option at all.  */
 static int mips_debug = 0;
 
-/* The previous instruction.  */
-static struct mips_cl_insn prev_insn;
-
-/* The instruction before prev_insn.  */
-static struct mips_cl_insn prev_prev_insn;
+/* A list of previous instructions, with index 0 being the most recent.  */
+static struct mips_cl_insn history[2];
 
-/* If we don't want information for prev_insn or prev_prev_insn, we
+/* If we don't want information for a history[] entry, we
    point the insn_mo field at this dummy integer.  */
 static const struct mips_opcode dummy_opcode = { NULL, NULL, 0, 0, 0, 0, 0 };
 
-/* Non-zero if prev_insn is valid.  */
-static int prev_insn_valid;
-
-/* The frag for the previous instruction.  */
-static struct frag *prev_insn_frag;
-
-/* The offset into prev_insn_frag for the previous instruction.  */
-static long prev_insn_where;
-
-/* The reloc type for the previous instruction, if any.  */
-static bfd_reloc_code_real_type prev_insn_reloc_type[3];
-
-/* The reloc for the previous instruction, if any.  */
-static fixS *prev_insn_fixp[3];
-
-/* 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 instruction uses an extend opcode (if
-   mips16).  */
-static int prev_insn_extended;
-
-/* Non-zero if the previous previous instruction was in a .set
-   noreorder.  */
-static int prev_prev_insn_unreordered;
-
 /* If this is set, it points to a frag holding nop instructions which
    were inserted before the start of a noreorder section.  If those
    nops turn out to be unnecessary, the size of the frag can be
@@ -1515,7 +1527,7 @@ reg_needs_delay (unsigned int reg)
 {
   unsigned long prev_pinfo;
 
-  prev_pinfo = prev_insn.insn_mo->pinfo;
+  prev_pinfo = history[0].insn_mo->pinfo;
   if (! mips_opts.noreorder
       && (((prev_pinfo & INSN_LOAD_MEMORY_DELAY)
           && ! gpr_interlocks)
@@ -1526,7 +1538,7 @@ reg_needs_delay (unsigned int reg)
         delay the use of general register rt for one instruction.  */
       /* Itbl support may require additional care here.  */
       know (prev_pinfo & INSN_WRITE_GPR_T);
-      if (reg == ((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT))
+      if (reg == ((history[0].insn_opcode >> OP_SH_RT) & OP_MASK_RT))
        return 1;
     }
 
@@ -1627,7 +1639,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
   /* Mark instruction labels in mips16 mode.  */
   mips16_mark_labels ();
 
-  prev_pinfo = prev_insn.insn_mo->pinfo;
+  prev_pinfo = history[0].insn_mo->pinfo;
   pinfo = ip->insn_mo->pinfo;
 
   if (mips_relax.sequence != 2
@@ -1676,7 +1688,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
          know (prev_pinfo & INSN_WRITE_GPR_T);
          if (mips_optimize == 0
              || insn_uses_reg (ip,
-                               ((prev_insn.insn_opcode >> OP_SH_RT)
+                               ((history[0].insn_opcode >> OP_SH_RT)
                                 & OP_MASK_RT),
                                MIPS_GR_REG))
            ++nops;
@@ -1705,7 +1717,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
            {
              if (mips_optimize == 0
                  || insn_uses_reg (ip,
-                                   ((prev_insn.insn_opcode >> OP_SH_FT)
+                                   ((history[0].insn_opcode >> OP_SH_FT)
                                     & OP_MASK_FT),
                                    MIPS_FP_REG))
                ++nops;
@@ -1714,7 +1726,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
            {
              if (mips_optimize == 0
                  || insn_uses_reg (ip,
-                                   ((prev_insn.insn_opcode >> OP_SH_FS)
+                                   ((history[0].insn_opcode >> OP_SH_FS)
                                     & OP_MASK_FS),
                                    MIPS_FP_REG))
                ++nops;
@@ -1758,7 +1770,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
 
       else if (mips_7000_hilo_fix
               && MF_HILO_INSN (prev_pinfo)
-              && insn_uses_reg (ip, ((prev_insn.insn_opcode >> OP_SH_RD)
+              && insn_uses_reg (ip, ((history[0].insn_opcode >> OP_SH_RD)
                                      & OP_MASK_RD),
                                 MIPS_GR_REG))
        {
@@ -1771,8 +1783,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
         insert one nop.  */
 
       else if (mips_7000_hilo_fix
-              && MF_HILO_INSN (prev_prev_insn.insn_opcode)
-              && insn_uses_reg (ip, ((prev_prev_insn.insn_opcode >> OP_SH_RD)
+              && MF_HILO_INSN (history[1].insn_opcode)
+              && insn_uses_reg (ip, ((history[1].insn_opcode >> OP_SH_RD)
                                        & OP_MASK_RD),
                                     MIPS_GR_REG))
 
@@ -1805,7 +1817,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                       || (pinfo & MIPS16_INSN_BRANCH)))
            ++nops;
        }
-      else if (prev_insn.insn_mo->pinfo & INSN_READ_HI)
+      else if (history[0].insn_mo->pinfo & INSN_READ_HI)
        {
          /* The previous instruction reads the HI register; if the
             current instruction writes to the HI register, we must
@@ -1831,7 +1843,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
       /* If the previous instruction was in a noreorder section, then
          we don't want to insert the nop after all.  */
       /* Itbl support may require additional care here.  */
-      if (prev_insn_unreordered)
+      if (history[0].noreorder_p)
        nops = 0;
 
       /* There are two cases which require two intervening
@@ -1843,15 +1855,15 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
         instruction, we must check for these cases compared to the
         instruction previous to the previous instruction.  */
       if ((! mips_opts.mips16
-          && (prev_prev_insn.insn_mo->pinfo & INSN_COPROC_MOVE_DELAY)
-          && (prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
+          && (history[1].insn_mo->pinfo & INSN_COPROC_MOVE_DELAY)
+          && (history[1].insn_mo->pinfo & INSN_WRITE_COND_CODE)
           && (pinfo & INSN_READ_COND_CODE)
           && ! cop_interlocks)
-         || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)
+         || ((history[1].insn_mo->pinfo & INSN_READ_LO)
              && (pinfo & INSN_WRITE_LO)
              && ! (hilo_interlocks
                    || (mips_opts.arch == CPU_R3900 && (pinfo & INSN_MULT))))
-         || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
+         || ((history[1].insn_mo->pinfo & INSN_READ_HI)
              && (pinfo & INSN_WRITE_HI)
              && ! (hilo_interlocks
                    || (mips_opts.arch == CPU_R3900 && (pinfo & INSN_MULT)))))
@@ -1859,19 +1871,19 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
       else
        prev_prev_nop = 0;
 
-      if (prev_prev_insn_unreordered)
+      if (history[1].noreorder_p)
        prev_prev_nop = 0;
 
       if (prev_prev_nop && nops == 0)
        ++nops;
 
-      if (mips_fix_vr4120 && prev_insn.insn_mo->name)
+      if (mips_fix_vr4120 && history[0].insn_mo->name)
        {
          /* We're out of bits in pinfo, so we must resort to string
             ops here.  Shortcuts are selected based on opcodes being
             limited to the VR4120 instruction set.  */
          int min_nops = 0;
-         const char *pn = prev_insn.insn_mo->name;
+         const char *pn = history[0].insn_mo->name;
          const char *tn = ip->insn_mo->name;
          if (strncmp (pn, "macc", 4) == 0
              || strncmp (pn, "dmacc", 5) == 0)
@@ -2024,8 +2036,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
 #endif
 
   /* Record the frag type before frag_var.  */
-  if (prev_insn_frag)
-    prev_insn_frag_type = prev_insn_frag->fr_type;
+  if (history[0].frag)
+    prev_insn_frag_type = history[0].frag->fr_type;
 
   if (address_expr
       && *reloc_type == BFD_RELOC_16_PCREL_S2
@@ -2064,7 +2076,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                                         mips16_small, mips16_ext,
                                         (prev_pinfo
                                          & INSN_UNCOND_BRANCH_DELAY),
-                                        (*prev_insn_reloc_type
+                                        (*history[0].reloc_type
                                          == BFD_RELOC_MIPS16_JMP)),
                    make_expr_symbol (address_expr), 0, NULL);
     }
@@ -2348,10 +2360,10 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              || nops != 0
              /* If we don't even know the previous insn, we can not
                 swap.  */
-             || ! prev_insn_valid
+             || ! history[0].valid_p
              /* If the previous insn is already in a branch delay
                 slot, then we can not swap.  */
-             || prev_insn_is_delay_slot
+             || history[0].delay_slot_p
              /* 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
@@ -2364,11 +2376,11 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                 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
+                history[0].noreorder_p, because history[0].valid_p will
                 be 0 in that case.  We don't want to use
-                prev_prev_insn_valid, because we do want to be able
+                history[1].valid_p, because we do want to be able
                 to swap at the start of a function.  */
-             || prev_prev_insn_unreordered
+             || history[1].noreorder_p
              /* 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
@@ -2428,31 +2440,31 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              || (! mips_opts.mips16
                  && (prev_pinfo & INSN_WRITE_GPR_T)
                  && insn_uses_reg (ip,
-                                   ((prev_insn.insn_opcode >> OP_SH_RT)
+                                   ((history[0].insn_opcode >> OP_SH_RT)
                                     & OP_MASK_RT),
                                    MIPS_GR_REG))
              || (! mips_opts.mips16
                  && (prev_pinfo & INSN_WRITE_GPR_D)
                  && insn_uses_reg (ip,
-                                   ((prev_insn.insn_opcode >> OP_SH_RD)
+                                   ((history[0].insn_opcode >> OP_SH_RD)
                                     & OP_MASK_RD),
                                    MIPS_GR_REG))
              || (mips_opts.mips16
                  && (((prev_pinfo & MIPS16_INSN_WRITE_X)
                       && insn_uses_reg (ip,
-                                        ((prev_insn.insn_opcode
+                                        ((history[0].insn_opcode
                                           >> MIPS16OP_SH_RX)
                                          & MIPS16OP_MASK_RX),
                                         MIPS16_REG))
                      || ((prev_pinfo & MIPS16_INSN_WRITE_Y)
                          && insn_uses_reg (ip,
-                                           ((prev_insn.insn_opcode
+                                           ((history[0].insn_opcode
                                              >> MIPS16OP_SH_RY)
                                             & MIPS16OP_MASK_RY),
                                            MIPS16_REG))
                      || ((prev_pinfo & MIPS16_INSN_WRITE_Z)
                          && insn_uses_reg (ip,
-                                           ((prev_insn.insn_opcode
+                                           ((history[0].insn_opcode
                                              >> MIPS16OP_SH_RZ)
                                             & MIPS16OP_MASK_RZ),
                                            MIPS16_REG))
@@ -2462,8 +2474,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                          && insn_uses_reg (ip, RA, MIPS_GR_REG))
                      || ((prev_pinfo & MIPS16_INSN_WRITE_GPR_Y)
                          && insn_uses_reg (ip,
-                                           MIPS16OP_EXTRACT_REG32R (prev_insn.
-                                                                    insn_opcode),
+                                           MIPS16OP_EXTRACT_REG32R
+                                             (history[0].insn_opcode),
                                            MIPS_GR_REG))))
              /* If the branch writes a register that the previous
                 instruction sets, we can not swap (we know that
@@ -2471,54 +2483,54 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              || (! mips_opts.mips16
                  && (prev_pinfo & INSN_WRITE_GPR_T)
                  && (((pinfo & INSN_WRITE_GPR_D)
-                      && (((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT)
+                      && (((history[0].insn_opcode >> OP_SH_RT) & OP_MASK_RT)
                           == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))
                      || ((pinfo & INSN_WRITE_GPR_31)
-                         && (((prev_insn.insn_opcode >> OP_SH_RT)
+                         && (((history[0].insn_opcode >> OP_SH_RT)
                               & OP_MASK_RT)
                              == RA))))
              || (! mips_opts.mips16
                  && (prev_pinfo & INSN_WRITE_GPR_D)
                  && (((pinfo & INSN_WRITE_GPR_D)
-                      && (((prev_insn.insn_opcode >> OP_SH_RD) & OP_MASK_RD)
+                      && (((history[0].insn_opcode >> OP_SH_RD) & OP_MASK_RD)
                           == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))
                      || ((pinfo & INSN_WRITE_GPR_31)
-                         && (((prev_insn.insn_opcode >> OP_SH_RD)
+                         && (((history[0].insn_opcode >> OP_SH_RD)
                               & OP_MASK_RD)
                              == RA))))
              || (mips_opts.mips16
                  && (pinfo & MIPS16_INSN_WRITE_31)
                  && ((prev_pinfo & MIPS16_INSN_WRITE_31)
                      || ((prev_pinfo & MIPS16_INSN_WRITE_GPR_Y)
-                         && (MIPS16OP_EXTRACT_REG32R (prev_insn.insn_opcode)
+                         && (MIPS16OP_EXTRACT_REG32R (history[0].insn_opcode)
                              == RA))))
              /* If the branch writes a register that the previous
                 instruction reads, we can not swap (we know that
                 branches only write to RD or to $31).  */
              || (! mips_opts.mips16
                  && (pinfo & INSN_WRITE_GPR_D)
-                 && insn_uses_reg (&prev_insn,
+                 && insn_uses_reg (&history[0],
                                    ((ip->insn_opcode >> OP_SH_RD)
                                     & OP_MASK_RD),
                                    MIPS_GR_REG))
              || (! mips_opts.mips16
                  && (pinfo & INSN_WRITE_GPR_31)
-                 && insn_uses_reg (&prev_insn, RA, MIPS_GR_REG))
+                 && insn_uses_reg (&history[0], RA, MIPS_GR_REG))
              || (mips_opts.mips16
                  && (pinfo & MIPS16_INSN_WRITE_31)
-                 && insn_uses_reg (&prev_insn, RA, MIPS_GR_REG))
+                 && insn_uses_reg (&history[0], RA, MIPS_GR_REG))
              /* If the previous previous instruction has a load
                 delay, and sets a register that the branch reads, we
                 can not swap.  */
              || (! mips_opts.mips16
               /* Itbl support may require additional care here.  */
-                 && (((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)
+                 && (((history[1].insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)
                       && ! cop_interlocks)
-                     || ((prev_prev_insn.insn_mo->pinfo
+                     || ((history[1].insn_mo->pinfo
                           & INSN_LOAD_MEMORY_DELAY)
                          && ! gpr_interlocks))
                  && insn_uses_reg (ip,
-                                   ((prev_prev_insn.insn_opcode >> OP_SH_RT)
+                                   ((history[1].insn_opcode >> OP_SH_RT)
                                     & OP_MASK_RT),
                                    MIPS_GR_REG))
              /* If one instruction sets a condition code and the
@@ -2533,11 +2545,11 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                  && (prev_pinfo & MIPS16_INSN_READ_PC))
              /* If the previous instruction was extended, we can not
                  swap.  */
-             || (mips_opts.mips16 && prev_insn_extended)
+             || (mips_opts.mips16 && history[0].extended_p)
              /* If the previous instruction had a fixup in mips16
                  mode, we can not swap.  This normally means that the
                  previous instruction was a 4 byte branch anyhow.  */
-             || (mips_opts.mips16 && prev_insn_fixp[0])
+             || (mips_opts.mips16 && history[0].fixp[0])
              /* If the previous instruction is a sync, sync.l, or
                 sync.p, we can not swap.  */
              || (prev_pinfo & INSN_SYNC))
@@ -2550,8 +2562,11 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              if (mips_relax.sequence)
                mips_relax.sizes[mips_relax.sequence - 1] += 4;
              /* Update the previous insn information.  */
-             prev_prev_insn = *ip;
-             prev_insn.insn_mo = &dummy_opcode;
+             history[1].insn_mo = ip->insn_mo;
+             history[1].use_extend = ip->use_extend;
+             history[1].extend = ip->extend;
+             history[1].insn_opcode = ip->insn_opcode;
+             history[0].insn_mo = &dummy_opcode;
            }
          else
            {
@@ -2561,7 +2576,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                  char *prev_f;
                  char temp[4];
 
-                 prev_f = prev_insn_frag->fr_literal + prev_insn_where;
+                 prev_f = history[0].frag->fr_literal + history[0].where;
                  if (!relaxed_branch)
                    {
                      /* If this is not a relaxed branch, then just
@@ -2580,31 +2595,31 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                         into the space freed by the moved instruction.  */
                      f = frag_more (4);
                      memcpy (f, prev_f, 4);
-                     prev_insn_frag->fr_fix -= 4;
-                     if (prev_insn_frag->fr_type == rs_machine_dependent)
-                       memmove (prev_f, prev_f + 4, prev_insn_frag->fr_var);
+                     history[0].frag->fr_fix -= 4;
+                     if (history[0].frag->fr_type == rs_machine_dependent)
+                       memmove (prev_f, prev_f + 4, history[0].frag->fr_var);
                    }
 
-                 if (prev_insn_fixp[0])
+                 if (history[0].fixp[0])
                    {
-                     prev_insn_fixp[0]->fx_frag = frag_now;
-                     prev_insn_fixp[0]->fx_where = f - frag_now->fr_literal;
+                     history[0].fixp[0]->fx_frag = frag_now;
+                     history[0].fixp[0]->fx_where = f - frag_now->fr_literal;
                    }
-                 if (prev_insn_fixp[1])
+                 if (history[0].fixp[1])
                    {
-                     prev_insn_fixp[1]->fx_frag = frag_now;
-                     prev_insn_fixp[1]->fx_where = f - frag_now->fr_literal;
+                     history[0].fixp[1]->fx_frag = frag_now;
+                     history[0].fixp[1]->fx_where = f - frag_now->fr_literal;
                    }
-                 if (prev_insn_fixp[2])
+                 if (history[0].fixp[2])
                    {
-                     prev_insn_fixp[2]->fx_frag = frag_now;
-                     prev_insn_fixp[2]->fx_where = f - frag_now->fr_literal;
+                     history[0].fixp[2]->fx_frag = frag_now;
+                     history[0].fixp[2]->fx_where = f - frag_now->fr_literal;
                    }
-                 if (prev_insn_fixp[0] && HAVE_NEWABI
-                     && prev_insn_frag != frag_now
-                     && (prev_insn_fixp[0]->fx_r_type
+                 if (history[0].fixp[0] && HAVE_NEWABI
+                     && history[0].frag != frag_now
+                     && (history[0].fixp[0]->fx_r_type
                          == BFD_RELOC_MIPS_GOT_DISP
-                         || (prev_insn_fixp[0]->fx_r_type
+                         || (history[0].fixp[0]->fx_r_type
                              == BFD_RELOC_MIPS_CALL16)))
                    {
                      /* To avoid confusion in tc_gen_reloc, we must
@@ -2617,21 +2632,21 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                    {
                      if (fixp[0])
                        {
-                         fixp[0]->fx_frag = prev_insn_frag;
-                         fixp[0]->fx_where = prev_insn_where;
+                         fixp[0]->fx_frag = history[0].frag;
+                         fixp[0]->fx_where = history[0].where;
                        }
                      if (fixp[1])
                        {
-                         fixp[1]->fx_frag = prev_insn_frag;
-                         fixp[1]->fx_where = prev_insn_where;
+                         fixp[1]->fx_frag = history[0].frag;
+                         fixp[1]->fx_where = history[0].where;
                        }
                      if (fixp[2])
                        {
-                         fixp[2]->fx_frag = prev_insn_frag;
-                         fixp[2]->fx_where = prev_insn_where;
+                         fixp[2]->fx_frag = history[0].frag;
+                         fixp[2]->fx_where = history[0].where;
                        }
                    }
-                 else if (prev_insn_frag->fr_type == rs_machine_dependent)
+                 else if (history[0].frag->fr_type == rs_machine_dependent)
                    {
                      if (fixp[0])
                        fixp[0]->fx_where -= 4;
@@ -2646,10 +2661,10 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                  char *prev_f;
                  char temp[2];
 
-                 assert (prev_insn_fixp[0] == NULL);
-                 assert (prev_insn_fixp[1] == NULL);
-                 assert (prev_insn_fixp[2] == NULL);
-                 prev_f = prev_insn_frag->fr_literal + prev_insn_where;
+                 assert (history[0].fixp[0] == NULL);
+                 assert (history[0].fixp[1] == NULL);
+                 assert (history[0].fixp[2] == NULL);
+                 prev_f = history[0].frag->fr_literal + history[0].where;
                  memcpy (temp, prev_f, 2);
                  memcpy (prev_f, f, 2);
                  if (*reloc_type != BFD_RELOC_MIPS16_JMP)
@@ -2664,42 +2679,45 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                    }
                  if (fixp[0])
                    {
-                     fixp[0]->fx_frag = prev_insn_frag;
-                     fixp[0]->fx_where = prev_insn_where;
+                     fixp[0]->fx_frag = history[0].frag;
+                     fixp[0]->fx_where = history[0].where;
                    }
                  if (fixp[1])
                    {
-                     fixp[1]->fx_frag = prev_insn_frag;
-                     fixp[1]->fx_where = prev_insn_where;
+                     fixp[1]->fx_frag = history[0].frag;
+                     fixp[1]->fx_where = history[0].where;
                    }
                  if (fixp[2])
                    {
-                     fixp[2]->fx_frag = prev_insn_frag;
-                     fixp[2]->fx_where = prev_insn_where;
+                     fixp[2]->fx_frag = history[0].frag;
+                     fixp[2]->fx_where = history[0].where;
                    }
                }
 
-             /* Update the previous insn information; leave prev_insn
+             /* Update the previous insn information; leave history[0]
                 unchanged.  */
-             prev_prev_insn = *ip;
+             history[1].insn_mo = ip->insn_mo;
+             history[1].use_extend = ip->use_extend;
+             history[1].extend = ip->extend;
+             history[1].insn_opcode = ip->insn_opcode;
            }
-         prev_insn_is_delay_slot = 1;
+         history[0].delay_slot_p = 1;
 
          /* If that was an unconditional branch, forget the previous
             insn information.  */
          if (pinfo & INSN_UNCOND_BRANCH_DELAY)
            {
-             prev_prev_insn.insn_mo = &dummy_opcode;
-             prev_insn.insn_mo = &dummy_opcode;
+             history[1].insn_mo = &dummy_opcode;
+             history[0].insn_mo = &dummy_opcode;
            }
 
-         prev_insn_fixp[0] = NULL;
-         prev_insn_fixp[1] = NULL;
-         prev_insn_fixp[2] = NULL;
-         prev_insn_reloc_type[0] = BFD_RELOC_UNUSED;
-         prev_insn_reloc_type[1] = BFD_RELOC_UNUSED;
-         prev_insn_reloc_type[2] = BFD_RELOC_UNUSED;
-         prev_insn_extended = 0;
+         history[0].fixp[0] = NULL;
+         history[0].fixp[1] = NULL;
+         history[0].fixp[2] = NULL;
+         history[0].reloc_type[0] = BFD_RELOC_UNUSED;
+         history[0].reloc_type[1] = BFD_RELOC_UNUSED;
+         history[0].reloc_type[2] = BFD_RELOC_UNUSED;
+         history[0].extended_p = 0;
        }
       else if (pinfo & INSN_COND_BRANCH_LIKELY)
        {
@@ -2709,60 +2727,77 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
             the next instruction.  */
          emit_nop ();
          /* Update the previous insn information.  */
-         prev_prev_insn = *ip;
-         prev_insn.insn_mo = &dummy_opcode;
-         prev_insn_fixp[0] = NULL;
-         prev_insn_fixp[1] = NULL;
-         prev_insn_fixp[2] = NULL;
-         prev_insn_reloc_type[0] = BFD_RELOC_UNUSED;
-         prev_insn_reloc_type[1] = BFD_RELOC_UNUSED;
-         prev_insn_reloc_type[2] = BFD_RELOC_UNUSED;
-         prev_insn_extended = 0;
-         prev_insn_is_delay_slot = 1;
+         history[1].insn_mo = ip->insn_mo;
+         history[1].use_extend = ip->use_extend;
+         history[1].extend = ip->extend;
+         history[1].insn_opcode = ip->insn_opcode;
+         history[0].insn_mo = &dummy_opcode;
+         history[0].fixp[0] = NULL;
+         history[0].fixp[1] = NULL;
+         history[0].fixp[2] = NULL;
+         history[0].reloc_type[0] = BFD_RELOC_UNUSED;
+         history[0].reloc_type[1] = BFD_RELOC_UNUSED;
+         history[0].reloc_type[2] = BFD_RELOC_UNUSED;
+         history[0].extended_p = 0;
+         history[0].delay_slot_p = 1;
        }
       else
        {
          /* Update the previous insn information.  */
          if (nops > 0)
-           prev_prev_insn.insn_mo = &dummy_opcode;
+           history[1].insn_mo = &dummy_opcode;
          else
-           prev_prev_insn = prev_insn;
-         prev_insn = *ip;
+           {
+             history[1].insn_mo = history[0].insn_mo;
+             history[1].use_extend = history[0].use_extend;
+             history[1].extend = history[0].extend;
+             history[1].insn_opcode = history[0].insn_opcode;
+           }
+         history[0].insn_mo = ip->insn_mo;
+         history[0].use_extend = ip->use_extend;
+         history[0].extend = ip->extend;
+         history[0].insn_opcode = ip->insn_opcode;
 
          /* Any time we see a branch, we always fill the delay slot
             immediately; since this insn is not a branch, we know it
             is not in a delay slot.  */
-         prev_insn_is_delay_slot = 0;
-
-         prev_insn_fixp[0] = fixp[0];
-         prev_insn_fixp[1] = fixp[1];
-         prev_insn_fixp[2] = fixp[2];
-         prev_insn_reloc_type[0] = reloc_type[0];
-         prev_insn_reloc_type[1] = reloc_type[1];
-         prev_insn_reloc_type[2] = reloc_type[2];
+         history[0].delay_slot_p = 0;
+
+         history[0].fixp[0] = fixp[0];
+         history[0].fixp[1] = fixp[1];
+         history[0].fixp[2] = fixp[2];
+         history[0].reloc_type[0] = reloc_type[0];
+         history[0].reloc_type[1] = reloc_type[1];
+         history[0].reloc_type[2] = reloc_type[2];
          if (mips_opts.mips16)
-           prev_insn_extended = (ip->use_extend
-                                 || *reloc_type > BFD_RELOC_UNUSED);
+           history[0].extended_p = (ip->use_extend
+                                    || *reloc_type > BFD_RELOC_UNUSED);
        }
 
-      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_valid = 1;
+      history[1].noreorder_p = history[0].noreorder_p;
+      history[0].noreorder_p = 0;
+      history[0].frag = frag_now;
+      history[0].where = f - frag_now->fr_literal;
+      history[0].valid_p = 1;
     }
   else if (mips_relax.sequence != 2)
     {
       /* We need to record a bit of information even when we are not
          reordering, in order to determine the base address for mips16
          PC relative relocs.  */
-      prev_prev_insn = prev_insn;
-      prev_insn = *ip;
-      prev_insn_reloc_type[0] = reloc_type[0];
-      prev_insn_reloc_type[1] = reloc_type[1];
-      prev_insn_reloc_type[2] = reloc_type[2];
-      prev_prev_insn_unreordered = prev_insn_unreordered;
-      prev_insn_unreordered = 1;
+      history[1].insn_mo = history[0].insn_mo;
+      history[1].use_extend = history[0].use_extend;
+      history[1].extend = history[0].extend;
+      history[1].insn_opcode = history[0].insn_opcode;
+      history[0].insn_mo = ip->insn_mo;
+      history[0].use_extend = ip->use_extend;
+      history[0].extend = ip->extend;
+      history[0].insn_opcode = ip->insn_opcode;
+      history[0].reloc_type[0] = reloc_type[0];
+      history[0].reloc_type[1] = reloc_type[1];
+      history[0].reloc_type[2] = reloc_type[2];
+      history[1].noreorder_p = history[0].noreorder_p;
+      history[0].noreorder_p = 1;
     }
 
   /* We just output an insn, so the next one doesn't have a label.  */
@@ -2778,21 +2813,21 @@ mips_no_prev_insn (int preserve)
 {
   if (! preserve)
     {
-      prev_insn.insn_mo = &dummy_opcode;
-      prev_prev_insn.insn_mo = &dummy_opcode;
+      history[0].insn_mo = &dummy_opcode;
+      history[1].insn_mo = &dummy_opcode;
       prev_nop_frag = NULL;
       prev_nop_frag_holds = 0;
       prev_nop_frag_required = 0;
       prev_nop_frag_since = 0;
     }
-  prev_insn_valid = 0;
-  prev_insn_is_delay_slot = 0;
-  prev_insn_unreordered = 0;
-  prev_insn_extended = 0;
-  prev_insn_reloc_type[0] = BFD_RELOC_UNUSED;
-  prev_insn_reloc_type[1] = BFD_RELOC_UNUSED;
-  prev_insn_reloc_type[2] = BFD_RELOC_UNUSED;
-  prev_prev_insn_unreordered = 0;
+  history[0].valid_p = 0;
+  history[0].delay_slot_p = 0;
+  history[0].noreorder_p = 0;
+  history[0].extended_p = 0;
+  history[0].reloc_type[0] = BFD_RELOC_UNUSED;
+  history[0].reloc_type[1] = BFD_RELOC_UNUSED;
+  history[0].reloc_type[2] = BFD_RELOC_UNUSED;
+  history[1].noreorder_p = 0;
   mips_clear_insn_labels ();
 }
 
@@ -2811,51 +2846,51 @@ mips_emit_delays (bfd_boolean insns)
 
       nops = 0;
       if ((! mips_opts.mips16
-          && ((prev_insn.insn_mo->pinfo
+          && ((history[0].insn_mo->pinfo
                & (INSN_LOAD_COPROC_DELAY
                   | INSN_COPROC_MOVE_DELAY
                   | INSN_WRITE_COND_CODE))
               && ! cop_interlocks))
          || (! hilo_interlocks
-             && (prev_insn.insn_mo->pinfo
+             && (history[0].insn_mo->pinfo
                  & (INSN_READ_LO
                     | INSN_READ_HI)))
          || (! mips_opts.mips16
-             && (prev_insn.insn_mo->pinfo & INSN_LOAD_MEMORY_DELAY)
+             && (history[0].insn_mo->pinfo & INSN_LOAD_MEMORY_DELAY)
              && ! gpr_interlocks)
          || (! mips_opts.mips16
-             && (prev_insn.insn_mo->pinfo & INSN_COPROC_MEMORY_DELAY)
+             && (history[0].insn_mo->pinfo & INSN_COPROC_MEMORY_DELAY)
              && ! cop_mem_interlocks))
        {
          /* Itbl support may require additional care here.  */
          ++nops;
          if ((! mips_opts.mips16
-              && ((prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
+              && ((history[0].insn_mo->pinfo & INSN_WRITE_COND_CODE)
                   && ! cop_interlocks))
              || (! hilo_interlocks
-                 && ((prev_insn.insn_mo->pinfo & INSN_READ_HI)
-                     || (prev_insn.insn_mo->pinfo & INSN_READ_LO))))
+                 && ((history[0].insn_mo->pinfo & INSN_READ_HI)
+                     || (history[0].insn_mo->pinfo & INSN_READ_LO))))
            ++nops;
 
-         if (prev_insn_unreordered)
+         if (history[0].noreorder_p)
            nops = 0;
        }
       else if ((! mips_opts.mips16
-               && ((prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
+               && ((history[1].insn_mo->pinfo & INSN_WRITE_COND_CODE)
                    && ! cop_interlocks))
               || (! hilo_interlocks
-                  && ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
-                      || (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))))
+                  && ((history[1].insn_mo->pinfo & INSN_READ_HI)
+                      || (history[1].insn_mo->pinfo & INSN_READ_LO))))
        {
          /* Itbl support may require additional care here.  */
-         if (! prev_prev_insn_unreordered)
+         if (! history[1].noreorder_p)
            ++nops;
        }
 
-      if (mips_fix_vr4120 && prev_insn.insn_mo->name)
+      if (mips_fix_vr4120 && history[0].insn_mo->name)
        {
          int min_nops = 0;
-         const char *pn = prev_insn.insn_mo->name;
+         const char *pn = history[0].insn_mo->name;
          if (strncmp (pn, "macc", 4) == 0
              || strncmp (pn, "dmacc", 5) == 0
              || strncmp (pn, "dmult", 5) == 0
@@ -2920,7 +2955,7 @@ macro_start (void)
 {
   memset (&mips_macro_warning.sizes, 0, sizeof (mips_macro_warning.sizes));
   mips_macro_warning.delay_slot_p = (mips_opts.noreorder
-                                    && (prev_insn.insn_mo->pinfo
+                                    && (history[0].insn_mo->pinfo
                                         & (INSN_UNCOND_BRANCH_DELAY
                                            | INSN_COND_BRANCH_DELAY
                                            | INSN_COND_BRANCH_LIKELY)) != 0);
index f1a8629..e1e66b2 100644 (file)
@@ -79,15 +79,6 @@ enum mips_pic_level
 
 extern enum mips_pic_level mips_pic;
 
-struct mips_cl_insn
-{
-  unsigned long insn_opcode;
-  const struct mips_opcode *insn_mo;
-  /* The next two fields are used when generating mips16 code.  */
-  bfd_boolean use_extend;
-  unsigned short extend;
-};
-
 extern int tc_get_register (int frame);
 
 #define md_after_parse_args() mips_after_parse_args()