This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] x86: Add .nop directive to assembler


On Mon, Feb 19, 2018 at 6:47 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Feb 19, 2018 at 6:44 AM, Maciej W. Rozycki <macro@mips.com> wrote:
>> On Mon, 19 Feb 2018, H.J. Lu wrote:
>>
>>> >>  I have a feeling the default should wire in HANDLE_ALIGN somehow.  For
>>> >> many targets, such as fixed instruction width RISC processors, there is
>>> >> only going to be one way of filling a given amount of space with no-op
>>> >> instructions, so I think there's no point in having code duplication
>>> >> here.  And even if there are more ways possible for a given target, then
>>> >> the `.align' way is still right even if suboptimal.
>>> >
>>> > How would you propose to express "I need three nop
>>> > instructions aka 12 bytes from here" with just .align?  (Note: no matter
>>> > how "here" is currently aligned!)
>>> >
>>>
>>> .align isn't the same as .nop.   However, HANDLE_ALIGN can be updated
>>> to shared the same code with md_generate_nops, like what I did for x86.
>>
>>  Yes, that's what I meant.  It's an internal code wiring thing, not to be
>> something observable by the user.
>>
>
> Let me work on it.

Here is the patch to implement HANDLE_ALIGN with i386_generate_nops.
Other targets can do something similar.


-- 
H.J.
From 4a1a555eb09bc9fab822b0099ce048d205a1d400 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 19 Feb 2018 07:32:28 -0800
Subject: [PATCH] x86: Implement HANDLE_ALIGN with i386_generate_nops

HANDLE_ALIGN can be implemented with i386_generate_nops.

	* write.c (HANDLE_ALIGN): Define with md_generate_nops if not
	defined.
	* config/tc-i386.c (i386_align_code): Merged with ...
	(i386_generate_nops): This.
	* config/tc-i386.h (i386_align_code): Removed.
	(HANDLE_ALIGN): Rewritten with i386_generate_nops.
---
 gas/config/tc-i386.c | 68 +++++++++++++++++++++++++---------------------------
 gas/config/tc-i386.h | 19 ++++++++-------
 2 files changed, 43 insertions(+), 44 deletions(-)

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index c67ea1f224..09b3694135 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1277,46 +1277,43 @@ i386_output_nops (char *where, const unsigned char *const *patt,
    single NOP instruction LIMIT.  */
 
 void
-i386_generate_nops (fragS *f, char *where, offsetT count, int limit)
+i386_generate_nops (fragS *fragP, char *where, offsetT count, int limit)
 {
   /* Output NOPs for .nop directive.  */
-  int max_single_nop_size;
-  const unsigned char *const *patt;
-
-  if (flag_code == CODE_16BIT)
-    {
-      patt = f16_patt;
-      max_single_nop_size = sizeof (f16_patt) / sizeof (f16_patt[0]);
-    }
-  else if (flag_code == CODE_64BIT)
-    {
-      patt = alt64_patt;
-      max_single_nop_size = sizeof (alt64_patt) / sizeof (alt64_patt[0]);
-    }
-  else
+  if (fragP->fr_type == rs_fill_nop)
     {
-      patt = alt_patt;
-      max_single_nop_size = sizeof (alt_patt) / sizeof (alt_patt[0]);
-    }
-  if (limit == 0)
-    limit = max_single_nop_size;
-  else if (limit > max_single_nop_size)
-    {
-      as_bad_where (f->fr_file, f->fr_line,
-		    _("invalide single nop size: %d (expect within [0, %d])"),
-		    limit, max_single_nop_size);
-      return;
-    }
+      int max_single_nop_size;
+      const unsigned char *const *patt;
 
-  i386_output_nops (where, patt, count, limit);
-}
+      if (flag_code == CODE_16BIT)
+	{
+	  patt = f16_patt;
+	  max_single_nop_size = sizeof (f16_patt) / sizeof (f16_patt[0]);
+	}
+      else if (flag_code == CODE_64BIT)
+	{
+	  patt = alt64_patt;
+	  max_single_nop_size = sizeof (alt64_patt) / sizeof (alt64_patt[0]);
+	}
+      else
+	{
+	  patt = alt_patt;
+	  max_single_nop_size = sizeof (alt_patt) / sizeof (alt_patt[0]);
+	}
+      if (limit == 0)
+	limit = max_single_nop_size;
+      else if (limit > max_single_nop_size)
+	{
+	  as_bad_where (fragP->fr_file, fragP->fr_line,
+			_("invalide single nop size: %d "
+			  "(expect within [0, %d])"),
+			limit, max_single_nop_size);
+	  return;
+	}
 
-void
-i386_align_code (fragS *fragP, int count)
-{
-  /* Only align for at least a positive non-zero boundary. */
-  if (count <= 0 || count > MAX_MEM_FOR_RS_ALIGN_CODE)
-    return;
+      i386_output_nops (where, patt, count, limit);
+      return;
+    }
 
   /* We need to decide which NOP sequence to use for 32bit and
      64bit. When -mtune= is used:
@@ -1442,7 +1439,6 @@ i386_align_code (fragS *fragP, int count)
 	  /* If the padding is less than 15 bytes, we use the normal
 	     ones.  Otherwise, we use a jump instruction and adjust
 	     its offset.   */
-	  int limit;
 
 	  /* For 64bit, the limit is 3 bytes.  */
 	  if (flag_code == CODE_64BIT
diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h
index 1250bc25f5..72484b2537 100644
--- a/gas/config/tc-i386.h
+++ b/gas/config/tc-i386.h
@@ -207,14 +207,6 @@ if ((n)									\
 
 #define MAX_MEM_FOR_RS_ALIGN_CODE  31
 
-extern void i386_align_code (fragS *, int);
-
-#define HANDLE_ALIGN(fragP)						\
-if (fragP->fr_type == rs_align_code) 					\
-  i386_align_code (fragP, (fragP->fr_next->fr_address			\
-			   - fragP->fr_address				\
-			   - fragP->fr_fix));
-
 void i386_print_statistics (FILE *);
 #define tc_print_statistics i386_print_statistics
 
@@ -286,6 +278,17 @@ extern void i386_generate_nops (fragS *, char *, offsetT, int);
 #define md_generate_nops(frag, where, amount, control) \
   i386_generate_nops ((frag), (where), (amount), (control))
 
+#define HANDLE_ALIGN(fragP)						\
+if (fragP->fr_type == rs_align_code) 					\
+  {									\
+    offsetT __count = (fragP->fr_next->fr_address			\
+		       - fragP->fr_address				\
+		       - fragP->fr_fix);				\
+    if (__count > 0 && __count <= MAX_MEM_FOR_RS_ALIGN_CODE)		\
+      md_generate_nops (fragP, fragP->fr_literal + fragP->fr_fix,	\
+			__count, 0);					\
+  }
+
 /* We want .cfi_* pseudo-ops for generating unwind info.  */
 #define TARGET_USE_CFIPOP 1
 
-- 
2.14.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]