diff options
author | Jan Hubicka <jh@suse.cz> | 2002-07-16 22:31:19 +0000 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2002-07-16 22:31:19 +0000 |
commit | 33fef721a111deff1e9a2d8232d68ab8361a266c (patch) | |
tree | 724a947d4db9668d1eaddda0f65d07a6f1e6f2d7 /gas | |
parent | f7ef9339220295678059f1b4d77a125af296bb82 (diff) | |
download | gdb-33fef721a111deff1e9a2d8232d68ab8361a266c.zip gdb-33fef721a111deff1e9a2d8232d68ab8361a266c.tar.gz gdb-33fef721a111deff1e9a2d8232d68ab8361a266c.tar.bz2 |
* tc-i386.c (i386_align_code): Implement x86_64 neutral code fillers.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 4 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 49 |
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 |