* dwarf2dbg.c (dwarf2_gen_line_info): Mirror the section symbol
[deliverable/binutils-gdb.git] / gas / config / tc-z8k.c
index 36d28b34c858856f3805dbc5bbb25a41a98ff228..f89b14b3b32e3928e760622dd822fa88c4978bbb 100644 (file)
@@ -1,5 +1,5 @@
-/* tc-z8k.c -- Assemble code for the Zilog Z800N
-   Copyright (C) 1992 Free Software Foundation.
+/* tc-z8k.c -- Assemble code for the Zilog Z800n
+   Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation.
 
    This file is part of GAS, the GNU Assembler.
 
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
+   along with GAS; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
 
 /*
   Written By Steve Chamberlain
   sac@cygnus.com
   */
-
-#include <stdio.h>
 #define DEFINE_TABLE
-#include "../opcodes/z8k-opc.h"
+#include <stdio.h>
+
+#include "opcodes/z8k-opc.h"
 
 #include "as.h"
-#include "read.h"
 #include "bfd.h"
 #include <ctype.h>
-#include "listing.h"
 
-<<<<<<< tc-z8k.c
-char comment_chars[]=
+const char comment_chars[] =
 {'!', 0};
-char line_separator_chars[]=
+const char line_separator_chars[] =
 {';', 0};
-=======
-const char  comment_chars[]  = { '!',0 };
-const char line_separator_chars[] = { ';' ,0};
-const char line_comment_chars[] = "";
->>>>>>> 1.5
+const char line_comment_chars[] =
+{'#', 0};
 
-extern int machine  ;
+extern int machine;
 extern int coff_flags;
 int segmented_mode;
-int md_reloc_size;
+const int md_reloc_size;
 
 /* This table describes all the machine specific pseudo-ops the assembler
    has to support.  The fields are:
@@ -58,8 +52,7 @@ int md_reloc_size;
 
 void cons ();
 
-
-void 
+void
 s_segm ()
 {
   segmented_mode = 1;
@@ -67,14 +60,61 @@ s_segm ()
   coff_flags = F_Z8001;
 }
 
-void 
+void
 s_unseg ()
 {
   segmented_mode = 0;
   machine = bfd_mach_z8002;
   coff_flags = F_Z8002;
 }
-const pseudo_typeS md_pseudo_table[]=
+
+static
+void
+even ()
+{
+  frag_align (1, 0, 0);
+  record_alignment (now_seg, 1);
+}
+
+void obj_coff_section ();
+
+int
+tohex (c)
+     int c;
+{
+  if (isdigit (c))
+    return c - '0';
+  if (islower (c))
+    return c - 'a' + 10;
+  return c - 'A' + 10;
+}
+
+void
+sval ()
+{
+
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer == '\'')
+    {
+      int c;
+      input_line_pointer++;
+      c = *input_line_pointer++;
+      while (c != '\'')
+       {
+         if (c == '%')
+           {
+             c = (tohex (input_line_pointer[0]) << 4)
+               | tohex (input_line_pointer[1]);
+             input_line_pointer += 2;
+           }
+         FRAG_APPEND_1_CHAR (c);
+         c = *input_line_pointer++;
+       }
+      demand_empty_rest_of_line ();
+    }
+
+}
+const pseudo_typeS md_pseudo_table[] =
 {
   {"int", cons, 2},
   {"data.b", cons, 1},
@@ -87,30 +127,34 @@ const pseudo_typeS md_pseudo_table[]=
   {"program", s_ignore, 0},
   {"z8001", s_segm, 0},
   {"z8002", s_unseg, 0},
+
+
+  {"segm", s_segm, 0},
+  {"unsegm", s_unseg, 0},
+  {"unseg", s_unseg, 0},
+  {"name", s_app_file, 0},
+  {"global", s_globl, 0},
+  {"wval", cons, 2},
+  {"lval", cons, 4},
+  {"bval", cons, 1},
+  {"sval", sval, 0},
+  {"rsect", obj_coff_section, 0},
+  {"sect", obj_coff_section, 0},
+  {"block", s_space, 0},
+  {"even", even, 0},
   {0, 0, 0}
 };
 
-
-const char EXP_CHARS[]= "eE";
+const char EXP_CHARS[] = "eE";
 
 /* Chars that mean this number is a floating point constant */
 /* As in 0f12.456 */
 /* or    0d1.2345e12 */
-<<<<<<< tc-z8k.c
-char FLT_CHARS[]= "rRsSfFdDxXpP";
-=======
 const char FLT_CHARS[] = "rRsSfFdDxXpP";
->>>>>>> 1.5
-
-
-const relax_typeS md_relax_table[1];
-
 
 static struct hash_control *opcode_hash_control;       /* Opcode mnemonics */
 
-
-
-void 
+void
 md_begin ()
 {
   opcode_entry_type *opcode;
@@ -119,7 +163,6 @@ md_begin ()
 
   opcode_hash_control = hash_new ();
 
-
   for (opcode = z8k_table; opcode->name; opcode++)
     {
       /* Only enter unique codes into the table */
@@ -134,10 +177,22 @@ md_begin ()
       prev_name = opcode->name;
     }
 
-/* default to z8002 */
-s_unseg();
-}
+  /* default to z8002 */
+  s_unseg ();
+
+  /* insert the pseudo ops too */
+  for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
+    {
+      opcode_entry_type *fake_opcode;
+      fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));
+      fake_opcode->name = md_pseudo_table[idx].poc_name,
+       fake_opcode->func = (void *) (md_pseudo_table + idx);
+      fake_opcode->opcode = 250;
+      hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
+    }
 
+  linkrelax = 1;
+}
 
 struct z8k_exp
 {
@@ -154,16 +209,18 @@ typedef struct z8k_op
 
   unsigned int x_reg;          /* any other register associated with the mode */
   expressionS exp;             /* any expression */
-}      op_type;
-
+}
 
+op_type;
 
 static expressionS *da_operand;
 static expressionS *imm_operand;
 
-
 int reg[16];
 int the_cc;
+int the_ctrl;
+int the_flags;
+int the_interrupt;
 
 char *
 DEFUN (whatreg, (reg, src),
@@ -198,7 +255,6 @@ DEFUN (whatreg, (reg, src),
 
   */
 
-
 /* try and parse a reg name, returns number of chars consumed */
 char *
 DEFUN (parse_reg, (src, mode, reg),
@@ -207,39 +263,68 @@ DEFUN (parse_reg, (src, mode, reg),
        unsigned int *reg)
 {
   char *res = 0;
+  char regno;
 
+  if (src[0] == 's' && src[1] == 'p')
+    {
+      if (segmented_mode)
+        {
+          *mode = CLASS_REG_LONG;
+          *reg = 14;
+        }
+      else
+        {
+          *mode = CLASS_REG_WORD;
+          *reg = 15;
+        }
+      return src + 2;
+    }
   if (src[0] == 'r')
     {
       if (src[1] == 'r')
-       {
-         *mode = CLASS_REG_LONG;
-         res = whatreg (reg, src + 2);
-       }
+        {
+          *mode = CLASS_REG_LONG;
+          res = whatreg (reg, src + 2);
+         regno = *reg;
+         if (regno > 14)
+               as_warn (_("register rr%d, out of range."),regno);
+        }
       else if (src[1] == 'h')
-       {
-         *mode = CLASS_REG_BYTE;
-         res = whatreg (reg, src + 2);
-       }
+        {
+          *mode = CLASS_REG_BYTE;
+          res = whatreg (reg, src + 2);
+         regno = *reg;
+         if (regno > 7)
+               as_warn (_("register rh%d, out of range."),regno);
+        }
       else if (src[1] == 'l')
-       {
-         *mode = CLASS_REG_BYTE;
-         res = whatreg (reg, src + 2) ;
-         *reg += 8;
-       }
+        {
+          *mode = CLASS_REG_BYTE;
+          res = whatreg (reg, src + 2);
+         regno = *reg;
+         if (regno > 7)
+               as_warn (_("register rl%d, out of range."),regno);
+          *reg += 8;
+        }
       else if (src[1] == 'q')
-       {
-         *mode = CLASS_REG_QUAD;
-         res = whatreg (reg, src + 2);
-       }
+        {
+          *mode = CLASS_REG_QUAD;
+          res = whatreg (reg, src + 2);
+         regno = *reg;
+         if (regno > 12)
+               as_warn (_("register rq%d, out of range."),regno);
+        }
       else
-       {
-         *mode = CLASS_REG_WORD;
-         res = whatreg (reg, src + 1);
-       }
+        {
+          *mode = CLASS_REG_WORD;
+          res = whatreg (reg, src + 1);
+         regno = *reg;
+         if (regno > 15)
+               as_warn (_("register r%d, out of range."),regno);
+        }
     }
   return res;
 
-
 }
 
 char *
@@ -249,29 +334,14 @@ DEFUN (parse_exp, (s, op),
 {
   char *save = input_line_pointer;
   char *new;
-  segT seg;
 
   input_line_pointer = s;
-  seg = expr (0, op);
+  expression (op);
+  if (op->X_op == O_absent)
+    as_bad (_("missing operand"));
   new = input_line_pointer;
   input_line_pointer = save;
-  if (SEG_NORMAL (seg))
-    return new;
-  switch (seg)
-    {
-    case SEG_ABSOLUTE:
-    case SEG_UNKNOWN:
-    case SEG_DIFFERENCE:
-    case SEG_BIG:
-    case SEG_REGISTER:
-      return new;
-    case SEG_ABSENT:
-      as_bad ("Missing operand");
-      return new;
-    default:
-      as_bad ("Don't understand operand of type %s", segment_name (seg));
-      return new;
-    }
+  return new;
 }
 
 /* The many forms of operand:
@@ -301,7 +371,7 @@ DEFUN (checkfor, (ptr, what),
     ptr++;
   else
     {
-      as_bad ("expected %c", what);
+      as_bad (_("expected %c"), what);
     }
   return ptr;
 }
@@ -317,7 +387,7 @@ DEFUN (regword, (mode, string),
   ok = CLASS_REG_WORD;
   if (ok != mode)
     {
-      as_bad ("register is wrong size for a word %s", string);
+      as_bad (_("register is wrong size for a word %s"), string);
     }
 }
 
@@ -332,19 +402,173 @@ DEFUN (regaddr, (mode, string),
   ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
   if (ok != mode)
     {
-      as_bad ("register is wrong size for address %s", string);
+      as_bad (_("register is wrong size for address %s"), string);
     }
 }
 
-struct cc_names
+struct ctrl_names
+{
+   int value;
+   char *name;
+};
+
+struct ctrl_names ctrl_table[] =
+{
+   0x2, "fcw",
+   0X3, "refresh",
+   0x4, "psapseg",
+   0x5, "psapoff",
+   0x5, "psap",
+   0x6, "nspseg",
+   0x7, "nspoff",
+   0x7, "nsp",
+   0, 0
+};
+   
+static void
+DEFUN (get_ctrl_operand, (ptr, mode, dst),
+       char **ptr AND
+       struct z8k_op *mode AND
+       unsigned int dst)
+{
+  char *src = *ptr;
+  int r;
+  int i;
+
+  while (*src == ' ')
+    src++;
+
+  mode->mode = CLASS_CTRL;
+  for (i = 0; ctrl_table[i].name; i++)
+    {
+      int j;
+
+      for (j = 0; ctrl_table[i].name[j]; j++)
+        {
+          if (ctrl_table[i].name[j] != src[j])
+            goto fail;
+        }
+      the_ctrl = ctrl_table[i].value;
+      *ptr = src + j;
+      return;
+    fail:;
+    }
+  the_ctrl = 0;
+  return;
+}
+
+struct flag_names
+{
+  int value;
+  char *name;
+
+};
+
+struct flag_names flag_table[] =
+{
+  0x1, "p",
+  0x1, "v",
+  0x2, "s",
+  0x4, "z",
+  0x8, "c",
+  0x0, "+",
+  0, 0
+};
+
+static void
+DEFUN (get_flags_operand, (ptr, mode, dst),
+       char **ptr AND
+       struct z8k_op *mode AND
+       unsigned int dst)
+{
+  char *src = *ptr;
+  int r;
+  int i;
+  int j;
+
+  while (*src == ' ')
+    src++;
+
+  mode->mode = CLASS_FLAGS;
+  the_flags = 0;
+  for (j = 0; j <= 9; j++)
+    {
+     if (!src[j])
+       goto done;
+     for (i = 0; flag_table[i].name; i++)
+        {
+          if (flag_table[i].name[0] == src[j])
+               {
+               the_flags = the_flags | flag_table[i].value;
+               goto match;
+               }
+        }
+      goto done;
+    match:
+     ;
+    }
+  done:
+  *ptr = src + j;
+  return;
+}
+
+
+struct interrupt_names
 {
   int value;
   char *name;
 
+};
 
+struct interrupt_names intr_table[] =
+{
+  0x1, "nvi",
+  0x2, "vi",
+  0x3, "both",
+  0x3, "all",
+  0, 0
 };
 
-struct cc_names table[]=
+static void
+DEFUN (get_interrupt_operand, (ptr, mode, dst),
+       char **ptr AND
+       struct z8k_op *mode AND
+       unsigned int dst)
+{
+  char *src = *ptr;
+  int r;
+  int i;
+
+  while (*src == ' ')
+    src++;
+
+  mode->mode = CLASS_IMM;
+  for (i = 0; intr_table[i].name; i++)
+    {
+      int j;
+
+      for (j = 0; intr_table[i].name[j]; j++)
+        {
+          if (intr_table[i].name[j] != src[j])
+            goto fail;
+        }
+      the_interrupt = intr_table[i].value;
+      *ptr = src + j;
+      return;
+    fail:;
+    }
+  the_interrupt = 0x0;
+  return;
+}
+
+struct cc_names
+{
+  int value;
+  char *name;
+
+};
+
+struct cc_names table[] =
 {
   0x0, "f",
   0x1, "lt",
@@ -400,14 +624,13 @@ DEFUN (get_cc_operand, (ptr, mode, dst),
     fail:;
     }
   the_cc = 0x8;
-  return;
 }
 
 static void
-DEFUN (get_operand, (ptr, mode, dst),
-       char **ptr AND
-       struct z8k_op *mode AND
-       unsigned int dst)
+get_operand (ptr, mode, dst)
+     char **ptr;
+     struct z8k_op *mode;
+     unsigned int dst;
 {
   char *src = *ptr;
   char *end;
@@ -417,7 +640,6 @@ DEFUN (get_operand, (ptr, mode, dst),
 
   mode->mode = 0;
 
-
   while (*src == ' ')
     src++;
   if (*src == '#')
@@ -455,7 +677,7 @@ DEFUN (get_operand, (ptr, mode, dst),
 
                  if (*src != ')')
                    {
-                     as_bad ("Missing ) in ra(rb)");
+                     as_bad (_("Missing ) in ra(rb)"));
                    }
                  else
                    {
@@ -463,7 +685,7 @@ DEFUN (get_operand, (ptr, mode, dst),
                    }
 
                  regaddr (mode->mode, "ra(rb) ra");
-                 regword (mode->mode, "ra(rb) rb");
+/*               regword (mode->mode, "ra(rb) rb");*/
                  mode->mode = CLASS_BX;
                  mode->reg = regn;
                  mode->x_reg = nr;
@@ -518,78 +740,101 @@ DEFUN (get_operand, (ptr, mode, dst),
 
 static
 char *
-DEFUN (get_operands, (opcode, op_end, operand),
-       opcode_entry_type * opcode AND
-       char *op_end AND
-       op_type * operand)
+get_operands (opcode, op_end, operand)
+     opcode_entry_type *opcode;
+     char *op_end;
+     op_type *operand;
 {
   char *ptr = op_end;
-
+char *savptr;
   switch (opcode->noperands)
-  {
-   case 0:
-    operand[0].mode = 0;
-    operand[1].mode = 0;
-    break;
-
-   case 1:
-    ptr++;
-    if (opcode->arg_info[0] == CLASS_CC)
-    {
-      get_cc_operand (&ptr, operand + 0, 0);
-    }
-    else
     {
+    case 0:
+      operand[0].mode = 0;
+      operand[1].mode = 0;
+      break;
 
-      get_operand (&ptr, operand + 0, 0);
-    }
-    operand[1].mode = 0;
-    break;
+    case 1:
+      ptr++;
+      if (opcode->arg_info[0] == CLASS_CC)
+        {
+          get_cc_operand (&ptr, operand + 0, 0);
+        }
+      else if (opcode->arg_info[0] == CLASS_FLAGS)
+        {
+          get_flags_operand (&ptr, operand + 0, 0);
+        }
+      else if (opcode->arg_info[0] == (CLASS_IMM +(ARG_IMM2)))
+        {
+          get_interrupt_operand (&ptr, operand + 0, 0);
+        }
+      else
+        {
+          get_operand (&ptr, operand + 0, 0);
+        }
+      operand[1].mode = 0;
+      break;
 
-   case 2:
-    ptr++;
-    if (opcode->arg_info[0] == CLASS_CC)
-    {
-      get_cc_operand (&ptr, operand + 0, 0);
-    }
-    else
-    {
+    case 2:
+      ptr++;
+      savptr = ptr;
+      if (opcode->arg_info[0] == CLASS_CC)
+        {
+          get_cc_operand (&ptr, operand + 0, 0);
+        }
+      else if (opcode->arg_info[0] == CLASS_CTRL)
+             {
+               get_ctrl_operand (&ptr, operand + 0, 0);
+               if (the_ctrl == 0)
+                 {
+                   ptr = savptr;
+                   get_operand (&ptr, operand + 0, 0);
+                   if (ptr == 0)
+                     return;
+                   if (*ptr == ',')
+                     ptr++;
+                   get_ctrl_operand (&ptr, operand + 1, 1);
+                   return ptr;
+                 }
+             }
+      else
+        {
+          get_operand (&ptr, operand + 0, 0);
+        }
+      if (ptr == 0)
+        return;
+      if (*ptr == ',')
+        ptr++;
+      get_operand (&ptr, operand + 1, 1);
+      break;
 
+    case 3:
+      ptr++;
       get_operand (&ptr, operand + 0, 0);
-    }
-    if (*ptr == ',')
-     ptr++;
-    get_operand (&ptr, operand + 1, 1);
-    break;
-
-   case 3:
-    ptr++;
-    get_operand (&ptr, operand + 0, 0);
-    if (*ptr == ',')
-     ptr++;
-    get_operand (&ptr, operand + 1, 1);
-    if (*ptr == ',')
-     ptr++;
-    get_operand (&ptr, operand + 2, 2);
-    break;
-
-   case 4:
-    ptr++;
-    get_operand (&ptr, operand + 0, 0);
-    if (*ptr == ',')
-     ptr++;
-    get_operand (&ptr, operand + 1, 1);
-    if (*ptr == ',')
-     ptr++;
-    get_operand (&ptr, operand + 2, 2);
-    if (*ptr == ',')
-     ptr++;
-    get_cc_operand (&ptr, operand + 3, 3);
-    break;
-   default:
-    abort ();
-  }
+      if (*ptr == ',')
+       ptr++;
+      get_operand (&ptr, operand + 1, 1);
+      if (*ptr == ',')
+       ptr++;
+      get_operand (&ptr, operand + 2, 2);
+      break;
 
+    case 4:
+      ptr++;
+      get_operand (&ptr, operand + 0, 0);
+      if (*ptr == ',')
+       ptr++;
+      get_operand (&ptr, operand + 1, 1);
+      if (*ptr == ',')
+       ptr++;
+      get_operand (&ptr, operand + 2, 2);
+      if (*ptr == ',')
+       ptr++;
+      get_cc_operand (&ptr, operand + 3, 3);
+      break;
+    default:
+      abort ();
+    }
 
   return ptr;
 }
@@ -599,9 +844,6 @@ DEFUN (get_operands, (opcode, op_end, operand),
    provided
    */
 
-
-
-
 static
 opcode_entry_type *
 DEFUN (get_specific, (opcode, operands),
@@ -617,80 +859,94 @@ DEFUN (get_specific, (opcode, operands),
   unsigned int this_index = opcode->idx;
 
   while (this_index == opcode->idx && !found)
-  {
-    unsigned int i;
-
-    this_try = opcode++;
-    for (i = 0; i < noperands; i++)
     {
-      int mode = operands[i].mode;
+      unsigned int i;
 
-      if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
-      {
-       /* it could be an pc rel operand, if this is a da mode and
+      this_try = opcode++;
+      for (i = 0; i < noperands; i++)
+       {
+         int mode = operands[i].mode;
+
+         if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
+           {
+             /* it could be an pc rel operand, if this is a da mode and
           we like disps, then insert it */
 
-       if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
-       {
-         /* This is the case */
-         operands[i].mode = CLASS_DISP;
-       }
-       else if (mode == CLASS_BA && this_try->arg_info[i])
-       {
-         /* Can't think of a way to turn what we've been given into
+             if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
+               {
+                 /* This is the case */
+                 operands[i].mode = CLASS_DISP;
+               }
+             else if (mode == CLASS_BA && this_try->arg_info[i])
+               {
+                 /* Can't think of a way to turn what we've been given into
             something that's ok */
-         goto fail;
+                 goto fail;
+               }
+             else if (this_try->arg_info[i] & CLASS_PR)
+               {
+                 if (mode == CLASS_REG_LONG && segmented_mode)
+                   {
+                     /* ok */
+                   }
+                 else if (mode == CLASS_REG_WORD && !segmented_mode)
+                   {
+                     /* ok */
+                   }
+                 else
+                   goto fail;
+               }
+             else
+               goto fail;
+           }
+         switch (mode & CLASS_MASK)
+           {
+           default:
+             break;
+           case CLASS_X:
+           case CLASS_IR:
+           case CLASS_BA:
+           case CLASS_BX:
+           case CLASS_DISP:
+           case CLASS_REG:
+           case CLASS_REG_WORD:
+           case CLASS_REG_BYTE:
+           case CLASS_REG_QUAD:
+           case CLASS_REG_LONG:
+           case CLASS_REGN0:
+             reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
+             break;
+           }
        }
-       else goto fail;
-      }
-      switch (mode & CLASS_MASK)
-      {
-       default: 
-       break;
-       case CLASS_X:
-       case CLASS_IR:
-       case CLASS_BA:
-       case CLASS_BX:
-       case CLASS_DISP:
-       case CLASS_REG:
-       case CLASS_REG_WORD:
-       case CLASS_REG_BYTE:
-       case CLASS_REG_QUAD:
-       case CLASS_REG_LONG:
-       case CLASS_REGN0:
-       reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
-       break;
-      }
+
+      found = 1;
+    fail:;
     }
-            
-    found = 1;
-   fail:;
-  }
   if (found)
-   return this_try;
+    return this_try;
   else
-   return 0;
+    return 0;
 }
-            
+
 static void
 DEFUN (check_operand, (operand, width, string),
-    struct z8k_op *operand AND
-            unsigned int width AND
-    char *string)
+       struct z8k_op *operand AND
+       unsigned int width AND
+       char *string)
 {
   if (operand->exp.X_add_symbol == 0
-      && operand->exp.X_subtract_symbol == 0)
-  {
-            
-    /* No symbol involved, let's look at offset, it's dangerous if any of
+      && operand->exp.X_op_symbol == 0)
+    {
+
+      /* No symbol involved, let's look at offset, it's dangerous if any of
        the high bits are not 0 or ff's, find out by oring or anding with
        the width and seeing if the answer is 0 or all fs*/
-    if ((operand->exp.X_add_number & ~width) != 0 &&
-       (operand->exp.X_add_number | width) != (~0))
-    {
-      as_warn ("operand %s0x%x out of range.", string, operand->exp.X_add_number);
+      if ((operand->exp.X_add_number & ~width) != 0 &&
+         (operand->exp.X_add_number | width) != (~0))
+       {
+         as_warn (_("operand %s0x%x out of range."), string, operand->exp.X_add_number);
+       }
     }
-  }
 
 }
 
@@ -703,59 +959,58 @@ DEFUN (newfix, (ptr, type, operand),
        expressionS * operand)
 {
   if (operand->X_add_symbol
-      || operand->X_subtract_symbol
+      || operand->X_op_symbol
       || operand->X_add_number)
     {
-      fix_new (frag_now,
-              ptr,
-              1,
-              operand->X_add_symbol,
-              operand->X_subtract_symbol,
-              operand->X_add_number,
-              0,
-              type);
+      fix_new_exp (frag_now,
+                  ptr,
+                  1,
+                  operand,
+                  0,
+                  type);
     }
 }
 
 static char *
-DEFUN (apply_fix,(ptr, type, operand, size),
-       charptr AND
+DEFUN (apply_fix, (ptr, type, operand, size),
+       char *ptr AND
        int type AND
-       expressionS *operand AND
+       expressionS * operand AND
        int size)
 {
   int n = operand->X_add_number;
+
   operand->X_add_number = n;
-  newfix((ptr - buffer)/2, type, operand);
+  newfix ((ptr - buffer) / 2, type, operand);
 #if 1
-  switch (size) {
-   case 8:                     /* 8 nibbles == 32 bits */
-    *ptr++ = n>> 28;
-    *ptr++ = n>> 24;
-    *ptr++ = n>> 20;
-    *ptr++ = n>> 16;
-   case 4:                     /* 4 niblles == 16 bits */
-    *ptr++ = n >> 12;
-    *ptr++ = n >> 8;
-   case 2:
-    *ptr++ = n >> 4;
-   case 1:
-    *ptr++ =   n >> 0;
-    break;
-  }
+  switch (size)
+    {
+    case 8:                    /* 8 nibbles == 32 bits */
+      *ptr++ = n >> 28;
+      *ptr++ = n >> 24;
+      *ptr++ = n >> 20;
+      *ptr++ = n >> 16;
+    case 4:                    /* 4 niblles == 16 bits */
+      *ptr++ = n >> 12;
+      *ptr++ = n >> 8;
+    case 2:
+      *ptr++ = n >> 4;
+    case 1:
+      *ptr++ = n >> 0;
+      break;
+    }
 #endif
-  return ptr;  
+  return ptr;
 
 }
 
-
 /* Now we know what sort of opcodes it is, lets build the bytes -
  */
 #define INSERT(x,y) *x++ = y>>24; *x++ = y>> 16; *x++=y>>8; *x++ =y;
 static void
-DEFUN (build_bytes, (this_try, operand),
-       opcode_entry_type * this_try AND
-       struct z8k_op *operand)
+build_bytes (this_try, operand)
+     opcode_entry_type * this_try;
+     struct z8k_op *operand;
 {
   unsigned int i;
 
@@ -767,119 +1022,167 @@ DEFUN (build_bytes, (this_try, operand),
   char high;
   int nib;
   int nibble;
-  unsigned short *class_ptr;
-   frag_wane (frag_now);
-   frag_new (0);
+  unsigned int *class_ptr;
+
+  frag_wane (frag_now);
+  frag_new (0);
 
   memset (buffer, 20, 0);
   class_ptr = this_try->byte_info;
- top:;
+top:;
 
   for (nibble = 0; c = *class_ptr++; nibble++)
-  {
-
-    switch (c & CLASS_MASK)
     {
-     default:
 
-      abort ();
-     case CLASS_ADDRESS:
-      /* Direct address, we don't cope with the SS mode right now */
-      if (segmented_mode)
-      {
-       output_ptr = apply_fix (output_ptr , R_DA | R_SEG, da_operand, 8);
-      }
-      else
-      {
-       output_ptr = apply_fix(output_ptr, R_DA, da_operand, 4);
-      }
-      da_operand = 0;
-      break;
-     case CLASS_DISP8:
-      /* pc rel 8 bit */
-output_ptr =       apply_fix (output_ptr, R_JR, da_operand, 2);
-      da_operand = 0;
+      switch (c & CLASS_MASK)
+       {
+       default:
 
-      break;
+         abort ();
+       case CLASS_ADDRESS:
+         /* Direct address, we don't cope with the SS mode right now */
+         if (segmented_mode)
+           {
+             da_operand->X_add_number |= 0x80000000;
+             output_ptr = apply_fix (output_ptr, R_IMM32, da_operand, 8);
+           }
+         else
+           {
+             output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
+           }
+         da_operand = 0;
+         break;
+       case CLASS_DISP8:
+         /* pc rel 8 bit */
+         output_ptr = apply_fix (output_ptr, R_JR, da_operand, 2);
+         da_operand = 0;
+         break;
 
-     case CLASS_CC:
-      *output_ptr++ = the_cc;
-      break;
-     case CLASS_BIT:
-      *output_ptr++ = c & 0xf;
-      break;
-     case CLASS_REGN0:
-      if (reg[c & 0xf] == 0)
-      {
-       as_bad ("can't use R0 here");
-      }
-     case CLASS_REG:
-     case CLASS_REG_BYTE:
-     case CLASS_REG_WORD:
-     case CLASS_REG_LONG:
-     case CLASS_REG_QUAD:
-      /* Insert bit mattern of
+       case CLASS_0DISP7:
+         /* pc rel 7 bit */
+         *output_ptr = 0;
+         output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
+         da_operand = 0;
+         break;
+
+       case CLASS_1DISP7:
+         /* pc rel 7 bit */
+         *output_ptr = 0x80;
+         output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
+          output_ptr[-2] =  0x8;
+         da_operand = 0;
+         break;
+
+       case CLASS_BIT_1OR2:
+         *output_ptr = c & 0xf;
+         if (imm_operand)
+           {
+             if (imm_operand->X_add_number == 2)
+               {
+                 *output_ptr |= 2;
+               }
+             else if (imm_operand->X_add_number != 1)
+               {
+                 as_bad (_("immediate must be 1 or 2"));
+               }
+           }
+         else
+           {
+             as_bad (_("immediate 1 or 2 expected"));
+           }
+         output_ptr++;
+         break;
+       case CLASS_CC:
+         *output_ptr++ = the_cc;
+         break;
+        case CLASS_0CCC:
+          *output_ptr++ = the_ctrl;
+          break;
+        case CLASS_1CCC:
+          *output_ptr++ = the_ctrl | 0x8;
+          break;
+        case CLASS_00II:
+          *output_ptr++ = (~the_interrupt & 0x3);
+          break;
+        case CLASS_01II:
+          *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
+          break;
+        case CLASS_FLAGS:
+          *output_ptr++ = the_flags;
+          break;
+       case CLASS_BIT:
+         *output_ptr++ = c & 0xf;
+         break;
+       case CLASS_REGN0:
+         if (reg[c & 0xf] == 0)
+           {
+             as_bad (_("can't use R0 here"));
+           }
+       case CLASS_REG:
+       case CLASS_REG_BYTE:
+       case CLASS_REG_WORD:
+       case CLASS_REG_LONG:
+       case CLASS_REG_QUAD:
+         /* Insert bit mattern of
         right reg */
-      *output_ptr++ = reg[c & 0xf];
-      break;
-     case CLASS_DISP:
-      output_ptr =  apply_fix (output_ptr,  R_DA, da_operand, 4);
-      da_operand = 0;
-      break;
-     case CLASS_IMM:
-     {
-       nib = 0;
-       switch (c & ARG_MASK)
-       {
-       case ARG_IMM4:
-        output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
-        break;
-       case ARG_IMM4M1:
-        imm_operand->X_add_number--;
-        output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
-        break;
-       case ARG_IMMNMINUS1:
-        imm_operand->X_add_number--;
-        output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand,1);
-        break;
-       case ARG_NIM8:
-        imm_operand->X_add_number = -imm_operand->X_add_number;
-       case ARG_IMM8:
-        output_ptr = apply_fix (output_ptr , R_IMM8, imm_operand, 2);
-        break;
-
-
-       case ARG_IMM16:
-        output_ptr= apply_fix(output_ptr, R_DA,        imm_operand, 4);
-        break;
-
-       case ARG_IMM32:
-        output_ptr = apply_fix (output_ptr, R_IMM32, imm_operand, 8);
-        break;
+         *output_ptr++ = reg[c & 0xf];
+         break;
+       case CLASS_DISP:
+         output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
+         da_operand = 0;
+         break;
 
-       default:
-        abort ();
-       }
-     }
+       case CLASS_IMM:
+         {
+           nib = 0;
+           switch (c & ARG_MASK)
+             {
+             case ARG_IMM4:
+               output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
+               break;
+             case ARG_IMM4M1:
+               imm_operand->X_add_number--;
+               output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
+               break;
+             case ARG_IMMNMINUS1:
+               imm_operand->X_add_number--;
+               output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
+               break;
+             case ARG_NIM8:
+               imm_operand->X_add_number = -imm_operand->X_add_number;
+             case ARG_IMM8:
+               output_ptr = apply_fix (output_ptr, R_IMM8, imm_operand, 2);
+               break;
+             case ARG_IMM16:
+               output_ptr = apply_fix (output_ptr, R_IMM16, imm_operand, 4);
+               break;
+
+             case ARG_IMM32:
+               output_ptr = apply_fix (output_ptr, R_IMM32, imm_operand, 8);
+               break;
+
+             default:
+               abort ();
+             }
+         }
+       }
     }
-  }
 
   /* Copy from the nibble buffer into the frag */
 
- {
-   int length = (output_ptr - buffer) / 2;
-   char *src = buffer;
-   char *fragp = frag_more (length);
-
-   while (src < output_ptr)
-   {
-     *fragp = (src[0] << 4) | src[1];
-     src += 2;
-     fragp++;
-   }
+  {
+    int length = (output_ptr - buffer) / 2;
+    char *src = buffer;
+    char *fragp = frag_more (length);
 
+    while (src < output_ptr)
+      {
+       *fragp = (src[0] << 4) | src[1];
+       src += 2;
+       fragp++;
+      }
 
- }
 }
 
 }
 
@@ -888,8 +1191,6 @@ output_ptr =       apply_fix (output_ptr, R_JR, da_operand, 2);
    the frags/bytes it assembles to.
    */
 
-
-
 void
 DEFUN (md_assemble, (str),
        char *str)
@@ -919,7 +1220,7 @@ DEFUN (md_assemble, (str),
 
   if (op_end == op_start)
     {
-      as_bad ("can't find opcode ");
+      as_bad (_("can't find opcode "));
     }
   c = *op_end;
 
@@ -928,40 +1229,65 @@ DEFUN (md_assemble, (str),
   opcode = (opcode_entry_type *) hash_find (opcode_hash_control,
                                            op_start);
 
+
   if (opcode == NULL)
     {
-      as_bad ("unknown opcode");
+      as_bad (_("unknown opcode"));
       return;
     }
 
+  if (opcode->opcode == 250)
+    {
+      /* was really a pseudo op */
 
-  input_line_pointer = get_operands (opcode, op_end,
-                                    operand);
-  *op_end = c;
-  prev_opcode = opcode;
+      pseudo_typeS *p;
+      char oc;
 
-  opcode = get_specific (opcode, operand);
+      char *old = input_line_pointer;
+      *op_end = c;
 
-  if (opcode == 0)
-    {
-      /* Couldn't find an opcode which matched the operands */
-      char *where = frag_more (2);
 
-      where[0] = 0x0;
-      where[1] = 0x0;
+      input_line_pointer = op_end;
 
-      as_bad ("Can't find opcode to match operands");
-      return;
+      oc = *old;
+      *old = '\n';
+      while (*input_line_pointer == ' ')
+       input_line_pointer++;
+      p = (pseudo_typeS *) (opcode->func);
+
+      (p->poc_handler) (p->poc_val);
+      input_line_pointer = old;
+      *old = oc;
     }
+  else
+    {
+      input_line_pointer = get_operands (opcode, op_end,
+                                        operand);
+      prev_opcode = opcode;
+
+      opcode = get_specific (opcode, operand);
+
+      if (opcode == 0)
+       {
+         /* Couldn't find an opcode which matched the operands */
+         char *where = frag_more (2);
 
-  build_bytes (opcode, operand);
+         where[0] = 0x0;
+         where[1] = 0x0;
+
+         as_bad (_("Can't find opcode to match operands"));
+         return;
+       }
+
+      build_bytes (opcode, operand);
+    }
 }
 
 void
 DEFUN (tc_crawl_symbol_chain, (headers),
        object_headers * headers)
 {
-  printf ("call to tc_crawl_symbol_chain \n");
+  printf (_("call to tc_crawl_symbol_chain \n"));
 }
 
 symbolS *
@@ -975,12 +1301,7 @@ void
 DEFUN (tc_headers_hook, (headers),
        object_headers * headers)
 {
-  printf ("call to tc_headers_hook \n");
-}
-
-void
-DEFUN_VOID (md_end)
-{
+  printf (_("call to tc_headers_hook \n"));
 }
 
 /* Various routines to kill one day */
@@ -1031,7 +1352,7 @@ md_atof (type, litP, sizeP)
 
     default:
       *sizeP = 0;
-      return "Bad call to MD_ATOF()";
+      return _("Bad call to MD_ATOF()");
     }
   t = atof_ieee (input_line_pointer, type, words);
   if (t)
@@ -1043,64 +1364,72 @@ md_atof (type, litP, sizeP)
       md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
       litP += sizeof (LITTLENUM_TYPE);
     }
-  return "";                   /* Someone should teach Dean about null pointers */
+  return 0;
 }
+\f
+CONST char *md_shortopts = "z:";
+struct option md_longopts[] = {
+  {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
 
 int
-md_parse_option (argP, cntP, vecP)
-     char **argP;
-     int *cntP;
-     char ***vecP;
-
+md_parse_option (c, arg)
+     int c;
+     char *arg;
 {
-  return 0;
-
-}
+  switch (c)
+    {
+    case 'z':
+      if (!strcmp (arg, "8001"))
+       s_segm ();
+      else if (!strcmp (arg, "8002"))
+       s_unseg ();
+      else
+       {
+         as_bad (_("invalid architecture -z%s"), arg);
+         return 0;
+       }
+      break;
 
-int md_short_jump_size;
+    default:
+      return 0;
+    }
 
-void 
-tc_aout_fix_to_chars ()
-{
-  printf ("call to tc_aout_fix_to_chars \n");
-  abort ();
+  return 1;
 }
 
-void 
-md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
-     char *ptr;
-     long from_addr;
-     long to_addr;
-     fragS *frag;
-     symbolS *to_symbol;
+void
+md_show_usage (stream)
+     FILE *stream;
 {
-  as_fatal ("failed sanity check.");
+  fprintf(stream, _("\
+Z8K options:\n\
+-z8001                 generate segmented code\n\
+-z8002                 generate unsegmented code\n"));
 }
-
+\f
 void
-md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
-     char *ptr;
-     long from_addr, to_addr;
-     fragS *frag;
-     symbolS *to_symbol;
+tc_aout_fix_to_chars ()
 {
-  as_fatal ("failed sanity check.");
+  printf (_("call to tc_aout_fix_to_chars \n"));
+  abort ();
 }
 
 void
-md_convert_frag (headers, fragP)
+md_convert_frag (headers, seg, fragP)
      object_headers *headers;
+     segT seg;
      fragS *fragP;
-
 {
-  printf ("call to md_convert_frag \n");
+  printf (_("call to md_convert_frag \n"));
   abort ();
 }
 
-long
+valueT
 DEFUN (md_section_align, (seg, size),
        segT seg AND
-       long size)
+       valueT size)
 {
   return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
 
@@ -1122,15 +1451,19 @@ md_apply_fix (fixP, val)
     case R_JR:
 
       *buf++ = val;
-/*    if (val != 0) abort();*/
+      /*    if (val != 0) abort();*/
       break;
 
+    case R_DISP7:
+
+      *buf++ += val;
+      /*    if (val != 0) abort();*/
+      break;
 
     case R_IMM8:
       buf[0] += val;
       break;
-      break;
-    case R_DA:
+    case R_IMM16:
       *buf++ = (val >> 8);
       *buf++ = val;
       break;
@@ -1140,69 +1473,58 @@ md_apply_fix (fixP, val)
       *buf++ = (val >> 8);
       *buf++ = val;
       break;
+#if 0
     case R_DA | R_SEG:
       *buf++ = (val >> 16);
       *buf++ = 0x00;
       *buf++ = (val >> 8);
       *buf++ = val;
       break;
+#endif
+
+    case 0:
+      md_number_to_chars (buf, val, fixP->fx_size);
+      break;
+
     default:
       abort ();
 
     }
 }
 
-void 
-DEFUN (md_operand, (expressionP), expressionS * expressionP)
-{
-}
-
-int md_long_jump_size;
 int
 md_estimate_size_before_relax (fragP, segment_type)
      register fragS *fragP;
      register segT segment_type;
 {
-  printf ("call tomd_estimate_size_before_relax \n");
+  printf (_("call tomd_estimate_size_before_relax \n"));
   abort ();
 }
 
 /* Put number into target byte order */
 
-void 
+void
 DEFUN (md_number_to_chars, (ptr, use, nbytes),
        char *ptr AND
-       long use AND
+       valueT use AND
        int nbytes)
 {
-  switch (nbytes)
-    {
-      case 4:*ptr++ = (use >> 24) & 0xff;
-    case 3:
-      *ptr++ = (use >> 16) & 0xff;
-    case 2:
-      *ptr++ = (use >> 8) & 0xff;
-    case 1:
-      *ptr++ = (use >> 0) & 0xff;
-      break;
-    default:
-      abort ();
-    }
+  number_to_chars_bigendian (ptr, use, nbytes);
 }
-long 
+long
 md_pcrel_from (fixP)
      fixS *fixP;
 {
   abort ();
 }
 
-void 
-tc_coff_symbol_emit_hook ()
+void
+tc_coff_symbol_emit_hook (s)
+     symbolS *s;
 {
 }
 
-
-void 
+void
 tc_reloc_mangle (fix_ptr, intr, base)
      fixS *fix_ptr;
      struct internal_reloc *intr;
@@ -1211,26 +1533,43 @@ tc_reloc_mangle (fix_ptr, intr, base)
 {
   symbolS *symbol_ptr;
 
+  if (fix_ptr->fx_addsy &&
+      fix_ptr->fx_subsy) 
+    {
+      symbolS *add = fix_ptr->fx_addsy;
+      symbolS *sub = fix_ptr->fx_subsy;
+      if (S_GET_SEGMENT(add) != S_GET_SEGMENT(sub))
+       {
+         as_bad(_("Can't subtract symbols in different sections %s %s"),
+                S_GET_NAME(add), S_GET_NAME(sub));
+       }
+      else {
+       int diff = S_GET_VALUE(add) - S_GET_VALUE(sub);
+       fix_ptr->fx_addsy = 0;
+       fix_ptr->fx_subsy = 0;
+       fix_ptr->fx_offset += diff;
+      }
+    }
   symbol_ptr = fix_ptr->fx_addsy;
 
   /* If this relocation is attached to a symbol then it's ok
      to output it */
   if (fix_ptr->fx_r_type == 0)
     {
-      /* cons likes to create reloc32's whatever the size of the reloc..
-       */
+      /* cons likes to create reloc32's whatever the size of the reloc.. */
       switch (fix_ptr->fx_size)
        {
-
        case 2:
-         intr->r_type = R_DA;
+         intr->r_type = R_IMM16;
          break;
        case 1:
          intr->r_type = R_IMM8;
          break;
+       case 4:
+         intr->r_type = R_IMM32;
+         break;
        default:
          abort ();
-
        }
 
     }
@@ -1246,6 +1585,5 @@ tc_reloc_mangle (fix_ptr, intr, base)
     intr->r_symndx = symbol_ptr->sy_number;
   else
     intr->r_symndx = -1;
-
-
 }
+
This page took 0.04095 seconds and 4 git commands to generate.