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,
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;
}
}