aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2002-07-16 22:31:19 +0000
committerJan Hubicka <jh@suse.cz>2002-07-16 22:31:19 +0000
commit33fef721a111deff1e9a2d8232d68ab8361a266c (patch)
tree724a947d4db9668d1eaddda0f65d07a6f1e6f2d7 /gas
parentf7ef9339220295678059f1b4d77a125af296bb82 (diff)
downloadfsf-binutils-gdb-33fef721a111deff1e9a2d8232d68ab8361a266c.zip
fsf-binutils-gdb-33fef721a111deff1e9a2d8232d68ab8361a266c.tar.gz
fsf-binutils-gdb-33fef721a111deff1e9a2d8232d68ab8361a266c.tar.bz2
* tc-i386.c (i386_align_code): Implement x86_64 neutral code fillers.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog4
-rw-r--r--gas/config/tc-i386.c49
2 files changed, 38 insertions, 15 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 95f4a61..86d2b3d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,7 @@
+Wed Jul 17 00:30:13 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * tc-i386.c (i386_align_code): Implement x86_64 neutral code fillers.
+
2002-07-16 Moritz Jodeit <moritz@jodeit.org>
* config/tc-z8k.c (build_bytes): Correct order of memset args.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index c7dbfbd..85611de 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -521,26 +521,45 @@ i386_align_code (fragP, count)
f32_15, f32_15, f32_15, f32_15, f32_15, f32_15, f32_15
};
- /* ??? We can't use these fillers for x86_64, since they often kills the
- upper halves. Solve later. */
- if (flag_code == CODE_64BIT)
- count = 1;
+ if (count <= 0 || count > 15)
+ return;
- if (count > 0 && count <= 15)
+ /* The recommended way to pad 64bit code is to use NOPs preceded by
+ maximally four 0x66 prefixes. Balance the size of nops. */
+ if (flag_code == CODE_64BIT)
{
- if (flag_code == CODE_16BIT)
+ int i;
+ int nnops = (count + 3) / 4;
+ int len = count / nnops;
+ int remains = count - nnops * len;
+ int pos = 0;
+
+ for (i = 0; i < remains; i++)
{
- memcpy (fragP->fr_literal + fragP->fr_fix,
- f16_patt[count - 1], count);
- if (count > 8)
- /* Adjust jump offset. */
- fragP->fr_literal[fragP->fr_fix + 1] = count - 2;
+ memset (fragP->fr_literal + fragP->fr_fix + pos, 0x66, len);
+ fragP->fr_literal[fragP->fr_fix + pos + len] = 0x90;
+ pos += len + 1;
+ }
+ for (; i < nnops; i++)
+ {
+ memset (fragP->fr_literal + fragP->fr_fix + pos, 0x66, len - 1);
+ fragP->fr_literal[fragP->fr_fix + pos + len - 1] = 0x90;
+ pos += len;
}
- else
- memcpy (fragP->fr_literal + fragP->fr_fix,
- f32_patt[count - 1], count);
- fragP->fr_var = count;
}
+ else
+ if (flag_code == CODE_16BIT)
+ {
+ memcpy (fragP->fr_literal + fragP->fr_fix,
+ f16_patt[count - 1], count);
+ if (count > 8)
+ /* Adjust jump offset. */
+ fragP->fr_literal[fragP->fr_fix + 1] = count - 2;
+ }
+ else
+ memcpy (fragP->fr_literal + fragP->fr_fix,
+ f32_patt[count - 1], count);
+ fragP->fr_var = count;
}
static INLINE unsigned int