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] |
Having found that x86-64 Linux has ill uses of rex64 prefixes in inline assembly like __asm__("rex64 ; fxsave %0" ...), which in case of the fxsave operand itself requiring use of some other REX form results in two REX prefixes emitted, resulting in the operation no longer being carried out with 64-bit operand size, I tried to prepare a patch for that when I found that the assembler needlessly rejects a (compiler generated) construct like "rex64/fxsave (%r12)". Thus this patch separates treatment of rex64 (and plain rex) from that of the other forms. Built and tested on x86_64-unknown-linux-gnu and i386-pc-linux-gnu. Jan gas/ 2005-11-21 Jan Beulich <jbeulich@novell.com> * config/tc-i386.c (add_prefix): More fine-grained handling of REX prefixes. Or new prefix value into i.prefix instead of assigning. gas/testsuite/ 2005-11-21 Jan Beulich <jbeulich@novell.com> * gas/i386/rex.[sd]: New. * gas/i386/i386.exp: Run new test. --- /home/jbeulich/src/binutils/mainline/2005-11-16/gas/config/tc-i386.c 2005-11-16 08:52:46.000000000 +0100 +++ 2005-11-16/gas/config/tc-i386.c 2005-11-21 11:48:00.067458832 +0100 @@ -730,55 +730,66 @@ add_prefix (prefix) unsigned int prefix; { int ret = 1; - int q; + unsigned int q; if (prefix >= REX_OPCODE && prefix < REX_OPCODE + 16 && flag_code == CODE_64BIT) - q = REX_PREFIX; + { + if ((i.prefix[REX_PREFIX] & prefix & REX_MODE64) + || ((i.prefix[REX_PREFIX] & (REX_EXTX | REX_EXTY | REX_EXTZ)) + && (prefix & (REX_EXTX | REX_EXTY | REX_EXTZ)))) + ret = 0; + q = REX_PREFIX; + } else - switch (prefix) - { - default: - abort (); + { + switch (prefix) + { + default: + abort (); - case CS_PREFIX_OPCODE: - case DS_PREFIX_OPCODE: - case ES_PREFIX_OPCODE: - case FS_PREFIX_OPCODE: - case GS_PREFIX_OPCODE: - case SS_PREFIX_OPCODE: - q = SEG_PREFIX; - break; + case CS_PREFIX_OPCODE: + case DS_PREFIX_OPCODE: + case ES_PREFIX_OPCODE: + case FS_PREFIX_OPCODE: + case GS_PREFIX_OPCODE: + case SS_PREFIX_OPCODE: + q = SEG_PREFIX; + break; - case REPNE_PREFIX_OPCODE: - case REPE_PREFIX_OPCODE: - ret = 2; - /* fall thru */ - case LOCK_PREFIX_OPCODE: - q = LOCKREP_PREFIX; - break; + case REPNE_PREFIX_OPCODE: + case REPE_PREFIX_OPCODE: + ret = 2; + /* fall thru */ + case LOCK_PREFIX_OPCODE: + q = LOCKREP_PREFIX; + break; - case FWAIT_OPCODE: - q = WAIT_PREFIX; - break; + case FWAIT_OPCODE: + q = WAIT_PREFIX; + break; - case ADDR_PREFIX_OPCODE: - q = ADDR_PREFIX; - break; + case ADDR_PREFIX_OPCODE: + q = ADDR_PREFIX; + break; - case DATA_PREFIX_OPCODE: - q = DATA_PREFIX; - break; - } + case DATA_PREFIX_OPCODE: + q = DATA_PREFIX; + break; + } + if (i.prefix[q] != 0) + ret = 0; + } - if (i.prefix[q] != 0) + if (ret) { - as_bad (_("same type of prefix used twice")); - return 0; + if (!i.prefix[q]) + ++i.prefixes; + i.prefix[q] |= prefix; } + else + as_bad (_("same type of prefix used twice")); - i.prefixes += 1; - i.prefix[q] = prefix; return ret; } --- /home/jbeulich/src/binutils/mainline/2005-11-16/gas/testsuite/gas/i386/i386.exp 2005-11-07 08:48:26.000000000 +0100 +++ 2005-11-16/gas/testsuite/gas/i386/i386.exp 2005-11-21 12:19:47.000000000 +0100 @@ -132,6 +132,21 @@ if [expr ([istarget "i*86-*-*"] || [ista run_dump_test "x86-64-vmx" run_dump_test "immed64" + if { ![istarget "*-*-aix*"] + && ![istarget "*-*-beos*"] + && ![istarget "*-*-*bsd*"] + && ![istarget "*-*-chaos*"] + && ![istarget "*-*-kaos*"] + && ![istarget "*-*-lynx*"] + && ![istarget "*-*-moss*"] + && ![istarget "*-*-nto-qnx*"] + && ![istarget "*-*-rtems*"] + && ![istarget "*-*-sco*"] + && ![istarget "*-*-solaris*"] + && ![istarget "*-*-sysv*"] } then { + run_dump_test "rex" + } + # For ELF targets verify that @unwind works. if { ([istarget "*-*-elf*"] || [istarget "*-*-linux*"] || [istarget "*-*-solaris2.*"]) --- /home/jbeulich/src/binutils/mainline/2005-11-16/gas/testsuite/gas/i386/rex.d 1970-01-01 01:00:00.000000000 +0100 +++ 2005-11-16/gas/testsuite/gas/i386/rex.d 2005-11-21 11:21:12.000000000 +0100 @@ -0,0 +1,17 @@ +#objdump: -dw +#name: x86-64 manual rex prefix use + +.*: +file format elf64-x86-64 + +Disassembly of section .text: + +0+ <_start>: +[ ]*[0-9a-f]+:[ ]+40 0f ae 00[ ]+rex fxsavel?[ ]+\(%rax\) +[ ]*[0-9a-f]+:[ ]+48 0f ae 00[ ]+(rex64 )?fxsaveq?[ ]+\(%rax\) +[ ]*[0-9a-f]+:[ ]+41 0f ae 00[ ]+fxsavel?[ ]+\(%r8\) +[ ]*[0-9a-f]+:[ ]+49 0f ae 00[ ]+(rex64Z? )?fxsaveq?[ ]+\(%r8\) +[ ]*[0-9a-f]+:[ ]+42 0f ae 04 05 00 00 00 00[ ]+fxsavel?[ ]+(0x0)?\(,%r8(,1)?\) +[ ]*[0-9a-f]+:[ ]+4a 0f ae 04 05 00 00 00 00[ ]+(rex64Y? )?fxsaveq?[ ]+(0x0)?\(,%r8(,1)?\) +[ ]*[0-9a-f]+:[ ]+43 0f ae 04 00[ ]+fxsavel?[ ]+\(%r8,%r8(,1)?\) +[ ]*[0-9a-f]+:[ ]+4b 0f ae 04 00[ ]+(rex64(YZ)? )?fxsaveq?[ ]+\(%r8,%r8(,1)?\) +#pass --- /home/jbeulich/src/binutils/mainline/2005-11-16/gas/testsuite/gas/i386/rex.s 1970-01-01 01:00:00.000000000 +0100 +++ 2005-11-16/gas/testsuite/gas/i386/rex.s 2005-11-21 11:12:07.000000000 +0100 @@ -0,0 +1,11 @@ + .text + +_start: + rex/fxsave (%rax) + rex64/fxsave (%rax) + rex/fxsave (%r8) + rex64/fxsave (%r8) + rex/fxsave (,%r8) + rex64/fxsave (,%r8) + rex/fxsave (%r8,%r8) + rex64/fxsave (%r8,%r8)
Attachment:
binutils-mainline-x86_64-rex.patch
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |