* config/tc-ppc.c (ppc_elf_suffix): Don't remove symbols other than
[deliverable/binutils-gdb.git] / gas / config / tc-z8k.c
index 489a01b6eec12c7488d5bdd95d50a11975ecd12c..3db750a6b42cfaafd337d8aa1c82175e1b0a2f7e 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-z8k.c -- Assemble code for the Zilog Z800n
-   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000
+   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 #define DEFINE_TABLE
 #include <stdio.h>
 
-#include "opcodes/z8k-opc.h"
-
 #include "as.h"
 #include "bfd.h"
-#include <ctype.h>
+#include "safe-ctype.h"
+#include "opcodes/z8k-opc.h"
 
 const char comment_chars[] = "!";
 const char line_comment_chars[] = "#";
@@ -39,46 +38,54 @@ extern int coff_flags;
 int segmented_mode;
 const int md_reloc_size;
 
-void cons ();
+/* This is non-zero if target was set from the command line.  */
+static int z8k_target_from_cmdline;
 
-void
-s_segm ()
+static void s_segm PARAMS ((int));
+static void even PARAMS ((int));
+static int tohex PARAMS ((int));
+static void sval PARAMS ((int));
+
+static void
+s_segm (segm)
+     int segm;
 {
+  if (segm)
+    {
   segmented_mode = 1;
   machine = bfd_mach_z8001;
   coff_flags = F_Z8001;
-}
-
-void
-s_unseg ()
-{
+    }
+  else
+    {
   segmented_mode = 0;
   machine = bfd_mach_z8002;
   coff_flags = F_Z8002;
+    }
 }
 
 static void
-even ()
+even (ignore)
+     int ignore ATTRIBUTE_UNUSED;
 {
   frag_align (1, 0, 0);
   record_alignment (now_seg, 1);
 }
 
-void obj_coff_section ();
-
-int
+static int
 tohex (c)
      int c;
 {
-  if (isdigit (c))
+  if (ISDIGIT (c))
     return c - '0';
-  if (islower (c))
+  if (ISLOWER (c))
     return c - 'a' + 10;
   return c - 'A' + 10;
 }
 
-void
-sval ()
+static void
+sval (ignore)
+     int ignore ATTRIBUTE_UNUSED;
 {
   SKIP_WHITESPACE ();
   if (*input_line_pointer == '\'')
@@ -118,12 +125,12 @@ const pseudo_typeS md_pseudo_table[] = {
   {"import" , s_ignore        , 0},
   {"page"   , listing_eject   , 0},
   {"program", s_ignore        , 0},
-  {"z8001"  , s_segm          , 0},
-  {"z8002"  , s_unseg         , 0},
+  {"z8001"  , s_segm          , 1},
+  {"z8002"  , s_segm          , 0},
 
-  {"segm"   , s_segm          , 0},
-  {"unsegm" , s_unseg         , 0},
-  {"unseg"  , s_unseg         , 0},
+  {"segm"   , s_segm          , 1},
+  {"unsegm" , s_segm          , 0},
+  {"unseg"  , s_segm          , 0},
   {"name"   , s_app_file      , 0},
   {"global" , s_globl         , 0},
   {"wval"   , cons            , 2},
@@ -150,41 +157,33 @@ static struct hash_control *opcode_hash_control;
 void
 md_begin ()
 {
-  opcode_entry_type *opcode;
-  char *prev_name = "";
-  int idx = 0;
+  const opcode_entry_type *opcode;
+  int idx = -1;
 
   opcode_hash_control = hash_new ();
 
   for (opcode = z8k_table; opcode->name; opcode++)
     {
       /* Only enter unique codes into the table.  */
-      char *src = opcode->name;
-
-      if (strcmp (opcode->name, prev_name))
-       {
-         hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
-         idx++;
-       }
-      opcode->idx = idx;
-      prev_name = opcode->name;
+      if (idx != opcode->idx)
+       hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+      idx = opcode->idx;
     }
 
   /* Default to z8002.  */
-  s_unseg ();
+  if (! z8k_target_from_cmdline)
+    s_segm (0);
 
   /* 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->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 {
@@ -218,12 +217,39 @@ int the_ctrl;
 int the_flags;
 int the_interrupt;
 
-char *
+static char *whatreg PARAMS ((int *, char *));
+static char *parse_reg PARAMS ((char *, int *, unsigned int *));
+static char *parse_exp PARAMS ((char *, expressionS *));
+static char *checkfor PARAMS ((char *, char));
+static void regword PARAMS ((int, char *));
+static void regaddr PARAMS ((int, char *));
+static void get_ctrl_operand
+  PARAMS ((char **, struct z8k_op *, unsigned int));
+static void get_flags_operand
+  PARAMS ((char **, struct z8k_op *, unsigned int));
+static void get_interrupt_operand
+  PARAMS ((char **, struct z8k_op *, unsigned int));
+static void get_cc_operand
+  PARAMS ((char **, struct z8k_op *, unsigned int));
+static void get_operand
+  PARAMS ((char **, struct z8k_op *, unsigned int));
+static char *get_operands
+  PARAMS ((const opcode_entry_type *, char *, op_type *));
+static opcode_entry_type *get_specific
+  PARAMS ((opcode_entry_type *, op_type *));
+static void newfix
+  PARAMS ((int, int, int, expressionS *));
+static char *apply_fix
+  PARAMS ((char *, int, expressionS *, int));
+static void build_bytes
+  PARAMS ((opcode_entry_type *, struct z8k_op *));
+
+static char *
 whatreg (reg, src)
      int *reg;
      char *src;
 {
-  if (isdigit (src[1]))
+  if (ISDIGIT (src[1]))
     {
       *reg = (src[0] - '0') * 10 + src[1] - '0';
       return src + 2;
@@ -252,7 +278,7 @@ whatreg (reg, src)
 /* Try to parse a reg name.  Return a pointer to the first character
    in SRC after the reg name.  */
 
-char *
+static char *
 parse_reg (src, mode, reg)
      char *src;
      int *mode;
@@ -261,7 +287,7 @@ parse_reg (src, mode, reg)
   char *res = 0;
   char regno;
 
-  if (src[0] == 's' && src[1] == 'p')
+  if (src[0] == 's' && src[1] == 'p' && (src[2] == 0 || src[2] == ','))
     {
       if (segmented_mode)
        {
@@ -279,6 +305,8 @@ parse_reg (src, mode, reg)
     {
       if (src[1] == 'r')
        {
+         if (src[2] < '0' || src[2] > '9')
+           return res;  /* Assume no register name but a label starting with 'rr'.  */
          *mode = CLASS_REG_LONG;
          res = whatreg (reg, src + 2);
          regno = *reg;
@@ -287,6 +315,8 @@ parse_reg (src, mode, reg)
        }
       else if (src[1] == 'h')
        {
+         if (src[2] < '0' || src[2] > '9')
+           return res;  /* Assume no register name but a label starting with 'rh'.  */
          *mode = CLASS_REG_BYTE;
          res = whatreg (reg, src + 2);
          regno = *reg;
@@ -295,6 +325,8 @@ parse_reg (src, mode, reg)
        }
       else if (src[1] == 'l')
        {
+         if (src[2] < '0' || src[2] > '9')
+           return res;  /* Assume no register name but a label starting with 'rl'.  */
          *mode = CLASS_REG_BYTE;
          res = whatreg (reg, src + 2);
          regno = *reg;
@@ -304,6 +336,8 @@ parse_reg (src, mode, reg)
        }
       else if (src[1] == 'q')
        {
+         if (src[2] < '0' || src[2] > '9')
+           return res;  /* Assume no register name but a label starting with 'rq'.  */
          *mode = CLASS_REG_QUAD;
          res = whatreg (reg, src + 2);
          regno = *reg;
@@ -312,6 +346,8 @@ parse_reg (src, mode, reg)
        }
       else
        {
+         if (src[1] < '0' || src[1] > '9')
+           return res;  /* Assume no register name but a label starting with 'r'.  */
          *mode = CLASS_REG_WORD;
          res = whatreg (reg, src + 1);
          regno = *reg;
@@ -322,7 +358,7 @@ parse_reg (src, mode, reg)
   return res;
 }
 
-char *
+static char *
 parse_exp (s, op)
      char *s;
      expressionS *op;
@@ -404,25 +440,24 @@ struct ctrl_names {
 };
 
 struct ctrl_names ctrl_table[] = {
-  0x2, "fcw",
-  0X3, "refresh",
-  0x4, "psapseg",
-  0x5, "psapoff",
-  0x5, "psap",
-  0x6, "nspseg",
-  0x7, "nspoff",
-  0x7, "nsp",
-  0  , 0
+  { 0x2, "fcw" },
+  { 0x3, "refresh" },
+  { 0x4, "psapseg" },
+  { 0x5, "psapoff" },
+  { 0x5, "psap" },
+  { 0x6, "nspseg" },
+  { 0x7, "nspoff" },
+  { 0x7, "nsp" },
+  { 0  , 0 }
 };
 
 static void
 get_ctrl_operand (ptr, mode, dst)
      char **ptr;
      struct z8k_op *mode;
-     unsigned int dst;
+     unsigned int dst ATTRIBUTE_UNUSED;
 {
   char *src = *ptr;
-  int r;
   int i;
 
   while (*src == ' ')
@@ -455,23 +490,22 @@ struct flag_names {
 };
 
 struct flag_names flag_table[] = {
-  0x1, "p",
-  0x1, "v",
-  0x2, "s",
-  0x4, "z",
-  0x8, "c",
-  0x0, "+",
-  0, 0
+  { 0x1, "p" },
+  { 0x1, "v" },
+  { 0x2, "s" },
+  { 0x4, "z" },
+  { 0x8, "c" },
+  { 0x0, "+" },
+  { 0, 0 }
 };
 
 static void
 get_flags_operand (ptr, mode, dst)
      char **ptr;
      struct z8k_op *mode;
-     unsigned int dst;
+     unsigned int dst ATTRIBUTE_UNUSED;
 {
   char *src = *ptr;
-  int r;
   int i;
   int j;
 
@@ -508,21 +542,20 @@ struct interrupt_names {
 };
 
 struct interrupt_names intr_table[] = {
-  0x1, "nvi",
-  0x2, "vi",
-  0x3, "both",
-  0x3, "all",
-  0, 0
+  { 0x1, "nvi" },
+  { 0x2, "vi" },
+  { 0x3, "both" },
+  { 0x3, "all" },
+  { 0, 0 }
 };
 
 static void
 get_interrupt_operand (ptr, mode, dst)
      char **ptr;
      struct z8k_op *mode;
-     unsigned int dst;
+     unsigned int dst ATTRIBUTE_UNUSED;
 {
   char *src = *ptr;
-  int r;
   int i;
 
   while (*src == ' ')
@@ -544,6 +577,8 @@ get_interrupt_operand (ptr, mode, dst)
     fail:
       ;
     }
+  /* No interrupt type specified, opcode won't do anything.  */
+  as_warn (_("opcode has no effect."));
   the_interrupt = 0x0;
   return;
 }
@@ -551,43 +586,41 @@ get_interrupt_operand (ptr, mode, dst)
 struct cc_names {
   int value;
   char *name;
-
 };
 
 struct cc_names table[] = {
-  0x0, "f",
-  0x1, "lt",
-  0x2, "le",
-  0x3, "ule",
-  0x4, "ov",
-  0x4, "pe",
-  0x5, "mi",
-  0x6, "eq",
-  0x6, "z",
-  0x7, "c",
-  0x7, "ult",
-  0x8, "t",
-  0x9, "ge",
-  0xa, "gt",
-  0xb, "ugt",
-  0xc, "nov",
-  0xc, "po",
-  0xd, "pl",
-  0xe, "ne",
-  0xe, "nz",
-  0xf, "nc",
-  0xf, "uge",
-  0  , 0
+  { 0x0, "f" },
+  { 0x1, "lt" },
+  { 0x2, "le" },
+  { 0x3, "ule" },
+  { 0x4, "ov" },
+  { 0x4, "pe" },
+  { 0x5, "mi" },
+  { 0x6, "eq" },
+  { 0x6, "z" },
+  { 0x7, "c" },
+  { 0x7, "ult" },
+  { 0x8, "t" },
+  { 0x9, "ge" },
+  { 0xa, "gt" },
+  { 0xb, "ugt" },
+  { 0xc, "nov" },
+  { 0xc, "po" },
+  { 0xd, "pl" },
+  { 0xe, "ne" },
+  { 0xe, "nz" },
+  { 0xf, "nc" },
+  { 0xf, "uge" },
+  { 0  ,  0 }
 };
 
 static void
 get_cc_operand (ptr, mode, dst)
      char **ptr;
      struct z8k_op *mode;
-     unsigned int dst;
+     unsigned int dst ATTRIBUTE_UNUSED;
 {
   char *src = *ptr;
-  int r;
   int i;
 
   while (*src == ' ')
@@ -616,13 +649,10 @@ static void
 get_operand (ptr, mode, dst)
      char **ptr;
      struct z8k_op *mode;
-     unsigned int dst;
+     unsigned int dst ATTRIBUTE_UNUSED;
 {
   char *src = *ptr;
   char *end;
-  unsigned int num;
-  unsigned int len;
-  unsigned int size;
 
   mode->mode = 0;
 
@@ -724,13 +754,14 @@ get_operand (ptr, mode, dst)
 
 static char *
 get_operands (opcode, op_end, operand)
-     opcode_entry_type *opcode;
+     const opcode_entry_type *opcode;
      char *op_end;
      op_type *operand;
 {
   char *ptr = op_end;
   char *savptr;
 
+  ptr++;
   switch (opcode->noperands)
     {
     case 0:
@@ -739,42 +770,37 @@ get_operands (opcode, op_end, operand)
       break;
 
     case 1:
-      ptr++;
       if (opcode->arg_info[0] == CLASS_CC)
-       {
-         get_cc_operand (&ptr, operand + 0, 0);
-       }
+       get_cc_operand (&ptr, operand + 0, 0);
+
       else if (opcode->arg_info[0] == CLASS_FLAGS)
-       {
-         get_flags_operand (&ptr, operand + 0, 0);
-       }
+       get_flags_operand (&ptr, operand + 0, 0);
+
       else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2)))
-       {
-         get_interrupt_operand (&ptr, operand + 0, 0);
-       }
+       get_interrupt_operand (&ptr, operand + 0, 0);
+
       else
-       {
-         get_operand (&ptr, operand + 0, 0);
-       }
+       get_operand (&ptr, operand + 0, 0);
+
       operand[1].mode = 0;
       break;
 
     case 2:
-      ptr++;
       savptr = ptr;
       if (opcode->arg_info[0] == CLASS_CC)
-       {
-         get_cc_operand (&ptr, operand + 0, 0);
-       }
+       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;
+               return NULL;
              if (*ptr == ',')
                ptr++;
              get_ctrl_operand (&ptr, operand + 1, 1);
@@ -782,18 +808,16 @@ get_operands (opcode, op_end, operand)
            }
        }
       else
-       {
-         get_operand (&ptr, operand + 0, 0);
-       }
+       get_operand (&ptr, operand + 0, 0);
+
       if (ptr == 0)
-       return;
+       return NULL;
       if (*ptr == ',')
        ptr++;
       get_operand (&ptr, operand + 1, 1);
       break;
 
     case 3:
-      ptr++;
       get_operand (&ptr, operand + 0, 0);
       if (*ptr == ',')
        ptr++;
@@ -804,7 +828,6 @@ get_operands (opcode, op_end, operand)
       break;
 
     case 4:
-      ptr++;
       get_operand (&ptr, operand + 0, 0);
       if (*ptr == ',')
        ptr++;
@@ -832,14 +855,12 @@ static opcode_entry_type *
 get_specific (opcode, operands)
      opcode_entry_type *opcode;
      op_type *operands;
-
 {
   opcode_entry_type *this_try = opcode;
   int found = 0;
   unsigned int noperands = opcode->noperands;
 
-  unsigned int dispreg;
-  unsigned int this_index = opcode->idx;
+  int this_index = opcode->idx;
 
   while (this_index == opcode->idx && !found)
     {
@@ -848,11 +869,11 @@ get_specific (opcode, operands)
       this_try = opcode++;
       for (i = 0; i < noperands; i++)
        {
-         int mode = operands[i].mode;
+         unsigned 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
+             /* It could be a 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)
@@ -912,6 +933,7 @@ get_specific (opcode, operands)
     return 0;
 }
 
+#if 0 /* Not used.  */
 static void
 check_operand (operand, width, string)
      struct z8k_op *operand;
@@ -935,13 +957,15 @@ check_operand (operand, width, string)
     }
 
 }
+#endif
 
 static char buffer[20];
 
 static void
-newfix (ptr, type, operand)
+newfix (ptr, type, size, operand)
      int ptr;
      int type;
+     int size;   /* nibbles.  */
      expressionS *operand;
 {
   if (operand->X_add_symbol
@@ -950,7 +974,7 @@ newfix (ptr, type, operand)
     {
       fix_new_exp (frag_now,
                   ptr,
-                  1,
+                  size / 2,
                   operand,
                   0,
                   type);
@@ -962,21 +986,19 @@ apply_fix (ptr, type, operand, size)
      char *ptr;
      int type;
      expressionS *operand;
-     int size;
+     int size;   /* nibbles.  */
 {
-  int n = operand->X_add_number;
+  long n = operand->X_add_number;
 
-  operand->X_add_number = n;
-  newfix ((ptr - buffer) / 2, type, operand);
-#if 1
+  newfix ((ptr - buffer) / 2, type, size + 1, operand);
   switch (size)
     {
-    case 8:                    /* 8 nibbles == 32 bits  */
+    case 8:                    /* 8 nibbles == 32 bits.  */
       *ptr++ = n >> 28;
       *ptr++ = n >> 24;
       *ptr++ = n >> 20;
       *ptr++ = n >> 16;
-    case 4:                    /* 4 niblles == 16 bits  */
+    case 4:                    /* 4 nibbles == 16 bits.  */
       *ptr++ = n >> 12;
       *ptr++ = n >> 8;
     case 2:
@@ -985,9 +1007,7 @@ apply_fix (ptr, type, operand, size)
       *ptr++ = n >> 0;
       break;
     }
-#endif
   return ptr;
-
 }
 
 /* Now we know what sort of opcodes it is.  Let's build the bytes.  */
@@ -997,28 +1017,20 @@ apply_fix (ptr, type, operand, size)
 static void
 build_bytes (this_try, operand)
      opcode_entry_type *this_try;
-     struct z8k_op *operand;
+     struct z8k_op *operand ATTRIBUTE_UNUSED;
 {
-  unsigned int i;
-
-  int length;
-  char *output;
   char *output_ptr = buffer;
-  char part;
   int c;
-  char high;
-  int nib;
   int nibble;
   unsigned int *class_ptr;
 
   frag_wane (frag_now);
   frag_new (0);
 
-  memset (buffer, 20, 0);
+  memset (buffer, 0, sizeof (buffer));
   class_ptr = this_try->byte_info;
 
- top:
-  for (nibble = 0; c = *class_ptr++; nibble++)
+  for (nibble = 0; (c = *class_ptr++); nibble++)
     {
 
       switch (c & CLASS_MASK)
@@ -1030,7 +1042,7 @@ build_bytes (this_try, operand)
          /* Direct address, we don't cope with the SS mode right now.  */
          if (segmented_mode)
            {
-             da_operand->X_add_number |= 0x80000000;
+             /* da_operand->X_add_number |= 0x80000000;  --  Now set at relocation time.  */
              output_ptr = apply_fix (output_ptr, R_IMM32, da_operand, 8);
            }
          else
@@ -1091,6 +1103,7 @@ build_bytes (this_try, operand)
        case CLASS_FLAGS:
          *output_ptr++ = the_flags;
          break;
+       case CLASS_IGNORE:
        case CLASS_BIT:
          *output_ptr++ = c & 0xf;
          break;
@@ -1113,43 +1126,49 @@ build_bytes (this_try, operand)
               output_ptr = apply_fix (output_ptr, R_CALLR, da_operand, 4);
               break;
             case ARG_DISP16:
-              output_ptr = apply_fix (output_ptr, R_REL16, da_operand, 4);
-              break;
-            default:
-         output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
-            }
+             output_ptr = apply_fix (output_ptr, R_REL16, da_operand, 4);
+             break;
+           default:
+             output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
+           }
          da_operand = 0;
          break;
 
        case CLASS_IMM:
          {
-           nib = 0;
            switch (c & ARG_MASK)
              {
-             case ARG_IMM4:
+             case ARG_NIM4:
+                if (imm_operand->X_add_number > 15)
+                  {
+                    as_bad (_("immediate value out of range"));
+                  }
+               imm_operand->X_add_number = -imm_operand->X_add_number;
                output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
                break;
+              /*case ARG_IMMNMINUS1: not used.  */
              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--;
+                /* Drop through.  */
+             case ARG_IMM4:
+                if (imm_operand->X_add_number > 15)
+                  {
+                    as_bad (_("immediate value out of range"));
+                  }
                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;
+                /* Drop through.  */
              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 ();
              }
@@ -1180,16 +1199,13 @@ void
 md_assemble (str)
      char *str;
 {
+  char c;
   char *op_start;
   char *op_end;
-  unsigned int i;
   struct z8k_op operand[3];
   opcode_entry_type *opcode;
   opcode_entry_type *prev_opcode;
 
-  char *dot = 0;
-  char c;
-
   /* Drop leading whitespace.  */
   while (*str == ' ')
     str++;
@@ -1218,14 +1234,13 @@ md_assemble (str)
 
   if (opcode->opcode == 250)
     {
-      /* Was really a pseudo op.  */
-
       pseudo_typeS *p;
       char oc;
-
       char *old = input_line_pointer;
       *op_end = c;
 
+      /* Was really a pseudo op.  */
+
       input_line_pointer = op_end;
 
       oc = *old;
@@ -1240,8 +1255,12 @@ md_assemble (str)
     }
   else
     {
-      input_line_pointer = get_operands (opcode, op_end, operand);
-      prev_opcode = opcode;
+      char *new_input_line_pointer;
+
+      new_input_line_pointer = get_operands (opcode, op_end, operand);
+      if (new_input_line_pointer)
+        input_line_pointer = new_input_line_pointer;
+      prev_opcode = opcode; /* XXX is this used ?? */
 
       opcode = get_specific (opcode, operand);
 
@@ -1263,21 +1282,23 @@ md_assemble (str)
 
 void
 tc_crawl_symbol_chain (headers)
-     object_headers *headers;
+     object_headers *headers ATTRIBUTE_UNUSED;
 {
   printf (_("call to tc_crawl_symbol_chain \n"));
 }
 
+/* We have no need to default values of symbols.  */
+
 symbolS *
 md_undefined_symbol (name)
-     char *name;
+     char *name ATTRIBUTE_UNUSED;
 {
   return 0;
 }
 
 void
 tc_headers_hook (headers)
-     object_headers *headers;
+     object_headers *headers ATTRIBUTE_UNUSED;
 {
   printf (_("call to tc_headers_hook \n"));
 }
@@ -1301,7 +1322,6 @@ md_atof (type, litP, sizeP)
   LITTLENUM_TYPE words[MAX_LITTLENUMS];
   LITTLENUM_TYPE *wordP;
   char *t;
-  char *atof_ieee ();
 
   switch (type)
     {
@@ -1346,11 +1366,14 @@ md_atof (type, litP, sizeP)
   return 0;
 }
 \f
-CONST char *md_shortopts = "z:";
+const char *md_shortopts = "z:";
 
-struct option md_longopts[] = {
-  {NULL, no_argument, NULL, 0}
-};
+struct option md_longopts[] =
+  {
+#define OPTION_RELAX  (OPTION_MD_BASE)
+    {"linkrelax", no_argument, NULL, OPTION_RELAX},
+    {NULL, no_argument, NULL, 0}
+  };
 
 size_t md_longopts_size = sizeof (md_longopts);
 
@@ -1363,14 +1386,19 @@ md_parse_option (c, arg)
     {
     case 'z':
       if (!strcmp (arg, "8001"))
-       s_segm ();
+       s_segm (1);
       else if (!strcmp (arg, "8002"))
-       s_unseg ();
+       s_segm (0);
       else
        {
          as_bad (_("invalid architecture -z%s"), arg);
          return 0;
        }
+      z8k_target_from_cmdline = 1;
+      break;
+
+    case OPTION_RELAX:
+      linkrelax = 1;
       break;
 
     default:
@@ -1385,25 +1413,19 @@ md_show_usage (stream)
      FILE *stream;
 {
   fprintf (stream, _("\
-Z8K options:\n\
--z8001                 generate segmented code\n\
--z8002                 generate unsegmented code\n"));
+ Z8K options:\n\
+  -z8001                  generate segmented code\n\
+  -z8002                  generate unsegmented code\n\
+  -linkrelax              create linker relaxable code\n"));
 }
 \f
-void
-tc_aout_fix_to_chars ()
-{
-  printf (_("call to tc_aout_fix_to_chars \n"));
-  abort ();
-}
-
 void
 md_convert_frag (headers, seg, fragP)
-     object_headers *headers;
-     segT seg;
-     fragS *fragP;
+     object_headers *headers ATTRIBUTE_UNUSED;
+     segT seg ATTRIBUTE_UNUSED;
+     fragS *fragP ATTRIBUTE_UNUSED;
 {
-  printf (_("call to md_convert_frag \n"));
+  printf (_("call to md_convert_frag\n"));
   abort ();
 }
 
@@ -1414,53 +1436,78 @@ md_section_align (seg, size)
 {
   return ((size + (1 << section_alignment[(int) seg]) - 1)
          & (-1 << section_alignment[(int) seg]));
-
 }
 
 void
-md_apply_fix (fixP, val)
-     fixS *fixP;
-     long val;
+md_apply_fix3 (fixP, valP, segment)
+     fixS * fixP;
+     valueT * valP;
+     segT segment ATTRIBUTE_UNUSED;
 {
+  long val = * (long *) valP;
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
 
   switch (fixP->fx_r_type)
     {
     case R_IMM4L:
-      buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);
+      buf[0] = (buf[0] & 0xf0) | (val & 0xf);
       break;
 
     case R_JR:
-
+      val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
+      if (val & 1)
+        as_bad (_("cannot branch to odd address"));
+      val /= 2;
+      if (val > 127 || val < -128)
+        as_bad (_("relative jump out of range"));
       *buf++ = val;
-#if 0
-      if (val != 0)
-       abort ();
-#endif
+      fixP->fx_no_overflow = 1;
       break;
 
     case R_DISP7:
+      val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
+      if (val & 1)
+        as_bad (_("cannot branch to odd address"));
+      val /= 2;
+      if (val > 0 || val < -128)
+        as_bad (_("relative jump out of range"));
+      *buf = (*buf & 0x80) | (val & 0x7f);
+      fixP->fx_no_overflow = 1;
+      break;
 
-      *buf++ += val;
-#if 0
-      if (val != 0)
-       abort ();
-#endif
+    case R_CALLR:
+      if (val > 8191 || val < -8192)
+        as_bad (_("relative call out of range"));
+      val = -val;
+      *buf++ = (buf[0] & 0xf0) | ((val >> 8) & 0xf);
+      *buf++ = val & 0xff;
       break;
 
     case R_IMM8:
-      buf[0] += val;
+      *buf++ = val;
       break;
+
     case R_IMM16:
       *buf++ = (val >> 8);
       *buf++ = val;
       break;
+
     case R_IMM32:
       *buf++ = (val >> 24);
       *buf++ = (val >> 16);
       *buf++ = (val >> 8);
       *buf++ = val;
       break;
+
+    case R_REL16:
+      val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
+      if (val > 32767 || val < -32768)
+        as_bad (_("relative address out of range"));
+      *buf++ = (val >> 8);
+      *buf++ = val;
+      fixP->fx_no_overflow = 1;
+      break;
+
 #if 0
     case R_DA | R_SEG:
       *buf++ = (val >> 16);
@@ -1475,16 +1522,20 @@ md_apply_fix (fixP, val)
       break;
 
     default:
+      printf(_("md_apply_fix3: unknown r_type 0x%x\n"), fixP->fx_r_type);
       abort ();
     }
+
+  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+    fixP->fx_done = 1;
 }
 
 int
 md_estimate_size_before_relax (fragP, segment_type)
-     register fragS *fragP;
-     register segT segment_type;
+     register fragS *fragP ATTRIBUTE_UNUSED;
+     register segT segment_type ATTRIBUTE_UNUSED;
 {
-  printf (_("call tomd_estimate_size_before_relax \n"));
+  printf (_("call to md_estimate_size_before_relax\n"));
   abort ();
 }
 
@@ -1501,14 +1552,14 @@ md_number_to_chars (ptr, use, nbytes)
 
 long
 md_pcrel_from (fixP)
-     fixS *fixP;
+     fixS *fixP ATTRIBUTE_UNUSED;
 {
   abort ();
 }
 
 void
 tc_coff_symbol_emit_hook (s)
-     symbolS *s;
+     symbolS *s ATTRIBUTE_UNUSED;
 {
 }
 
This page took 0.039558 seconds and 4 git commands to generate.