Sanitize support for the ESA sparc simulator.
[deliverable/binutils-gdb.git] / gas / config / tc-a29k.c
index 6da39d01f9bcada34e6163fa9e700727aad6c5a2..4c3ede1195b087f2d90985a98b8bfbbfeb3089fc 100644 (file)
@@ -104,7 +104,7 @@ const char line_comment_chars[] = "#";
 
 /* We needed an unused char for line separation to work around the
    lack of macros, using sed and such.  */
-const char line_separator_chars[] = "";
+const char line_separator_chars[] = "@";
 
 /* Chars that can be used to separate mant from exp in floating point nums */
 const char EXP_CHARS[] = "eE";
@@ -851,11 +851,21 @@ md_apply_fix (fixP, val)
 
     case RELOC_JUMPTARG:       /* 00XX00XX pattern in a word */
       if (!fixP->fx_done)
-       /* let linker deal */
-       ;
+       {
+         /* The linker tries to support both AMD and old GNU style
+             R_IREL relocs.  That means that if the addend is exactly
+             the negative of the address within the section, the
+             linker will not handle it correctly.  */
+         if (fixP->fx_pcrel
+             && val != 0
+             && val == - (fixP->fx_frag->fr_address + fixP->fx_where))
+           as_bad_where
+             (fixP->fx_file, fixP->fx_line,
+              "the linker will not handle this relocation correctly");
+       }
       else if (fixP->fx_pcrel)
        {
-         long v = val >> 16;
+         long v = val >> 17;
          if (v != 0 && v != -1)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          "call/jmp target out of range");
@@ -1071,6 +1081,48 @@ md_show_usage (stream)
 {
 }
 \f
+/* This is called when a line is unrecognized.  This is used to handle
+   definitions of a29k style local labels.  */
+
+int
+a29k_unrecognized_line (c)
+     int c;
+{
+  int lab;
+  char *s;
+
+  if (c != '$'
+      || ! isdigit ((unsigned char) input_line_pointer[0]))
+    return 0;
+
+  s = input_line_pointer;
+
+  lab = 0;
+  while (isdigit ((unsigned char) *s))
+    {
+      lab = lab * 10 + *s - '0';
+      ++s;
+    }
+
+  if (*s != ':')
+    {
+      /* Not a label definition.  */
+      return 0;
+    }
+
+  if (dollar_label_defined (lab))
+    {
+      as_bad ("label \"$%d\" redefined", lab);
+      return 0;
+    }
+
+  define_dollar_label (lab);
+  colon (dollar_label_name (lab, 0));
+  input_line_pointer = s + 1;
+
+  return 1;
+}
+
 /* Default the values of symbols known that should be "predefined".  We
    don't bother to predefine them unless you actually use one, since there
    are a lot of them.  */
@@ -1148,6 +1200,31 @@ md_operand (expressionP)
       else
        expressionP->X_op = O_constant;
     }
+  else if (input_line_pointer[0] == '$'
+          && isdigit ((unsigned char) input_line_pointer[1]))
+    {
+      long lab;
+      char *name;
+      symbolS *sym;
+
+      /* This is a local label.  */
+      ++input_line_pointer;
+      lab = (long) get_absolute_expression ();
+      if (dollar_label_defined (lab))
+       {
+         name = dollar_label_name (lab, 0);
+         sym = symbol_find (name);
+       }
+      else
+       {
+         name = dollar_label_name (lab, 1);
+         sym = symbol_find_or_make (name);
+       }
+
+      expressionP->X_op = O_symbol;
+      expressionP->X_add_symbol = sym;
+      expressionP->X_add_number = 0;
+    }
   else if (input_line_pointer[0] == '$')
     {
       char *s;
@@ -1183,7 +1260,6 @@ md_operand (expressionP)
        }
       else 
        {
-         /* FIXME: We should handle a29k local labels here.  */
          return;
        }
 
This page took 0.025573 seconds and 4 git commands to generate.