diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td index 5580ba74e64e..5309ce50c9a3 100644 --- a/llvm/lib/Target/X86/X86InstrSSE.td +++ b/llvm/lib/Target/X86/X86InstrSSE.td @@ -642,7 +642,8 @@ def FsANDNPSrm : PSI<0x55, MRMSrcMem, } } -/// basic_sse1_fp_binop_rm - SSE1 binops come in both scalar and vector forms. +/// basic_sse12_fp_binop_rm - SSE 1 & 2 binops come in both scalar and +/// vector forms. /// /// In addition, we also have a special variant of the scalar form here to /// represent the associated intrinsic operation. This form is unlike the @@ -653,9 +654,8 @@ def FsANDNPSrm : PSI<0x55, MRMSrcMem, /// six "instructions". /// let Constraints = "$src1 = $dst" in { -multiclass basic_sse1_fp_binop_rm opc, string OpcodeStr, - SDNode OpNode, Intrinsic F32Int, - bit Commutable = 0> { +multiclass basic_sse12_fp_binop_rm opc, string OpcodeStr, + SDNode OpNode, bit Commutable = 0> { // Scalar operation, reg+reg. def SSrr : SSI opc, string OpcodeStr, let isCommutable = Commutable; } + def SDrr : SDI { + let isCommutable = Commutable; + } + // Scalar operation, reg+mem. def SSrm : SSI; + def SDrm : SDI; + // Vector operation, reg+reg. def PSrr : PSI opc, string OpcodeStr, let isCommutable = Commutable; } + def PDrr : PDI { + let isCommutable = Commutable; + } + // Vector operation, reg+mem. def PSrm : PSI; + def PDrm : PDI; + // Intrinsic operation, reg+reg. def SSrr_Int : SSI; + !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"), + [(set VR128:$dst, (!nameconcat("int_x86_sse_", + !strconcat(OpcodeStr, "_ss")) VR128:$src1, + VR128:$src2))]>; + // int_x86_sse_xxx_ss + + def SDrr_Int : SDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_sd")) VR128:$src1, + VR128:$src2))]>; + // int_x86_sse2_xxx_sd // Intrinsic operation, reg+mem. def SSrm_Int : SSI("int_x86_sse_", + !strconcat(OpcodeStr, "_ss")) VR128:$src1, sse_load_f32:$src2))]>; + // int_x86_sse_xxx_ss + + def SDrm_Int : SDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_sd")) VR128:$src1, + sse_load_f64:$src2))]>; + // int_x86_sse2_xxx_sd } } // Arithmetic instructions -defm ADD : basic_sse1_fp_binop_rm<0x58, "add", fadd, int_x86_sse_add_ss, 1>; -defm MUL : basic_sse1_fp_binop_rm<0x59, "mul", fmul, int_x86_sse_mul_ss, 1>; -defm SUB : basic_sse1_fp_binop_rm<0x5C, "sub", fsub, int_x86_sse_sub_ss>; -defm DIV : basic_sse1_fp_binop_rm<0x5E, "div", fdiv, int_x86_sse_div_ss>; +defm ADD : basic_sse12_fp_binop_rm<0x58, "add", fadd, 1>; +defm MUL : basic_sse12_fp_binop_rm<0x59, "mul", fmul, 1>; +defm SUB : basic_sse12_fp_binop_rm<0x5C, "sub", fsub>; +defm DIV : basic_sse12_fp_binop_rm<0x5E, "div", fdiv>; -/// sse1_fp_binop_rm - Other SSE1 binops +/// sse12_fp_binop_rm - Other SSE 1 & 2 binops /// -/// This multiclass is like basic_sse1_fp_binop_rm, with the addition of +/// This multiclass is like basic_sse12_fp_binop_rm, with the addition of /// instructions for a full-vector intrinsic form. Operations that map /// onto C operators don't use this form since they just use the plain /// vector form instead of having a separate vector intrinsic form. @@ -714,11 +758,8 @@ defm DIV : basic_sse1_fp_binop_rm<0x5E, "div", fdiv, int_x86_sse_div_ss>; /// This provides a total of eight "instructions". /// let Constraints = "$src1 = $dst" in { -multiclass sse1_fp_binop_rm opc, string OpcodeStr, - SDNode OpNode, - Intrinsic F32Int, - Intrinsic V4F32Int, - bit Commutable = 0> { +multiclass sse12_fp_binop_rm opc, string OpcodeStr, + SDNode OpNode, bit Commutable = 0> { // Scalar operation, reg+reg. def SSrr : SSI opc, string OpcodeStr, let isCommutable = Commutable; } + def SDrr : SDI { + let isCommutable = Commutable; + } + // Scalar operation, reg+mem. def SSrm : SSI; + def SDrm : SDI; + // Vector operation, reg+reg. def PSrr : PSI opc, string OpcodeStr, let isCommutable = Commutable; } + def PDrr : PDI { + let isCommutable = Commutable; + } + // Vector operation, reg+mem. def PSrm : PSI; + def PDrm : PDI; + // Intrinsic operation, reg+reg. def SSrr_Int : SSI { + !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"), + [(set VR128:$dst, (!nameconcat("int_x86_sse_", + !strconcat(OpcodeStr, "_ss")) VR128:$src1, + VR128:$src2))]> { + // int_x86_sse_xxx_ss + let isCommutable = Commutable; + } + + def SDrr_Int : SDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_sd")) VR128:$src1, + VR128:$src2))]> { + // int_x86_sse2_xxx_sd let isCommutable = Commutable; } // Intrinsic operation, reg+mem. def SSrm_Int : SSI("int_x86_sse_", + !strconcat(OpcodeStr, "_ss")) VR128:$src1, sse_load_f32:$src2))]>; + // int_x86_sse_xxx_ss + + def SDrm_Int : SDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_sd")) VR128:$src1, + sse_load_f64:$src2))]>; + // int_x86_sse2_xxx_sd // Vector intrinsic operation, reg+reg. def PSrr_Int : PSI { + !strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"), + [(set VR128:$dst, (!nameconcat("int_x86_sse_", + !strconcat(OpcodeStr, "_ps")) VR128:$src1, + VR128:$src2))]> { + // int_x86_sse_xxx_ps + let isCommutable = Commutable; + } + + def PDrr_Int : PDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_pd")) VR128:$src1, + VR128:$src2))]> { + // int_x86_sse2_xxx_pd let isCommutable = Commutable; } // Vector intrinsic operation, reg+mem. def PSrm_Int : PSI; + !strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"), + [(set VR128:$dst, (!nameconcat("int_x86_sse_", + !strconcat(OpcodeStr, "_ps")) VR128:$src1, + (memopv4f32 addr:$src2)))]>; + // int_x86_sse_xxx_ps + + def PDrm_Int : PDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_pd")) VR128:$src1, + (memopv2f64 addr:$src2)))]>; + // int_x86_sse2_xxx_pd } } -defm MAX : sse1_fp_binop_rm<0x5F, "max", X86fmax, - int_x86_sse_max_ss, int_x86_sse_max_ps>; -defm MIN : sse1_fp_binop_rm<0x5D, "min", X86fmin, - int_x86_sse_min_ss, int_x86_sse_min_ps>; +defm MAX : sse12_fp_binop_rm<0x5F, "max", X86fmax>; +defm MIN : sse12_fp_binop_rm<0x5D, "min", X86fmin>; //===----------------------------------------------------------------------===// // SSE packed FP Instructions @@ -1444,148 +1553,6 @@ def FsANDNPDrm : PDI<0x55, MRMSrcMem, } } -/// basic_sse2_fp_binop_rm - SSE2 binops come in both scalar and vector forms. -/// -/// In addition, we also have a special variant of the scalar form here to -/// represent the associated intrinsic operation. This form is unlike the -/// plain scalar form, in that it takes an entire vector (instead of a scalar) -/// and leaves the top elements unmodified (therefore these cannot be commuted). -/// -/// These three forms can each be reg+reg or reg+mem, so there are a total of -/// six "instructions". -/// -let Constraints = "$src1 = $dst" in { -multiclass basic_sse2_fp_binop_rm opc, string OpcodeStr, - SDNode OpNode, Intrinsic F64Int, - bit Commutable = 0> { - // Scalar operation, reg+reg. - def SDrr : SDI { - let isCommutable = Commutable; - } - - // Scalar operation, reg+mem. - def SDrm : SDI; - - // Vector operation, reg+reg. - def PDrr : PDI { - let isCommutable = Commutable; - } - - // Vector operation, reg+mem. - def PDrm : PDI; - - // Intrinsic operation, reg+reg. - def SDrr_Int : SDI; - - // Intrinsic operation, reg+mem. - def SDrm_Int : SDI; -} -} - -// Arithmetic instructions -defm ADD : basic_sse2_fp_binop_rm<0x58, "add", fadd, int_x86_sse2_add_sd, 1>; -defm MUL : basic_sse2_fp_binop_rm<0x59, "mul", fmul, int_x86_sse2_mul_sd, 1>; -defm SUB : basic_sse2_fp_binop_rm<0x5C, "sub", fsub, int_x86_sse2_sub_sd>; -defm DIV : basic_sse2_fp_binop_rm<0x5E, "div", fdiv, int_x86_sse2_div_sd>; - -/// sse2_fp_binop_rm - Other SSE2 binops -/// -/// This multiclass is like basic_sse2_fp_binop_rm, with the addition of -/// instructions for a full-vector intrinsic form. Operations that map -/// onto C operators don't use this form since they just use the plain -/// vector form instead of having a separate vector intrinsic form. -/// -/// This provides a total of eight "instructions". -/// -let Constraints = "$src1 = $dst" in { -multiclass sse2_fp_binop_rm opc, string OpcodeStr, - SDNode OpNode, - Intrinsic F64Int, - Intrinsic V2F64Int, - bit Commutable = 0> { - - // Scalar operation, reg+reg. - def SDrr : SDI { - let isCommutable = Commutable; - } - - // Scalar operation, reg+mem. - def SDrm : SDI; - - // Vector operation, reg+reg. - def PDrr : PDI { - let isCommutable = Commutable; - } - - // Vector operation, reg+mem. - def PDrm : PDI; - - // Intrinsic operation, reg+reg. - def SDrr_Int : SDI { - let isCommutable = Commutable; - } - - // Intrinsic operation, reg+mem. - def SDrm_Int : SDI; - - // Vector intrinsic operation, reg+reg. - def PDrr_Int : PDI { - let isCommutable = Commutable; - } - - // Vector intrinsic operation, reg+mem. - def PDrm_Int : PDI; -} -} - -defm MAX : sse2_fp_binop_rm<0x5F, "max", X86fmax, - int_x86_sse2_max_sd, int_x86_sse2_max_pd>; -defm MIN : sse2_fp_binop_rm<0x5D, "min", X86fmin, - int_x86_sse2_min_sd, int_x86_sse2_min_pd>; - //===---------------------------------------------------------------------===// // SSE packed FP Instructions