or1k: add support for l.swa/l.lwa atomic instructions
[deliverable/binutils-gdb.git] / gas / read.c
index b4aa3912d06e5e6a30e7298c913e75a3bfbee12e..8e1b06edf6bdad5e0f412bc1b22de8f57ef4ac1c 100644 (file)
@@ -263,8 +263,11 @@ read_begin (void)
   obstack_begin (&notes, chunksize);
   obstack_begin (&cond_obstack, chunksize);
 
+#ifndef tc_line_separator_chars
+#define tc_line_separator_chars line_separator_chars
+#endif
   /* Use machine dependent syntax.  */
-  for (p = line_separator_chars; *p; p++)
+  for (p = tc_line_separator_chars; *p; p++)
     is_end_of_line[(unsigned char) *p] = 2;
   /* Use more.  FIXME-SOMEDAY.  */
 
@@ -3848,19 +3851,22 @@ parse_mri_cons (expressionS *exp, unsigned int nbytes);
 
 #ifndef TC_PARSE_CONS_EXPRESSION
 #ifdef BITFIELD_CONS_EXPRESSIONS
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (parse_bitfield_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE)
 static void
 parse_bitfield_cons (expressionS *exp, unsigned int nbytes);
 #endif
 #ifdef REPEAT_CONS_EXPRESSIONS
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (parse_repeat_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE)
 static void
 parse_repeat_cons (expressionS *exp, unsigned int nbytes);
 #endif
 
 /* If we haven't gotten one yet, just call expression.  */
 #ifndef TC_PARSE_CONS_EXPRESSION
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (expression (EXP), TC_PARSE_CONS_RETURN_NONE)
 #endif
 #endif
 
@@ -3868,7 +3874,7 @@ void
 do_parse_cons_expression (expressionS *exp,
                          int nbytes ATTRIBUTE_UNUSED)
 {
-  TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+  (void) TC_PARSE_CONS_EXPRESSION (exp, nbytes);
 }
 
 
@@ -3911,6 +3917,14 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long.  */
   c = 0;
   do
     {
+      TC_PARSE_CONS_RETURN_TYPE ret = TC_PARSE_CONS_RETURN_NONE;
+#ifdef TC_CONS_FIX_CHECK
+      fixS **cur_fix = &frchain_now->fix_tail;
+
+      if (*cur_fix != NULL)
+       cur_fix = &(*cur_fix)->fx_next;
+#endif
+
 #ifdef TC_M68K
       if (flag_m68k_mri)
        parse_mri_cons (&exp, (unsigned int) nbytes);
@@ -3923,7 +3937,7 @@ cons_worker (int nbytes,  /* 1=.byte, 2=.word, 4=.long.  */
              ignore_rest_of_line ();
              return;
            }
-         TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
+         ret = TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
        }
 
       if (rva)
@@ -3933,7 +3947,10 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long.  */
          else
            as_fatal (_("rva without symbol"));
        }
-      emit_expr (&exp, (unsigned int) nbytes);
+      emit_expr_with_reloc (&exp, (unsigned int) nbytes, ret);
+#ifdef TC_CONS_FIX_CHECK
+      TC_CONS_FIX_CHECK (&exp, nbytes, *cur_fix);
+#endif
       ++c;
     }
   while (*input_line_pointer++ == ',');
@@ -4076,6 +4093,14 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
 
 void
 emit_expr (expressionS *exp, unsigned int nbytes)
+{
+  emit_expr_with_reloc (exp, nbytes, TC_PARSE_CONS_RETURN_NONE);
+}
+
+void
+emit_expr_with_reloc (expressionS *exp,
+                     unsigned int nbytes,
+                     TC_PARSE_CONS_RETURN_TYPE reloc)
 {
   operatorT op;
   char *p;
@@ -4218,6 +4243,12 @@ emit_expr (expressionS *exp, unsigned int nbytes)
 
   p = frag_more ((int) nbytes);
 
+  if (reloc != TC_PARSE_CONS_RETURN_NONE)
+    {
+      emit_expr_fix (exp, nbytes, frag_now, p, reloc);
+      return;
+    }
+
 #ifndef WORKING_DOT_WORD
   /* If we have the difference of two symbols in a word, save it on
      the broken_words list.  See the code in write.c.  */
@@ -4376,23 +4407,41 @@ emit_expr (expressionS *exp, unsigned int nbytes)
        }
     }
   else
-    emit_expr_fix (exp, nbytes, frag_now, p);
+    emit_expr_fix (exp, nbytes, frag_now, p, TC_PARSE_CONS_RETURN_NONE);
 }
 
 void
-emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p)
+emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p,
+              TC_PARSE_CONS_RETURN_TYPE r ATTRIBUTE_UNUSED)
 {
-  memset (p, 0, nbytes);
+  int offset = 0;
+  unsigned int size = nbytes;
+
+  memset (p, 0, size);
 
   /* Generate a fixS to record the symbol value.  */
 
 #ifdef TC_CONS_FIX_NEW
-  TC_CONS_FIX_NEW (frag, p - frag->fr_literal, nbytes, exp);
+  TC_CONS_FIX_NEW (frag, p - frag->fr_literal + offset, size, exp, r);
 #else
-  {
-    bfd_reloc_code_real_type r;
+  if (r != TC_PARSE_CONS_RETURN_NONE)
+    {
+      reloc_howto_type *reloc_howto;
 
-    switch (nbytes)
+      reloc_howto = bfd_reloc_type_lookup (stdoutput, r);
+      size = bfd_get_reloc_size (reloc_howto);
+
+      if (size > nbytes)
+       {
+         as_bad (_("%s relocations do not fit in %u bytes\n"),
+                 reloc_howto->name, nbytes);
+         return;
+       }
+      else if (target_big_endian)
+       offset = nbytes - size;
+    }
+  else
+    switch (size)
       {
       case 1:
        r = BFD_RELOC_8;
@@ -4410,13 +4459,11 @@ emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p)
        r = BFD_RELOC_64;
        break;
       default:
-       as_bad (_("unsupported BFD relocation size %u"), nbytes);
-       r = BFD_RELOC_32;
-       break;
+       as_bad (_("unsupported BFD relocation size %u"), size);
+       return;
       }
-    fix_new_exp (frag, p - frag->fr_literal, (int) nbytes, exp,
-                0, r);
-  }
+  fix_new_exp (frag, p - frag->fr_literal + offset, size,
+              exp, 0, r);
 #endif
 }
 \f
@@ -4552,9 +4599,7 @@ parse_bitfield_cons (exp, nbytes)
 
 #ifdef TC_M68K
 static void
-parse_mri_cons (exp, nbytes)
-     expressionS *exp;
-     unsigned int nbytes;
+parse_mri_cons (expressionS *exp, unsigned int nbytes)
 {
   if (*input_line_pointer != '\''
       && (input_line_pointer[1] != '\''
This page took 0.025286 seconds and 4 git commands to generate.