Wed Jun 26 16:23:08 1996 James G. Smith <jsmith@cygnus.co.uk>
authorJackie Smith Cashion <jsmith@redhat.com>
Wed, 26 Jun 1996 15:28:00 +0000 (15:28 +0000)
committerJackie Smith Cashion <jsmith@redhat.com>
Wed, 26 Jun 1996 15:28:00 +0000 (15:28 +0000)
* config/tc-mips.c: Added cop_interlocks, to avoid NOP insertion
  between co-processor comparisons and branches for the VR4300.

The preliminary documentation was slightly unclear on this issue, but
NEC have confirmed that there is an interlock within the CPU.

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

index 17f2406a3eca245986e487f41dd9f6c6df8bdf68..eaa0bd88b53c9d9354ed32451b3527f3f6f1aedd 100644 (file)
@@ -1,3 +1,8 @@
+Wed Jun 26 16:23:08 1996  James G. Smith  <jsmith@cygnus.co.uk>
+
+       * config/tc-mips.c: Added cop_interlocks, to avoid NOP insertion
+       between co-processor comparisons and branches for the VR4300.
+
 Mon Jun 24 18:02:50 1996  Jason Molenda  (crash@godzilla.cygnus.co.jp)
 
        * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir,
index 932bfc78a2970a8f700f111146eee3500c692e92..1f7f951d3ed4792df2ada680d856eb60cd0ac298 100644 (file)
@@ -144,6 +144,10 @@ static int mips_4100 = -1;
    require nops to be inserted.  */
 static int interlocks = -1;
 
+/* As with "interlocks" this is used by hardware that has FP
+   (co-processor) interlocks.  */
+static int cop_interlocks = -1;
+
 /* MIPS PIC level.  */
 
 enum mips_pic_level
@@ -688,11 +692,16 @@ md_begin ()
   if (mips_4100 < 0)
     mips_4100 = 0;
 
-  if (mips_4650 || mips_4010 || mips_4100)
+  if (mips_4650 || mips_4010 || mips_4100 || mips_cpu == 4300)
     interlocks = 1;
   else
     interlocks = 0;
 
+  if (mips_cpu == 4300)
+    cop_interlocks = 1;
+  else
+    cop_interlocks = 0;
+
   if (mips_isa < 2 && mips_trap)
     as_bad ("trap exception not supported at ISA 1");
 
@@ -999,6 +1008,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
         the contents of the current insn.  */
       if (mips_isa < 4
          && ((prev_pinfo & INSN_LOAD_COPROC_DELAY)
+              && ! cop_interlocks
              || (mips_isa < 2
                  && (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))
        {
@@ -1016,6 +1026,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
        }
       else if (mips_isa < 4
               && ((prev_pinfo & INSN_COPROC_MOVE_DELAY)
+                   && ! cop_interlocks
                   || (mips_isa < 2
                       && (prev_pinfo & INSN_COPROC_MEMORY_DELAY))))
        {
@@ -1068,7 +1079,8 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
            }
        }
       else if (mips_isa < 4
-              && (prev_pinfo & INSN_WRITE_COND_CODE))
+              && (prev_pinfo & INSN_WRITE_COND_CODE)
+               && ! cop_interlocks)
        {
          /* The previous instruction sets the coprocessor condition
             codes, but does not require a general coprocessor delay
@@ -1083,7 +1095,8 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
        {
          /* The previous instruction reads the LO register; if the
             current instruction writes to the LO register, we must
-            insert two NOPS.  The R4650 and VR4100 have interlocks.  */
+            insert two NOPS.  The R4650, VR4100 and VR4300 have
+            interlocks.  */
          if (! interlocks
              && (mips_optimize == 0
                  || (pinfo & INSN_WRITE_LO)))
@@ -1093,7 +1106,8 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
        {
          /* The previous instruction reads the HI register; if the
             current instruction writes to the HI register, we must
-            insert a NOP.  The R4650 and VR4100 have interlocks.  */
+            insert a NOP.  The R4650, VR4100 and VR4300 have
+            interlocks.  */
          if (! interlocks
              && (mips_optimize == 0
                  || (pinfo & INSN_WRITE_HI)))
@@ -1105,15 +1119,16 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
         coprocessor instruction which requires a general coprocessor
         delay and then reading the condition codes 2) reading the HI
         or LO register and then writing to it (except on the R4650,
-        and VR4100 which have interlocks).  If we are not already
-        emitting a NOP instruction, we must check for these cases
-        compared to the instruction previous to the previous
+        VR4100, and VR4300 which have interlocks).  If we are not
+        already emitting a NOP instruction, we must check for these
+        cases compared to the instruction previous to the previous
         instruction.  */
       if (nops == 0
          && ((mips_isa < 4
               && (prev_prev_insn.insn_mo->pinfo & INSN_COPROC_MOVE_DELAY)
               && (prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
-              && (pinfo & INSN_READ_COND_CODE))
+              && (pinfo & INSN_READ_COND_CODE)
+               && ! cop_interlocks)
              || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)
                  && (pinfo & INSN_WRITE_LO)
                  && ! interlocks)
@@ -1427,6 +1442,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
        }
       else if (pinfo & INSN_COND_BRANCH_LIKELY)
        {
+printf("DBG: append_insn: inserting a NOP (INSN_COND_BRANCH_LIKELY)\n");
          /* We don't yet optimize a branch likely.  What we should do
             is look at the target, copy the instruction found there
             into the delay slot, and increment the branch to jump to
@@ -1492,10 +1508,11 @@ mips_emit_delays ()
 
       nop = 0;
       if ((mips_isa < 4
-          && (prev_insn.insn_mo->pinfo
-              & (INSN_LOAD_COPROC_DELAY
-                 | INSN_COPROC_MOVE_DELAY
-                 | INSN_WRITE_COND_CODE)))
+          && (! cop_interlocks
+               && (prev_insn.insn_mo->pinfo
+                   & (INSN_LOAD_COPROC_DELAY
+                      | INSN_COPROC_MOVE_DELAY
+                      | INSN_WRITE_COND_CODE))))
          || (! interlocks
              && (prev_insn.insn_mo->pinfo
                  & (INSN_READ_LO
@@ -1507,14 +1524,16 @@ mips_emit_delays ()
        {
          nop = 1;
          if ((mips_isa < 4
-              && (prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
+              && (! cop_interlocks
+                   && prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
              || (! interlocks
                  && ((prev_insn.insn_mo->pinfo & INSN_READ_HI)
                      || (prev_insn.insn_mo->pinfo & INSN_READ_LO))))
            emit_nop ();
        }
       else if ((mips_isa < 4
-               && (prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
+               && (! cop_interlocks
+                    && prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
               || (! interlocks
                   && ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
                       || (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))))
@@ -5577,7 +5596,7 @@ mips_ip (str, ip)
            case 'j':           /* 16 bit signed immediate */
              imm_reloc = BFD_RELOC_LO16;
              c = my_getSmallExpression (&imm_expr, s);
-             if (c)
+             if (c != '\0')
                {
                  if (c != 'l')
                    {
@@ -5595,7 +5614,7 @@ mips_ip (str, ip)
                }
              if (*args == 'i')
                {
-                 if (imm_expr.X_op != O_constant
+                 if ((c == '\0' && imm_expr.X_op != O_constant)
                      || imm_expr.X_add_number < 0
                      || imm_expr.X_add_number >= 0x10000)
                    {
@@ -5629,7 +5648,7 @@ mips_ip (str, ip)
                    max = 0x8000;
                  else
                    max = 0x10000;
-                 if (imm_expr.X_op != O_constant
+                 if ((c == '\0' && imm_expr.X_op != O_constant)
                      || imm_expr.X_add_number < -0x8000
                      || imm_expr.X_add_number >= max
                      || (more