[llvm] r278031 - [X86] Improve code size on X86 segment moves

Nirav Dave via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 8 11:01:04 PDT 2016


Author: niravd
Date: Mon Aug  8 13:01:04 2016
New Revision: 278031

URL: http://llvm.org/viewvc/llvm-project?rev=278031&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/test/MC/X86/x86-16.s
    llvm/trunk/test/MC/X86/x86-32.s

Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=278031&r1=278030&r2=278031&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Mon Aug  8 13:01:04 2016
@@ -2331,6 +2331,30 @@ bool X86AsmParser::ParseInstruction(Pars
     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.

Modified: llvm/trunk/test/MC/X86/x86-16.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-16.s?rev=278031&r1=278030&r2=278031&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/x86-16.s (original)
+++ llvm/trunk/test/MC/X86/x86-16.s Mon Aug  8 13:01:04 2016
@@ -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

Modified: llvm/trunk/test/MC/X86/x86-32.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-32.s?rev=278031&r1=278030&r2=278031&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/x86-32.s (original)
+++ llvm/trunk/test/MC/X86/x86-32.s Mon Aug  8 13:01:04 2016
@@ -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




More information about the llvm-commits mailing list