1*9880d681SAndroid Build Coastguard Worker//===-- X86InstrXOP.td - XOP Instruction Set ---------------*- tablegen -*-===// 2*9880d681SAndroid Build Coastguard Worker// 3*9880d681SAndroid Build Coastguard Worker// The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker// 5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker// 8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker// 10*9880d681SAndroid Build Coastguard Worker// This file describes XOP (eXtended OPerations) 11*9880d681SAndroid Build Coastguard Worker// 12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workermulticlass xop2op<bits<8> opc, string OpcodeStr, Intrinsic Int, PatFrag memop> { 15*9880d681SAndroid Build Coastguard Worker def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), 16*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), 17*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, (Int VR128:$src))]>, XOP; 18*9880d681SAndroid Build Coastguard Worker def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), 19*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), 20*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, (Int (bitconvert (memop addr:$src))))]>, XOP; 21*9880d681SAndroid Build Coastguard Worker} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { 24*9880d681SAndroid Build Coastguard Worker defm VPHSUBWD : xop2op<0xE2, "vphsubwd", int_x86_xop_vphsubwd, loadv2i64>; 25*9880d681SAndroid Build Coastguard Worker defm VPHSUBDQ : xop2op<0xE3, "vphsubdq", int_x86_xop_vphsubdq, loadv2i64>; 26*9880d681SAndroid Build Coastguard Worker defm VPHSUBBW : xop2op<0xE1, "vphsubbw", int_x86_xop_vphsubbw, loadv2i64>; 27*9880d681SAndroid Build Coastguard Worker defm VPHADDWQ : xop2op<0xC7, "vphaddwq", int_x86_xop_vphaddwq, loadv2i64>; 28*9880d681SAndroid Build Coastguard Worker defm VPHADDWD : xop2op<0xC6, "vphaddwd", int_x86_xop_vphaddwd, loadv2i64>; 29*9880d681SAndroid Build Coastguard Worker defm VPHADDUWQ : xop2op<0xD7, "vphadduwq", int_x86_xop_vphadduwq, loadv2i64>; 30*9880d681SAndroid Build Coastguard Worker defm VPHADDUWD : xop2op<0xD6, "vphadduwd", int_x86_xop_vphadduwd, loadv2i64>; 31*9880d681SAndroid Build Coastguard Worker defm VPHADDUDQ : xop2op<0xDB, "vphaddudq", int_x86_xop_vphaddudq, loadv2i64>; 32*9880d681SAndroid Build Coastguard Worker defm VPHADDUBW : xop2op<0xD1, "vphaddubw", int_x86_xop_vphaddubw, loadv2i64>; 33*9880d681SAndroid Build Coastguard Worker defm VPHADDUBQ : xop2op<0xD3, "vphaddubq", int_x86_xop_vphaddubq, loadv2i64>; 34*9880d681SAndroid Build Coastguard Worker defm VPHADDUBD : xop2op<0xD2, "vphaddubd", int_x86_xop_vphaddubd, loadv2i64>; 35*9880d681SAndroid Build Coastguard Worker defm VPHADDDQ : xop2op<0xCB, "vphadddq", int_x86_xop_vphadddq, loadv2i64>; 36*9880d681SAndroid Build Coastguard Worker defm VPHADDBW : xop2op<0xC1, "vphaddbw", int_x86_xop_vphaddbw, loadv2i64>; 37*9880d681SAndroid Build Coastguard Worker defm VPHADDBQ : xop2op<0xC3, "vphaddbq", int_x86_xop_vphaddbq, loadv2i64>; 38*9880d681SAndroid Build Coastguard Worker defm VPHADDBD : xop2op<0xC2, "vphaddbd", int_x86_xop_vphaddbd, loadv2i64>; 39*9880d681SAndroid Build Coastguard Worker} 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker// Scalar load 2 addr operand instructions 42*9880d681SAndroid Build Coastguard Workermulticlass xop2opsld<bits<8> opc, string OpcodeStr, Intrinsic Int, 43*9880d681SAndroid Build Coastguard Worker Operand memop, ComplexPattern mem_cpat> { 44*9880d681SAndroid Build Coastguard Worker def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), 45*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), 46*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, (Int VR128:$src))]>, XOP; 47*9880d681SAndroid Build Coastguard Worker def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), (ins memop:$src), 48*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), 49*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, (Int (bitconvert mem_cpat:$src)))]>, XOP; 50*9880d681SAndroid Build Coastguard Worker} 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Workermulticlass xop2op128<bits<8> opc, string OpcodeStr, Intrinsic Int, 53*9880d681SAndroid Build Coastguard Worker PatFrag memop> { 54*9880d681SAndroid Build Coastguard Worker def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), 55*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), 56*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, (Int VR128:$src))]>, XOP; 57*9880d681SAndroid Build Coastguard Worker def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), 58*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), 59*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, (Int (bitconvert (memop addr:$src))))]>, XOP; 60*9880d681SAndroid Build Coastguard Worker} 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Workermulticlass xop2op256<bits<8> opc, string OpcodeStr, Intrinsic Int, 63*9880d681SAndroid Build Coastguard Worker PatFrag memop> { 64*9880d681SAndroid Build Coastguard Worker def rrY : IXOP<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src), 65*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), 66*9880d681SAndroid Build Coastguard Worker [(set VR256:$dst, (Int VR256:$src))]>, XOP, VEX_L; 67*9880d681SAndroid Build Coastguard Worker def rmY : IXOP<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src), 68*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), 69*9880d681SAndroid Build Coastguard Worker [(set VR256:$dst, (Int (bitconvert (memop addr:$src))))]>, XOP, VEX_L; 70*9880d681SAndroid Build Coastguard Worker} 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in { 73*9880d681SAndroid Build Coastguard Worker defm VFRCZSS : xop2opsld<0x82, "vfrczss", int_x86_xop_vfrcz_ss, 74*9880d681SAndroid Build Coastguard Worker ssmem, sse_load_f32>; 75*9880d681SAndroid Build Coastguard Worker defm VFRCZPS : xop2op128<0x80, "vfrczps", int_x86_xop_vfrcz_ps, loadv4f32>; 76*9880d681SAndroid Build Coastguard Worker defm VFRCZPS : xop2op256<0x80, "vfrczps", int_x86_xop_vfrcz_ps_256, loadv8f32>; 77*9880d681SAndroid Build Coastguard Worker} 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble in { 80*9880d681SAndroid Build Coastguard Worker defm VFRCZSD : xop2opsld<0x83, "vfrczsd", int_x86_xop_vfrcz_sd, 81*9880d681SAndroid Build Coastguard Worker sdmem, sse_load_f64>; 82*9880d681SAndroid Build Coastguard Worker defm VFRCZPD : xop2op128<0x81, "vfrczpd", int_x86_xop_vfrcz_pd, loadv2f64>; 83*9880d681SAndroid Build Coastguard Worker defm VFRCZPD : xop2op256<0x81, "vfrczpd", int_x86_xop_vfrcz_pd_256, loadv4f64>; 84*9880d681SAndroid Build Coastguard Worker} 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workermulticlass xop3op<bits<8> opc, string OpcodeStr, SDNode OpNode, 87*9880d681SAndroid Build Coastguard Worker ValueType vt128> { 88*9880d681SAndroid Build Coastguard Worker def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), 89*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2), 90*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 91*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 92*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2))))]>, 93*9880d681SAndroid Build Coastguard Worker XOP_4VOp3, Sched<[WriteVarVecShift]>; 94*9880d681SAndroid Build Coastguard Worker def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), 95*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, i128mem:$src2), 96*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 97*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 98*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), 99*9880d681SAndroid Build Coastguard Worker (vt128 (bitconvert (loadv2i64 addr:$src2))))))]>, 100*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_W, Sched<[WriteVarVecShift, ReadAfterLd]>; 101*9880d681SAndroid Build Coastguard Worker def mr : IXOP<opc, MRMSrcMem, (outs VR128:$dst), 102*9880d681SAndroid Build Coastguard Worker (ins i128mem:$src1, VR128:$src2), 103*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 104*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 105*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 (bitconvert (loadv2i64 addr:$src1))), 106*9880d681SAndroid Build Coastguard Worker (vt128 VR128:$src2))))]>, 107*9880d681SAndroid Build Coastguard Worker XOP_4VOp3, Sched<[WriteVarVecShift, ReadAfterLd]>; 108*9880d681SAndroid Build Coastguard Worker} 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { 111*9880d681SAndroid Build Coastguard Worker defm VPROTB : xop3op<0x90, "vprotb", X86vprot, v16i8>; 112*9880d681SAndroid Build Coastguard Worker defm VPROTD : xop3op<0x92, "vprotd", X86vprot, v4i32>; 113*9880d681SAndroid Build Coastguard Worker defm VPROTQ : xop3op<0x93, "vprotq", X86vprot, v2i64>; 114*9880d681SAndroid Build Coastguard Worker defm VPROTW : xop3op<0x91, "vprotw", X86vprot, v8i16>; 115*9880d681SAndroid Build Coastguard Worker defm VPSHAB : xop3op<0x98, "vpshab", X86vpsha, v16i8>; 116*9880d681SAndroid Build Coastguard Worker defm VPSHAD : xop3op<0x9A, "vpshad", X86vpsha, v4i32>; 117*9880d681SAndroid Build Coastguard Worker defm VPSHAQ : xop3op<0x9B, "vpshaq", X86vpsha, v2i64>; 118*9880d681SAndroid Build Coastguard Worker defm VPSHAW : xop3op<0x99, "vpshaw", X86vpsha, v8i16>; 119*9880d681SAndroid Build Coastguard Worker defm VPSHLB : xop3op<0x94, "vpshlb", X86vpshl, v16i8>; 120*9880d681SAndroid Build Coastguard Worker defm VPSHLD : xop3op<0x96, "vpshld", X86vpshl, v4i32>; 121*9880d681SAndroid Build Coastguard Worker defm VPSHLQ : xop3op<0x97, "vpshlq", X86vpshl, v2i64>; 122*9880d681SAndroid Build Coastguard Worker defm VPSHLW : xop3op<0x95, "vpshlw", X86vpshl, v8i16>; 123*9880d681SAndroid Build Coastguard Worker} 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Workermulticlass xop3opimm<bits<8> opc, string OpcodeStr, SDNode OpNode, 126*9880d681SAndroid Build Coastguard Worker ValueType vt128> { 127*9880d681SAndroid Build Coastguard Worker def ri : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), 128*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, u8imm:$src2), 129*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 130*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 131*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), imm:$src2)))]>, XOP; 132*9880d681SAndroid Build Coastguard Worker def mi : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), 133*9880d681SAndroid Build Coastguard Worker (ins i128mem:$src1, u8imm:$src2), 134*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 135*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 136*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 (bitconvert (loadv2i64 addr:$src1))), imm:$src2)))]>, XOP; 137*9880d681SAndroid Build Coastguard Worker} 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { 140*9880d681SAndroid Build Coastguard Worker defm VPROTB : xop3opimm<0xC0, "vprotb", X86vproti, v16i8>; 141*9880d681SAndroid Build Coastguard Worker defm VPROTD : xop3opimm<0xC2, "vprotd", X86vproti, v4i32>; 142*9880d681SAndroid Build Coastguard Worker defm VPROTQ : xop3opimm<0xC3, "vprotq", X86vproti, v2i64>; 143*9880d681SAndroid Build Coastguard Worker defm VPROTW : xop3opimm<0xC1, "vprotw", X86vproti, v8i16>; 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker// Instruction where second source can be memory, but third must be register 147*9880d681SAndroid Build Coastguard Workermulticlass xop4opm2<bits<8> opc, string OpcodeStr, Intrinsic Int> { 148*9880d681SAndroid Build Coastguard Worker let isCommutable = 1 in 149*9880d681SAndroid Build Coastguard Worker def rr : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), 150*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, VR128:$src3), 151*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 152*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 153*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 154*9880d681SAndroid Build Coastguard Worker (Int VR128:$src1, VR128:$src2, VR128:$src3))]>, XOP_4V, VEX_I8IMM; 155*9880d681SAndroid Build Coastguard Worker def rm : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), 156*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, i128mem:$src2, VR128:$src3), 157*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 158*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 159*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 160*9880d681SAndroid Build Coastguard Worker (Int VR128:$src1, (bitconvert (loadv2i64 addr:$src2)), 161*9880d681SAndroid Build Coastguard Worker VR128:$src3))]>, XOP_4V, VEX_I8IMM; 162*9880d681SAndroid Build Coastguard Worker} 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { 165*9880d681SAndroid Build Coastguard Worker defm VPMADCSWD : xop4opm2<0xB6, "vpmadcswd", int_x86_xop_vpmadcswd>; 166*9880d681SAndroid Build Coastguard Worker defm VPMADCSSWD : xop4opm2<0xA6, "vpmadcsswd", int_x86_xop_vpmadcsswd>; 167*9880d681SAndroid Build Coastguard Worker defm VPMACSWW : xop4opm2<0x95, "vpmacsww", int_x86_xop_vpmacsww>; 168*9880d681SAndroid Build Coastguard Worker defm VPMACSWD : xop4opm2<0x96, "vpmacswd", int_x86_xop_vpmacswd>; 169*9880d681SAndroid Build Coastguard Worker defm VPMACSSWW : xop4opm2<0x85, "vpmacssww", int_x86_xop_vpmacssww>; 170*9880d681SAndroid Build Coastguard Worker defm VPMACSSWD : xop4opm2<0x86, "vpmacsswd", int_x86_xop_vpmacsswd>; 171*9880d681SAndroid Build Coastguard Worker defm VPMACSSDQL : xop4opm2<0x87, "vpmacssdql", int_x86_xop_vpmacssdql>; 172*9880d681SAndroid Build Coastguard Worker defm VPMACSSDQH : xop4opm2<0x8F, "vpmacssdqh", int_x86_xop_vpmacssdqh>; 173*9880d681SAndroid Build Coastguard Worker defm VPMACSSDD : xop4opm2<0x8E, "vpmacssdd", int_x86_xop_vpmacssdd>; 174*9880d681SAndroid Build Coastguard Worker defm VPMACSDQL : xop4opm2<0x97, "vpmacsdql", int_x86_xop_vpmacsdql>; 175*9880d681SAndroid Build Coastguard Worker defm VPMACSDQH : xop4opm2<0x9F, "vpmacsdqh", int_x86_xop_vpmacsdqh>; 176*9880d681SAndroid Build Coastguard Worker defm VPMACSDD : xop4opm2<0x9E, "vpmacsdd", int_x86_xop_vpmacsdd>; 177*9880d681SAndroid Build Coastguard Worker} 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker// Instruction where second source can be memory, third must be imm8 180*9880d681SAndroid Build Coastguard Workermulticlass xopvpcom<bits<8> opc, string Suffix, SDNode OpNode, ValueType vt128> { 181*9880d681SAndroid Build Coastguard Worker let isCommutable = 1 in 182*9880d681SAndroid Build Coastguard Worker def ri : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), 183*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, XOPCC:$cc), 184*9880d681SAndroid Build Coastguard Worker !strconcat("vpcom${cc}", Suffix, 185*9880d681SAndroid Build Coastguard Worker "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 186*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 187*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), 188*9880d681SAndroid Build Coastguard Worker i8immZExt3:$cc)))]>, 189*9880d681SAndroid Build Coastguard Worker XOP_4V; 190*9880d681SAndroid Build Coastguard Worker def mi : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), 191*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, i128mem:$src2, XOPCC:$cc), 192*9880d681SAndroid Build Coastguard Worker !strconcat("vpcom${cc}", Suffix, 193*9880d681SAndroid Build Coastguard Worker "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 194*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 195*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), 196*9880d681SAndroid Build Coastguard Worker (vt128 (bitconvert (loadv2i64 addr:$src2))), 197*9880d681SAndroid Build Coastguard Worker i8immZExt3:$cc)))]>, 198*9880d681SAndroid Build Coastguard Worker XOP_4V; 199*9880d681SAndroid Build Coastguard Worker let isAsmParserOnly = 1, hasSideEffects = 0 in { 200*9880d681SAndroid Build Coastguard Worker def ri_alt : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), 201*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, u8imm:$src3), 202*9880d681SAndroid Build Coastguard Worker !strconcat("vpcom", Suffix, 203*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 204*9880d681SAndroid Build Coastguard Worker []>, XOP_4V; 205*9880d681SAndroid Build Coastguard Worker let mayLoad = 1 in 206*9880d681SAndroid Build Coastguard Worker def mi_alt : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), 207*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, i128mem:$src2, u8imm:$src3), 208*9880d681SAndroid Build Coastguard Worker !strconcat("vpcom", Suffix, 209*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 210*9880d681SAndroid Build Coastguard Worker []>, XOP_4V; 211*9880d681SAndroid Build Coastguard Worker } 212*9880d681SAndroid Build Coastguard Worker} 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { // SSE integer instructions 215*9880d681SAndroid Build Coastguard Worker defm VPCOMB : xopvpcom<0xCC, "b", X86vpcom, v16i8>; 216*9880d681SAndroid Build Coastguard Worker defm VPCOMW : xopvpcom<0xCD, "w", X86vpcom, v8i16>; 217*9880d681SAndroid Build Coastguard Worker defm VPCOMD : xopvpcom<0xCE, "d", X86vpcom, v4i32>; 218*9880d681SAndroid Build Coastguard Worker defm VPCOMQ : xopvpcom<0xCF, "q", X86vpcom, v2i64>; 219*9880d681SAndroid Build Coastguard Worker defm VPCOMUB : xopvpcom<0xEC, "ub", X86vpcomu, v16i8>; 220*9880d681SAndroid Build Coastguard Worker defm VPCOMUW : xopvpcom<0xED, "uw", X86vpcomu, v8i16>; 221*9880d681SAndroid Build Coastguard Worker defm VPCOMUD : xopvpcom<0xEE, "ud", X86vpcomu, v4i32>; 222*9880d681SAndroid Build Coastguard Worker defm VPCOMUQ : xopvpcom<0xEF, "uq", X86vpcomu, v2i64>; 223*9880d681SAndroid Build Coastguard Worker} 224*9880d681SAndroid Build Coastguard Worker 225*9880d681SAndroid Build Coastguard Workermulticlass xop4op<bits<8> opc, string OpcodeStr, SDNode OpNode, 226*9880d681SAndroid Build Coastguard Worker ValueType vt128> { 227*9880d681SAndroid Build Coastguard Worker def rrr : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), 228*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, VR128:$src3), 229*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 230*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 231*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 232*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), 233*9880d681SAndroid Build Coastguard Worker (vt128 VR128:$src3))))]>, 234*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_I8IMM; 235*9880d681SAndroid Build Coastguard Worker def rrm : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), 236*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, i128mem:$src3), 237*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 238*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 239*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 240*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), 241*9880d681SAndroid Build Coastguard Worker (vt128 (bitconvert (loadv2i64 addr:$src3))))))]>, 242*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_I8IMM, VEX_W, MemOp4; 243*9880d681SAndroid Build Coastguard Worker def rmr : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), 244*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, i128mem:$src2, VR128:$src3), 245*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 246*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 247*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 248*9880d681SAndroid Build Coastguard Worker (v16i8 (OpNode (vt128 VR128:$src1), (vt128 (bitconvert (loadv2i64 addr:$src2))), 249*9880d681SAndroid Build Coastguard Worker (vt128 VR128:$src3))))]>, 250*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_I8IMM; 251*9880d681SAndroid Build Coastguard Worker // For disassembler 252*9880d681SAndroid Build Coastguard Worker let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in 253*9880d681SAndroid Build Coastguard Worker def rrr_REV : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), 254*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, VR128:$src3), 255*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 256*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 257*9880d681SAndroid Build Coastguard Worker []>, XOP_4V, VEX_I8IMM, VEX_W, MemOp4; 258*9880d681SAndroid Build Coastguard Worker} 259*9880d681SAndroid Build Coastguard Worker 260*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { 261*9880d681SAndroid Build Coastguard Worker defm VPPERM : xop4op<0xA3, "vpperm", X86vpperm, v16i8>; 262*9880d681SAndroid Build Coastguard Worker} 263*9880d681SAndroid Build Coastguard Worker 264*9880d681SAndroid Build Coastguard Worker// Instruction where either second or third source can be memory 265*9880d681SAndroid Build Coastguard Workermulticlass xop4op_int<bits<8> opc, string OpcodeStr, 266*9880d681SAndroid Build Coastguard Worker Intrinsic Int128, Intrinsic Int256> { 267*9880d681SAndroid Build Coastguard Worker // 128-bit Instruction 268*9880d681SAndroid Build Coastguard Worker def rrr : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), 269*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, VR128:$src3), 270*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 271*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 272*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, (Int128 VR128:$src1, VR128:$src2, VR128:$src3))]>, 273*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_I8IMM; 274*9880d681SAndroid Build Coastguard Worker def rrm : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), 275*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, i128mem:$src3), 276*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 277*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 278*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 279*9880d681SAndroid Build Coastguard Worker (Int128 VR128:$src1, VR128:$src2, 280*9880d681SAndroid Build Coastguard Worker (bitconvert (loadv2i64 addr:$src3))))]>, 281*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_I8IMM, VEX_W, MemOp4; 282*9880d681SAndroid Build Coastguard Worker def rmr : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), 283*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, i128mem:$src2, VR128:$src3), 284*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 285*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 286*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 287*9880d681SAndroid Build Coastguard Worker (Int128 VR128:$src1, (bitconvert (loadv2i64 addr:$src2)), 288*9880d681SAndroid Build Coastguard Worker VR128:$src3))]>, 289*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_I8IMM; 290*9880d681SAndroid Build Coastguard Worker // For disassembler 291*9880d681SAndroid Build Coastguard Worker let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in 292*9880d681SAndroid Build Coastguard Worker def rrr_REV : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), 293*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, VR128:$src3), 294*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 295*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 296*9880d681SAndroid Build Coastguard Worker []>, XOP_4V, VEX_I8IMM, VEX_W, MemOp4; 297*9880d681SAndroid Build Coastguard Worker 298*9880d681SAndroid Build Coastguard Worker // 256-bit Instruction 299*9880d681SAndroid Build Coastguard Worker def rrrY : IXOPi8<opc, MRMSrcReg, (outs VR256:$dst), 300*9880d681SAndroid Build Coastguard Worker (ins VR256:$src1, VR256:$src2, VR256:$src3), 301*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 302*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 303*9880d681SAndroid Build Coastguard Worker [(set VR256:$dst, (Int256 VR256:$src1, VR256:$src2, VR256:$src3))]>, 304*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_I8IMM, VEX_L; 305*9880d681SAndroid Build Coastguard Worker def rrmY : IXOPi8<opc, MRMSrcMem, (outs VR256:$dst), 306*9880d681SAndroid Build Coastguard Worker (ins VR256:$src1, VR256:$src2, i256mem:$src3), 307*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 308*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 309*9880d681SAndroid Build Coastguard Worker [(set VR256:$dst, 310*9880d681SAndroid Build Coastguard Worker (Int256 VR256:$src1, VR256:$src2, 311*9880d681SAndroid Build Coastguard Worker (bitconvert (loadv4i64 addr:$src3))))]>, 312*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_I8IMM, VEX_W, MemOp4, VEX_L; 313*9880d681SAndroid Build Coastguard Worker def rmrY : IXOPi8<opc, MRMSrcMem, (outs VR256:$dst), 314*9880d681SAndroid Build Coastguard Worker (ins VR256:$src1, f256mem:$src2, VR256:$src3), 315*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 316*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 317*9880d681SAndroid Build Coastguard Worker [(set VR256:$dst, 318*9880d681SAndroid Build Coastguard Worker (Int256 VR256:$src1, (bitconvert (loadv4i64 addr:$src2)), 319*9880d681SAndroid Build Coastguard Worker VR256:$src3))]>, 320*9880d681SAndroid Build Coastguard Worker XOP_4V, VEX_I8IMM, VEX_L; 321*9880d681SAndroid Build Coastguard Worker // For disassembler 322*9880d681SAndroid Build Coastguard Worker let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in 323*9880d681SAndroid Build Coastguard Worker def rrrY_REV : IXOPi8<opc, MRMSrcReg, (outs VR256:$dst), 324*9880d681SAndroid Build Coastguard Worker (ins VR256:$src1, VR256:$src2, VR256:$src3), 325*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 326*9880d681SAndroid Build Coastguard Worker "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 327*9880d681SAndroid Build Coastguard Worker []>, XOP_4V, VEX_I8IMM, VEX_W, MemOp4, VEX_L; 328*9880d681SAndroid Build Coastguard Worker} 329*9880d681SAndroid Build Coastguard Worker 330*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { 331*9880d681SAndroid Build Coastguard Worker defm VPCMOV : xop4op_int<0xA2, "vpcmov", 332*9880d681SAndroid Build Coastguard Worker int_x86_xop_vpcmov, int_x86_xop_vpcmov_256>; 333*9880d681SAndroid Build Coastguard Worker} 334*9880d681SAndroid Build Coastguard Worker 335*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasXOP] in { 336*9880d681SAndroid Build Coastguard Worker def : Pat<(v2i64 (or (and VR128:$src3, VR128:$src1), 337*9880d681SAndroid Build Coastguard Worker (X86andnp VR128:$src3, VR128:$src2))), 338*9880d681SAndroid Build Coastguard Worker (VPCMOVrrr VR128:$src1, VR128:$src2, VR128:$src3)>; 339*9880d681SAndroid Build Coastguard Worker 340*9880d681SAndroid Build Coastguard Worker def : Pat<(v4i64 (or (and VR256:$src3, VR256:$src1), 341*9880d681SAndroid Build Coastguard Worker (X86andnp VR256:$src3, VR256:$src2))), 342*9880d681SAndroid Build Coastguard Worker (VPCMOVrrrY VR256:$src1, VR256:$src2, VR256:$src3)>; 343*9880d681SAndroid Build Coastguard Worker} 344*9880d681SAndroid Build Coastguard Worker 345*9880d681SAndroid Build Coastguard Workermulticlass xop5op<bits<8> opc, string OpcodeStr, SDNode OpNode, 346*9880d681SAndroid Build Coastguard Worker ValueType vt128, ValueType vt256, 347*9880d681SAndroid Build Coastguard Worker ValueType id128, ValueType id256, 348*9880d681SAndroid Build Coastguard Worker PatFrag ld_128, PatFrag ld_256> { 349*9880d681SAndroid Build Coastguard Worker def rr : IXOP5<opc, MRMSrcReg, (outs VR128:$dst), 350*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, VR128:$src3, u8imm:$src4), 351*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 352*9880d681SAndroid Build Coastguard Worker "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), 353*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 354*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), 355*9880d681SAndroid Build Coastguard Worker (id128 VR128:$src3), (i8 imm:$src4))))]>; 356*9880d681SAndroid Build Coastguard Worker def rm : IXOP5<opc, MRMSrcMem, (outs VR128:$dst), 357*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, i128mem:$src3, u8imm:$src4), 358*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 359*9880d681SAndroid Build Coastguard Worker "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), 360*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 361*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), 362*9880d681SAndroid Build Coastguard Worker (id128 (bitconvert (loadv2i64 addr:$src3))), 363*9880d681SAndroid Build Coastguard Worker (i8 imm:$src4))))]>, 364*9880d681SAndroid Build Coastguard Worker VEX_W, MemOp4; 365*9880d681SAndroid Build Coastguard Worker def mr : IXOP5<opc, MRMSrcMem, (outs VR128:$dst), 366*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, f128mem:$src2, VR128:$src3, u8imm:$src4), 367*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 368*9880d681SAndroid Build Coastguard Worker "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), 369*9880d681SAndroid Build Coastguard Worker [(set VR128:$dst, 370*9880d681SAndroid Build Coastguard Worker (vt128 (OpNode (vt128 VR128:$src1), 371*9880d681SAndroid Build Coastguard Worker (vt128 (bitconvert (ld_128 addr:$src2))), 372*9880d681SAndroid Build Coastguard Worker (id128 VR128:$src3), (i8 imm:$src4))))]>; 373*9880d681SAndroid Build Coastguard Worker // For disassembler 374*9880d681SAndroid Build Coastguard Worker let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in 375*9880d681SAndroid Build Coastguard Worker def rr_REV : IXOP5<opc, MRMSrcReg, (outs VR128:$dst), 376*9880d681SAndroid Build Coastguard Worker (ins VR128:$src1, VR128:$src2, VR128:$src3, u8imm:$src4), 377*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 378*9880d681SAndroid Build Coastguard Worker "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), 379*9880d681SAndroid Build Coastguard Worker []>, VEX_W, MemOp4; 380*9880d681SAndroid Build Coastguard Worker 381*9880d681SAndroid Build Coastguard Worker def rrY : IXOP5<opc, MRMSrcReg, (outs VR256:$dst), 382*9880d681SAndroid Build Coastguard Worker (ins VR256:$src1, VR256:$src2, VR256:$src3, u8imm:$src4), 383*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 384*9880d681SAndroid Build Coastguard Worker "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), 385*9880d681SAndroid Build Coastguard Worker [(set VR256:$dst, 386*9880d681SAndroid Build Coastguard Worker (vt256 (OpNode (vt256 VR256:$src1), (vt256 VR256:$src2), 387*9880d681SAndroid Build Coastguard Worker (id256 VR256:$src3), (i8 imm:$src4))))]>, VEX_L; 388*9880d681SAndroid Build Coastguard Worker def rmY : IXOP5<opc, MRMSrcMem, (outs VR256:$dst), 389*9880d681SAndroid Build Coastguard Worker (ins VR256:$src1, VR256:$src2, i256mem:$src3, u8imm:$src4), 390*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 391*9880d681SAndroid Build Coastguard Worker "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), 392*9880d681SAndroid Build Coastguard Worker [(set VR256:$dst, 393*9880d681SAndroid Build Coastguard Worker (vt256 (OpNode (vt256 VR256:$src1), (vt256 VR256:$src2), 394*9880d681SAndroid Build Coastguard Worker (id256 (bitconvert (loadv4i64 addr:$src3))), 395*9880d681SAndroid Build Coastguard Worker (i8 imm:$src4))))]>, VEX_W, MemOp4, VEX_L; 396*9880d681SAndroid Build Coastguard Worker def mrY : IXOP5<opc, MRMSrcMem, (outs VR256:$dst), 397*9880d681SAndroid Build Coastguard Worker (ins VR256:$src1, f256mem:$src2, VR256:$src3, u8imm:$src4), 398*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 399*9880d681SAndroid Build Coastguard Worker "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), 400*9880d681SAndroid Build Coastguard Worker [(set VR256:$dst, 401*9880d681SAndroid Build Coastguard Worker (vt256 (OpNode (vt256 VR256:$src1), 402*9880d681SAndroid Build Coastguard Worker (vt256 (bitconvert (ld_256 addr:$src2))), 403*9880d681SAndroid Build Coastguard Worker (id256 VR256:$src3), (i8 imm:$src4))))]>, VEX_L; 404*9880d681SAndroid Build Coastguard Worker // For disassembler 405*9880d681SAndroid Build Coastguard Worker let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in 406*9880d681SAndroid Build Coastguard Worker def rrY_REV : IXOP5<opc, MRMSrcReg, (outs VR256:$dst), 407*9880d681SAndroid Build Coastguard Worker (ins VR256:$src1, VR256:$src2, VR256:$src3, u8imm:$src4), 408*9880d681SAndroid Build Coastguard Worker !strconcat(OpcodeStr, 409*9880d681SAndroid Build Coastguard Worker "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), 410*9880d681SAndroid Build Coastguard Worker []>, VEX_W, MemOp4, VEX_L; 411*9880d681SAndroid Build Coastguard Worker} 412*9880d681SAndroid Build Coastguard Worker 413*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble in 414*9880d681SAndroid Build Coastguard Worker defm VPERMIL2PD : xop5op<0x49, "vpermil2pd", X86vpermil2, v2f64, v4f64, 415*9880d681SAndroid Build Coastguard Worker v2i64, v4i64, loadv2f64, loadv4f64>; 416*9880d681SAndroid Build Coastguard Worker 417*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in 418*9880d681SAndroid Build Coastguard Worker defm VPERMIL2PS : xop5op<0x48, "vpermil2ps", X86vpermil2, v4f32, v8f32, 419*9880d681SAndroid Build Coastguard Worker v4i32, v8i32, loadv4f32, loadv8f32>; 420*9880d681SAndroid Build Coastguard Worker 421