Index: llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -366,13 +366,15 @@ // OpSize - OpSizeFixed implies instruction never needs a 0x66 prefix. // OpSize16 means this is a 16-bit instruction and needs 0x66 prefix in // 32-bit mode. OpSize32 means this is a 32-bit instruction needs a 0x66 - // prefix in 16-bit mode. + // prefix in 16-bit mode. OpSizeIgnore means that the instruction may + // take a optional 0x66 byte but should not emit with one. OpSizeShift = 7, OpSizeMask = 0x3 << OpSizeShift, - OpSizeFixed = 0 << OpSizeShift, - OpSize16 = 1 << OpSizeShift, - OpSize32 = 2 << OpSizeShift, + OpSizeFixed = 0 << OpSizeShift, + OpSize16 = 1 << OpSizeShift, + OpSize32 = 2 << OpSizeShift, + OpSizeIgnore = 3 << OpSizeShift, // AsSize - AdSizeX implies this instruction determines its need of 0x67 // prefix from a normal ModRM memory operand. The other types indicate that Index: llvm/lib/Target/X86/X86InstrFormats.td =================================================================== --- llvm/lib/Target/X86/X86InstrFormats.td +++ llvm/lib/Target/X86/X86InstrFormats.td @@ -157,9 +157,10 @@ class OperandSize val> { bits<2> Value = val; } -def OpSizeFixed : OperandSize<0>; // Never needs a 0x66 prefix. -def OpSize16 : OperandSize<1>; // Needs 0x66 prefix in 32-bit mode. -def OpSize32 : OperandSize<2>; // Needs 0x66 prefix in 16-bit mode. +def OpSizeFixed : OperandSize<0>; // Never needs a 0x66 prefix. +def OpSize16 : OperandSize<1>; // Needs 0x66 prefix in 32-bit mode. +def OpSize32 : OperandSize<2>; // Needs 0x66 prefix in 16-bit mode. +def OpSizeIgnore : OperandSize<3>; // Takes 0x66 prefix, never emits. // Address size for encodings that change based on mode. class AddressSize val> { @@ -174,6 +175,7 @@ // emitter that various prefix bytes are required. class OpSize16 { OperandSize OpSize = OpSize16; } class OpSize32 { OperandSize OpSize = OpSize32; } +class OpSizeIgnore { OperandSize OpSize = OpSizeIgnore; } class AdSize16 { AddressSize AdSize = AdSize16; } class AdSize32 { AddressSize AdSize = AdSize32; } class AdSize64 { AddressSize AdSize = AdSize64; } Index: llvm/lib/Target/X86/X86InstrInfo.td =================================================================== --- llvm/lib/Target/X86/X86InstrInfo.td +++ llvm/lib/Target/X86/X86InstrInfo.td @@ -3158,8 +3158,8 @@ // Force mov without a suffix with a segment and mem to prefer the 'l' form of // the move. All segment/mem forms are equivalent, this has the shortest // encoding. -def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV32sm SEGMENT_REG:$seg, i32mem:$mem), 0>; -def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV32ms i32mem:$mem, SEGMENT_REG:$seg), 0>; +def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV16sm SEGMENT_REG:$seg, i16mem:$mem), 0>; +def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV16ms i16mem:$mem, SEGMENT_REG:$seg), 0>; // Match 'movq , ' as an alias for movabsq. def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>; Index: llvm/lib/Target/X86/X86InstrSystem.td =================================================================== --- llvm/lib/Target/X86/X86InstrSystem.td +++ llvm/lib/Target/X86/X86InstrSystem.td @@ -175,11 +175,7 @@ "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV_REG_SR>; let mayStore = 1 in { def MOV16ms : I<0x8C, MRMDestMem, (outs), (ins i16mem:$dst, SEGMENT_REG:$src), - "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV_MEM_SR>, OpSize16; -def MOV32ms : I<0x8C, MRMDestMem, (outs), (ins i32mem:$dst, SEGMENT_REG:$src), - "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV_MEM_SR>, OpSize32; -def MOV64ms : RI<0x8C, MRMDestMem, (outs), (ins i64mem:$dst, SEGMENT_REG:$src), - "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV_MEM_SR>; + "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV_MEM_SR>, OpSizeIgnore; } def MOV16sr : I<0x8E, MRMSrcReg, (outs SEGMENT_REG:$dst), (ins GR16:$src), "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV_SR_REG>, OpSize16; @@ -189,11 +185,7 @@ "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV_SR_REG>; let mayLoad = 1 in { def MOV16sm : I<0x8E, MRMSrcMem, (outs SEGMENT_REG:$dst), (ins i16mem:$src), - "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV_SR_MEM>, OpSize16; -def MOV32sm : I<0x8E, MRMSrcMem, (outs SEGMENT_REG:$dst), (ins i32mem:$src), - "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV_SR_MEM>, OpSize32; -def MOV64sm : RI<0x8E, MRMSrcMem, (outs SEGMENT_REG:$dst), (ins i64mem:$src), - "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV_SR_MEM>; + "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV_SR_MEM>, OpSizeIgnore; } } // SchedRW Index: llvm/lib/Target/X86/X86SchedSandyBridge.td =================================================================== --- llvm/lib/Target/X86/X86SchedSandyBridge.td +++ llvm/lib/Target/X86/X86SchedSandyBridge.td @@ -1549,7 +1549,7 @@ let ResourceCycles = [1,1]; } def: InstRW<[SBWriteResGroup49], (instregex "JMP(16|32|64)m")>; -def: InstRW<[SBWriteResGroup49], (instregex "MOV64sm")>; +def: InstRW<[SBWriteResGroup49], (instregex "MOV16sm")>; def SBWriteResGroup50 : SchedWriteRes<[SBPort23,SBPort05]> { let Latency = 6; Index: llvm/test/MC/Disassembler/X86/x86-16.txt =================================================================== --- llvm/test/MC/Disassembler/X86/x86-16.txt +++ llvm/test/MC/Disassembler/X86/x86-16.txt @@ -207,7 +207,7 @@ # CHECK: movw %cs, %ax 0x8c 0xc8 -# CHECK: movl %cs, (%eax) +# CHECK: movw %cs, (%eax) 0x67 0x66 0x8c 0x08 # CHECK: movw %cs, (%eax) @@ -216,7 +216,7 @@ # CHECK: movl %eax, %cs 0x66 0x8e 0xc8 -# CHECK: movl (%eax), %cs +# CHECK: movw (%eax), %cs 0x67 0x66 0x8e 0x08 # CHECK: movw (%eax), %cs Index: llvm/test/MC/X86/x86-16.s =================================================================== --- llvm/test/MC/X86/x86-16.s +++ llvm/test/MC/X86/x86-16.s @@ -248,9 +248,9 @@ // CHECK: encoding: [0x8c,0xc8] movw %cs, %ax -// CHECK: movl %cs, (%eax) -// CHECK: encoding: [0x67,0x66,0x8c,0x08] - movl %cs, (%eax) +// CHECK: movw %cs, (%eax) +// CHECK: encoding: [0x67,0x8c,0x08] + mov %cs, (%eax) // CHECK: movw %cs, (%eax) // CHECK: encoding: [0x67,0x8c,0x08] @@ -272,9 +272,9 @@ // CHECK: encoding: [0x8e,0xc8] mov %ax, %cs -// CHECK: movl (%eax), %cs -// CHECK: encoding: [0x67,0x66,0x8e,0x08] - movl (%eax), %cs +// CHECK: movw (%eax), %cs +// CHECK: encoding: [0x67,0x8e,0x08] + mov (%eax), %cs // CHECK: movw (%eax), %cs // CHECK: encoding: [0x67,0x8e,0x08] Index: llvm/test/MC/X86/x86-32.s =================================================================== --- llvm/test/MC/X86/x86-32.s +++ llvm/test/MC/X86/x86-32.s @@ -355,12 +355,12 @@ // CHECK: encoding: [0x66,0x8c,0xc8] movw %cs, %ax -// CHECK: movl %cs, (%eax) +// CHECK: movw %cs, (%eax) // CHECK: encoding: [0x8c,0x08] - movl %cs, (%eax) + mov %cs, (%eax) // CHECK: movw %cs, (%eax) -// CHECK: encoding: [0x66,0x8c,0x08] +// CHECK: encoding: [0x8c,0x08] movw %cs, (%eax) // CHECK: movl %eax, %cs @@ -379,12 +379,12 @@ // CHECK: encoding: [0x8e,0xc8] mov %ax, %cs -// CHECK: movl (%eax), %cs +// CHECK: movw (%eax), %cs // CHECK: encoding: [0x8e,0x08] - movl (%eax), %cs + mov (%eax), %cs // CHECK: movw (%eax), %cs -// CHECK: encoding: [0x66,0x8e,0x08] +// CHECK: encoding: [0x8e,0x08] movw (%eax), %cs // radr://8033374 Index: llvm/test/MC/X86/x86-64.s =================================================================== --- llvm/test/MC/X86/x86-64.s +++ llvm/test/MC/X86/x86-64.s @@ -1082,8 +1082,8 @@ // rdar://8208615 -mov (%rsi), %gs // CHECK: movl (%rsi), %gs # encoding: [0x8e,0x2e] -mov %gs, (%rsi) // CHECK: movl %gs, (%rsi) # encoding: [0x8c,0x2e] +mov (%rsi), %gs // CHECK: movw (%rsi), %gs # encoding: [0x8e,0x2e] +mov %gs, (%rsi) // CHECK: movw %gs, (%rsi) # encoding: [0x8c,0x2e] // rdar://8431864