This is the mail archive of the binutils@sources.redhat.com 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] |
This is an update to the earlier sent out patch that wasn't accepted for the reason of the FSF copyright assignment not yet in place. Note that when applying this together with the earlier posted Intel syntax patch, then there is going to be a failure in the intelbad gas test introduced with the Intel syntax patch. This can be addressed by simply adding an error expectation for line 7 to testsuite/gas/i386/intelbad.l. Jan gas: 2004-07-02 Jan Beulich <jbeulich@novell.com> * config/tc-i386.c (optimize_imm): Adjust immediates to only those permissible for the selected instruction suffix. (match_template): Don't permit 64-bit general purpose operands in 32-bit mode. (finalize_imm): Permit 64-bit immediates. (build_modrm_byte): Don't treat 32-bit addressing in 64-bit mode specially except for the width of the used base and/or index registers. For 32-bit displacements, use sign-extended relocations only when using 64-bit addressing. Force zero displacement on rip-relative addressing when there is no other displacement. (i386_index_check): Don't treat 32-bit addressing in 64-bit mode specially except for the width of the used base and/or index registers. (parse_register): Disallow Reg64 registers in 32-bit mode. * testsuite/gas/i386/x86-64-addr32.[ds]: New test for x86-64 32-bit addressing in 64-bit mode. * testsuite/gas/i386/x86-64-rip.[ds]: New test for x86-64 rip-relative addressing. * testsuite/gas/i386/i386.exp: Run the two new tests. opcodes: 2004-07-02 Jan Beulich <jbeulich@novell.com> * i386-dis.c (OP_E): Show rip-relative addressing in 64-bit mode regardless of address size prefix in effect. (ptr_reg): Size or address registers does not depend on rex64, but on the presence of an address size override. (OP_MMX): Use rex.x only for xmm registers. (OP_EM): Use rex.z only for xmm registers. diff -Naur /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/config/tc-i386.c 2004-07-02.08.43-fixes/gas/config/tc-i386.c --- /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/config/tc-i386.c 2004-06-28 16:51:56.000000000 +0200 +++ 2004-07-02.08.43-fixes/gas/config/tc-i386.c 2004-07-02 11:16:11.482954688 +0200 @@ -1922,15 +1922,13 @@ i.types[op] = Imm64 | Imm32S; break; case LONG_MNEM_SUFFIX: - i.types[op] = Imm32 | Imm64; + i.types[op] = Imm32; break; case WORD_MNEM_SUFFIX: - i.types[op] = Imm16 | Imm32 | Imm64; - break; + i.types[op] = Imm16; break; case BYTE_MNEM_SUFFIX: - i.types[op] = Imm8 | Imm8S | Imm16 | Imm32S | Imm32; - break; + i.types[op] = Imm8 | Imm8S; break; } break; @@ -2018,9 +2016,18 @@ : (i.suffix == LONG_DOUBLE_MNEM_SUFFIX ? No_xSuf : 0)))))); - for (t = current_templates->start; - t < current_templates->end; - t++) + t = current_templates->start; + if (i.suffix == QWORD_MNEM_SUFFIX + && flag_code != CODE_64BIT + && (!intel_syntax + || (!(t->opcode_modifier & IgnoreSize) + && !intel_float_operand(t->name))) + && (!(t->operand_types[0] & (RegMMX|RegXMM)) + || !(t->operand_types[t->operands > 1] & (RegMMX|RegXMM))) + && (t->base_opcode != 0x0fc7 + || t->extension_opcode != 1 /* cmpxchg8b */)) + t = current_templates->end; + for (; t < current_templates->end; t++) { /* Must have right number of operands. */ if (i.operands != t->operands) @@ -2504,7 +2511,7 @@ unsigned int overlap0, overlap1, overlap2; overlap0 = i.types[0] & i.tm.operand_types[0]; - if ((overlap0 & (Imm8 | Imm8S | Imm16 | Imm32 | Imm32S)) + if ((overlap0 & (Imm8 | Imm8S | Imm16 | Imm32 | Imm32S | Imm64)) && overlap0 != Imm8 && overlap0 != Imm8S && overlap0 != Imm16 && overlap0 != Imm32S && overlap0 != Imm32 && overlap0 != Imm64) @@ -2537,7 +2544,7 @@ i.types[0] = overlap0; overlap1 = i.types[1] & i.tm.operand_types[1]; - if ((overlap1 & (Imm8 | Imm8S | Imm16 | Imm32S | Imm32)) + if ((overlap1 & (Imm8 | Imm8S | Imm16 | Imm32S | Imm32 | Imm64)) && overlap1 != Imm8 && overlap1 != Imm8S && overlap1 != Imm16 && overlap1 != Imm32S && overlap1 != Imm32 && overlap1 != Imm64) @@ -2733,21 +2740,7 @@ if (i.index_reg == 0) { /* Operand is just <disp> */ - if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0) - && (flag_code != CODE_64BIT)) - { - i.rm.regmem = NO_BASE_REGISTER_16; - i.types[op] &= ~Disp; - i.types[op] |= Disp16; - } - else if (flag_code != CODE_64BIT - || (i.prefix[ADDR_PREFIX] != 0)) - { - i.rm.regmem = NO_BASE_REGISTER; - i.types[op] &= ~Disp; - i.types[op] |= Disp32; - } - else + if (flag_code == CODE_64BIT) { /* 64bit mode overwrites the 32bit absolute addressing by RIP relative addressing and @@ -2756,8 +2749,17 @@ i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; i.sib.base = NO_BASE_REGISTER; i.sib.index = NO_INDEX_REGISTER; - i.types[op] &= ~Disp; - i.types[op] |= Disp32S; + i.types[op] = ((i.prefix[ADDR_PREFIX] == 0) ? Disp32S : Disp32); + } + else if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0)) + { + i.rm.regmem = NO_BASE_REGISTER_16; + i.types[op] = Disp16; + } + else + { + i.rm.regmem = NO_BASE_REGISTER; + i.types[op] = Disp32; } } else /* !i.base_reg && i.index_reg */ @@ -2782,6 +2784,8 @@ i.types[op] &= ~Disp; i.types[op] |= Disp32S; i.flags[op] = Operand_PCrel; + if (! i.disp_operands) + fake_zero_displacement = 1; } else if (i.base_reg->reg_type & Reg16) { @@ -2818,10 +2822,7 @@ if (flag_code == CODE_64BIT && (i.types[op] & Disp)) { - if (i.types[op] & Disp8) - i.types[op] = Disp8 | Disp32S; - else - i.types[op] = Disp32S; + i.types[op] = (i.types[op] & Disp8) | (i.prefix[ADDR_PREFIX] == 0 ? Disp32S : Disp32); } i.rm.regmem = i.base_reg->reg_num; if ((i.base_reg->reg_flags & RegRex) != 0) @@ -4001,28 +4002,16 @@ ok = 1; if (flag_code == CODE_64BIT) { - if (i.prefix[ADDR_PREFIX] == 0) - { - /* 64bit checks. */ - if ((i.base_reg - && ((i.base_reg->reg_type & Reg64) == 0) - && (i.base_reg->reg_type != BaseIndex - || i.index_reg)) - || (i.index_reg - && ((i.index_reg->reg_type & (Reg64 | BaseIndex)) - != (Reg64 | BaseIndex)))) - ok = 0; - } - else - { - /* 32bit checks. */ - if ((i.base_reg - && (i.base_reg->reg_type & (Reg32 | RegRex)) != Reg32) - || (i.index_reg - && ((i.index_reg->reg_type & (Reg32 | BaseIndex | RegRex)) - != (Reg32 | BaseIndex)))) - ok = 0; - } + unsigned RegXX = (i.prefix[ADDR_PREFIX] == 0 ? Reg64 : Reg32); + + if ((i.base_reg + && ((i.base_reg->reg_type & RegXX) == 0) + && (i.base_reg->reg_type != BaseIndex + || i.index_reg)) + || (i.index_reg + && ((i.index_reg->reg_type & (RegXX | BaseIndex)) + != (RegXX | BaseIndex)))) + ok = 0; } else { @@ -4055,8 +4044,7 @@ if (!ok) { #if INFER_ADDR_PREFIX - if (flag_code != CODE_64BIT - && i.prefix[ADDR_PREFIX] == 0 && stackop_size != '\0') + if (i.prefix[ADDR_PREFIX] == 0) { i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE; i.prefixes += 1; @@ -4065,7 +4053,7 @@ FIXME. There doesn't seem to be any real need for separate Disp16 and Disp32 flags. The same goes for Imm16 and Imm32. Removing them would probably clean up the code quite a lot. */ - if (i.types[this_operand] & (Disp16 | Disp32)) + if (flag_code != CODE_64BIT && (i.types[this_operand] & (Disp16 | Disp32))) i.types[this_operand] ^= (Disp16 | Disp32); fudged = 1; goto tryprefix; @@ -4078,9 +4066,8 @@ as_bad (_("`%s' is not a valid %s bit base/index expression"), operand_string, flag_code_names[flag_code]); - return 0; } - return 1; + return ok; } /* Parse OPERAND_STRING into the i386_insn structure I. Returns non-zero @@ -4904,7 +4891,7 @@ } if (r != NULL - && (r->reg_flags & (RegRex64 | RegRex)) != 0 + && ((r->reg_flags & (RegRex64 | RegRex)) | (r->reg_type & Reg64)) != 0 && flag_code != CODE_64BIT) { return (const reg_entry *) NULL; diff -Naur /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/i386.exp 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/i386.exp --- /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/i386.exp 2004-05-12 05:06:10.000000000 +0200 +++ 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/i386.exp 2004-07-02 11:16:11.483954536 +0200 @@ -105,7 +105,9 @@ set ASFLAGS "$ASFLAGS --64" run_dump_test "x86_64" + run_dump_test "x86-64-addr32" run_dump_test "x86-64-opcode" + run_dump_test "x86-64-rip" run_list_test "x86-64-inval" "-al" set ASFLAGS "$old_ASFLAGS" diff -Naur /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-addr32.d 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86-64-addr32.d --- /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-addr32.d 1970-01-01 01:00:00.000000000 +0100 +++ 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86-64-addr32.d 2004-06-02 14:45:09.000000000 +0200 @@ -0,0 +1,13 @@ +#as: -J +#objdump: -drw +#name: x86-64 32-bit addressing + +.*: +file format elf64-x86-64 + +Disassembly of section .text: + +0+000 <.text>: +[ ]*0:[ ]+67 48 8d 80 00 00 00 00[ ]+addr32[ ]+lea[ ]+0x0\(%[re]ax\),%rax.* +[ ]*8:[ ]+67 49 8d 80 00 00 00 00[ ]+addr32[ ]+lea[ ]+0x0\(%r8d?\),%rax.* +[ ]*10:[ ]+67 48 8d 05 00 00 00 00[ ]+addr32[ ]+lea[ ]+0\(%[re]ip\),%rax.* +[ ]*18:[ ]+67 48 8d 04 25 00 00 00 00[ ]+addr32[ ]+lea[ ]+0x0,%rax.* diff -Naur /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-addr32.s 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86-64-addr32.s --- /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-addr32.s 1970-01-01 01:00:00.000000000 +0100 +++ 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86-64-addr32.s 2004-06-02 14:05:47.000000000 +0200 @@ -0,0 +1,5 @@ +.text + lea symbol(%eax), %rax + lea symbol(%r8d), %rax + addr32 lea symbol(%rip), %rax + addr32 lea symbol, %rax diff -Naur /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86_64.d 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86_64.d --- /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86_64.d 2001-06-12 04:03:10.000000000 +0200 +++ 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86_64.d 2004-06-30 15:44:44.000000000 +0200 @@ -37,7 +37,7 @@ [ ]+5a: 44 0f 20 c0[ ]+mov[ ]+%cr8,%rax [ ]+5e: 44 0f 22 c0[ ]+mov[ ]+%rax,%cr8 [ ]+62: f3 48 a5[ ]+repz movsq %ds:\(%rsi\),%es:\(%rdi\) -[ ]+65: f3 66 a5[ ]+repz movsw %ds:\(%esi\),%es:\(%edi\) +[ ]+65: f3 66 a5[ ]+repz movsw %ds:\(%rsi\),%es:\(%rdi\) [ ]+68: f3 48 a5[ ]+repz movsq %ds:\(%rsi\),%es:\(%rdi\) [ ]+6b: b0 11[ ]+mov[ ]+\$0x11,%al [ ]+6d: b4 11[ ]+mov[ ]+\$0x11,%ah diff -Naur /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-rip.d 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86-64-rip.d --- /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-rip.d 1970-01-01 01:00:00.000000000 +0100 +++ 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86-64-rip.d 2004-06-02 14:13:15.000000000 +0200 @@ -0,0 +1,13 @@ +#as: -J +#objdump: -drw +#name: x86-64 rip addressing + +.*: +file format elf64-x86-64 + +Disassembly of section .text: + +0+000 <.text>: +[ ]*0:[ ]+8d 05 00 00 00 00[ ]+lea[ ]+0\(%rip\),%eax[ ]*(#.*)? +[ ]*6:[ ]+8d 05 11 11 11 11[ ]+lea[ ]+286331153\(%rip\),%eax[ ]*(#.*)? +[ ]*c:[ ]+8d 05 01 00 00 00[ ]+lea[ ]+1\(%rip\),%eax[ ]*(#.*)? +[ ]*12:[ ]+8d 05 00 00 00 00[ ]+lea[ ]+0\(%rip\),%eax[ ]*(#.*)? diff -Naur /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-rip.s 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86-64-rip.s --- /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-rip.s 1970-01-01 01:00:00.000000000 +0100 +++ 2004-07-02.08.43-fixes/gas/testsuite/gas/i386/x86-64-rip.s 2004-06-02 12:00:40.000000000 +0200 @@ -0,0 +1,5 @@ +.text + leal symbol(%rip), %eax + leal 0x11111111(%rip), %eax + leal 1(%rip), %eax + leal (%rip), %eax diff -Naur /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/opcodes/i386-dis.c 2004-07-02.08.43-fixes/opcodes/i386-dis.c --- /home/jbeulich/src/binutils/mainline/2004-07-02.08.43/opcodes/i386-dis.c 2004-06-28 16:52:05.000000000 +0200 +++ 2004-07-02.08.43-fixes/opcodes/i386-dis.c 2004-07-02 11:18:32.266552328 +0200 @@ -3166,7 +3166,7 @@ if ((base & 7) == 5) { havebase = 0; - if (mode_64bit && !havesib && (sizeflag & AFLAG)) + if (mode_64bit && !havesib) riprel = 1; disp = get32s (); } @@ -3856,8 +3856,8 @@ const char *s; *obufp++ = open_char; - USED_REX (REX_MODE64); - if (rex & REX_MODE64) + used_prefixes |= (prefixes & PREFIX_ADDR); + if (mode_64bit) { if (!(sizeflag & AFLAG)) s = names32[code - eAX_reg]; @@ -3939,15 +3939,17 @@ static void OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) { - int add = 0; - USED_REX (REX_EXTX); - if (rex & REX_EXTX) - add = 8; used_prefixes |= (prefixes & PREFIX_DATA); if (prefixes & PREFIX_DATA) - sprintf (scratchbuf, "%%xmm%d", reg + add); + { + int add = 0; + USED_REX (REX_EXTX); + if (rex & REX_EXTX) + add = 8; + sprintf (scratchbuf, "%%xmm%d", reg + add); + } else - sprintf (scratchbuf, "%%mm%d", reg + add); + sprintf (scratchbuf, "%%mm%d", reg); oappend (scratchbuf + intel_syntax); } @@ -3965,24 +3967,26 @@ static void OP_EM (int bytemode, int sizeflag) { - int add = 0; if (mod != 3) { OP_E (bytemode, sizeflag); return; } - USED_REX (REX_EXTZ); - if (rex & REX_EXTZ) - add = 8; /* Skip mod/rm byte. */ MODRM_CHECK; codep++; used_prefixes |= (prefixes & PREFIX_DATA); if (prefixes & PREFIX_DATA) - sprintf (scratchbuf, "%%xmm%d", rm + add); + { + int add = 0; + USED_REX (REX_EXTZ); + if (rex & REX_EXTZ) + add = 8; + sprintf (scratchbuf, "%%xmm%d", rm + add); + } else - sprintf (scratchbuf, "%%mm%d", rm + add); + sprintf (scratchbuf, "%%mm%d", rm); oappend (scratchbuf + intel_syntax); }
Attachment:
binutils-mainline-x86_64.patch
Description: Binary data
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |