mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
[x86] Fix MOV8ao8 et al for 16-bit mode, fix up disassembler to understand
It seems there is no separate instruction class for having AdSize *and* OpSize bits set, which is required in order to disambiguate between all these instructions. So add that to the disassembler. Hm, perhaps we do need an AdSize16 bit after all? git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198759 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4f32ce2436
commit
aab59870a4
@ -92,6 +92,8 @@ enum attributeBits {
|
||||
"operands change width") \
|
||||
ENUM_ENTRY(IC_ADSIZE, 3, "requires an ADSIZE prefix, so " \
|
||||
"operands change width") \
|
||||
ENUM_ENTRY(IC_OPSIZE_ADSIZE, 3, "requires both OPSIZE and ADSIZE " \
|
||||
"prefixes") \
|
||||
ENUM_ENTRY(IC_XD, 2, "may say something about the opcode " \
|
||||
"but not the operands") \
|
||||
ENUM_ENTRY(IC_XS, 2, "may say something about the opcode " \
|
||||
|
@ -1165,11 +1165,16 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
||||
|
||||
// Emit the address size opcode prefix as needed.
|
||||
bool need_address_override;
|
||||
// The AdSize prefix is only for 32-bit and 64-bit modes; in 16-bit mode we
|
||||
// need the address override only for JECXZ instead. Since it's only one
|
||||
// instruction, we special-case it rather than introducing an AdSize16 bit.
|
||||
// The AdSize prefix is only for 32-bit and 64-bit modes. Hm, perhaps we
|
||||
// should introduce an AdSize16 bit instead of having seven special cases?
|
||||
if ((!is16BitMode() && TSFlags & X86II::AdSize) ||
|
||||
(is16BitMode() && MI.getOpcode() == X86::JECXZ_32)) {
|
||||
(is16BitMode() && (MI.getOpcode() == X86::JECXZ_32 ||
|
||||
MI.getOpcode() == X86::MOV8o8a ||
|
||||
MI.getOpcode() == X86::MOV16o16a ||
|
||||
MI.getOpcode() == X86::MOV32o32a ||
|
||||
MI.getOpcode() == X86::MOV8ao8 ||
|
||||
MI.getOpcode() == X86::MOV16ao16 ||
|
||||
MI.getOpcode() == X86::MOV32ao32))) {
|
||||
need_address_override = true;
|
||||
} else if (MemOperand == -1) {
|
||||
need_address_override = false;
|
||||
|
@ -1140,29 +1140,49 @@ def MOV64mi32 : RIi32<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
|
||||
let hasSideEffects = 0 in {
|
||||
|
||||
/// moffs8, moffs16 and moffs32 versions of moves. The immediate is a
|
||||
/// 32-bit offset from the PC. These are only valid in x86-32 mode.
|
||||
/// 32-bit offset from the segment base. These are only valid in x86-32 mode.
|
||||
let SchedRW = [WriteALU] in {
|
||||
let mayLoad = 1 in {
|
||||
def MOV8o8a : Ii32 <0xA0, RawFrm, (outs), (ins offset8:$src),
|
||||
"mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
|
||||
Requires<[Not64BitMode]>;
|
||||
Requires<[In32BitMode]>;
|
||||
def MOV16o16a : Ii32 <0xA1, RawFrm, (outs), (ins offset16:$src),
|
||||
"mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>, OpSize,
|
||||
Requires<[Not64BitMode]>;
|
||||
Requires<[In32BitMode]>;
|
||||
def MOV32o32a : Ii32 <0xA1, RawFrm, (outs), (ins offset32:$src),
|
||||
"mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
|
||||
OpSize16, Requires<[Not64BitMode]>;
|
||||
OpSize16, Requires<[In32BitMode]>;
|
||||
|
||||
def MOV8o8a_16 : Ii16 <0xA0, RawFrm, (outs), (ins offset8:$src),
|
||||
"mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
|
||||
AdSize, Requires<[In16BitMode]>;
|
||||
def MOV16o16a_16 : Ii16 <0xA1, RawFrm, (outs), (ins offset16:$src),
|
||||
"mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>, OpSize,
|
||||
AdSize, Requires<[In16BitMode]>;
|
||||
def MOV32o32a_16 : Ii16 <0xA1, RawFrm, (outs), (ins offset32:$src),
|
||||
"mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
|
||||
AdSize, OpSize16, Requires<[In16BitMode]>;
|
||||
}
|
||||
let mayStore = 1 in {
|
||||
def MOV8ao8 : Ii32 <0xA2, RawFrm, (outs offset8:$dst), (ins),
|
||||
"mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
|
||||
Requires<[Not64BitMode]>;
|
||||
Requires<[In32BitMode]>;
|
||||
def MOV16ao16 : Ii32 <0xA3, RawFrm, (outs offset16:$dst), (ins),
|
||||
"mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>, OpSize,
|
||||
Requires<[Not64BitMode]>;
|
||||
Requires<[In32BitMode]>;
|
||||
def MOV32ao32 : Ii32 <0xA3, RawFrm, (outs offset32:$dst), (ins),
|
||||
"mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
|
||||
OpSize16, Requires<[Not64BitMode]>;
|
||||
OpSize16, Requires<[In32BitMode]>;
|
||||
|
||||
def MOV8ao8_16 : Ii16 <0xA2, RawFrm, (outs offset8:$dst), (ins),
|
||||
"mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
|
||||
AdSize, Requires<[In16BitMode]>;
|
||||
def MOV16ao16_16 : Ii16 <0xA3, RawFrm, (outs offset16:$dst), (ins),
|
||||
"mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>, OpSize,
|
||||
AdSize, Requires<[In16BitMode]>;
|
||||
def MOV32ao32_16 : Ii16 <0xA3, RawFrm, (outs offset32:$dst), (ins),
|
||||
"mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
|
||||
OpSize16, AdSize, Requires<[In16BitMode]>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,17 @@
|
||||
// CHECK: shll %eax # encoding: [0x66,0xd1,0xe0]
|
||||
sal $1, %eax
|
||||
|
||||
// moffset forms of moves
|
||||
|
||||
// CHECK: movb 0, %al # encoding: [0xa0,0x00,0x00]
|
||||
movb 0, %al
|
||||
|
||||
// CHECK: movw 0, %ax # encoding: [0xa1,0x00,0x00]
|
||||
movw 0, %ax
|
||||
|
||||
// CHECK: movl 0, %eax # encoding: [0x66,0xa1,0x00,0x00]
|
||||
movl 0, %eax
|
||||
|
||||
into
|
||||
// CHECK: into
|
||||
// CHECK: encoding: [0xce]
|
||||
|
@ -94,8 +94,11 @@ static inline bool inheritsFrom(InstructionContext child,
|
||||
inheritsFrom(child, IC_64BIT_XD) ||
|
||||
inheritsFrom(child, IC_64BIT_XS));
|
||||
case IC_OPSIZE:
|
||||
return inheritsFrom(child, IC_64BIT_OPSIZE);
|
||||
return (inheritsFrom(child, IC_64BIT_OPSIZE) ||
|
||||
inheritsFrom(child, IC_OPSIZE_ADSIZE));
|
||||
case IC_ADSIZE:
|
||||
return inheritsFrom(child, IC_OPSIZE_ADSIZE);
|
||||
case IC_OPSIZE_ADSIZE:
|
||||
case IC_64BIT_ADSIZE:
|
||||
return false;
|
||||
case IC_XD:
|
||||
|
@ -456,6 +456,8 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||
else if (HasOpSizePrefix &&
|
||||
(Prefix == X86Local::XS || Prefix == X86Local::T8XS))
|
||||
insnContext = IC_XS_OPSIZE;
|
||||
else if (HasOpSizePrefix && HasAdSizePrefix)
|
||||
insnContext = IC_OPSIZE_ADSIZE;
|
||||
else if (HasOpSizePrefix)
|
||||
insnContext = IC_OPSIZE;
|
||||
else if (HasAdSizePrefix)
|
||||
|
Loading…
Reference in New Issue
Block a user