diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2005-06-20 23:18:39 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2005-06-20 23:18:39 +0000 |
commit | b300c311a0740cbe64b5781b34d2f3a9c778273f (patch) | |
tree | baa95ec6806b2a612df96a2de97ba3770f312e40 /gas/config/tc-i386.c | |
parent | 973a3492d553c8b18c8a3257b4874253c0efa68a (diff) | |
download | gdb-b300c311a0740cbe64b5781b34d2f3a9c778273f.zip gdb-b300c311a0740cbe64b5781b34d2f3a9c778273f.tar.gz gdb-b300c311a0740cbe64b5781b34d2f3a9c778273f.tar.bz2 |
gas/
2005-06-20 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-20 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-20 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.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r-- | gas/config/tc-i386.c | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 18df9cf..76c43f9 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.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; } } |