diff --git a/gas/ChangeLog b/gas/ChangeLog index fc33e1bcd5..af1cbbc0f1 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2005-06-20 H.J. Lu + + 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. + 2005-06-17 Jan Beulich * config/tc-i386.c (reloc): Also handle BFD_RELOC_64_PCREL. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 18df9cfe36..76c43f90d5 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1409,7 +1409,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, @@ -2065,43 +2069,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.op[op].disps->X_op == O_constant) + { + offsetT disp = i.op[op].disps->X_add_number; - if (i.types[op] & Disp16) - { - /* 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. */ - - disp = (((disp & 0xffff) ^ 0x8000) - 0x8000); + 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; } - 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] & (Disp32 | Disp32S | Disp16)) - && fits_in_signed_byte (disp)) - i.types[op] |= Disp8; + else + /* We only support 64bit displacement on constants. */ + i.types[op] &= ~Disp64; } } diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 1dd1ccf4c3..3340bfbf54 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-06-20 H.J. Lu + + PR 1013 + * i386/x86_64.s: Add absolute 64bit addressing tests for mov. + * i386/x86_64.s: Updated. + 2005-06-17 Jan Beulich * gas/i386/x86-64-pcrel.s: Add insn requiring 64-bit pc-relative diff --git a/gas/testsuite/gas/i386/x86_64.d b/gas/testsuite/gas/i386/x86_64.d index 7cea081b62..43b9132138 100644 --- a/gas/testsuite/gas/i386/x86_64.d +++ b/gas/testsuite/gas/i386/x86_64.d @@ -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 : + 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 diff --git a/gas/testsuite/gas/i386/x86_64.s b/gas/testsuite/gas/i386/x86_64.s index 4e94a502c7..812007ffae 100644 --- a/gas/testsuite/gas/i386/x86_64.s +++ b/gas/testsuite/gas/i386/x86_64.s @@ -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 diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 45a802652a..44e0493208 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,9 @@ +2005-06-20 H.J. Lu + + PR 1013 + * i386.h (i386_optab): Update comments for 64bit addressing on + mov. Allow 64bit addressing for mov and movq. + 2005-06-11 John David Anglin * hppa.h (pa_opcodes): Use cM and cX instead of cm and cx, diff --git a/include/opcode/i386.h b/include/opcode/i386.h index df1131df30..449ffee3fe 100644 --- a/include/opcode/i386.h +++ b/include/opcode/i386.h @@ -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 } },