This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: PATCH: PR 1013: x86_64 assembler doesn't tak 64bit address
- From: "H. J. Lu" <hjl at lucon dot org>
- To: Jan Beulich <JBeulich at novell dot com>
- Cc: binutils at sources dot redhat dot com
- Date: Fri, 17 Jun 2005 13:17:56 -0700
- Subject: Re: PATCH: PR 1013: x86_64 assembler doesn't tak 64bit address
- References: <s2b28f29.094@lyle.provo.novell.com>
On Fri, Jun 17, 2005 at 08:52:19AM -0600, Jan Beulich wrote:
> >+{ "mov", 2, 0xa0, X, Cpu64, bwlq_Suf|D|W, { Disp64, Acc, 0 } },
>
> One more note: If you change this here, you'll also want to add
>
> { "movq", 2, 0xa0, X, Cpu64, bwlq_Suf|D|W, { Disp64, Acc, 0 } },
>
> further down the file.
>
Here is the updated patch.
H.J.
----
gas/
2005-06-17 H.J. Lu <hongjiu.lu@intel.com>
PR 1013
* config/tc-i386.c (md_assemble): Don't call optimize_disp on
movabs.
(optimize_disp): Optimize only if possible. Don't use 64bit
displacement on non-constants and do same on constants if
possible.
gas/testsuite/
2005-06-17 H.J. Lu <hongjiu.lu@intel.com>
PR 1013
* i386/x86_64.s: Add absolute 64bit addressing tests for mov.
* i386/x86_64.s: Updated.
include/opcode/
2005-06-17 H.J. Lu <hongjiu.lu@intel.com>
PR 1013
* i386.h (i386_optab): Update comments for 64bit addressing on
mov. Allow 64bit addressing for mov and movq.
--- binutils/gas/config/tc-i386.c.64 2005-06-14 13:39:10.000000000 -0700
+++ binutils/gas/config/tc-i386.c 2005-06-17 13:13:16.000000000 -0700
@@ -1399,7 +1399,11 @@ md_assemble (line)
if (i.imm_operands)
optimize_imm ();
- if (i.disp_operands)
+ /* Don't optimize displacement for movabs since it only takes 64bit
+ displacement. */
+ if (i.disp_operands
+ && (flag_code != CODE_64BIT
+ || strcmp (mnemonic, "movabs") != 0))
optimize_disp ();
/* Next, we find a template that matches the given insn,
@@ -2055,43 +2059,51 @@ optimize_disp ()
int op;
for (op = i.operands; --op >= 0;)
- if ((i.types[op] & Disp) && i.op[op].disps->X_op == O_constant)
+ if (i.types[op] & Disp)
{
- offsetT disp = i.op[op].disps->X_add_number;
-
- if (i.types[op] & Disp16)
+ if (i.op[op].disps->X_op == O_constant)
{
- /* We know this operand is at most 16 bits, so
- convert to a signed 16 bit number before trying
- to see whether it will fit in an even smaller
- size. */
+ offsetT disp = i.op[op].disps->X_add_number;
- disp = (((disp & 0xffff) ^ 0x8000) - 0x8000);
- }
- else if (i.types[op] & Disp32)
- {
- /* We know this operand is at most 32 bits, so convert to a
- signed 32 bit number before trying to see whether it will
- fit in an even smaller size. */
- disp &= (((offsetT) 2 << 31) - 1);
- disp = (disp ^ ((offsetT) 1 << 31)) - ((addressT) 1 << 31);
- }
- if (!disp && (i.types[op] & BaseIndex))
- {
- i.types[op] &= ~Disp;
- i.op[op].disps = 0;
- i.disp_operands--;
- }
- else if (flag_code == CODE_64BIT)
- {
- if (fits_in_signed_long (disp))
- i.types[op] |= Disp32S;
- if (fits_in_unsigned_long (disp))
- i.types[op] |= Disp32;
+ if ((i.types[op] & Disp16)
+ && (disp & ~(offsetT) 0xffff) == 0)
+ {
+ /* If this operand is at most 16 bits, convert
+ to a signed 16 bit number and don't use 64bit
+ displacement. */
+ disp = (((disp & 0xffff) ^ 0x8000) - 0x8000);
+ i.types[op] &= ~Disp64;
+ }
+ if ((i.types[op] & Disp32)
+ && (disp & ~(((offsetT) 2 << 31) - 1)) == 0)
+ {
+ /* If this operand is at most 32 bits, convert
+ to a signed 32 bit number and don't use 64bit
+ displacement. */
+ disp &= (((offsetT) 2 << 31) - 1);
+ disp = (disp ^ ((offsetT) 1 << 31)) - ((addressT) 1 << 31);
+ i.types[op] &= ~Disp64;
+ }
+ if (!disp && (i.types[op] & BaseIndex))
+ {
+ i.types[op] &= ~Disp;
+ i.op[op].disps = 0;
+ i.disp_operands--;
+ }
+ else if (flag_code == CODE_64BIT)
+ {
+ if (fits_in_signed_long (disp))
+ i.types[op] |= Disp32S;
+ if (fits_in_unsigned_long (disp))
+ i.types[op] |= Disp32;
+ }
+ if ((i.types[op] & (Disp32 | Disp32S | Disp16))
+ && fits_in_signed_byte (disp))
+ i.types[op] |= Disp8;
}
- if ((i.types[op] & (Disp32 | Disp32S | Disp16))
- && fits_in_signed_byte (disp))
- i.types[op] |= Disp8;
+ else
+ /* We only support 64bit displacement on constants. */
+ i.types[op] &= ~Disp64;
}
}
--- binutils/gas/testsuite/gas/i386/x86_64.d.64 2005-03-17 12:31:20.000000000 -0800
+++ binutils/gas/testsuite/gas/i386/x86_64.d 2005-06-17 13:04:00.000000000 -0700
@@ -122,4 +122,22 @@ Disassembly of section .text:
1f0: 8b 04 25 00 00 00 00 mov[ ]+0x0,%eax
1f7: 8b 80 00 00 00 00[ ]+mov[ ]+0x0\(%rax\),%eax
1fd: 8b 05 00 00 00 00[ ]+mov[ ]+0\(%rip\),%eax.*
+
+0+203 <foo>:
+ 203: a0 11 22 33 44 55 66 77 88 mov[ ]+0x8877665544332211,%al
+ 20c: 66 a1 11 22 33 44 55 66 77 88 mov[ ]+0x8877665544332211,%ax
+ 216: a1 11 22 33 44 55 66 77 88 mov[ ]+0x8877665544332211,%eax
+ 21f: 48 a1 11 22 33 44 55 66 77 88 mov[ ]+0x8877665544332211,%rax
+ 229: a2 11 22 33 44 55 66 77 88 mov[ ]+%al,0x8877665544332211
+ 232: 66 a3 11 22 33 44 55 66 77 88 mov[ ]+%ax,0x8877665544332211
+ 23c: a3 11 22 33 44 55 66 77 88 mov[ ]+%eax,0x8877665544332211
+ 245: 48 a3 11 22 33 44 55 66 77 88 mov[ ]+%rax,0x8877665544332211
+ 24f: a0 11 22 33 44 55 66 77 88 mov[ ]+0x8877665544332211,%al
+ 258: 66 a1 11 22 33 44 55 66 77 88 mov[ ]+0x8877665544332211,%ax
+ 262: a1 11 22 33 44 55 66 77 88 mov[ ]+0x8877665544332211,%eax
+ 26b: 48 a1 11 22 33 44 55 66 77 88 mov[ ]+0x8877665544332211,%rax
+ 275: a2 11 22 33 44 55 66 77 88 mov[ ]+%al,0x8877665544332211
+ 27e: 66 a3 11 22 33 44 55 66 77 88 mov[ ]+%ax,0x8877665544332211
+ 288: a3 11 22 33 44 55 66 77 88 mov[ ]+%eax,0x8877665544332211
+ 291: 48 a3 11 22 33 44 55 66 77 88 mov[ ]+%rax,0x8877665544332211
#pass
--- binutils/gas/testsuite/gas/i386/x86_64.s.64 2005-03-17 12:31:20.000000000 -0800
+++ binutils/gas/testsuite/gas/i386/x86_64.s 2005-06-17 12:30:30.000000000 -0700
@@ -150,5 +150,25 @@ mov eax, [rax+symbol]
#RIP relative
mov eax, [rip+symbol]
+foo:
+.att_syntax
+#absolute 64bit addressing
+mov 0x8877665544332211,%al
+mov 0x8877665544332211,%ax
+mov 0x8877665544332211,%eax
+mov 0x8877665544332211,%rax
+mov %al,0x8877665544332211
+mov %ax,0x8877665544332211
+mov %eax,0x8877665544332211
+mov %rax,0x8877665544332211
+movb 0x8877665544332211,%al
+movw 0x8877665544332211,%ax
+movl 0x8877665544332211,%eax
+movq 0x8877665544332211,%rax
+movb %al,0x8877665544332211
+movw %ax,0x8877665544332211
+movl %eax,0x8877665544332211
+movq %rax,0x8877665544332211
+
# Get a good alignment.
.p2align 4,0
--- binutils/include/opcode/i386.h.64 2005-05-10 08:10:22.000000000 -0700
+++ binutils/include/opcode/i386.h 2005-06-17 13:12:20.000000000 -0700
@@ -83,12 +83,13 @@ static const template i386_optab[] =
/* Move instructions. */
#define MOV_AX_DISP32 0xa0
-/* In the 64bit mode the short form mov immediate is redefined to have
- 64bit displacement value. */
+/* We put the 64bit displacement first and we only mark constants
+ larger than 32bit as Disp64. */
+{ "mov", 2, 0xa0, X, Cpu64, bwlq_Suf|D|W, { Disp64, Acc, 0 } },
{ "mov", 2, 0xa0, X, CpuNo64,bwl_Suf|D|W, { Disp16|Disp32, Acc, 0 } },
{ "mov", 2, 0x88, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
/* In the 64bit mode the short form mov immediate is redefined to have
- 64bit displacement value. */
+ 64bit value. */
{ "mov", 2, 0xb0, X, 0, bwl_Suf|W|ShortForm, { EncImm, Reg8|Reg16|Reg32, 0 } },
{ "mov", 2, 0xc6, 0, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0 } },
{ "mov", 2, 0xb0, X, Cpu64, q_Suf|W|ShortForm, { Imm64, Reg64, 0 } },
@@ -1004,6 +1005,9 @@ static const template i386_optab[] =
{"movq", 2, 0x0f7f, X, CpuMMX, NoSuf|IgnoreSize|Modrm, { RegMMX, RegMMX|LongMem, 0 } },
{"movq", 2, 0xf30f7e,X,CpuSSE2,NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } },
{"movq", 2, 0x660fd6,X,CpuSSE2,NoSuf|IgnoreSize|Modrm, { RegXMM, RegXMM|LLongMem, 0 } },
+/* We put the 64bit displacement first and we only mark constants
+ larger than 32bit as Disp64. */
+{"movq", 2, 0xa0, X, Cpu64, NoSuf|D|W|Size64, { Disp64, Acc, 0 } },
{"movq", 2, 0x88, X, Cpu64, NoSuf|D|W|Modrm|Size64,{ Reg64, Reg64|AnyMem, 0 } },
{"movq", 2, 0xc6, 0, Cpu64, NoSuf|W|Modrm|Size64, { Imm32S, Reg64|WordMem, 0 } },
{"movq", 2, 0xb0, X, Cpu64, NoSuf|W|ShortForm|Size64,{ Imm64, Reg64, 0 } },