| Jan Sjödin | 7c0face | 2011-12-12 19:37:49 +0000 | [diff] [blame] | 1 | //====- X86InstrXOP.td - Describe the X86 Instruction Set --*- tablegen -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file describes XOP (eXtended OPerations) |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | multiclass xop2op<bits<8> opc, string OpcodeStr, X86MemOperand x86memop> { |
| 15 | def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), |
| 16 | !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), |
| 17 | []>, VEX; |
| 18 | def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src), |
| 19 | !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), |
| 20 | []>, VEX; |
| 21 | } |
| 22 | |
| 23 | let isAsmParserOnly = 1 in { |
| 24 | defm VPHSUBWD : xop2op<0xE2, "vphsubwd", f128mem>; |
| 25 | defm VPHSUBDQ : xop2op<0xE3, "vphsubdq", f128mem>; |
| 26 | defm VPHSUBBW : xop2op<0xE1, "vphsubbw", f128mem>; |
| 27 | defm VPHADDWQ : xop2op<0xC7, "vphaddwq", f128mem>; |
| 28 | defm VPHADDWD : xop2op<0xC6, "vphaddwd", f128mem>; |
| 29 | defm VPHADDUWQ : xop2op<0xD7, "vphadduwq", f128mem>; |
| 30 | defm VPHADDUWD : xop2op<0xD6, "vphadduwd", f128mem>; |
| 31 | defm VPHADDUDQ : xop2op<0xDB, "vphaddudq", f128mem>; |
| 32 | defm VPHADDUBW : xop2op<0xD1, "vphaddubw", f128mem>; |
| 33 | defm VPHADDUBQ : xop2op<0xD3, "vphaddubq", f128mem>; |
| 34 | defm VPHADDUBD : xop2op<0xD2, "vphaddubd", f128mem>; |
| 35 | defm VPHADDDQ : xop2op<0xCB, "vphadddq", f128mem>; |
| 36 | defm VPHADDBW : xop2op<0xC1, "vphaddbw", f128mem>; |
| 37 | defm VPHADDBQ : xop2op<0xC3, "vphaddbq", f128mem>; |
| 38 | defm VPHADDBD : xop2op<0xC2, "vphaddbd", f128mem>; |
| 39 | defm VFRCZSS : xop2op<0x82, "vfrczss", f32mem>; |
| 40 | defm VFRCZSD : xop2op<0x83, "vfrczsd", f64mem>; |
| 41 | defm VFRCZPS : xop2op<0x80, "vfrczps", f128mem>; |
| 42 | defm VFRCZPD : xop2op<0x81, "vfrczpd", f128mem>; |
| 43 | } |
| 44 | |
| 45 | multiclass xop2op256<bits<8> opc, string OpcodeStr> { |
| 46 | def rrY : IXOP<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src), |
| 47 | !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), |
| 48 | []>, VEX, VEX_L; |
| 49 | def rmY : IXOP<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src), |
| 50 | !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), |
| 51 | []>, VEX; |
| 52 | } |
| 53 | |
| 54 | let isAsmParserOnly = 1 in { |
| 55 | defm VFRCZPS : xop2op256<0x80, "vfrczps">; |
| 56 | defm VFRCZPD : xop2op256<0x81, "vfrczpd">; |
| 57 | } |
| 58 | |
| 59 | multiclass xop3op<bits<8> opc, string OpcodeStr> { |
| 60 | def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), |
| 61 | (ins VR128:$src1, VR128:$src2), |
| 62 | !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), |
| 63 | []>, VEX_4VOp3; |
| 64 | def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), |
| 65 | (ins VR128:$src1, f128mem:$src2), |
| 66 | !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), |
| 67 | []>, VEX_4V, VEX_W; |
| 68 | def mr : IXOP<opc, MRMSrcMem, (outs VR128:$dst), |
| 69 | (ins f128mem:$src1, VR128:$src2), |
| 70 | !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), |
| 71 | []>, VEX_4VOp3; |
| 72 | } |
| 73 | |
| 74 | let isAsmParserOnly = 1 in { |
| 75 | defm VPSHLW : xop3op<0x95, "vpshlw">; |
| 76 | defm VPSHLQ : xop3op<0x97, "vpshlq">; |
| 77 | defm VPSHLD : xop3op<0x96, "vpshld">; |
| 78 | defm VPSHLB : xop3op<0x94, "vpshlb">; |
| 79 | defm VPSHAW : xop3op<0x99, "vpshaw">; |
| 80 | defm VPSHAQ : xop3op<0x9B, "vpshaq">; |
| 81 | defm VPSHAD : xop3op<0x9A, "vpshad">; |
| 82 | defm VPSHAB : xop3op<0x98, "vpshab">; |
| 83 | defm VPROTW : xop3op<0x91, "vprotw">; |
| 84 | defm VPROTQ : xop3op<0x93, "vprotq">; |
| 85 | defm VPROTD : xop3op<0x92, "vprotd">; |
| 86 | defm VPROTB : xop3op<0x90, "vprotb">; |
| 87 | } |
| 88 | |
| 89 | multiclass xop3opimm<bits<8> opc, string OpcodeStr> { |
| 90 | def ri : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), |
| 91 | (ins VR128:$src1, i8imm:$src2), |
| 92 | !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), |
| 93 | []>, VEX; |
| 94 | def mi : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), |
| 95 | (ins f128mem:$src1, i8imm:$src2), |
| 96 | !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), |
| 97 | []>, VEX; |
| 98 | } |
| 99 | |
| 100 | let isAsmParserOnly = 1 in { |
| 101 | defm VPROTW : xop3opimm<0xC1, "vprotw">; |
| 102 | defm VPROTQ : xop3opimm<0xC3, "vprotq">; |
| 103 | defm VPROTD : xop3opimm<0xC2, "vprotd">; |
| 104 | defm VPROTB : xop3opimm<0xC0, "vprotb">; |
| 105 | } |
| 106 | |
| 107 | // Instruction where second source can be memory, but third must be register |
| 108 | multiclass xop4opm2<bits<8> opc, string OpcodeStr> { |
| 109 | def rr : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), |
| 110 | (ins VR128:$src1, VR128:$src2, VR128:$src3), |
| 111 | !strconcat(OpcodeStr, |
| 112 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| 113 | []>, VEX_4V, VEX_I8IMM; |
| 114 | def rm : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), |
| 115 | (ins VR128:$src1, f128mem:$src2, VR128:$src3), |
| 116 | !strconcat(OpcodeStr, |
| 117 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| 118 | []>, VEX_4V, VEX_I8IMM; |
| 119 | } |
| 120 | |
| 121 | let isAsmParserOnly = 1 in { |
| 122 | defm VPMADCSWD : xop4opm2<0xB6, "vpmadcswd">; |
| 123 | defm VPMADCSSWD : xop4opm2<0xA6, "vpmadcsswd">; |
| 124 | defm VPMACSWW : xop4opm2<0x95, "vpmacsww">; |
| 125 | defm VPMACSWD : xop4opm2<0x96, "vpmacswd">; |
| 126 | defm VPMACSSWW : xop4opm2<0x85, "vpmacssww">; |
| 127 | defm VPMACSSWD : xop4opm2<0x86, "vpmacsswd">; |
| 128 | defm VPMACSSDQL : xop4opm2<0x87, "vpmacssdql">; |
| 129 | defm VPMACSSDQH : xop4opm2<0x8F, "vpmacssdqh">; |
| 130 | defm VPMACSSDD : xop4opm2<0x8E, "vpmacssdd">; |
| 131 | defm VPMACSDQL : xop4opm2<0x97, "vpmacsdql">; |
| 132 | defm VPMACSDQH : xop4opm2<0x9F, "vpmacsdqh">; |
| 133 | defm VPMACSDD : xop4opm2<0x9E, "vpmacsdd">; |
| 134 | } |
| 135 | |
| 136 | // Instruction where second source can be memory, third must be imm8 |
| 137 | multiclass xop4opimm<bits<8> opc, string OpcodeStr> { |
| 138 | def ri : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), |
| 139 | (ins VR128:$src1, VR128:$src2, i8imm:$src3), |
| 140 | !strconcat(OpcodeStr, |
| 141 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| 142 | []>, VEX_4V; |
| 143 | def mi : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), |
| 144 | (ins VR128:$src1, f128mem:$src2, i8imm:$src3), |
| 145 | !strconcat(OpcodeStr, |
| 146 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| 147 | []>, VEX_4V; |
| 148 | } |
| 149 | |
| 150 | let isAsmParserOnly = 1 in { |
| 151 | defm VPCOMW : xop4opimm<0xCD, "vpcomw">; |
| 152 | defm VPCOMUW : xop4opimm<0xED, "vpcomuw">; |
| 153 | defm VPCOMUQ : xop4opimm<0xEF, "vpcomuq">; |
| 154 | defm VPCOMUD : xop4opimm<0xEE, "vpcomud">; |
| 155 | defm VPCOMUB : xop4opimm<0xEC, "vpcomub">; |
| 156 | defm VPCOMQ : xop4opimm<0xCF, "vpcomq">; |
| 157 | defm VPCOMD : xop4opimm<0xCE, "vpcomd">; |
| 158 | defm VPCOMB : xop4opimm<0xCC, "vpcomb">; |
| 159 | } |
| 160 | |
| 161 | // Instruction where either second or third source can be memory |
| 162 | multiclass xop4op<bits<8> opc, string OpcodeStr> { |
| 163 | def rr : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), |
| 164 | (ins VR128:$src1, VR128:$src2, VR128:$src3), |
| 165 | !strconcat(OpcodeStr, |
| 166 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| 167 | []>, VEX_4V, VEX_I8IMM; |
| 168 | def rm : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), |
| 169 | (ins VR128:$src1, VR128:$src2, f128mem:$src3), |
| 170 | !strconcat(OpcodeStr, |
| 171 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| Craig Topper | cd93de9 | 2011-12-30 04:48:54 +0000 | [diff] [blame^] | 172 | []>, VEX_4V, VEX_I8IMM, VEX_W, MemOp4; |
| Jan Sjödin | 7c0face | 2011-12-12 19:37:49 +0000 | [diff] [blame] | 173 | def mr : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), |
| 174 | (ins VR128:$src1, f128mem:$src2, VR128:$src3), |
| 175 | !strconcat(OpcodeStr, |
| 176 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| 177 | []>, VEX_4V, VEX_I8IMM; |
| 178 | } |
| 179 | |
| 180 | let isAsmParserOnly = 1 in { |
| 181 | defm VPPERM : xop4op<0xA3, "vpperm">; |
| 182 | defm VPCMOV : xop4op<0xA2, "vpcmov">; |
| 183 | } |
| 184 | |
| 185 | multiclass xop4op256<bits<8> opc, string OpcodeStr> { |
| 186 | def rrY : IXOPi8<opc, MRMSrcReg, (outs VR256:$dst), |
| 187 | (ins VR256:$src1, VR256:$src2, VR256:$src3), |
| 188 | !strconcat(OpcodeStr, |
| 189 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| 190 | []>, VEX_4V, VEX_I8IMM; |
| 191 | def rmY : IXOPi8<opc, MRMSrcMem, (outs VR256:$dst), |
| 192 | (ins VR256:$src1, VR256:$src2, f256mem:$src3), |
| 193 | !strconcat(OpcodeStr, |
| 194 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| Craig Topper | cd93de9 | 2011-12-30 04:48:54 +0000 | [diff] [blame^] | 195 | []>, VEX_4V, VEX_I8IMM, VEX_W, MemOp4; |
| Jan Sjödin | 7c0face | 2011-12-12 19:37:49 +0000 | [diff] [blame] | 196 | def mrY : IXOPi8<opc, MRMSrcMem, (outs VR256:$dst), |
| 197 | (ins VR256:$src1, f256mem:$src2, VR256:$src3), |
| 198 | !strconcat(OpcodeStr, |
| 199 | "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), |
| 200 | []>, VEX_4V, VEX_I8IMM; |
| 201 | } |
| 202 | |
| 203 | let isAsmParserOnly = 1 in { |
| 204 | defm VPCMOV : xop4op256<0xA2, "vpcmov">; |
| 205 | } |
| 206 | |
| 207 | multiclass xop5op<bits<8> opc, string OpcodeStr> { |
| 208 | def rr : IXOP5<opc, MRMSrcReg, (outs VR128:$dst), |
| 209 | (ins VR128:$src1, VR128:$src2, VR128:$src3, i8imm:$src4), |
| 210 | !strconcat(OpcodeStr, |
| 211 | "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), |
| 212 | []>; |
| 213 | def rm : IXOP5<opc, MRMSrcMem, (outs VR128:$dst), |
| 214 | (ins VR128:$src1, VR128:$src2, f128mem:$src3, i8imm:$src4), |
| 215 | !strconcat(OpcodeStr, |
| 216 | "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), |
| Craig Topper | cd93de9 | 2011-12-30 04:48:54 +0000 | [diff] [blame^] | 217 | []>, VEX_W, MemOp4; |
| Jan Sjödin | 7c0face | 2011-12-12 19:37:49 +0000 | [diff] [blame] | 218 | def mr : IXOP5<opc, MRMSrcMem, (outs VR128:$dst), |
| 219 | (ins VR128:$src1, f128mem:$src2, VR128:$src3, i8imm:$src4), |
| 220 | !strconcat(OpcodeStr, |
| 221 | "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), |
| 222 | []>; |
| 223 | def rrY : IXOP5<opc, MRMSrcReg, (outs VR256:$dst), |
| 224 | (ins VR256:$src1, VR256:$src2, VR256:$src3, i8imm:$src4), |
| 225 | !strconcat(OpcodeStr, |
| 226 | "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), |
| 227 | []>; |
| 228 | def rmY : IXOP5<opc, MRMSrcMem, (outs VR256:$dst), |
| 229 | (ins VR256:$src1, VR256:$src2, f256mem:$src3, i8imm:$src4), |
| 230 | !strconcat(OpcodeStr, |
| 231 | "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), |
| Craig Topper | cd93de9 | 2011-12-30 04:48:54 +0000 | [diff] [blame^] | 232 | []>, VEX_W, MemOp4; |
| Jan Sjödin | 7c0face | 2011-12-12 19:37:49 +0000 | [diff] [blame] | 233 | def mrY : IXOP5<opc, MRMSrcMem, (outs VR256:$dst), |
| 234 | (ins VR256:$src1, f256mem:$src2, VR256:$src3, i8imm:$src4), |
| 235 | !strconcat(OpcodeStr, |
| 236 | "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), |
| 237 | []>; |
| 238 | } |
| 239 | |
| 240 | let isAsmParserOnly = 1 in { |
| 241 | defm VPERMIL2PD : xop5op<0x49, "vpermil2pd">; |
| 242 | defm VPERMIL2PS : xop5op<0x48, "vpermil2ps">; |
| 243 | } |