* config/tc-mips.c (macro): Don't use the target register as a
authorIan Lance Taylor <ian@airs.com>
Wed, 15 Feb 1995 16:48:18 +0000 (16:48 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 15 Feb 1995 16:48:18 +0000 (16:48 +0000)
base register when building the address for M_L{W,D}{L,R}_AB.

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

index 4a714dc87f3dc90c8b3d0d9dd53db94f8149ebe9..89bbf401c8a2fcefdd0b9097963335fdcfa5bc68 100644 (file)
@@ -1,5 +1,13 @@
+Wed Feb 15 11:46:02 1995  Ian Lance Taylor  <ian@cygnus.com>
+
+       * config/tc-mips.c (macro): Don't use the target register as a
+       base register when building the address for M_L{W,D}{L,R}_AB.
+
 Mon Feb 13 14:44:32 1995  Ian Lance Taylor  <ian@cygnus.com>
 
+       * config/tc-mips.c (KT0, KT1): Define.
+       (mips_ip): Recognize $kt0 and $kt1 as register names.
+
        * config/tc-sparc.h (tc_fix_adjustable): Define if OBJ_ELF.
        * config/tc-sparc.c (md_apply_fix): If OBJ_ELF, subtract out the
        value of a defined symbol; the value was added in by
index e38cbbc317e18ff399d8de36b5c8d8962b321c21..6110ca7cbd5def2e7818dbe6843188d79aad0d3c 100644 (file)
@@ -24,6 +24,7 @@
 #include "as.h"
 #include "config.h"
 #include "subsegs.h"
+#include "libiberty.h"
 
 #include <ctype.h>
 
@@ -51,6 +52,8 @@ static char *mips_regmask_frag;
 
 #define AT  1
 #define PIC_CALL_REG 25
+#define KT0 26
+#define KT1 27
 #define GP  28
 #define SP  29
 #define FP  30
@@ -118,6 +121,9 @@ static int file_mips_isa;
 /* The CPU type as a number: 2000, 3000, 4000, 4400, etc.  */
 static int mips_cpu = -1;
 
+/* Whether the 4650 instructions (mad/madu) are permitted.  */
+static int mips_4650 = -1;
+
 /* MIPS PIC level.  */
 
 enum mips_pic_level
@@ -561,6 +567,14 @@ md_begin ()
          if (mips_cpu == -1)
            mips_cpu = 4600;
        }
+      else if (strcmp (cpu, "r4650") == 0)
+       {
+         mips_isa = 3;
+         if (mips_cpu == -1)
+           mips_cpu = 4650;
+         if (mips_4650 == -1)
+           mips_4650 = 1;
+       }
       else
        {
          mips_isa = 1;
@@ -572,6 +586,9 @@ md_begin ()
        free (a);
     }
 
+  if (mips_4650 < 0)
+    mips_4650 = 0;
+
   if (mips_isa < 2 && mips_trap)
     as_bad ("trap exception not supported at ISA 1");
 
@@ -892,18 +909,20 @@ append_insn (place, ip, address_expr, reloc_type)
        {
          /* The previous instruction reads the LO register; if the
             current instruction writes to the LO register, we must
-            insert two NOPS.  */
-         if (mips_optimize == 0
-             || (pinfo & INSN_WRITE_LO))
+            insert two NOPS.  The R4650 has interlocks.  */
+         if (! mips_4650
+             && (mips_optimize == 0
+                 || (pinfo & INSN_WRITE_LO)))
            nops += 2;
        }
       else if (prev_insn.insn_mo->pinfo & INSN_READ_HI)
        {
          /* The previous instruction reads the HI register; if the
             current instruction writes to the HI register, we must
-            insert a NOP.  */
-         if (mips_optimize == 0
-             || (pinfo & INSN_WRITE_HI))
+            insert a NOP.  The R4650 has interlocks.  */
+         if (! mips_4650
+             && (mips_optimize == 0
+                 || (pinfo & INSN_WRITE_HI)))
            nops += 2;
        }
 
@@ -911,18 +930,20 @@ append_insn (place, ip, address_expr, reloc_type)
         instructions: 1) setting the condition codes using a move to
         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.  If we are not already
-        emitting a NOP instruction, we must check for these cases
-        compared to the instruction previous to the previous
-        instruction.  */
+        or LO register and then writing to it (except on the R4650,
+        which has 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
          && (((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))
              || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)
-                 && (pinfo & INSN_WRITE_LO))
+                 && (pinfo & INSN_WRITE_LO)
+                 && ! mips_4650)
              || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
-                 && (pinfo & INSN_WRITE_HI))))
+                 && (pinfo & INSN_WRITE_HI)
+                 && ! mips_4650)))
        ++nops;
 
       /* If we are being given a nop instruction, don't bother with
@@ -1079,9 +1100,11 @@ append_insn (place, ip, address_expr, reloc_type)
              || (prev_pinfo
                  & (INSN_LOAD_COPROC_DELAY
                     | INSN_COPROC_MOVE_DELAY
-                    | INSN_WRITE_COND_CODE
-                    | INSN_READ_LO
-                    | INSN_READ_HI))
+                    | INSN_WRITE_COND_CODE))
+             || (! mips_4650
+                 && (prev_pinfo
+                     & (INSN_READ_LO
+                        | INSN_READ_HI)))
              || (mips_isa < 2
                  && (prev_pinfo
                      & (INSN_LOAD_MEMORY_DELAY
@@ -1265,9 +1288,11 @@ mips_emit_delays ()
       if ((prev_insn.insn_mo->pinfo
           & (INSN_LOAD_COPROC_DELAY
              | INSN_COPROC_MOVE_DELAY
-             | INSN_WRITE_COND_CODE
-             | INSN_READ_LO
-             | INSN_READ_HI))
+             | INSN_WRITE_COND_CODE))
+         || (! mips_4650
+             && (prev_insn.insn_mo->pinfo
+                 & (INSN_READ_LO
+                    | INSN_READ_HI)))
          || (mips_isa < 2
              && (prev_insn.insn_mo->pinfo
                  & (INSN_LOAD_MEMORY_DELAY
@@ -1275,13 +1300,15 @@ mips_emit_delays ()
        {
          nop = 1;
          if ((prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
-             || (prev_insn.insn_mo->pinfo & INSN_READ_HI)
-             || (prev_insn.insn_mo->pinfo & INSN_READ_LO))
+             || (! mips_4650
+                 && ((prev_insn.insn_mo->pinfo & INSN_READ_HI)
+                     || (prev_insn.insn_mo->pinfo & INSN_READ_LO))))
            emit_nop ();
        }
       else if ((prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
-              || (prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
-              || (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))
+              || (! mips_4650
+                  && ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
+                      || (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))))
        nop = 1;
       if (nop)
        {
@@ -1814,6 +1841,7 @@ macro (ip)
   int likely = 0;
   int dbl = 0;
   int coproc = 0;
+  int lr = 0;
   offsetT maxnum;
   bfd_reloc_code_real_type r;
   char *p;
@@ -2821,9 +2849,11 @@ macro (ip)
       goto ld;
     case M_LWL_AB:
       s = "lwl";
+      lr = 1;
       goto ld;
     case M_LWR_AB:
       s = "lwr";
+      lr = 1;
       goto ld;
     case M_LDC1_AB:
       s = "ldc1";
@@ -2839,9 +2869,11 @@ macro (ip)
       goto ld;
     case M_LDL_AB:
       s = "ldl";
+      lr = 1;
       goto ld;
     case M_LDR_AB:
       s = "ldr";
+      lr = 1;
       goto ld;
     case M_LL_AB:
       s = "ll";
@@ -2852,7 +2884,7 @@ macro (ip)
     case M_LWU_AB:
       s = "lwu";
     ld:
-      if (breg == treg || coproc)
+      if (breg == treg || coproc || lr)
        {
          tempreg = AT;
          used_at = 1;
@@ -4186,14 +4218,16 @@ mips_ip (str, ip)
 
       if (insn->pinfo == INSN_MACRO)
        insn_isa = insn->match;
-      else if (insn->pinfo & INSN_ISA2)
+      else if ((insn->pinfo & INSN_ISA) == INSN_ISA2)
        insn_isa = 2;
-      else if (insn->pinfo & INSN_ISA3)
+      else if ((insn->pinfo & INSN_ISA) == INSN_ISA3)
        insn_isa = 3;
       else
        insn_isa = 1;
 
-      if (insn_isa > mips_isa)
+      if (insn_isa > mips_isa
+         || ((insn->pinfo & INSN_ISA) == INSN_4650
+             && ! mips_4650))
        {
          if (insn + 1 < &mips_opcodes[NUMOPCODES]
              && strcmp (insn->name, insn[1].name) == 0)
@@ -4387,6 +4421,16 @@ mips_ip (str, ip)
                          s += 3;
                          regno = AT;
                        }
+                     else if (s[1] == 'k' && s[2] == 't' && s[3] == '0')
+                       {
+                         s += 4;
+                         regno = KT0;
+                       }
+                     else if (s[1] == 'k' && s[2] == 't' && s[3] == '1')
+                       {
+                         s += 4;
+                         regno = KT1;
+                       }
                      else
                        goto notreg;
                    }
@@ -5035,6 +5079,10 @@ struct option md_longopts[] = {
   {"EB", no_argument, NULL, OPTION_EB},
 #define OPTION_EL (OPTION_MD_BASE + 11)
   {"EL", no_argument, NULL, OPTION_EL},
+#define OPTION_M4650 (OPTION_MD_BASE + 12)
+  {"m4650", no_argument, NULL, OPTION_M4650},
+#define OPTION_NO_M4650 (OPTION_MD_BASE + 13)
+  {"no-m4650", no_argument, NULL, OPTION_NO_M4650},
 
 #ifdef OBJ_ELF
 #define OPTION_CALL_SHARED (OPTION_MD_BASE + 6)
@@ -5159,6 +5207,12 @@ md_parse_option (c, arg)
                  mips_cpu = 4400;
                else if (strcmp (p, "4600") == 0)
                  mips_cpu = 4600;
+               else if (strcmp (p, "4650") == 0)
+                 {
+                   mips_cpu = 4650;
+                   if (mips_4650 < 0)
+                     mips_4650 = 1;
+                 }
                break;
 
              case '6':
@@ -5183,6 +5237,14 @@ md_parse_option (c, arg)
       }
       break;
 
+    case OPTION_M4650:
+      mips_4650 = 1;
+      break;
+
+    case OPTION_NO_M4650:
+      mips_4650 = 0;
+      break;
+
     case OPTION_MEMBEDDED_PIC:
       mips_pic = EMBEDDED_PIC;
 #ifdef GPOPT