x86: Encode AVX256/AVX512 vpsub[bwdq] with VEX128/EVEX128
[deliverable/binutils-gdb.git] / gas / write.c
index 8efdbc506f411d9fb3b5278cf2ef894ec0f965ba..4c8e42b4b498376f858c43bab4a5119b10252c29 100644 (file)
@@ -1,5 +1,5 @@
 /* write.c - emit .o file
-   Copyright (C) 1986-2017 Free Software Foundation, Inc.
+   Copyright (C) 1986-2018 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -435,6 +435,8 @@ cvt_frag_to_fill (segT sec ATTRIBUTE_UNUSED, fragS *fragP)
 {
   switch (fragP->fr_type)
     {
+    case rs_space_nop:
+      goto skip_align;
     case rs_align:
     case rs_align_code:
     case rs_align_test:
@@ -443,6 +445,7 @@ cvt_frag_to_fill (segT sec ATTRIBUTE_UNUSED, fragS *fragP)
 #ifdef HANDLE_ALIGN
       HANDLE_ALIGN (fragP);
 #endif
+skip_align:
       know (fragP->fr_next != NULL);
       fragP->fr_offset = (fragP->fr_next->fr_address
                          - fragP->fr_address
@@ -450,14 +453,18 @@ cvt_frag_to_fill (segT sec ATTRIBUTE_UNUSED, fragS *fragP)
       if (fragP->fr_offset < 0)
        {
          as_bad_where (fragP->fr_file, fragP->fr_line,
-                       _("attempt to .org/.space backwards? (%ld)"),
+                       _("attempt to .org/.space/.nops backwards? (%ld)"),
                        (long) fragP->fr_offset);
          fragP->fr_offset = 0;
        }
-      fragP->fr_type = rs_fill;
+      if (fragP->fr_type == rs_space_nop)
+       fragP->fr_type = rs_fill_nop;
+      else
+       fragP->fr_type = rs_fill;
       break;
 
     case rs_fill:
+    case rs_fill_nop:
       break;
 
     case rs_leb128:
@@ -724,7 +731,7 @@ resolve_reloc_expr_symbols (void)
              as_bad_where (r->file, r->line, _("invalid reloc expression"));
              sec = NULL;
            }
-         else if (sym != NULL)
+         else if (sym != NULL && sec != NULL)
            {
              /* Convert relocs against local symbols to refer to the
                 corresponding section symbol plus offset instead.  Keep
@@ -1106,7 +1113,11 @@ fixup_segment (fixS *fixP, segT this_segment)
                  else
                    sprintf (buf2, "%ld", (long) add_number);
                  as_bad_where (fixP->fx_file, fixP->fx_line,
-                               _("value of %s too large for field of %d bytes at %s"),
+                               ngettext ("value of %s too large for field "
+                                         "of %d byte at %s",
+                                         "value of %s too large for field "
+                                         "of %d bytes at %s",
+                                         fixP->fx_size),
                                buf2, fixP->fx_size, buf);
                } /* Generic error checking.  */
            }
@@ -1458,7 +1469,10 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
   if (obstack_room (ob) < header_size)
     first_newf = frag_alloc (ob);
   if (obstack_room (ob) < header_size)
-    as_fatal (_("can't extend frag %u chars"), header_size);
+    as_fatal (ngettext ("can't extend frag %lu char",
+                       "can't extend frag %lu chars",
+                       (unsigned long) header_size),
+             (unsigned long) header_size);
   last_newf = first_newf;
   obstack_blank_fast (ob, header_size);
   last_newf->fr_type = rs_fill;
@@ -1563,6 +1577,20 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
     }
 }
 
+#ifndef md_generate_nops
+/* Genenerate COUNT bytes of no-op instructions to WHERE.  A target
+   backend must override this with proper no-op instructions.   */
+
+static void
+md_generate_nops (fragS *f ATTRIBUTE_UNUSED,
+                 char *where ATTRIBUTE_UNUSED,
+                 offsetT count ATTRIBUTE_UNUSED,
+                 int control ATTRIBUTE_UNUSED)
+{
+  as_bad (_("unimplemented .nops directive"));
+}
+#endif
+
 static void
 write_contents (bfd *abfd ATTRIBUTE_UNUSED,
                asection *sec,
@@ -1586,22 +1614,52 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
       char *fill_literal;
       offsetT count;
 
-      gas_assert (f->fr_type == rs_fill);
+      gas_assert (f->fr_type == rs_fill || f->fr_type == rs_fill_nop);
       if (f->fr_fix)
        {
          x = bfd_set_section_contents (stdoutput, sec,
                                        f->fr_literal, (file_ptr) offset,
                                        (bfd_size_type) f->fr_fix);
          if (!x)
-           as_fatal (_("can't write %ld bytes to section %s of %s because: '%s'"),
-                     (long) f->fr_fix, sec->name,
-                     stdoutput->filename,
+           as_fatal (ngettext ("can't write %ld byte "
+                               "to section %s of %s: '%s'",
+                               "can't write %ld bytes "
+                               "to section %s of %s: '%s'",
+                               (long) f->fr_fix),
+                     (long) f->fr_fix,
+                     sec->name, stdoutput->filename,
                      bfd_errmsg (bfd_get_error ()));
          offset += f->fr_fix;
        }
-      fill_literal = f->fr_literal + f->fr_fix;
+
       fill_size = f->fr_var;
       count = f->fr_offset;
+      fill_literal = f->fr_literal + f->fr_fix;
+
+      if (f->fr_type == rs_fill_nop)
+       {
+         gas_assert (count >= 0 && fill_size == 1);
+         if (count > 0)
+           {
+             char *buf = xmalloc (count);
+             md_generate_nops (f, buf, count, *fill_literal);
+             x = bfd_set_section_contents
+               (stdoutput, sec, buf, (file_ptr) offset,
+                (bfd_size_type) count);
+             if (!x)
+               as_fatal (ngettext ("can't fill %ld byte "
+                                   "in section %s of %s: '%s'",
+                                   "can't fill %ld bytes "
+                                   "in section %s of %s: '%s'",
+                                   (long) count), (long) count,
+                                   sec->name, stdoutput->filename,
+                                   bfd_errmsg (bfd_get_error ()));
+             offset += count;
+             free (buf);
+           }
+         continue;
+       }
+
       gas_assert (count >= 0);
       if (fill_size && count)
        {
@@ -1616,9 +1674,13 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
                                                (file_ptr) offset,
                                                (bfd_size_type) fill_size);
                  if (!x)
-                   as_fatal (_("can't fill %ld bytes in section %s of %s because '%s'"),
-                             (long) fill_size, sec->name,
-                             stdoutput->filename,
+                   as_fatal (ngettext ("can't fill %ld byte "
+                                       "in section %s of %s: '%s'",
+                                       "can't fill %ld bytes "
+                                       "in section %s of %s: '%s'",
+                                       (long) fill_size),
+                             (long) fill_size,
+                             sec->name, stdoutput->filename,
                              bfd_errmsg (bfd_get_error ()));
                  offset += fill_size;
                }
@@ -1648,9 +1710,13 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
                    (stdoutput, sec, buf, (file_ptr) offset,
                     (bfd_size_type) n_per_buf * fill_size);
                  if (!x)
-                   as_fatal (_("cannot fill %ld bytes in section %s of %s because: '%s'"),
-                             (long)(n_per_buf * fill_size), sec->name,
-                             stdoutput->filename,
+                   as_fatal (ngettext ("can't fill %ld byte "
+                                       "in section %s of %s: '%s'",
+                                       "can't fill %ld bytes "
+                                       "in section %s of %s: '%s'",
+                                       (long) (n_per_buf * fill_size)),
+                             (long) (n_per_buf * fill_size),
+                             sec->name, stdoutput->filename,
                              bfd_errmsg (bfd_get_error ()));
                  offset += n_per_buf * fill_size;
                }
@@ -2107,12 +2173,11 @@ write_object_file (void)
 
              if (S_IS_COMMON (symp)
                  && !TC_FAKE_LABEL (sname)
-                 && !S_IS_WEAKREFR (symp)
-                 && (!S_IS_EXTERNAL (symp) || S_IS_LOCAL (symp)))
+                 && !S_IS_WEAKREFR (symp))
                {
                  expressionS *e = symbol_get_value_expression (symp);
 
-                 as_bad (_("Local symbol `%s' can't be equated to common symbol `%s'"),
+                 as_bad (_("`%s' can't be equated to common symbol `%s'"),
                          sname, S_GET_NAME (e->X_add_symbol));
                }
              if (S_GET_SEGMENT (symp) == reg_section)
@@ -2423,7 +2488,11 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
            if (offset % fragP->fr_var != 0)
              {
                as_bad_where (fragP->fr_file, fragP->fr_line,
-                             _("alignment padding (%lu bytes) not a multiple of %ld"),
+                             ngettext ("alignment padding (%lu byte) "
+                                       "not a multiple of %ld",
+                                       "alignment padding (%lu bytes) "
+                                       "not a multiple of %ld",
+                                       (unsigned long) offset),
                              (unsigned long) offset, (long) fragP->fr_var);
                offset -= (offset % fragP->fr_var);
              }
@@ -2439,6 +2508,7 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
          break;
 
        case rs_space:
+       case rs_space_nop:
          break;
 
        case rs_machine_dependent:
@@ -2743,6 +2813,7 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
                break;
 
              case rs_space:
+             case rs_space_nop:
                growth = 0;
                if (symbolP)
                  {
@@ -2769,7 +2840,7 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
                          }
 
                        as_warn_where (fragP->fr_file, fragP->fr_line,
-                                      _(".space or .fill with negative value, ignored"));
+                                      _(".space, .nops or .fill with negative value, ignored"));
                        fragP->fr_symbol = 0;
                      }
                    else
This page took 0.031597 seconds and 4 git commands to generate.