* tc-m68hc11.c (s_m68hc11_parse_pseudo_instruction):
[deliverable/binutils-gdb.git] / gas / config / tc-vax.c
index b0ac3f745f3680328b80338ae1e6fb946189a2ff..185a9a242d19a093a7d6bafd0d4ce798c93e9350 100644 (file)
@@ -1,13 +1,13 @@
 /* tc-vax.c - vax-specific -
    Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1998, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006
+   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    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,
@@ -396,23 +396,20 @@ md_estimate_size_before_relax (fragS *fragP, segT segment)
                  || S_IS_WEAK (fragP->fr_symbol)
                  || S_IS_EXTERNAL (fragP->fr_symbol)))
            {
-             if (p[0] & 0x10)
-               {
-                 if (flag_want_pic)
-                   as_fatal ("PIC reference to %s is indirect.\n",
-                             S_GET_NAME (fragP->fr_symbol));
-               }
+             /* Indirect references cannot go through the GOT or PLT,
+                let's hope they'll become local in the final link.  */
+             if ((ELF_ST_VISIBILITY (S_GET_OTHER (fragP->fr_symbol))
+                  != STV_DEFAULT)
+                 || (p[0] & 0x10))
+               reloc_type = BFD_RELOC_32_PCREL;
+             else if (((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLS
+                      || ((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLG
+                      || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JSB
+                      || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JMP
+                      || S_IS_FUNCTION (fragP->fr_symbol))
+               reloc_type = BFD_RELOC_32_PLT_PCREL;
              else
-               {
-                 if (((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLS
-                     || ((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLG
-                     || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JSB
-                     || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JMP
-                     || S_IS_FUNCTION (fragP->fr_symbol))
-                   reloc_type = BFD_RELOC_32_PLT_PCREL;
-                 else
-                   reloc_type = BFD_RELOC_32_GOT_PCREL;
-               }
+               reloc_type = BFD_RELOC_32_GOT_PCREL;
            }
 #endif
          switch (RELAX_STATE (fragP->fr_subtype))
@@ -852,6 +849,8 @@ static const struct vot
   {"jbcs",     {"rlvbb?", 0x800000e3}},
   {"jbsc",     {"rlvbb?", 0x800000e4}},
   {"jbcc",     {"rlvbb?", 0x800000e5}},
+  {"jbssi",    {"rlvbb?", 0x800000e6}},
+  {"jbcci",    {"rlvbb?", 0x800000e7}},
   {"jlbs",     {"rlb?", 0x800000e8}},
   {"jlbc",     {"rlb?", 0x800000e9}},
 
@@ -959,11 +958,11 @@ vip_begin (int synthetic_too,             /* 1 means include jXXX op-codes.  */
   op_hash = hash_new ();
 
   for (vP = votstrs; *vP->vot_name && !retval; vP++)
-    retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);
+    retval = hash_insert (op_hash, vP->vot_name, (void *) &vP->vot_detail);
 
   if (synthetic_too)
     for (vP = synthetic_votstrs; *vP->vot_name && !retval; vP++)
-      retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);
+      retval = hash_insert (op_hash, vP->vot_name, (void *) &vP->vot_detail);
 
 #ifndef CONST_TABLE
   vip_op_defaults (immediate, indirect, displen);
@@ -1272,10 +1271,8 @@ vip_op (char *optext, struct vop *vopP)
      get the types wrong below, we lose at compile time rather than at
      lint or run time.  */
   char access_mode;            /* vop_access.  */
-  char width;                  /* vop_width.  */
 
   access_mode = vopP->vop_access;
-  width = vopP->vop_width;
   /* None of our code bugs (yet), no user text errors, no warnings
      even.  */
   err = wrn = 0;
@@ -2035,8 +2032,6 @@ main (void)
    We declare arrays non-local in case some of our tiny-minded machines
    default to small stacks. Also, helps with some debuggers.  */
 
-#include <stdio.h>
-
 char answer[100];              /* Human types into here.  */
 char *p;                       /*  */
 char *myerr;
@@ -2403,7 +2398,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 #endif
 
   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
-  assert (reloc->howto != 0);
+  gas_assert (reloc->howto != 0);
 
   return reloc;
 }
@@ -2716,6 +2711,7 @@ md_assemble (char *instruction_string)
   if (need_pass_2 || goofed)
     return;
 
+  dwarf2_emit_insn (0);
   /* Emit op-code.  */
   /* Remember where it is, in case we want to modify the op-code later.  */
   opcode_low_byteP = frag_more (v.vit_opcode_nbytes);
@@ -3154,7 +3150,8 @@ md_assemble (char *instruction_string)
                          if (flag_want_pic && operandP->vop_mode == 8
                                && this_add_symbol != NULL)
                            {
-                             as_warn (_("Symbol used as immediate operand in PIC mode."));
+                             as_warn (_("Symbol %s used as immediate operand in PIC mode."),
+                                      S_GET_NAME (this_add_symbol));
                            }
 #endif
                          p[0] = (operandP->vop_mode << 4) | 0xF;
@@ -3170,7 +3167,8 @@ md_assemble (char *instruction_string)
                                                  min (sizeof (valueT),
                                                       (size_t) nbytes));
                              if ((size_t) nbytes > sizeof (valueT))
-                               memset (p + 5, '\0', nbytes - sizeof (valueT));
+                               memset (p + 1 + sizeof (valueT),
+                                       '\0', nbytes - sizeof (valueT));
                            }
                          else
                            {
@@ -3267,3 +3265,149 @@ md_begin (void)
       fP->high = &big_operand_bits[i][SIZE_OF_LARGE_NUMBER - 1];
     }
 }
+
+static char *vax_cons_special_reloc;
+
+void
+vax_cons (expressionS *exp, int size)
+{
+  char *save;
+
+  SKIP_WHITESPACE ();
+  vax_cons_special_reloc = NULL;
+  save = input_line_pointer;
+  if (input_line_pointer[0] == '%')
+    {
+      if (strncmp (input_line_pointer + 1, "pcrel", 5) == 0)
+       {
+         input_line_pointer += 6;
+         vax_cons_special_reloc = "pcrel";
+       }
+      if (vax_cons_special_reloc)
+       {
+         int bad = 0;
+
+         switch (size)
+           {
+           case 1:
+             if (*input_line_pointer != '8')
+               bad = 1;
+             input_line_pointer--;
+             break;
+           case 2:
+             if (input_line_pointer[0] != '1' || input_line_pointer[1] != '6')
+               bad = 1;
+             break;
+           case 4:
+             if (input_line_pointer[0] != '3' || input_line_pointer[1] != '2')
+               bad = 1;
+             break;
+           default:
+             bad = 1;
+             break;
+           }
+
+         if (bad)
+           {
+             as_bad (_("Illegal operands: Only %%r_%s%d allowed in %d-byte data fields"),
+                     vax_cons_special_reloc, size * 8, size);
+           }
+         else
+           {
+             input_line_pointer += 2;
+             if (*input_line_pointer != '(')
+               {
+                 as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
+                         vax_cons_special_reloc, size * 8);
+                 bad = 1;
+               }
+           }
+
+         if (bad)
+           {
+             input_line_pointer = save;
+             vax_cons_special_reloc = NULL;
+           }
+         else
+           {
+             int c;
+             char *end = ++input_line_pointer;
+             int npar = 0;
+
+             while (! is_end_of_line[(c = *end)])
+               {
+                 if (c == '(')
+                   npar++;
+                 else if (c == ')')
+                   {
+                     if (!npar)
+                       break;
+                     npar--;
+                   }
+                 end++;
+               }
+
+             if (c != ')')
+               as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
+                       vax_cons_special_reloc, size * 8);
+             else
+               {
+                 *end = '\0';
+                 expression (exp);
+                 *end = c;
+                 if (input_line_pointer != end)
+                   {
+                     as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
+                             vax_cons_special_reloc, size * 8);
+                   }
+                 else
+                   {
+                     input_line_pointer++;
+                     SKIP_WHITESPACE ();
+                     c = *input_line_pointer;
+                     if (! is_end_of_line[c] && c != ',')
+                       as_bad (_("Illegal operands: garbage after %%r_%s%d()"),
+                               vax_cons_special_reloc, size * 8);
+                   }
+               }
+           }
+       }
+    }
+  if (vax_cons_special_reloc == NULL)
+    expression (exp);
+}
+
+/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
+   reloc for a cons.  */
+
+void
+vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp)
+{
+  bfd_reloc_code_real_type r;
+
+  r = (nbytes == 1 ? BFD_RELOC_8 :
+       (nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32));
+
+  if (vax_cons_special_reloc)
+    {
+      if (*vax_cons_special_reloc == 'p')
+       {
+         switch (nbytes)
+           {
+           case 1: r = BFD_RELOC_8_PCREL; break;
+           case 2: r = BFD_RELOC_16_PCREL; break;
+           case 4: r = BFD_RELOC_32_PCREL; break;
+           default: abort ();
+           }
+       }
+    }
+
+  fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
+  vax_cons_special_reloc = NULL;
+}
+
+char *
+md_atof (int type, char * litP, int * sizeP)
+{
+  return vax_md_atof (type, litP, sizeP);
+}
This page took 0.026564 seconds and 4 git commands to generate.