This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
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