forked from OSchip/llvm-project
[X86] Improve code size on X86 segment moves
Moves of a value to a segment register from a 16-bit register is equivalent to one from it's corresponding 32-bit register. Match gas's behavior and rewrite instructions to the shorter of equivalent forms. Reviewers: rnk, ab Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D23166 llvm-svn: 278031
This commit is contained in:
parent
9d09275fa6
commit
f45fd2ba87
|
@ -2331,6 +2331,30 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
|||
static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
|
||||
}
|
||||
|
||||
// Moving a 32 or 16 bit value into a segment register has the same
|
||||
// behavior. Modify such instructions to always take shorter form.
|
||||
if ((Name == "mov" || Name == "movw" || Name == "movl") &&
|
||||
(Operands.size() == 3)) {
|
||||
X86Operand &Op1 = (X86Operand &)*Operands[1];
|
||||
X86Operand &Op2 = (X86Operand &)*Operands[2];
|
||||
SMLoc Loc = Op1.getEndLoc();
|
||||
if (Op1.isReg() && Op2.isReg() &&
|
||||
X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
|
||||
Op2.getReg()) &&
|
||||
(X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
|
||||
X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
|
||||
// Change instruction name to match new instruction.
|
||||
if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
|
||||
Name = is16BitMode() ? "movw" : "movl";
|
||||
Operands[0] = X86Operand::CreateToken(Name, NameLoc);
|
||||
}
|
||||
// Select the correct equivalent 16-/32-bit source register.
|
||||
unsigned Reg =
|
||||
getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
|
||||
Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
|
||||
}
|
||||
}
|
||||
|
||||
// This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
|
||||
// "outb %al, %dx". Out doesn't take a memory form, but this is a widely
|
||||
// documented form in various unofficial manuals, so a lot of code uses it.
|
||||
|
|
|
@ -256,10 +256,22 @@ cmovnae %bx,%bx
|
|||
// CHECK: encoding: [0x67,0x8c,0x08]
|
||||
movw %cs, (%eax)
|
||||
|
||||
// CHECK: movl %eax, %cs
|
||||
// CHECK: encoding: [0x66,0x8e,0xc8]
|
||||
// CHECK: movw %ax, %cs
|
||||
// CHECK: encoding: [0x8e,0xc8]
|
||||
movl %eax, %cs
|
||||
|
||||
// CHECK: movw %ax, %cs
|
||||
// CHECK: encoding: [0x8e,0xc8]
|
||||
mov %eax, %cs
|
||||
|
||||
// CHECK: movw %ax, %cs
|
||||
// CHECK: encoding: [0x8e,0xc8]
|
||||
movw %ax, %cs
|
||||
|
||||
// CHECK: movw %ax, %cs
|
||||
// CHECK: encoding: [0x8e,0xc8]
|
||||
mov %ax, %cs
|
||||
|
||||
// CHECK: movl (%eax), %cs
|
||||
// CHECK: encoding: [0x67,0x66,0x8e,0x08]
|
||||
movl (%eax), %cs
|
||||
|
|
|
@ -367,6 +367,18 @@ cmovnae %bx,%bx
|
|||
// CHECK: encoding: [0x8e,0xc8]
|
||||
movl %eax, %cs
|
||||
|
||||
// CHECK: movl %eax, %cs
|
||||
// CHECK: encoding: [0x8e,0xc8]
|
||||
movw %ax, %cs
|
||||
|
||||
// CHECK: movl %eax, %cs
|
||||
// CHECK: encoding: [0x8e,0xc8]
|
||||
mov %eax, %cs
|
||||
|
||||
// CHECK: movl %eax, %cs
|
||||
// CHECK: encoding: [0x8e,0xc8]
|
||||
mov %ax, %cs
|
||||
|
||||
// CHECK: movl (%eax), %cs
|
||||
// CHECK: encoding: [0x8e,0x08]
|
||||
movl (%eax), %cs
|
||||
|
|
Loading…
Reference in New Issue