1f4a2713aSLionel Sambuc//===-- X86InstrFMA.td - FMA Instruction Set ---------------*- tablegen -*-===// 2f4a2713aSLionel Sambuc// 3f4a2713aSLionel Sambuc// The LLVM Compiler Infrastructure 4f4a2713aSLionel Sambuc// 5f4a2713aSLionel Sambuc// This file is distributed under the University of Illinois Open Source 6f4a2713aSLionel Sambuc// License. See LICENSE.TXT for details. 7f4a2713aSLionel Sambuc// 8f4a2713aSLionel Sambuc//===----------------------------------------------------------------------===// 9f4a2713aSLionel Sambuc// 10f4a2713aSLionel Sambuc// This file describes FMA (Fused Multiply-Add) instructions. 11f4a2713aSLionel Sambuc// 12f4a2713aSLionel Sambuc//===----------------------------------------------------------------------===// 13f4a2713aSLionel Sambuc 14f4a2713aSLionel Sambuc//===----------------------------------------------------------------------===// 15f4a2713aSLionel Sambuc// FMA3 - Intel 3 operand Fused Multiply-Add instructions 16f4a2713aSLionel Sambuc//===----------------------------------------------------------------------===// 17f4a2713aSLionel Sambuc 18f4a2713aSLionel Sambuclet Constraints = "$src1 = $dst" in { 19f4a2713aSLionel Sambucmulticlass fma3p_rm<bits<8> opc, string OpcodeStr, 20f4a2713aSLionel Sambuc PatFrag MemFrag128, PatFrag MemFrag256, 21f4a2713aSLionel Sambuc ValueType OpVT128, ValueType OpVT256, 22*0a6a1f1dSLionel Sambuc bit IsRVariantCommutable = 0, bit IsMVariantCommutable = 0, 23f4a2713aSLionel Sambuc SDPatternOperator Op = null_frag> { 24*0a6a1f1dSLionel Sambuc let usesCustomInserter = 1, isCommutable = IsRVariantCommutable in 25f4a2713aSLionel Sambuc def r : FMA3<opc, MRMSrcReg, (outs VR128:$dst), 26f4a2713aSLionel Sambuc (ins VR128:$src1, VR128:$src2, VR128:$src3), 27f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 28f4a2713aSLionel Sambuc "\t{$src3, $src2, $dst|$dst, $src2, $src3}"), 29f4a2713aSLionel Sambuc [(set VR128:$dst, (OpVT128 (Op VR128:$src2, 30f4a2713aSLionel Sambuc VR128:$src1, VR128:$src3)))]>; 31f4a2713aSLionel Sambuc 32*0a6a1f1dSLionel Sambuc let mayLoad = 1, isCommutable = IsMVariantCommutable in 33f4a2713aSLionel Sambuc def m : FMA3<opc, MRMSrcMem, (outs VR128:$dst), 34f4a2713aSLionel Sambuc (ins VR128:$src1, VR128:$src2, f128mem:$src3), 35f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 36f4a2713aSLionel Sambuc "\t{$src3, $src2, $dst|$dst, $src2, $src3}"), 37f4a2713aSLionel Sambuc [(set VR128:$dst, (OpVT128 (Op VR128:$src2, VR128:$src1, 38f4a2713aSLionel Sambuc (MemFrag128 addr:$src3))))]>; 39f4a2713aSLionel Sambuc 40*0a6a1f1dSLionel Sambuc let usesCustomInserter = 1, isCommutable = IsRVariantCommutable in 41f4a2713aSLionel Sambuc def rY : FMA3<opc, MRMSrcReg, (outs VR256:$dst), 42f4a2713aSLionel Sambuc (ins VR256:$src1, VR256:$src2, VR256:$src3), 43f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 44f4a2713aSLionel Sambuc "\t{$src3, $src2, $dst|$dst, $src2, $src3}"), 45f4a2713aSLionel Sambuc [(set VR256:$dst, (OpVT256 (Op VR256:$src2, VR256:$src1, 46f4a2713aSLionel Sambuc VR256:$src3)))]>, VEX_L; 47f4a2713aSLionel Sambuc 48*0a6a1f1dSLionel Sambuc let mayLoad = 1, isCommutable = IsMVariantCommutable in 49f4a2713aSLionel Sambuc def mY : FMA3<opc, MRMSrcMem, (outs VR256:$dst), 50f4a2713aSLionel Sambuc (ins VR256:$src1, VR256:$src2, f256mem:$src3), 51f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 52f4a2713aSLionel Sambuc "\t{$src3, $src2, $dst|$dst, $src2, $src3}"), 53f4a2713aSLionel Sambuc [(set VR256:$dst, 54f4a2713aSLionel Sambuc (OpVT256 (Op VR256:$src2, VR256:$src1, 55f4a2713aSLionel Sambuc (MemFrag256 addr:$src3))))]>, VEX_L; 56f4a2713aSLionel Sambuc} 57f4a2713aSLionel Sambuc} // Constraints = "$src1 = $dst" 58f4a2713aSLionel Sambuc 59f4a2713aSLionel Sambucmulticlass fma3p_forms<bits<8> opc132, bits<8> opc213, bits<8> opc231, 60f4a2713aSLionel Sambuc string OpcodeStr, string PackTy, 61f4a2713aSLionel Sambuc PatFrag MemFrag128, PatFrag MemFrag256, 62f4a2713aSLionel Sambuc SDNode Op, ValueType OpTy128, ValueType OpTy256> { 63*0a6a1f1dSLionel Sambuc // For 213, both the register and memory variant are commutable. 64*0a6a1f1dSLionel Sambuc // Indeed, the commutable operands are 1 and 2 and both live in registers 65*0a6a1f1dSLionel Sambuc // for both variants. 66f4a2713aSLionel Sambuc defm r213 : fma3p_rm<opc213, 67f4a2713aSLionel Sambuc !strconcat(OpcodeStr, "213", PackTy), 68*0a6a1f1dSLionel Sambuc MemFrag128, MemFrag256, OpTy128, OpTy256, 69*0a6a1f1dSLionel Sambuc /* IsRVariantCommutable */ 1, 70*0a6a1f1dSLionel Sambuc /* IsMVariantCommutable */ 1, 71*0a6a1f1dSLionel Sambuc Op>; 72*0a6a1f1dSLionel Sambuclet hasSideEffects = 0 in { 73f4a2713aSLionel Sambuc defm r132 : fma3p_rm<opc132, 74f4a2713aSLionel Sambuc !strconcat(OpcodeStr, "132", PackTy), 75f4a2713aSLionel Sambuc MemFrag128, MemFrag256, OpTy128, OpTy256>; 76*0a6a1f1dSLionel Sambuc // For 231, only the register variant is commutable. 77*0a6a1f1dSLionel Sambuc // For the memory variant the folded operand must be in 3. Thus, 78*0a6a1f1dSLionel Sambuc // in that case, it cannot be swapped with 2. 79f4a2713aSLionel Sambuc defm r231 : fma3p_rm<opc231, 80f4a2713aSLionel Sambuc !strconcat(OpcodeStr, "231", PackTy), 81*0a6a1f1dSLionel Sambuc MemFrag128, MemFrag256, OpTy128, OpTy256, 82*0a6a1f1dSLionel Sambuc /* IsRVariantCommutable */ 1, 83*0a6a1f1dSLionel Sambuc /* IsMVariantCommutable */ 0>; 84*0a6a1f1dSLionel Sambuc} // hasSideEffects = 0 85f4a2713aSLionel Sambuc} 86f4a2713aSLionel Sambuc 87f4a2713aSLionel Sambuc// Fused Multiply-Add 88f4a2713aSLionel Sambuclet ExeDomain = SSEPackedSingle in { 89f4a2713aSLionel Sambuc defm VFMADDPS : fma3p_forms<0x98, 0xA8, 0xB8, "vfmadd", "ps", loadv4f32, 90f4a2713aSLionel Sambuc loadv8f32, X86Fmadd, v4f32, v8f32>; 91f4a2713aSLionel Sambuc defm VFMSUBPS : fma3p_forms<0x9A, 0xAA, 0xBA, "vfmsub", "ps", loadv4f32, 92f4a2713aSLionel Sambuc loadv8f32, X86Fmsub, v4f32, v8f32>; 93f4a2713aSLionel Sambuc defm VFMADDSUBPS : fma3p_forms<0x96, 0xA6, 0xB6, "vfmaddsub", "ps", 94f4a2713aSLionel Sambuc loadv4f32, loadv8f32, X86Fmaddsub, 95f4a2713aSLionel Sambuc v4f32, v8f32>; 96f4a2713aSLionel Sambuc defm VFMSUBADDPS : fma3p_forms<0x97, 0xA7, 0xB7, "vfmsubadd", "ps", 97f4a2713aSLionel Sambuc loadv4f32, loadv8f32, X86Fmsubadd, 98f4a2713aSLionel Sambuc v4f32, v8f32>; 99f4a2713aSLionel Sambuc} 100f4a2713aSLionel Sambuc 101f4a2713aSLionel Sambuclet ExeDomain = SSEPackedDouble in { 102f4a2713aSLionel Sambuc defm VFMADDPD : fma3p_forms<0x98, 0xA8, 0xB8, "vfmadd", "pd", loadv2f64, 103f4a2713aSLionel Sambuc loadv4f64, X86Fmadd, v2f64, v4f64>, VEX_W; 104f4a2713aSLionel Sambuc defm VFMSUBPD : fma3p_forms<0x9A, 0xAA, 0xBA, "vfmsub", "pd", loadv2f64, 105f4a2713aSLionel Sambuc loadv4f64, X86Fmsub, v2f64, v4f64>, VEX_W; 106f4a2713aSLionel Sambuc defm VFMADDSUBPD : fma3p_forms<0x96, 0xA6, 0xB6, "vfmaddsub", "pd", 107f4a2713aSLionel Sambuc loadv2f64, loadv4f64, X86Fmaddsub, 108f4a2713aSLionel Sambuc v2f64, v4f64>, VEX_W; 109f4a2713aSLionel Sambuc defm VFMSUBADDPD : fma3p_forms<0x97, 0xA7, 0xB7, "vfmsubadd", "pd", 110f4a2713aSLionel Sambuc loadv2f64, loadv4f64, X86Fmsubadd, 111f4a2713aSLionel Sambuc v2f64, v4f64>, VEX_W; 112f4a2713aSLionel Sambuc} 113f4a2713aSLionel Sambuc 114f4a2713aSLionel Sambuc// Fused Negative Multiply-Add 115f4a2713aSLionel Sambuclet ExeDomain = SSEPackedSingle in { 116f4a2713aSLionel Sambuc defm VFNMADDPS : fma3p_forms<0x9C, 0xAC, 0xBC, "vfnmadd", "ps", loadv4f32, 117f4a2713aSLionel Sambuc loadv8f32, X86Fnmadd, v4f32, v8f32>; 118f4a2713aSLionel Sambuc defm VFNMSUBPS : fma3p_forms<0x9E, 0xAE, 0xBE, "vfnmsub", "ps", loadv4f32, 119f4a2713aSLionel Sambuc loadv8f32, X86Fnmsub, v4f32, v8f32>; 120f4a2713aSLionel Sambuc} 121f4a2713aSLionel Sambuclet ExeDomain = SSEPackedDouble in { 122f4a2713aSLionel Sambuc defm VFNMADDPD : fma3p_forms<0x9C, 0xAC, 0xBC, "vfnmadd", "pd", loadv2f64, 123f4a2713aSLionel Sambuc loadv4f64, X86Fnmadd, v2f64, v4f64>, VEX_W; 124f4a2713aSLionel Sambuc defm VFNMSUBPD : fma3p_forms<0x9E, 0xAE, 0xBE, "vfnmsub", "pd", 125f4a2713aSLionel Sambuc loadv2f64, loadv4f64, X86Fnmsub, v2f64, 126f4a2713aSLionel Sambuc v4f64>, VEX_W; 127f4a2713aSLionel Sambuc} 128f4a2713aSLionel Sambuc 129f4a2713aSLionel Sambuclet Constraints = "$src1 = $dst" in { 130f4a2713aSLionel Sambucmulticlass fma3s_rm<bits<8> opc, string OpcodeStr, X86MemOperand x86memop, 131f4a2713aSLionel Sambuc RegisterClass RC, ValueType OpVT, PatFrag mem_frag, 132*0a6a1f1dSLionel Sambuc bit IsRVariantCommutable = 0, bit IsMVariantCommutable = 0, 133f4a2713aSLionel Sambuc SDPatternOperator OpNode = null_frag> { 134*0a6a1f1dSLionel Sambuc let usesCustomInserter = 1, isCommutable = IsRVariantCommutable in 135f4a2713aSLionel Sambuc def r : FMA3<opc, MRMSrcReg, (outs RC:$dst), 136f4a2713aSLionel Sambuc (ins RC:$src1, RC:$src2, RC:$src3), 137f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 138f4a2713aSLionel Sambuc "\t{$src3, $src2, $dst|$dst, $src2, $src3}"), 139f4a2713aSLionel Sambuc [(set RC:$dst, 140f4a2713aSLionel Sambuc (OpVT (OpNode RC:$src2, RC:$src1, RC:$src3)))]>; 141*0a6a1f1dSLionel Sambuc 142*0a6a1f1dSLionel Sambuc let mayLoad = 1, isCommutable = IsMVariantCommutable in 143f4a2713aSLionel Sambuc def m : FMA3<opc, MRMSrcMem, (outs RC:$dst), 144f4a2713aSLionel Sambuc (ins RC:$src1, RC:$src2, x86memop:$src3), 145f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 146f4a2713aSLionel Sambuc "\t{$src3, $src2, $dst|$dst, $src2, $src3}"), 147f4a2713aSLionel Sambuc [(set RC:$dst, 148f4a2713aSLionel Sambuc (OpVT (OpNode RC:$src2, RC:$src1, 149f4a2713aSLionel Sambuc (mem_frag addr:$src3))))]>; 150f4a2713aSLionel Sambuc} 151f4a2713aSLionel Sambuc} // Constraints = "$src1 = $dst" 152f4a2713aSLionel Sambuc 153f4a2713aSLionel Sambucmulticlass fma3s_forms<bits<8> opc132, bits<8> opc213, bits<8> opc231, 154*0a6a1f1dSLionel Sambuc string OpStr, string PackTy, string PT2, Intrinsic Int, 155f4a2713aSLionel Sambuc SDNode OpNode, RegisterClass RC, ValueType OpVT, 156f4a2713aSLionel Sambuc X86MemOperand x86memop, Operand memop, PatFrag mem_frag, 157f4a2713aSLionel Sambuc ComplexPattern mem_cpat> { 158*0a6a1f1dSLionel Sambuclet hasSideEffects = 0 in { 159f4a2713aSLionel Sambuc defm r132 : fma3s_rm<opc132, !strconcat(OpStr, "132", PackTy), 160f4a2713aSLionel Sambuc x86memop, RC, OpVT, mem_frag>; 161*0a6a1f1dSLionel Sambuc // See the other defm of r231 for the explanation regarding the 162*0a6a1f1dSLionel Sambuc // commutable flags. 163f4a2713aSLionel Sambuc defm r231 : fma3s_rm<opc231, !strconcat(OpStr, "231", PackTy), 164*0a6a1f1dSLionel Sambuc x86memop, RC, OpVT, mem_frag, 165*0a6a1f1dSLionel Sambuc /* IsRVariantCommutable */ 1, 166*0a6a1f1dSLionel Sambuc /* IsMVariantCommutable */ 0>; 167f4a2713aSLionel Sambuc} 168f4a2713aSLionel Sambuc 169*0a6a1f1dSLionel Sambuc// See the other defm of r213 for the explanation regarding the 170*0a6a1f1dSLionel Sambuc// commutable flags. 171f4a2713aSLionel Sambucdefm r213 : fma3s_rm<opc213, !strconcat(OpStr, "213", PackTy), 172*0a6a1f1dSLionel Sambuc x86memop, RC, OpVT, mem_frag, 173*0a6a1f1dSLionel Sambuc /* IsRVariantCommutable */ 1, 174*0a6a1f1dSLionel Sambuc /* IsMVariantCommutable */ 1, 175*0a6a1f1dSLionel Sambuc OpNode>; 176f4a2713aSLionel Sambuc} 177f4a2713aSLionel Sambuc 178f4a2713aSLionel Sambucmulticlass fma3s<bits<8> opc132, bits<8> opc213, bits<8> opc231, 179f4a2713aSLionel Sambuc string OpStr, Intrinsic IntF32, Intrinsic IntF64, 180f4a2713aSLionel Sambuc SDNode OpNode> { 181*0a6a1f1dSLionel Sambuc defm SS : fma3s_forms<opc132, opc213, opc231, OpStr, "ss", "SS", IntF32, OpNode, 182f4a2713aSLionel Sambuc FR32, f32, f32mem, ssmem, loadf32, sse_load_f32>; 183*0a6a1f1dSLionel Sambuc defm SD : fma3s_forms<opc132, opc213, opc231, OpStr, "sd", "PD", IntF64, OpNode, 184f4a2713aSLionel Sambuc FR64, f64, f64mem, sdmem, loadf64, sse_load_f64>, VEX_W; 185*0a6a1f1dSLionel Sambuc 186*0a6a1f1dSLionel Sambuc def : Pat<(IntF32 VR128:$src1, VR128:$src2, VR128:$src3), 187*0a6a1f1dSLionel Sambuc (COPY_TO_REGCLASS 188*0a6a1f1dSLionel Sambuc (!cast<Instruction>(NAME#"SSr213r") 189*0a6a1f1dSLionel Sambuc (COPY_TO_REGCLASS $src2, FR32), 190*0a6a1f1dSLionel Sambuc (COPY_TO_REGCLASS $src1, FR32), 191*0a6a1f1dSLionel Sambuc (COPY_TO_REGCLASS $src3, FR32)), 192*0a6a1f1dSLionel Sambuc VR128)>; 193*0a6a1f1dSLionel Sambuc 194*0a6a1f1dSLionel Sambuc def : Pat<(IntF64 VR128:$src1, VR128:$src2, VR128:$src3), 195*0a6a1f1dSLionel Sambuc (COPY_TO_REGCLASS 196*0a6a1f1dSLionel Sambuc (!cast<Instruction>(NAME#"SDr213r") 197*0a6a1f1dSLionel Sambuc (COPY_TO_REGCLASS $src2, FR64), 198*0a6a1f1dSLionel Sambuc (COPY_TO_REGCLASS $src1, FR64), 199*0a6a1f1dSLionel Sambuc (COPY_TO_REGCLASS $src3, FR64)), 200*0a6a1f1dSLionel Sambuc VR128)>; 201f4a2713aSLionel Sambuc} 202f4a2713aSLionel Sambuc 203f4a2713aSLionel Sambucdefm VFMADD : fma3s<0x99, 0xA9, 0xB9, "vfmadd", int_x86_fma_vfmadd_ss, 204f4a2713aSLionel Sambuc int_x86_fma_vfmadd_sd, X86Fmadd>, VEX_LIG; 205f4a2713aSLionel Sambucdefm VFMSUB : fma3s<0x9B, 0xAB, 0xBB, "vfmsub", int_x86_fma_vfmsub_ss, 206f4a2713aSLionel Sambuc int_x86_fma_vfmsub_sd, X86Fmsub>, VEX_LIG; 207f4a2713aSLionel Sambuc 208f4a2713aSLionel Sambucdefm VFNMADD : fma3s<0x9D, 0xAD, 0xBD, "vfnmadd", int_x86_fma_vfnmadd_ss, 209f4a2713aSLionel Sambuc int_x86_fma_vfnmadd_sd, X86Fnmadd>, VEX_LIG; 210f4a2713aSLionel Sambucdefm VFNMSUB : fma3s<0x9F, 0xAF, 0xBF, "vfnmsub", int_x86_fma_vfnmsub_ss, 211f4a2713aSLionel Sambuc int_x86_fma_vfnmsub_sd, X86Fnmsub>, VEX_LIG; 212f4a2713aSLionel Sambuc 213f4a2713aSLionel Sambuc 214f4a2713aSLionel Sambuc//===----------------------------------------------------------------------===// 215f4a2713aSLionel Sambuc// FMA4 - AMD 4 operand Fused Multiply-Add instructions 216f4a2713aSLionel Sambuc//===----------------------------------------------------------------------===// 217f4a2713aSLionel Sambuc 218f4a2713aSLionel Sambuc 219f4a2713aSLionel Sambucmulticlass fma4s<bits<8> opc, string OpcodeStr, RegisterClass RC, 220f4a2713aSLionel Sambuc X86MemOperand x86memop, ValueType OpVT, SDNode OpNode, 221f4a2713aSLionel Sambuc PatFrag mem_frag> { 222f4a2713aSLionel Sambuc let isCommutable = 1 in 223f4a2713aSLionel Sambuc def rr : FMA4<opc, MRMSrcReg, (outs RC:$dst), 224f4a2713aSLionel Sambuc (ins RC:$src1, RC:$src2, RC:$src3), 225f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 226f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 227f4a2713aSLionel Sambuc [(set RC:$dst, 228f4a2713aSLionel Sambuc (OpVT (OpNode RC:$src1, RC:$src2, RC:$src3)))]>, VEX_W, VEX_LIG, MemOp4; 229f4a2713aSLionel Sambuc def rm : FMA4<opc, MRMSrcMem, (outs RC:$dst), 230f4a2713aSLionel Sambuc (ins RC:$src1, RC:$src2, x86memop:$src3), 231f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 232f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 233f4a2713aSLionel Sambuc [(set RC:$dst, (OpNode RC:$src1, RC:$src2, 234f4a2713aSLionel Sambuc (mem_frag addr:$src3)))]>, VEX_W, VEX_LIG, MemOp4; 235f4a2713aSLionel Sambuc def mr : FMA4<opc, MRMSrcMem, (outs RC:$dst), 236f4a2713aSLionel Sambuc (ins RC:$src1, x86memop:$src2, RC:$src3), 237f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 238f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 239f4a2713aSLionel Sambuc [(set RC:$dst, 240f4a2713aSLionel Sambuc (OpNode RC:$src1, (mem_frag addr:$src2), RC:$src3))]>, VEX_LIG; 241f4a2713aSLionel Sambuc// For disassembler 242*0a6a1f1dSLionel Sambuclet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in 243f4a2713aSLionel Sambuc def rr_REV : FMA4<opc, MRMSrcReg, (outs RC:$dst), 244f4a2713aSLionel Sambuc (ins RC:$src1, RC:$src2, RC:$src3), 245f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 246f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), []>, 247f4a2713aSLionel Sambuc VEX_LIG; 248f4a2713aSLionel Sambuc} 249f4a2713aSLionel Sambuc 250f4a2713aSLionel Sambucmulticlass fma4s_int<bits<8> opc, string OpcodeStr, Operand memop, 251f4a2713aSLionel Sambuc ComplexPattern mem_cpat, Intrinsic Int> { 252*0a6a1f1dSLionel Sambuclet isCodeGenOnly = 1 in { 253f4a2713aSLionel Sambuc let isCommutable = 1 in 254f4a2713aSLionel Sambuc def rr_Int : FMA4<opc, MRMSrcReg, (outs VR128:$dst), 255f4a2713aSLionel Sambuc (ins VR128:$src1, VR128:$src2, VR128:$src3), 256f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 257f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 258f4a2713aSLionel Sambuc [(set VR128:$dst, 259f4a2713aSLionel Sambuc (Int VR128:$src1, VR128:$src2, VR128:$src3))]>, VEX_W, VEX_LIG, MemOp4; 260f4a2713aSLionel Sambuc def rm_Int : FMA4<opc, MRMSrcMem, (outs VR128:$dst), 261f4a2713aSLionel Sambuc (ins VR128:$src1, VR128:$src2, memop:$src3), 262f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 263f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 264f4a2713aSLionel Sambuc [(set VR128:$dst, (Int VR128:$src1, VR128:$src2, 265f4a2713aSLionel Sambuc mem_cpat:$src3))]>, VEX_W, VEX_LIG, MemOp4; 266f4a2713aSLionel Sambuc def mr_Int : FMA4<opc, MRMSrcMem, (outs VR128:$dst), 267f4a2713aSLionel Sambuc (ins VR128:$src1, memop:$src2, VR128:$src3), 268f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 269f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 270f4a2713aSLionel Sambuc [(set VR128:$dst, 271f4a2713aSLionel Sambuc (Int VR128:$src1, mem_cpat:$src2, VR128:$src3))]>, VEX_LIG; 272*0a6a1f1dSLionel Sambuc} // isCodeGenOnly = 1 273f4a2713aSLionel Sambuc} 274f4a2713aSLionel Sambuc 275f4a2713aSLionel Sambucmulticlass fma4p<bits<8> opc, string OpcodeStr, SDNode OpNode, 276f4a2713aSLionel Sambuc ValueType OpVT128, ValueType OpVT256, 277f4a2713aSLionel Sambuc PatFrag ld_frag128, PatFrag ld_frag256> { 278f4a2713aSLionel Sambuc let isCommutable = 1 in 279f4a2713aSLionel Sambuc def rr : FMA4<opc, MRMSrcReg, (outs VR128:$dst), 280f4a2713aSLionel Sambuc (ins VR128:$src1, VR128:$src2, VR128:$src3), 281f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 282f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 283f4a2713aSLionel Sambuc [(set VR128:$dst, 284f4a2713aSLionel Sambuc (OpVT128 (OpNode VR128:$src1, VR128:$src2, VR128:$src3)))]>, 285f4a2713aSLionel Sambuc VEX_W, MemOp4; 286f4a2713aSLionel Sambuc def rm : FMA4<opc, MRMSrcMem, (outs VR128:$dst), 287f4a2713aSLionel Sambuc (ins VR128:$src1, VR128:$src2, f128mem:$src3), 288f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 289f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 290f4a2713aSLionel Sambuc [(set VR128:$dst, (OpNode VR128:$src1, VR128:$src2, 291f4a2713aSLionel Sambuc (ld_frag128 addr:$src3)))]>, VEX_W, MemOp4; 292f4a2713aSLionel Sambuc def mr : FMA4<opc, MRMSrcMem, (outs VR128:$dst), 293f4a2713aSLionel Sambuc (ins VR128:$src1, f128mem:$src2, VR128:$src3), 294f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 295f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 296f4a2713aSLionel Sambuc [(set VR128:$dst, 297f4a2713aSLionel Sambuc (OpNode VR128:$src1, (ld_frag128 addr:$src2), VR128:$src3))]>; 298f4a2713aSLionel Sambuc let isCommutable = 1 in 299f4a2713aSLionel Sambuc def rrY : FMA4<opc, MRMSrcReg, (outs VR256:$dst), 300f4a2713aSLionel Sambuc (ins VR256:$src1, VR256:$src2, VR256:$src3), 301f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 302f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 303f4a2713aSLionel Sambuc [(set VR256:$dst, 304f4a2713aSLionel Sambuc (OpVT256 (OpNode VR256:$src1, VR256:$src2, VR256:$src3)))]>, 305f4a2713aSLionel Sambuc VEX_W, MemOp4, VEX_L; 306f4a2713aSLionel Sambuc def rmY : FMA4<opc, MRMSrcMem, (outs VR256:$dst), 307f4a2713aSLionel Sambuc (ins VR256:$src1, VR256:$src2, f256mem:$src3), 308f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 309f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 310f4a2713aSLionel Sambuc [(set VR256:$dst, (OpNode VR256:$src1, VR256:$src2, 311f4a2713aSLionel Sambuc (ld_frag256 addr:$src3)))]>, VEX_W, MemOp4, VEX_L; 312f4a2713aSLionel Sambuc def mrY : FMA4<opc, MRMSrcMem, (outs VR256:$dst), 313f4a2713aSLionel Sambuc (ins VR256:$src1, f256mem:$src2, VR256:$src3), 314f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 315f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), 316f4a2713aSLionel Sambuc [(set VR256:$dst, (OpNode VR256:$src1, 317f4a2713aSLionel Sambuc (ld_frag256 addr:$src2), VR256:$src3))]>, VEX_L; 318f4a2713aSLionel Sambuc// For disassembler 319*0a6a1f1dSLionel Sambuclet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in { 320f4a2713aSLionel Sambuc def rr_REV : FMA4<opc, MRMSrcReg, (outs VR128:$dst), 321f4a2713aSLionel Sambuc (ins VR128:$src1, VR128:$src2, VR128:$src3), 322f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 323f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), []>; 324f4a2713aSLionel Sambuc def rrY_REV : FMA4<opc, MRMSrcReg, (outs VR256:$dst), 325f4a2713aSLionel Sambuc (ins VR256:$src1, VR256:$src2, VR256:$src3), 326f4a2713aSLionel Sambuc !strconcat(OpcodeStr, 327f4a2713aSLionel Sambuc "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), []>, 328f4a2713aSLionel Sambuc VEX_L; 329f4a2713aSLionel Sambuc} // isCodeGenOnly = 1 330f4a2713aSLionel Sambuc} 331f4a2713aSLionel Sambuc 332f4a2713aSLionel Sambucdefm VFMADDSS4 : fma4s<0x6A, "vfmaddss", FR32, f32mem, f32, X86Fmadd, loadf32>, 333f4a2713aSLionel Sambuc fma4s_int<0x6A, "vfmaddss", ssmem, sse_load_f32, 334f4a2713aSLionel Sambuc int_x86_fma_vfmadd_ss>; 335f4a2713aSLionel Sambucdefm VFMADDSD4 : fma4s<0x6B, "vfmaddsd", FR64, f64mem, f64, X86Fmadd, loadf64>, 336f4a2713aSLionel Sambuc fma4s_int<0x6B, "vfmaddsd", sdmem, sse_load_f64, 337f4a2713aSLionel Sambuc int_x86_fma_vfmadd_sd>; 338f4a2713aSLionel Sambucdefm VFMSUBSS4 : fma4s<0x6E, "vfmsubss", FR32, f32mem, f32, X86Fmsub, loadf32>, 339f4a2713aSLionel Sambuc fma4s_int<0x6E, "vfmsubss", ssmem, sse_load_f32, 340f4a2713aSLionel Sambuc int_x86_fma_vfmsub_ss>; 341f4a2713aSLionel Sambucdefm VFMSUBSD4 : fma4s<0x6F, "vfmsubsd", FR64, f64mem, f64, X86Fmsub, loadf64>, 342f4a2713aSLionel Sambuc fma4s_int<0x6F, "vfmsubsd", sdmem, sse_load_f64, 343f4a2713aSLionel Sambuc int_x86_fma_vfmsub_sd>; 344f4a2713aSLionel Sambucdefm VFNMADDSS4 : fma4s<0x7A, "vfnmaddss", FR32, f32mem, f32, 345f4a2713aSLionel Sambuc X86Fnmadd, loadf32>, 346f4a2713aSLionel Sambuc fma4s_int<0x7A, "vfnmaddss", ssmem, sse_load_f32, 347f4a2713aSLionel Sambuc int_x86_fma_vfnmadd_ss>; 348f4a2713aSLionel Sambucdefm VFNMADDSD4 : fma4s<0x7B, "vfnmaddsd", FR64, f64mem, f64, 349f4a2713aSLionel Sambuc X86Fnmadd, loadf64>, 350f4a2713aSLionel Sambuc fma4s_int<0x7B, "vfnmaddsd", sdmem, sse_load_f64, 351f4a2713aSLionel Sambuc int_x86_fma_vfnmadd_sd>; 352f4a2713aSLionel Sambucdefm VFNMSUBSS4 : fma4s<0x7E, "vfnmsubss", FR32, f32mem, f32, 353f4a2713aSLionel Sambuc X86Fnmsub, loadf32>, 354f4a2713aSLionel Sambuc fma4s_int<0x7E, "vfnmsubss", ssmem, sse_load_f32, 355f4a2713aSLionel Sambuc int_x86_fma_vfnmsub_ss>; 356f4a2713aSLionel Sambucdefm VFNMSUBSD4 : fma4s<0x7F, "vfnmsubsd", FR64, f64mem, f64, 357f4a2713aSLionel Sambuc X86Fnmsub, loadf64>, 358f4a2713aSLionel Sambuc fma4s_int<0x7F, "vfnmsubsd", sdmem, sse_load_f64, 359f4a2713aSLionel Sambuc int_x86_fma_vfnmsub_sd>; 360f4a2713aSLionel Sambuc 361f4a2713aSLionel Sambuclet ExeDomain = SSEPackedSingle in { 362f4a2713aSLionel Sambuc defm VFMADDPS4 : fma4p<0x68, "vfmaddps", X86Fmadd, v4f32, v8f32, 363f4a2713aSLionel Sambuc loadv4f32, loadv8f32>; 364f4a2713aSLionel Sambuc defm VFMSUBPS4 : fma4p<0x6C, "vfmsubps", X86Fmsub, v4f32, v8f32, 365f4a2713aSLionel Sambuc loadv4f32, loadv8f32>; 366f4a2713aSLionel Sambuc defm VFNMADDPS4 : fma4p<0x78, "vfnmaddps", X86Fnmadd, v4f32, v8f32, 367f4a2713aSLionel Sambuc loadv4f32, loadv8f32>; 368f4a2713aSLionel Sambuc defm VFNMSUBPS4 : fma4p<0x7C, "vfnmsubps", X86Fnmsub, v4f32, v8f32, 369f4a2713aSLionel Sambuc loadv4f32, loadv8f32>; 370f4a2713aSLionel Sambuc defm VFMADDSUBPS4 : fma4p<0x5C, "vfmaddsubps", X86Fmaddsub, v4f32, v8f32, 371f4a2713aSLionel Sambuc loadv4f32, loadv8f32>; 372f4a2713aSLionel Sambuc defm VFMSUBADDPS4 : fma4p<0x5E, "vfmsubaddps", X86Fmsubadd, v4f32, v8f32, 373f4a2713aSLionel Sambuc loadv4f32, loadv8f32>; 374f4a2713aSLionel Sambuc} 375f4a2713aSLionel Sambuc 376f4a2713aSLionel Sambuclet ExeDomain = SSEPackedDouble in { 377f4a2713aSLionel Sambuc defm VFMADDPD4 : fma4p<0x69, "vfmaddpd", X86Fmadd, v2f64, v4f64, 378f4a2713aSLionel Sambuc loadv2f64, loadv4f64>; 379f4a2713aSLionel Sambuc defm VFMSUBPD4 : fma4p<0x6D, "vfmsubpd", X86Fmsub, v2f64, v4f64, 380f4a2713aSLionel Sambuc loadv2f64, loadv4f64>; 381f4a2713aSLionel Sambuc defm VFNMADDPD4 : fma4p<0x79, "vfnmaddpd", X86Fnmadd, v2f64, v4f64, 382f4a2713aSLionel Sambuc loadv2f64, loadv4f64>; 383f4a2713aSLionel Sambuc defm VFNMSUBPD4 : fma4p<0x7D, "vfnmsubpd", X86Fnmsub, v2f64, v4f64, 384f4a2713aSLionel Sambuc loadv2f64, loadv4f64>; 385f4a2713aSLionel Sambuc defm VFMADDSUBPD4 : fma4p<0x5D, "vfmaddsubpd", X86Fmaddsub, v2f64, v4f64, 386f4a2713aSLionel Sambuc loadv2f64, loadv4f64>; 387f4a2713aSLionel Sambuc defm VFMSUBADDPD4 : fma4p<0x5F, "vfmsubaddpd", X86Fmsubadd, v2f64, v4f64, 388f4a2713aSLionel Sambuc loadv2f64, loadv4f64>; 389f4a2713aSLionel Sambuc} 390f4a2713aSLionel Sambuc 391