S/390: Fix 16 bit pc relative relocs.
[deliverable/binutils-gdb.git] / gas / config / tc-i960.c
index 0af3a80c35e9ebcdecf39dacc101fdf5c130666d..70ac3798d85f2872bcd5ecd8661b0982d65a4cfd 100644 (file)
@@ -1,13 +1,11 @@
 /* tc-i960.c - All the i80960-specific stuff
-   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright (C) 1989-2016 Free Software Foundation, Inc.
 
    This file is part of GAS.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
@@ -66,7 +64,6 @@
 #include "as.h"
 
 #include "safe-ctype.h"
-#include "obstack.h"
 
 #include "opcode/i960.h"
 
@@ -243,7 +240,7 @@ struct regop
    operands.  */
 static const struct
   {
-    char *reg_name;
+    const char *reg_name;
     int reg_num;
   }
 regnames[] =
@@ -338,7 +335,7 @@ regnames[] =
    'abase' (indirect addressing) registers.  */
 static const struct
 {
-  char *areg_name;
+  const char *areg_name;
   int areg_num;
 }
 aregs[] =
@@ -453,7 +450,7 @@ static int br_cnt;
 /* Name of the table of pointers to branches.  A local (i.e.,
    non-external) symbol.  */
 
-static void ctrl_fmt (char *, long, int);
+static void ctrl_fmt (const char *, long, int);
 
 \f
 void
@@ -498,7 +495,7 @@ md_begin (void)
    string is not consumed in the evaluation -- tolerate no dangling junk!  */
 
 static void
-parse_expr (char *textP,               /* Text of expression to be parsed.  */
+parse_expr (const char *textP,         /* Text of expression to be parsed.  */
            expressionS *expP)          /* Where to put the results of parsing.  */
 {
   char *save_in;               /* Save global here.  */
@@ -516,7 +513,7 @@ parse_expr (char *textP,            /* Text of expression to be parsed.  */
   else
     {
       save_in = input_line_pointer;    /* Save global.  */
-      input_line_pointer = textP;      /* Make parser work for us.  */
+      input_line_pointer = (char *) textP;     /* Make parser work for us.  */
 
       (void) expression (expP);
       if ((size_t) (input_line_pointer - textP) != strlen (textP))
@@ -561,13 +558,13 @@ emit (long instr)         /* Word to be output, host byte order.  */
                address displacement is greater than 13 bits.  */
 
 static void
-get_cdisp (char *dispP, /* Displacement as specified in source instruction.  */
-          char *ifmtP, /* "COBR" or "CTRL" (for use in error message).  */
+get_cdisp (const char *dispP, /* Displacement as specified in source instruction.  */
+          const char *ifmtP, /* "COBR" or "CTRL" (for use in error message).  */
           long instr,  /* Instruction needing the displacement.  */
           int numbits, /* # bits of displacement (13 for COBR, 24 for CTRL).  */
           int var_frag,/* 1 if varying length code fragment should be emitted;
                           0 if an address fix should be emitted.  */
-          int callj)   /* 1 if callj relocation should be done; else 0.  */       
+          int callj)   /* 1 if callj relocation should be done; else 0.  */
 {
   expressionS e;               /* Parsed expression.  */
   fixS *fixP;                  /* Structure describing needed address fix.  */
@@ -580,6 +577,7 @@ get_cdisp (char *dispP, /* Displacement as specified in source instruction.  */
     {
     case O_illegal:
       as_bad (_("expression syntax error"));
+      break;
 
     case O_symbol:
       if (S_GET_SEGMENT (e.X_add_symbol) == now_seg
@@ -805,7 +803,7 @@ parse_regop (struct regop *regopP,  /* Where to put description of register opera
 }
 
 /* get_ispec:  parse a memory operand for an index specification
-   
+
    Here, an "index specification" is taken to be anything surrounded
    by square brackets and NOT followed by anything else.
 
@@ -814,7 +812,7 @@ parse_regop (struct regop *regopP,  /* Where to put description of register opera
 
 static char *
 get_ispec (char *textP)  /* Pointer to memory operand from source instruction, no white space.  */
-          
+
 {
   /* Points to start of index specification.  */
   char *start;
@@ -1043,7 +1041,7 @@ parse_memop (memS *memP,  /* Where to put the results.  */
     case I_BIT:
       /* Treat missing displacement as displacement of 0.  */
       mode |= D_BIT;
-      /* Fall into next case.  */
+      /* Fall through.  */
     case D_BIT | A_BIT | I_BIT:
     case D_BIT | I_BIT:
       /* Set MEMB bit in mode, and OR in mode bits.  */
@@ -1069,7 +1067,7 @@ mem_fmt (char *args[],            /* args[0]->opcode mnemonic, args[1-3]->operands.  */
   char opdesc;                 /* Operand descriptor byte.  */
   memS instr;                  /* Description of binary to be output.  */
   char *outP;                  /* Where the binary was output to.  */
-  expressionS expr;            /* Parsed expression.  */
+  expressionS exp            /* Parsed expression.  */
   /* ->description of deferred address fixup.  */
   fixS *fixP;
 
@@ -1097,7 +1095,7 @@ mem_fmt (char *args[],            /* args[0]->opcode mnemonic, args[1-3]->operands.  */
 
   /* Parse the displacement; this must be done before emitting the
      opcode, in case it is an expression using `.'.  */
-  parse_expr (instr.e, &expr);
+  parse_expr (instr.e, &exp);
 
   /* Output opcode.  */
   outP = emit (instr.opcode);
@@ -1106,7 +1104,7 @@ mem_fmt (char *args[],            /* args[0]->opcode mnemonic, args[1-3]->operands.  */
     return;
 
   /* Process the displacement.  */
-  switch (expr.X_op)
+  switch (exp.X_op)
     {
     case O_illegal:
       as_bad (_("expression syntax error"));
@@ -1114,23 +1112,23 @@ mem_fmt (char *args[],          /* args[0]->opcode mnemonic, args[1-3]->operands.  */
 
     case O_constant:
       if (instr.disp == 32)
-       (void) emit (offs (expr));      /* Output displacement.  */
+       (void) emit (offs (exp));       /* Output displacement.  */
       else
        {
          /* 12-bit displacement.  */
-         if (offs (expr) & ~0xfff)
+         if (offs (exp) & ~0xfff)
            {
              /* Won't fit in 12 bits: convert already-output
                 instruction to MEMB format, output
                 displacement.  */
              mema_to_memb (outP);
-             (void) emit (offs (expr));
+             (void) emit (offs (exp));
            }
          else
            {
              /* WILL fit in 12 bits:  OR into opcode and
                 overwrite the binary we already put out.  */
-             instr.opcode |= offs (expr);
+             instr.opcode |= offs (exp);
              md_number_to_chars (outP, instr.opcode, 4);
            }
        }
@@ -1148,7 +1146,7 @@ mem_fmt (char *args[],            /* args[0]->opcode mnemonic, args[1-3]->operands.  */
       outP = emit ((long) 0);
       fixP = fix_new_exp (frag_now,
                          outP - frag_now->fr_literal,
-                         4, & expr, 0, NO_RELOC);
+                         4, &exp, 0, NO_RELOC);
       /* Steve's linker relaxing hack.  Mark this 32-bit relocation as
          being in the instruction stream, specifically as part of a callx
          instruction.  */
@@ -1249,7 +1247,7 @@ parse_ldconst (char *arg[])       /* See above.  */
     {
     default:
       /* We're dependent on one or more symbols -- use "lda".  */
-      arg[0] = "lda";
+      arg[0] = (char *) "lda";
       break;
 
     case O_constant:
@@ -1261,31 +1259,31 @@ parse_ldconst (char *arg[])     /* See above.  */
               ldconst  64,<reg>  -> shlo 8,3,<reg>
               ldconst  -1,<reg>  -> subo 1,0,<reg>
               ldconst -31,<reg>  -> subo 31,0,<reg>
-        
+
          Anything else becomes:
                 lda xxx,<reg>.  */
       n = offs (e);
       if ((0 <= n) && (n <= 31))
-       arg[0] = "mov";
+       arg[0] = (char *) "mov";
       else if ((-31 <= n) && (n <= -1))
        {
-         arg[0] = "subo";
+         arg[0] = (char *) "subo";
          arg[3] = arg[2];
          sprintf (buf, "%d", -n);
          arg[1] = buf;
-         arg[2] = "0";
+         arg[2] = (char *) "0";
        }
       else if ((32 <= n) && (n <= 62))
        {
-         arg[0] = "addo";
+         arg[0] = (char *) "addo";
          arg[3] = arg[2];
-         arg[1] = "31";
+         arg[1] = (char *) "31";
          sprintf (buf, "%d", n - 31);
          arg[2] = buf;
        }
       else if ((shift = shift_ok (n)) != 0)
        {
-         arg[0] = "shlo";
+         arg[0] = (char *) "shlo";
          arg[3] = arg[2];
          sprintf (buf, "%d", shift);
          arg[1] = buf;
@@ -1293,7 +1291,7 @@ parse_ldconst (char *arg[])       /* See above.  */
          arg[2] = buf2;
        }
       else
-       arg[0] = "lda";
+       arg[0] = (char *) "lda";
       break;
 
     case O_illegal:
@@ -1497,7 +1495,7 @@ brlab_next (void)
 }
 
 static void
-ctrl_fmt (char *targP,         /* Pointer to text of lone operand (if any).  */
+ctrl_fmt (const char *targP,           /* Pointer to text of lone operand (if any).  */
          long opcode,          /* Template of instruction.  */
          int num_ops)          /* Number of operands.  */
 {
@@ -1667,29 +1665,30 @@ md_assemble (char *textP)
          break;
        case REG:
          if (branch_predict)
-           as_warn (bp_error_msg);
+           as_warn ("%s", bp_error_msg);
          reg_fmt (args, oP);
          break;
        case MEM1:
          if (args[0][0] == 'c' && args[0][1] == 'a')
            {
              if (branch_predict)
-               as_warn (bp_error_msg);
+               as_warn ("%s", bp_error_msg);
              mem_fmt (args, oP, 1);
              break;
            }
+         /* Fall through.  */
        case MEM2:
        case MEM4:
        case MEM8:
        case MEM12:
        case MEM16:
          if (branch_predict)
-           as_warn (bp_error_msg);
+           as_warn ("%s", bp_error_msg);
          mem_fmt (args, oP, 0);
          break;
        case CALLJ:
          if (branch_predict)
-           as_warn (bp_error_msg);
+           as_warn ("%s", bp_error_msg);
          /* Output opcode & set up "fixup" (relocation); flag
             relocation as 'callj' type.  */
          know (oP->num_ops == 1);
@@ -1710,67 +1709,10 @@ md_number_to_chars (char *buf,
   number_to_chars_littleendian (buf, value, n);
 }
 
-#define MAX_LITTLENUMS 6
-#define LNUM_SIZE      sizeof (LITTLENUM_TYPE)
-
-/* md_atof:    convert ascii to floating point
-
-   Turn a string at input_line_pointer into a floating point constant of type
-   'type', and store the appropriate bytes at *litP.  The number of LITTLENUMS
-   emitted is returned at 'sizeP'.  An error message is returned, or a pointer
-   to an empty message if OK.
-
-   Note we call the i386 floating point routine, rather than complicating
-   things with more files or symbolic links.  */
-
-char *
+const char *
 md_atof (int type, char *litP, int *sizeP)
 {
-  LITTLENUM_TYPE words[MAX_LITTLENUMS];
-  LITTLENUM_TYPE *wordP;
-  int prec;
-  char *t;
-
-  switch (type)
-    {
-    case 'f':
-    case 'F':
-      prec = 2;
-      break;
-
-    case 'd':
-    case 'D':
-      prec = 4;
-      break;
-
-    case 't':
-    case 'T':
-      prec = 5;
-      type = 'x';              /* That's what atof_ieee() understands.  */
-      break;
-
-    default:
-      *sizeP = 0;
-      return _("Bad call to md_atof()");
-    }
-
-  t = atof_ieee (input_line_pointer, type, words);
-  if (t)
-    input_line_pointer = t;
-
-  *sizeP = prec * LNUM_SIZE;
-
-  /* Output the LITTLENUMs in REVERSE order in accord with i80960
-     word-order.  (Dunno why atof_ieee doesn't do it in the right
-     order in the first place -- probably because it's a hack of
-     atof_m68k.)  */
-  for (wordP = words + prec - 1; prec--;)
-    {
-      md_number_to_chars (litP, (long) (*wordP--), LNUM_SIZE);
-      litP += sizeof (LITTLENUM_TYPE);
-    }
-
-  return 0;
+  return ieee_md_atof (type, litP, sizeP, FALSE);
 }
 
 static void
@@ -1811,7 +1753,7 @@ md_number_to_field (char *instrP,         /* Pointer to instruction to be fixed.  */
     {
       /* Put bit field into instruction and write back in target
          * byte order.  */
-      val &= ~(-1 << (int) numbits);   /* Clear unused sign bits.  */
+      val &= ~(-(1 << (int) numbits)); /* Clear unused sign bits.  */
       instr |= val;
       md_number_to_chars (instrP, instr, 4);
     }
@@ -1869,7 +1811,7 @@ size_t md_longopts_size = sizeof (md_longopts);
 
 struct tabentry
 {
-  char *flag;
+  const char *flag;
   int arch;
 };
 static const struct tabentry arch_tab[] =
@@ -1887,7 +1829,7 @@ static const struct tabentry arch_tab[] =
 };
 
 int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
 {
   switch (c)
     {
@@ -1907,7 +1849,7 @@ md_parse_option (int c, char *arg)
     case 'A':
       {
        const struct tabentry *tp;
-       char *p = arg;
+       const char *p = arg;
 
        for (tp = arch_tab; tp->flag != NULL; tp++)
          if (!strcmp (p, tp->flag))
@@ -2157,8 +2099,6 @@ brtab_emit (void)
   char buf[20];
   /* Where the binary was output to.  */
   char *p;
-  /* Pointer to description of deferred address fixup.  */
-  fixS *fixP;
 
   if (!instrument_branches)
     return;
@@ -2174,9 +2114,9 @@ brtab_emit (void)
     {
       sprintf (buf, "%s%d", BR_LABEL_BASE, i);
       p = emit (0);
-      fixP = fix_new (frag_now,
-                     p - frag_now->fr_literal,
-                     4, symbol_find (buf), 0, 0, NO_RELOC);
+      fix_new (frag_now,
+              p - frag_now->fr_literal,
+              4, symbol_find (buf), 0, 0, NO_RELOC);
     }
 }
 
@@ -2349,7 +2289,7 @@ parse_po (int po_num)     /* Pseudo-op number:  currently S_LEAFPROC or S_SYSPROC.
        passed fixup structure.  */
 
 int
-reloc_callj (fixS *fixP)  /* Relocation that can be done at assembly time.  */    
+reloc_callj (fixS *fixP)  /* Relocation that can be done at assembly time.  */
 {
   /* Points to the binary for the instruction being relocated.  */
   char *where;
@@ -2397,8 +2337,7 @@ s_endian (int ignore ATTRIBUTE_UNUSED)
   char *name;
   char c;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
   if (strcasecmp (name, "little") == 0)
     ;
   else if (strcasecmp (name, "big") == 0)
@@ -2406,7 +2345,7 @@ s_endian (int ignore ATTRIBUTE_UNUSED)
   else
     as_warn (_("ignoring unrecognized .endian type `%s'"), name);
 
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   demand_empty_rest_of_line ();
 }
@@ -2529,7 +2468,7 @@ md_section_align (segT seg,
   int align;
 
   align = bfd_get_section_alignment (stdoutput, seg);
-  return (addr + (1 << align) - 1) & (-1 << align);
+  return (addr + (1 << align) - 1) & -(1 << align);
 }
 
 extern int coff_flags;
@@ -2686,7 +2625,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
 {
   arelent * reloc;
 
-  reloc = xmalloc (sizeof (arelent));
+  reloc = XNEW (arelent);
 
   /* HACK: Is this right?  */
   fixP->fx_r_type = tc_bfd_fix2rtype (fixP);
@@ -2695,15 +2634,15 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
   if (reloc->howto == NULL)
     {
       as_bad_where (fixP->fx_file, fixP->fx_line,
-                   "internal error: can't export reloc type %d (`%s')",
+                   _("internal error: can't export reloc type %d (`%s')"),
                    fixP->fx_r_type,
                    bfd_get_reloc_code_name (fixP->fx_r_type));
       return NULL;
     }
 
-  assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+  gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
 
-  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+  reloc->sym_ptr_ptr = XNEW (asymbol *);
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   reloc->addend = fixP->fx_addnumber;
This page took 0.031423 seconds and 4 git commands to generate.