Don't define RISC-V .p2align
authorAndrew Waterman <andrew@sifive.com>
Mon, 19 Dec 2016 06:53:51 +0000 (22:53 -0800)
committerAlan Modra <amodra@gmail.com>
Tue, 20 Dec 2016 01:56:34 +0000 (12:26 +1030)
* config/tc-riscv.c (riscv_pseudo_table): Remove "align",
"p2align", and "balign".
(s_align): Remove.
(riscv_handle_align): New function.
(riscv_frag_align_code): Likewise.
(riscv_make_nops): Likewise.
* config/tc-riscv.h (MAX_MEM_FOR_RS_ALIGN_CODE): Change to 7.
(HANDLE_ALIGN): Define.
(md_do_align): Define.
(riscv_handle_align): Declare.
(riscv_frag_align_code): Likewise.

gas/ChangeLog
gas/config/tc-riscv.c
gas/config/tc-riscv.h

index a603984e698d61efcbeefd8cd0a11f7dfb25b608..f7d36b50495d2d4c3fe98f1a16f3f29da107c2b1 100644 (file)
@@ -1,3 +1,17 @@
+2015-12-20  Andrew Waterman  <andrew@sifive.com>
+
+       * config/tc-riscv.c (riscv_pseudo_table): Remove "align",
+       "p2align", and "balign".
+       (s_align): Remove.
+       (riscv_handle_align): New function.
+       (riscv_frag_align_code): Likewise.
+       (riscv_make_nops): Likewise.
+       * config/tc-riscv.h (MAX_MEM_FOR_RS_ALIGN_CODE): Change to 7.
+       (HANDLE_ALIGN): Define.
+       (md_do_align): Define.
+       (riscv_handle_align): Declare.
+       (riscv_frag_align_code): Likewise.
+
 2016-12-20  Andrew Waterman  <andrew@sifive.com>
 
        * config/tc-riscv.h (xlen): Delete.
index 77c92cfac307c295e733cabd3c819a72e67fa9d5..2d953c54cada06efa150663d418b53bf52f48e8d 100644 (file)
@@ -2185,63 +2185,82 @@ s_bss (int ignore ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
-/* Align to a given power of two.  */
-
 static void
-s_align (int bytes_p)
+riscv_make_nops (char *buf, bfd_vma bytes)
 {
-  int fill_value = 0, fill_value_specified = 0;
-  int min_text_alignment = riscv_opts.rvc ? 2 : 4;
-  int alignment = get_absolute_expression(), bytes;
+  bfd_vma i = 0;
 
-  if (bytes_p)
+  if (bytes % 4 == 2)
     {
-      bytes = alignment;
-      if (bytes < 1 || (bytes & (bytes-1)) != 0)
-       as_bad (_("alignment not a power of 2: %d"), bytes);
-      for (alignment = 0; bytes > 1; bytes >>= 1)
-       alignment++;
+      md_number_to_chars (buf, RVC_NOP, 2);
+      i += 2;
     }
 
-  bytes = 1 << alignment;
+  gas_assert ((bytes - i) % 4 == 0);
 
-  if (alignment < 0 || alignment > 31)
-    as_bad (_("unsatisfiable alignment: %d"), alignment);
+  for ( ; i < bytes; i += 4)
+    md_number_to_chars (buf + i, RISCV_NOP, 4);
+}
 
-  if (*input_line_pointer == ',')
-    {
-      ++input_line_pointer;
-      fill_value = get_absolute_expression ();
-      fill_value_specified = 1;
-    }
+/* Called from md_do_align.  Used to create an alignment frag in a
+   code section by emitting a worst-case NOP sequence that the linker
+   will later relax to the correct number of NOPs.  We can't compute
+   the correct alignment now because of other linker relaxations.  */
+
+bfd_boolean
+riscv_frag_align_code (int n)
+{
+  bfd_vma bytes = (bfd_vma)1 << n;
+  bfd_vma min_text_alignment = riscv_opts.rvc ? 2 : 4;
+
+  /* When not relaxing, riscv_handle_align handles code alignment.  */
+  if (!riscv_opts.relax)
+    return FALSE;
 
-  if (!fill_value_specified
-      && subseg_text_p (now_seg)
-      && bytes > min_text_alignment)
+  if (bytes > min_text_alignment)
     {
-      /* Emit the worst-case NOP string.  The linker will delete any
-        unnecessary NOPs.  This allows us to support code alignment
-        in spite of linker relaxations.  */
-      bfd_vma i, worst_case_bytes = bytes - min_text_alignment;
+      bfd_vma worst_case_bytes = bytes - min_text_alignment;
       char *nops = frag_more (worst_case_bytes);
-      for (i = 0; i < worst_case_bytes - 2; i += 4)
-       md_number_to_chars (nops + i, RISCV_NOP, 4);
-      if (i < worst_case_bytes)
-       md_number_to_chars (nops + i, RVC_NOP, 2);
-
       expressionS ex;
+
       ex.X_op = O_constant;
       ex.X_add_number = worst_case_bytes;
 
+      riscv_make_nops (nops, worst_case_bytes);
+
       fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
                   &ex, FALSE, BFD_RELOC_RISCV_ALIGN);
     }
-  else if (alignment)
-    frag_align (alignment, fill_value, 0);
 
-  record_alignment (now_seg, alignment);
+  return TRUE;
+}
 
-  demand_empty_rest_of_line ();
+/* Implement HANDLE_ALIGN.  */
+
+void
+riscv_handle_align (fragS *fragP)
+{
+  switch (fragP->fr_type)
+    {
+    case rs_align_code:
+      /* When relaxing, riscv_frag_align_code handles code alignment.  */
+      if (!riscv_opts.relax)
+       {
+         bfd_signed_vma count = fragP->fr_next->fr_address
+                                - fragP->fr_address - fragP->fr_fix;
+
+         if (count <= 0)
+           break;
+
+         count &= MAX_MEM_FOR_RS_ALIGN_CODE;
+         riscv_make_nops (fragP->fr_literal + fragP->fr_fix, count);
+         fragP->fr_var = count;
+       }
+      break;
+
+    default:
+      break;
+    }
 }
 
 int
@@ -2488,9 +2507,6 @@ static const pseudo_typeS riscv_pseudo_table[] =
   {"dtprelword", s_dtprel, 4},
   {"dtpreldword", s_dtprel, 8},
   {"bss", s_bss, 0},
-  {"align", s_align, 0},
-  {"p2align", s_align, 0},
-  {"balign", s_align, 1},
   {"uleb128", s_riscv_leb128, 0},
   {"sleb128", s_riscv_leb128, 1},
 
index 5e07fdae6430de243d9c5bf98fd77bdf93d8ca3a..5d6b83f94af799339585fbda952b15e37b25f022 100644 (file)
@@ -48,8 +48,18 @@ extern int riscv_relax_frag (asection *, struct frag *, long);
 #define md_undefined_symbol(name)      (0)
 #define md_operand(x)
 
-/* FIXME: it is unclear if this is used, or if it is even correct.  */
-#define MAX_MEM_FOR_RS_ALIGN_CODE  (1 + 2)
+extern bfd_boolean riscv_frag_align_code (int);
+#define md_do_align(N, FILL, LEN, MAX, LABEL)                          \
+  if ((N) != 0 && !(FILL) && !need_pass_2 && subseg_text_p (now_seg))  \
+    {                                                                  \
+      if (riscv_frag_align_code (N))                                   \
+       goto LABEL;                                                     \
+    }
+
+extern void riscv_handle_align (fragS *);
+#define HANDLE_ALIGN riscv_handle_align
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE 7
 
 /* The ISA of the target may change based on command-line arguments.  */
 #define TARGET_FORMAT riscv_target_format()