* config/tc-mips.c (macro): Handle M_U{L,S}D[_A] (unaligned double
authorIan Lance Taylor <ian@airs.com>
Wed, 15 Feb 1995 20:43:57 +0000 (20:43 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 15 Feb 1995 20:43:57 +0000 (20:43 +0000)
loads and stores).

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

index 5585fd6ae4e66d9144d422563bc0afe2bbb731a5..f0e6a0c59ac3e7def615b25aebcb16f078b673fb 100644 (file)
@@ -1,8 +1,3 @@
-Wed Feb 15 15:31:57 1995  Ian Lance Taylor  <ian@cygnus.com>
-
-       * config/tc-i386.c (tc_i386_fix_adjustable): Do adjust global
-       symbols if OBJ_AOUT.
-
 Wed Feb 15 15:07:00 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
 
        * config/tc-ppc.c (md_pseudo_table): If ELF, go to ppc_elf_cons
@@ -26,6 +21,12 @@ Wed Feb 15 15:07:00 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
 
 Wed Feb 15 11:46:02 1995  Ian Lance Taylor  <ian@cygnus.com>
 
+       * config/tc-mips.c (macro): Handle M_U{L,S}D[_A] (unaligned double
+       loads and stores).
+
+       * config/tc-i386.c (tc_i386_fix_adjustable): Do adjust global
+       symbols if OBJ_AOUT.
+
        * 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.
 
index 6110ca7cbd5def2e7818dbe6843188d79aad0d3c..b42299d97e1c06ffe3a416dbd63d355b1b2dfb2b 100644 (file)
@@ -1843,6 +1843,7 @@ macro (ip)
   int coproc = 0;
   int lr = 0;
   offsetT maxnum;
+  int off;
   bfd_reloc_code_real_type r;
   char *p;
   int hold_mips_optimize;
@@ -3569,6 +3570,8 @@ macro2 (ip)
   int likely = 0;
   int dbl = 0;
   int coproc = 0;
+  int lr = 0;
+  int off;
   offsetT maxnum;
   bfd_reloc_code_real_type r;
   char *p;
@@ -4029,58 +4032,73 @@ macro2 (ip)
       macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg, treg, AT);
       break;
 
+    case M_ULD:
+      s = "ldl";
+      s2 = "ldr";
+      off = 7;
+      goto ulw;
     case M_ULW:
-      if (offset_expr.X_add_number >= 0x7ffd)
+      s = "lwl";
+      s2 = "lwr";
+      off = 3;
+    ulw:
+      if (offset_expr.X_add_number >= 0x8000 - off)
        as_bad ("operand overflow");
       if (byte_order == LITTLE_ENDIAN)
-       offset_expr.X_add_number += 3;
-      macro_build ((char *) NULL, &icnt, &offset_expr, "lwl", "t,o(b)", treg,
+       offset_expr.X_add_number += off;
+      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
                   (int) BFD_RELOC_LO16, breg);
       if (byte_order == LITTLE_ENDIAN)
-       offset_expr.X_add_number -= 3;
+       offset_expr.X_add_number -= off;
       else
-       offset_expr.X_add_number += 3;
-      macro_build ((char *) NULL, &icnt, &offset_expr, "lwr", "t,o(b)", treg,
+       offset_expr.X_add_number += off;
+      macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", treg,
                   (int) BFD_RELOC_LO16, breg);
       return;
 
+    case M_ULD_A:
+      s = "ldl";
+      s2 = "ldr";
+      off = 7;
+      goto ulwa;
+    case M_ULW_A:
+      s = "lwl";
+      s2 = "lwr";
+      off = 3;
+    ulwa:
+      load_address (&icnt, AT, &offset_expr);
+      if (byte_order == LITTLE_ENDIAN)
+       expr1.X_add_number = off;
+      else
+       expr1.X_add_number = 0;
+      macro_build ((char *) NULL, &icnt, &expr1, s, "t,o(b)", treg,
+                  (int) BFD_RELOC_LO16, AT);
+      if (byte_order == LITTLE_ENDIAN)
+       expr1.X_add_number = 0;
+      else
+       expr1.X_add_number = off;
+      macro_build ((char *) NULL, &icnt, &expr1, s2, "t,o(b)", treg,
+                  (int) BFD_RELOC_LO16, AT);
+      break;
+
     case M_ULH_A:
     case M_ULHU_A:
-    case M_ULW_A:
       load_address (&icnt, AT, &offset_expr);
-      if (mask == M_ULW_A)
-       {
-         if (byte_order == LITTLE_ENDIAN)
-           expr1.X_add_number = 3;
-         else
-           expr1.X_add_number = 0;
-         macro_build ((char *) NULL, &icnt, &expr1, "lwl", "t,o(b)", treg,
-                      (int) BFD_RELOC_LO16, AT);
-         if (byte_order == LITTLE_ENDIAN)
-           expr1.X_add_number = 0;
-         else
-           expr1.X_add_number = 3;
-         macro_build ((char *) NULL, &icnt, &expr1, "lwr", "t,o(b)", treg,
-                      (int) BFD_RELOC_LO16, AT);
-       }
+      if (byte_order == BIG_ENDIAN)
+       expr1.X_add_number = 0;
+      macro_build ((char *) NULL, &icnt, &expr1,
+                  mask == M_ULH_A ? "lb" : "lbu", "t,o(b)", treg,
+                  (int) BFD_RELOC_LO16, AT);
+      if (byte_order == BIG_ENDIAN)
+       expr1.X_add_number = 1;
       else
-       {
-         if (byte_order == BIG_ENDIAN)
-           expr1.X_add_number = 0;
-         macro_build ((char *) NULL, &icnt, &expr1,
-                      mask == M_ULH_A ? "lb" : "lbu", "t,o(b)", treg,
-                      (int) BFD_RELOC_LO16, AT);
-         if (byte_order == BIG_ENDIAN)
-           expr1.X_add_number = 1;
-         else
-           expr1.X_add_number = 0;
-         macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,
-                      (int) BFD_RELOC_LO16, AT);
-         macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,
-                      treg, 8);
-         macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,
-                      treg, AT);
-       }
+       expr1.X_add_number = 0;
+      macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,
+                  (int) BFD_RELOC_LO16, AT);
+      macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,
+                  treg, 8);
+      macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,
+                  treg, AT);
       break;
 
     case M_USH:
@@ -4099,64 +4117,79 @@ macro2 (ip)
                   (int) BFD_RELOC_LO16, breg);
       break;
 
+    case M_USD:
+      s = "sdl";
+      s2 = "sdr";
+      off = 7;
+      goto usw;
     case M_USW:
-      if (offset_expr.X_add_number >= 0x7ffd)
+      s = "swl";
+      s2 = "swr";
+      off = 3;
+    usw:
+      if (offset_expr.X_add_number >= 0x8000 - off)
        as_bad ("operand overflow");
       if (byte_order == LITTLE_ENDIAN)
-       offset_expr.X_add_number += 3;
-      macro_build ((char *) NULL, &icnt, &offset_expr, "swl", "t,o(b)", treg,
+       offset_expr.X_add_number += off;
+      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
                   (int) BFD_RELOC_LO16, breg);
       if (byte_order == LITTLE_ENDIAN)
-       offset_expr.X_add_number -= 3;
+       offset_expr.X_add_number -= off;
       else
-       offset_expr.X_add_number += 3;
-      macro_build ((char *) NULL, &icnt, &offset_expr, "swr", "t,o(b)", treg,
+       offset_expr.X_add_number += off;
+      macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", treg,
                   (int) BFD_RELOC_LO16, breg);
       return;
 
-    case M_USH_A:
+    case M_USD_A:
+      s = "sdl";
+      s2 = "sdr";
+      off = 7;
+      goto uswa;
     case M_USW_A:
+      s = "swl";
+      s2 = "swr";
+      off = 3;
+    uswa:
       load_address (&icnt, AT, &offset_expr);
-      if (mask == M_USW_A)
-       {
-         if (byte_order == LITTLE_ENDIAN)
-           expr1.X_add_number = 3;
-         else
-           expr1.X_add_number = 0;
-         macro_build ((char *) NULL, &icnt, &expr1, "swl", "t,o(b)", treg,
-                      (int) BFD_RELOC_LO16, AT);
-         if (byte_order == LITTLE_ENDIAN)
-           expr1.X_add_number = 0;
-         else
-           expr1.X_add_number = 3;
-         macro_build ((char *) NULL, &icnt, &expr1, "swr", "t,o(b)", treg,
-                      (int) BFD_RELOC_LO16, AT);
-       }
+      if (byte_order == LITTLE_ENDIAN)
+       expr1.X_add_number = off;
       else
-       {
-         if (byte_order == LITTLE_ENDIAN)
-           expr1.X_add_number = 0;
-         macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,
-                      (int) BFD_RELOC_LO16, AT);
-         macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", treg,
-                      treg, 8);
-         if (byte_order == LITTLE_ENDIAN)
-           expr1.X_add_number = 1;
-         else
-           expr1.X_add_number = 0;
-         macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,
-                      (int) BFD_RELOC_LO16, AT);
-         if (byte_order == LITTLE_ENDIAN)
-           expr1.X_add_number = 0;
-         else
-           expr1.X_add_number = 1;
-         macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,
-                      (int) BFD_RELOC_LO16, AT);
-         macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,
-                      treg, 8);
-         macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,
-                      treg, AT);
-       }
+       expr1.X_add_number = 0;
+      macro_build ((char *) NULL, &icnt, &expr1, s, "t,o(b)", treg,
+                  (int) BFD_RELOC_LO16, AT);
+      if (byte_order == LITTLE_ENDIAN)
+       expr1.X_add_number = 0;
+      else
+       expr1.X_add_number = off;
+      macro_build ((char *) NULL, &icnt, &expr1, s2, "t,o(b)", treg,
+                  (int) BFD_RELOC_LO16, AT);
+      break;
+
+    case M_USH_A:
+      load_address (&icnt, AT, &offset_expr);
+      if (byte_order == LITTLE_ENDIAN)
+       expr1.X_add_number = 0;
+      macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,
+                  (int) BFD_RELOC_LO16, AT);
+      macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", treg,
+                  treg, 8);
+      if (byte_order == LITTLE_ENDIAN)
+       expr1.X_add_number = 1;
+      else
+       expr1.X_add_number = 0;
+      macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,
+                  (int) BFD_RELOC_LO16, AT);
+      if (byte_order == LITTLE_ENDIAN)
+       expr1.X_add_number = 0;
+      else
+       expr1.X_add_number = 1;
+      macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,
+                  (int) BFD_RELOC_LO16, AT);
+      macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,
+                  treg, 8);
+      macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,
+                  treg, AT);
       break;
 
     default: