diff options
| author | Craig Topper <craig.topper@gmail.com> | 2012-04-03 05:20:24 +0000 | 
|---|---|---|
| committer | Craig Topper <craig.topper@gmail.com> | 2012-04-03 05:20:24 +0000 | 
| commit | 7629d63bc432d8ecbc4632bc353709622dc8ea28 (patch) | |
| tree | 962b247102b346feeadbd14207315d05f16b2d64 /llvm/lib | |
| parent | eedc49c3d4701a6614ea6e804e29b957acedb9a7 (diff) | |
| download | bcm5719-llvm-7629d63bc432d8ecbc4632bc353709622dc8ea28.tar.gz bcm5719-llvm-7629d63bc432d8ecbc4632bc353709622dc8ea28.zip  | |
Add support for AVX enhanced comparison predicates. Patch from Kay Tiong Khoo.
llvm-svn: 153935
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86AsmPrinter.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrSSE.td | 78 | 
5 files changed, 49 insertions, 41 deletions
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index fbd81d2d009..602087756b2 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -1527,6 +1527,9 @@ static int readOperands(struct InternalInstruction* insn) {        if (insn->spec->operands[index].type == TYPE_IMM3 &&            insn->immediates[insn->numImmediatesConsumed - 1] > 7)          return -1; +      if (insn->spec->operands[index].type == TYPE_IMM5 && +          insn->immediates[insn->numImmediatesConsumed - 1] > 31) +        return -1;        if (insn->spec->operands[index].type == TYPE_XMM128 ||            insn->spec->operands[index].type == TYPE_XMM256)          sawRegImm = 1; diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h index d2e30f17660..13e113609bf 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h @@ -273,6 +273,7 @@ struct ContextDecision {    ENUM_ENTRY(TYPE_IMM32,      "4-byte")                                        \    ENUM_ENTRY(TYPE_IMM64,      "8-byte")                                        \    ENUM_ENTRY(TYPE_IMM3,       "1-byte immediate operand between 0 and 7")      \ +  ENUM_ENTRY(TYPE_IMM5,       "1-byte immediate operand between 0 and 31")     \    ENUM_ENTRY(TYPE_RM8,        "1-byte register or memory operand")             \    ENUM_ENTRY(TYPE_RM16,       "2-byte")                                        \    ENUM_ENTRY(TYPE_RM32,       "4-byte")                                        \ diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index f1cedf3a86c..7db7ccbedcf 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -19,7 +19,6 @@  #include "X86MachineFunctionInfo.h"  #include "X86TargetMachine.h"  #include "InstPrinter/X86ATTInstPrinter.h" -#include "InstPrinter/X86IntelInstPrinter.h"  #include "llvm/CallingConv.h"  #include "llvm/DerivedTypes.h"  #include "llvm/Module.h" @@ -265,8 +264,8 @@ void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,  void X86AsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op,                                 raw_ostream &O) {    unsigned char value = MI->getOperand(Op).getImm(); -  assert(value <= 7 && "Invalid ssecc argument!");    switch (value) { +  default: llvm_unreachable("Invalid ssecc argument!");    case    0: O << "eq"; break;    case    1: O << "lt"; break;    case    2: O << "le"; break; diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index dd7cf500cb1..6a2531269d8 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -374,6 +374,11 @@ def SSECC : Operand<i8> {    let OperandType = "OPERAND_IMMEDIATE";  } +def AVXCC : Operand<i8> { +  let PrintMethod = "printSSECC"; +  let OperandType = "OPERAND_IMMEDIATE"; +} +  class ImmSExtAsmOperandClass : AsmOperandClass {    let SuperClasses = [ImmAsmOperand];    let RenderMethod = "addImmOperands"; diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td index df426279ea5..6afdcf7d2e1 100644 --- a/llvm/lib/Target/X86/X86InstrSSE.td +++ b/llvm/lib/Target/X86/X86InstrSSE.td @@ -2162,15 +2162,15 @@ def : Pat<(v4f64 (fextend (loadv4f32 addr:$src))),  // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions  multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop, -                            SDNode OpNode, ValueType VT, PatFrag ld_frag, -                            string asm, string asm_alt, +                            Operand CC, SDNode OpNode, ValueType VT,  +                            PatFrag ld_frag, string asm, string asm_alt,                              OpndItins itins> {    def rr : SIi8<0xC2, MRMSrcReg, -                (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm, +                (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,                  [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))],                  itins.rr>;    def rm : SIi8<0xC2, MRMSrcMem, -                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm, +                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,                  [(set RC:$dst, (OpNode (VT RC:$src1),                                           (ld_frag addr:$src2), imm:$cc))],                                           itins.rm>; @@ -2187,57 +2187,57 @@ multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,    }  } -defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32, +defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, AVXCC, X86cmpss, f32, loadf32,                   "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",                   "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",                   SSE_ALU_F32S>,                   XS, VEX_4V, VEX_LIG; -defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64, +defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, AVXCC, X86cmpsd, f64, loadf64,                   "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",                   "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",                   SSE_ALU_F32S>, // same latency as 32 bit compare                   XD, VEX_4V, VEX_LIG;  let Constraints = "$src1 = $dst" in { -  defm CMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32, +  defm CMPSS : sse12_cmp_scalar<FR32, f32mem, SSECC, X86cmpss, f32, loadf32,                    "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",                    "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}", SSE_ALU_F32S>,                    XS; -  defm CMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64, +  defm CMPSD : sse12_cmp_scalar<FR64, f64mem, SSECC, X86cmpsd, f64, loadf64,                    "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",                    "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}",                    SSE_ALU_F32S>, // same latency as 32 bit compare                    XD;  } -multiclass sse12_cmp_scalar_int<RegisterClass RC, X86MemOperand x86memop, +multiclass sse12_cmp_scalar_int<X86MemOperand x86memop, Operand CC,                           Intrinsic Int, string asm, OpndItins itins> {    def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst), -                      (ins VR128:$src1, VR128:$src, SSECC:$cc), asm, +                      (ins VR128:$src1, VR128:$src, CC:$cc), asm,                          [(set VR128:$dst, (Int VR128:$src1,                                                 VR128:$src, imm:$cc))],                                                 itins.rr>;    def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst), -                      (ins VR128:$src1, x86memop:$src, SSECC:$cc), asm, +                      (ins VR128:$src1, x86memop:$src, CC:$cc), asm,                          [(set VR128:$dst, (Int VR128:$src1,                                                 (load addr:$src), imm:$cc))],                                                 itins.rm>;  }  // Aliases to match intrinsics which expect XMM operand(s). -defm Int_VCMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss, +defm Int_VCMPSS  : sse12_cmp_scalar_int<f32mem, AVXCC, int_x86_sse_cmp_ss,                       "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}",                       SSE_ALU_F32S>,                       XS, VEX_4V; -defm Int_VCMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd, +defm Int_VCMPSD  : sse12_cmp_scalar_int<f64mem, AVXCC, int_x86_sse2_cmp_sd,                       "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}",                       SSE_ALU_F32S>, // same latency as f32                       XD, VEX_4V;  let Constraints = "$src1 = $dst" in { -  defm Int_CMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss, +  defm Int_CMPSS  : sse12_cmp_scalar_int<f32mem, SSECC, int_x86_sse_cmp_ss,                         "cmp${cc}ss\t{$src, $dst|$dst, $src}",                         SSE_ALU_F32S>, XS; -  defm Int_CMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd, +  defm Int_CMPSD  : sse12_cmp_scalar_int<f64mem, SSECC, int_x86_sse2_cmp_sd,                         "cmp${cc}sd\t{$src, $dst|$dst, $src}",                         SSE_ALU_F32S>, // same latency as f32                         XD; @@ -2308,50 +2308,50 @@ let Defs = [EFLAGS] in {  // sse12_cmp_packed - sse 1 & 2 compare packed instructions  multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop, -                            Intrinsic Int, string asm, string asm_alt, -                            Domain d> { -  let isAsmParserOnly = 1 in { -    def rri : PIi8<0xC2, MRMSrcReg, -               (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm, -               [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))], -               IIC_SSE_CMPP_RR, d>; -    def rmi : PIi8<0xC2, MRMSrcMem, -               (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm, -               [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))], -               IIC_SSE_CMPP_RM, d>; -  } +                            Operand CC, Intrinsic Int, string asm,  +                            string asm_alt, Domain d> { +  def rri : PIi8<0xC2, MRMSrcReg, +             (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm, +             [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))], +             IIC_SSE_CMPP_RR, d>; +  def rmi : PIi8<0xC2, MRMSrcMem, +             (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm, +             [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))], +             IIC_SSE_CMPP_RM, d>;    // Accept explicit immediate argument form instead of comparison code. -  def rri_alt : PIi8<0xC2, MRMSrcReg, -             (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc), -             asm_alt, [], IIC_SSE_CMPP_RR, d>; -  def rmi_alt : PIi8<0xC2, MRMSrcMem, -             (outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc), -             asm_alt, [], IIC_SSE_CMPP_RM, d>; +  let neverHasSideEffects = 1 in { +    def rri_alt : PIi8<0xC2, MRMSrcReg, +               (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc), +               asm_alt, [], IIC_SSE_CMPP_RR, d>; +    def rmi_alt : PIi8<0xC2, MRMSrcMem, +               (outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc), +               asm_alt, [], IIC_SSE_CMPP_RM, d>; +  }  } -defm VCMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps, +defm VCMPPS : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse_cmp_ps,                 "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",                 "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",                 SSEPackedSingle>, TB, VEX_4V; -defm VCMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd, +defm VCMPPD : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse2_cmp_pd,                 "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",                 "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",                 SSEPackedDouble>, TB, OpSize, VEX_4V; -defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_ps_256, +defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_ps_256,                 "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",                 "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",                 SSEPackedSingle>, TB, VEX_4V; -defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_pd_256, +defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_pd_256,                 "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",                 "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",                 SSEPackedDouble>, TB, OpSize, VEX_4V;  let Constraints = "$src1 = $dst" in { -  defm CMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps, +  defm CMPPS : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse_cmp_ps,                   "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",                   "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",                   SSEPackedSingle>, TB; -  defm CMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd, +  defm CMPPD : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse2_cmp_pd,                   "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",                   "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",                   SSEPackedDouble>, TB, OpSize;  | 

