From bb803fd76e6204f45e425367b657fe39d655d215 Mon Sep 17 00:00:00 2001 From: Michael Kuperstein Date: Sun, 5 Jul 2015 10:25:41 +0000 Subject: [PATCH] [X86] Fix incorrect/inefficient pushw encodings for x86-64 targets Correctly support assembling "pushw $imm8" on x86-64 targets. Also some cleanup of the PUSH instructions (PUSH64i16 and PUSHi16 actually represent the same instruction) This fixes PR23996 Patch by: david.l.kreitzer@intel.com Differential Revision: http://reviews.llvm.org/D10878 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241404 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 1 - lib/Target/X86/X86InstrInfo.td | 12 +++------ test/MC/ELF/relax-arith.s | 8 ++++++ test/MC/ELF/relax-arith2.s | 12 +++++++++ test/MC/ELF/relax-arith4.s | 25 +++++++++++++++++++ 5 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 test/MC/ELF/relax-arith4.s diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 3e0dc142460..629802f5dc5 100644 --- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -220,7 +220,6 @@ static unsigned getRelaxedOpcodeArith(unsigned Op) { case X86::PUSH32i8: return X86::PUSHi32; case X86::PUSH16i8: return X86::PUSHi16; case X86::PUSH64i8: return X86::PUSH64i32; - case X86::PUSH64i16: return X86::PUSH64i32; } } diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 6f38cb8eaf3..61b474588b7 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1028,14 +1028,13 @@ def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[], IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>; def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm), - "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16, - Requires<[Not64BitMode]>; + "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16; +def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm), + "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16; + def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm), "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32, Requires<[Not64BitMode]>; -def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm), - "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16, - Requires<[Not64BitMode]>; def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm), "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32, Requires<[Not64BitMode]>; @@ -1081,9 +1080,6 @@ let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1, SchedRW = [WriteStore] in { def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm), "push{q}\t$imm", [], IIC_PUSH_IMM>, Requires<[In64BitMode]>; -def PUSH64i16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm), - "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16, - Requires<[In64BitMode]>; def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm), "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32, Requires<[In64BitMode]>; diff --git a/test/MC/ELF/relax-arith.s b/test/MC/ELF/relax-arith.s index d4f37a9ddf9..15e44ebff7e 100644 --- a/test/MC/ELF/relax-arith.s +++ b/test/MC/ELF/relax-arith.s @@ -115,3 +115,11 @@ bar: cmpl $foo, bar cmp $foo, %rbx cmpq $foo, bar + +// CHECK: Disassembly of section push: +// CHECK-NEXT: push: +// CHECK-NEXT: 0: 66 68 00 00 pushw $0 +// CHECK-NEXT: 4: 68 00 00 00 00 pushq $0 + .section push,"x" + pushw $foo + push $foo diff --git a/test/MC/ELF/relax-arith2.s b/test/MC/ELF/relax-arith2.s index a6c55adf894..b05418482e3 100644 --- a/test/MC/ELF/relax-arith2.s +++ b/test/MC/ELF/relax-arith2.s @@ -116,3 +116,15 @@ bar: cmpl $1, bar cmp $-1, %rbx cmpq $42, bar + +// CHECK: Disassembly of section push: +// CHECK-NEXT: push: +// CHECK-NEXT: 0: 66 6a 80 pushw $-128 +// CHECK-NEXT: 3: 66 6a 7f pushw $127 +// CHECK-NEXT: 6: 6a 80 pushq $-128 +// CHECK-NEXT: 8: 6a 7f pushq $127 + .section push,"x" + pushw $-128 + pushw $127 + push $-128 + push $127 diff --git a/test/MC/ELF/relax-arith4.s b/test/MC/ELF/relax-arith4.s new file mode 100644 index 00000000000..3fd3cadb76a --- /dev/null +++ b/test/MC/ELF/relax-arith4.s @@ -0,0 +1,25 @@ +// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - | llvm-objdump -d - | FileCheck %s + +// Test for proper instruction relaxation behavior for the push $imm +// instruction forms. This is the 32-bit version of the push $imm tests from +// relax-arith.s and relax-arith2.s. + +// CHECK: Disassembly of section push8: +// CHECK-NEXT: push8: +// CHECK-NEXT: 0: 66 6a 80 pushw $-128 +// CHECK-NEXT: 3: 66 6a 7f pushw $127 +// CHECK-NEXT: 6: 6a 80 pushl $-128 +// CHECK-NEXT: 8: 6a 7f pushl $127 + .section push8,"x" + pushw $-128 + pushw $127 + push $-128 + push $127 + +// CHECK: Disassembly of section push32: +// CHECK-NEXT: push32: +// CHECK-NEXT: 0: 66 68 00 00 pushw $0 +// CHECK-NEXT: 4: 68 00 00 00 00 pushl $0 + .section push32,"x" + pushw $foo + push $foo -- 2.34.1