mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
Merge basic binops SSE 1 & 2 instruction classes. This is a step towards refactoring
common code between SSE versions. llvm-svn: 104860
This commit is contained in:
parent
7452bd4219
commit
8b867a678f
@ -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
|
/// In addition, we also have a special variant of the scalar form here to
|
||||||
/// represent the associated intrinsic operation. This form is unlike the
|
/// represent the associated intrinsic operation. This form is unlike the
|
||||||
@ -653,9 +654,8 @@ def FsANDNPSrm : PSI<0x55, MRMSrcMem,
|
|||||||
/// six "instructions".
|
/// six "instructions".
|
||||||
///
|
///
|
||||||
let Constraints = "$src1 = $dst" in {
|
let Constraints = "$src1 = $dst" in {
|
||||||
multiclass basic_sse1_fp_binop_rm<bits<8> opc, string OpcodeStr,
|
multiclass basic_sse12_fp_binop_rm<bits<8> opc, string OpcodeStr,
|
||||||
SDNode OpNode, Intrinsic F32Int,
|
SDNode OpNode, bit Commutable = 0> {
|
||||||
bit Commutable = 0> {
|
|
||||||
// Scalar operation, reg+reg.
|
// Scalar operation, reg+reg.
|
||||||
def SSrr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
|
def SSrr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
|
||||||
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
||||||
@ -663,12 +663,23 @@ multiclass basic_sse1_fp_binop_rm<bits<8> opc, string OpcodeStr,
|
|||||||
let isCommutable = Commutable;
|
let isCommutable = Commutable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def SDrr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
|
||||||
|
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set FR64:$dst, (OpNode FR64:$src1, FR64:$src2))]> {
|
||||||
|
let isCommutable = Commutable;
|
||||||
|
}
|
||||||
|
|
||||||
// Scalar operation, reg+mem.
|
// Scalar operation, reg+mem.
|
||||||
def SSrm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
|
def SSrm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
|
||||||
(ins FR32:$src1, f32mem:$src2),
|
(ins FR32:$src1, f32mem:$src2),
|
||||||
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set FR32:$dst, (OpNode FR32:$src1, (load addr:$src2)))]>;
|
[(set FR32:$dst, (OpNode FR32:$src1, (load addr:$src2)))]>;
|
||||||
|
|
||||||
|
def SDrm : SDI<opc, MRMSrcMem, (outs FR64:$dst),
|
||||||
|
(ins FR64:$src1, f64mem:$src2),
|
||||||
|
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set FR64:$dst, (OpNode FR64:$src1, (load addr:$src2)))]>;
|
||||||
|
|
||||||
// Vector operation, reg+reg.
|
// Vector operation, reg+reg.
|
||||||
def PSrr : PSI<opc, MRMSrcReg, (outs VR128:$dst),
|
def PSrr : PSI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, VR128:$src2),
|
(ins VR128:$src1, VR128:$src2),
|
||||||
@ -677,36 +688,69 @@ multiclass basic_sse1_fp_binop_rm<bits<8> opc, string OpcodeStr,
|
|||||||
let isCommutable = Commutable;
|
let isCommutable = Commutable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def PDrr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, VR128:$src2),
|
||||||
|
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (v2f64 (OpNode VR128:$src1, VR128:$src2)))]> {
|
||||||
|
let isCommutable = Commutable;
|
||||||
|
}
|
||||||
|
|
||||||
// Vector operation, reg+mem.
|
// Vector operation, reg+mem.
|
||||||
def PSrm : PSI<opc, MRMSrcMem, (outs VR128:$dst),
|
def PSrm : PSI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, f128mem:$src2),
|
(ins VR128:$src1, f128mem:$src2),
|
||||||
!strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set VR128:$dst, (OpNode VR128:$src1, (memopv4f32 addr:$src2)))]>;
|
[(set VR128:$dst, (OpNode VR128:$src1, (memopv4f32 addr:$src2)))]>;
|
||||||
|
|
||||||
|
def PDrm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, f128mem:$src2),
|
||||||
|
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (OpNode VR128:$src1, (memopv2f64 addr:$src2)))]>;
|
||||||
|
|
||||||
// Intrinsic operation, reg+reg.
|
// Intrinsic operation, reg+reg.
|
||||||
def SSrr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst),
|
def SSrr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, VR128:$src2),
|
(ins VR128:$src1, VR128:$src2),
|
||||||
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2))]>;
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse_",
|
||||||
|
!strconcat(OpcodeStr, "_ss")) VR128:$src1,
|
||||||
|
VR128:$src2))]>;
|
||||||
|
// int_x86_sse_xxx_ss
|
||||||
|
|
||||||
|
def SDrr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, VR128:$src2),
|
||||||
|
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse2_",
|
||||||
|
!strconcat(OpcodeStr, "_sd")) VR128:$src1,
|
||||||
|
VR128:$src2))]>;
|
||||||
|
// int_x86_sse2_xxx_sd
|
||||||
|
|
||||||
// Intrinsic operation, reg+mem.
|
// Intrinsic operation, reg+mem.
|
||||||
def SSrm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
|
def SSrm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, ssmem:$src2),
|
(ins VR128:$src1, ssmem:$src2),
|
||||||
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set VR128:$dst, (F32Int VR128:$src1,
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse_",
|
||||||
|
!strconcat(OpcodeStr, "_ss")) VR128:$src1,
|
||||||
sse_load_f32:$src2))]>;
|
sse_load_f32:$src2))]>;
|
||||||
|
// int_x86_sse_xxx_ss
|
||||||
|
|
||||||
|
def SDrm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, sdmem:$src2),
|
||||||
|
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse2_",
|
||||||
|
!strconcat(OpcodeStr, "_sd")) VR128:$src1,
|
||||||
|
sse_load_f64:$src2))]>;
|
||||||
|
// int_x86_sse2_xxx_sd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arithmetic instructions
|
// Arithmetic instructions
|
||||||
defm ADD : basic_sse1_fp_binop_rm<0x58, "add", fadd, int_x86_sse_add_ss, 1>;
|
defm ADD : basic_sse12_fp_binop_rm<0x58, "add", fadd, 1>;
|
||||||
defm MUL : basic_sse1_fp_binop_rm<0x59, "mul", fmul, int_x86_sse_mul_ss, 1>;
|
defm MUL : basic_sse12_fp_binop_rm<0x59, "mul", fmul, 1>;
|
||||||
defm SUB : basic_sse1_fp_binop_rm<0x5C, "sub", fsub, int_x86_sse_sub_ss>;
|
defm SUB : basic_sse12_fp_binop_rm<0x5C, "sub", fsub>;
|
||||||
defm DIV : basic_sse1_fp_binop_rm<0x5E, "div", fdiv, int_x86_sse_div_ss>;
|
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
|
/// instructions for a full-vector intrinsic form. Operations that map
|
||||||
/// onto C operators don't use this form since they just use the plain
|
/// onto C operators don't use this form since they just use the plain
|
||||||
/// vector form instead of having a separate vector intrinsic form.
|
/// 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".
|
/// This provides a total of eight "instructions".
|
||||||
///
|
///
|
||||||
let Constraints = "$src1 = $dst" in {
|
let Constraints = "$src1 = $dst" in {
|
||||||
multiclass sse1_fp_binop_rm<bits<8> opc, string OpcodeStr,
|
multiclass sse12_fp_binop_rm<bits<8> opc, string OpcodeStr,
|
||||||
SDNode OpNode,
|
SDNode OpNode, bit Commutable = 0> {
|
||||||
Intrinsic F32Int,
|
|
||||||
Intrinsic V4F32Int,
|
|
||||||
bit Commutable = 0> {
|
|
||||||
|
|
||||||
// Scalar operation, reg+reg.
|
// Scalar operation, reg+reg.
|
||||||
def SSrr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
|
def SSrr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
|
||||||
@ -727,12 +768,23 @@ multiclass sse1_fp_binop_rm<bits<8> opc, string OpcodeStr,
|
|||||||
let isCommutable = Commutable;
|
let isCommutable = Commutable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def SDrr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
|
||||||
|
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set FR64:$dst, (OpNode FR64:$src1, FR64:$src2))]> {
|
||||||
|
let isCommutable = Commutable;
|
||||||
|
}
|
||||||
|
|
||||||
// Scalar operation, reg+mem.
|
// Scalar operation, reg+mem.
|
||||||
def SSrm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
|
def SSrm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
|
||||||
(ins FR32:$src1, f32mem:$src2),
|
(ins FR32:$src1, f32mem:$src2),
|
||||||
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set FR32:$dst, (OpNode FR32:$src1, (load addr:$src2)))]>;
|
[(set FR32:$dst, (OpNode FR32:$src1, (load addr:$src2)))]>;
|
||||||
|
|
||||||
|
def SDrm : SDI<opc, MRMSrcMem, (outs FR64:$dst),
|
||||||
|
(ins FR64:$src1, f64mem:$src2),
|
||||||
|
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set FR64:$dst, (OpNode FR64:$src1, (load addr:$src2)))]>;
|
||||||
|
|
||||||
// Vector operation, reg+reg.
|
// Vector operation, reg+reg.
|
||||||
def PSrr : PSI<opc, MRMSrcReg, (outs VR128:$dst),
|
def PSrr : PSI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, VR128:$src2),
|
(ins VR128:$src1, VR128:$src2),
|
||||||
@ -741,47 +793,104 @@ multiclass sse1_fp_binop_rm<bits<8> opc, string OpcodeStr,
|
|||||||
let isCommutable = Commutable;
|
let isCommutable = Commutable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def PDrr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, VR128:$src2),
|
||||||
|
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (v2f64 (OpNode VR128:$src1, VR128:$src2)))]> {
|
||||||
|
let isCommutable = Commutable;
|
||||||
|
}
|
||||||
|
|
||||||
// Vector operation, reg+mem.
|
// Vector operation, reg+mem.
|
||||||
def PSrm : PSI<opc, MRMSrcMem, (outs VR128:$dst),
|
def PSrm : PSI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, f128mem:$src2),
|
(ins VR128:$src1, f128mem:$src2),
|
||||||
!strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set VR128:$dst, (OpNode VR128:$src1, (memopv4f32 addr:$src2)))]>;
|
[(set VR128:$dst, (OpNode VR128:$src1, (memopv4f32 addr:$src2)))]>;
|
||||||
|
|
||||||
|
def PDrm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, f128mem:$src2),
|
||||||
|
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (OpNode VR128:$src1, (memopv2f64 addr:$src2)))]>;
|
||||||
|
|
||||||
// Intrinsic operation, reg+reg.
|
// Intrinsic operation, reg+reg.
|
||||||
def SSrr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst),
|
def SSrr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, VR128:$src2),
|
(ins VR128:$src1, VR128:$src2),
|
||||||
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2))]> {
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse_",
|
||||||
|
!strconcat(OpcodeStr, "_ss")) VR128:$src1,
|
||||||
|
VR128:$src2))]> {
|
||||||
|
// int_x86_sse_xxx_ss
|
||||||
|
let isCommutable = Commutable;
|
||||||
|
}
|
||||||
|
|
||||||
|
def SDrr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, VR128:$src2),
|
||||||
|
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse2_",
|
||||||
|
!strconcat(OpcodeStr, "_sd")) VR128:$src1,
|
||||||
|
VR128:$src2))]> {
|
||||||
|
// int_x86_sse2_xxx_sd
|
||||||
let isCommutable = Commutable;
|
let isCommutable = Commutable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intrinsic operation, reg+mem.
|
// Intrinsic operation, reg+mem.
|
||||||
def SSrm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
|
def SSrm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, ssmem:$src2),
|
(ins VR128:$src1, ssmem:$src2),
|
||||||
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set VR128:$dst, (F32Int VR128:$src1,
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse_",
|
||||||
|
!strconcat(OpcodeStr, "_ss")) VR128:$src1,
|
||||||
sse_load_f32:$src2))]>;
|
sse_load_f32:$src2))]>;
|
||||||
|
// int_x86_sse_xxx_ss
|
||||||
|
|
||||||
|
def SDrm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, sdmem:$src2),
|
||||||
|
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse2_",
|
||||||
|
!strconcat(OpcodeStr, "_sd")) VR128:$src1,
|
||||||
|
sse_load_f64:$src2))]>;
|
||||||
|
// int_x86_sse2_xxx_sd
|
||||||
|
|
||||||
// Vector intrinsic operation, reg+reg.
|
// Vector intrinsic operation, reg+reg.
|
||||||
def PSrr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst),
|
def PSrr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, VR128:$src2),
|
(ins VR128:$src1, VR128:$src2),
|
||||||
!strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set VR128:$dst, (V4F32Int VR128:$src1, VR128:$src2))]> {
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse_",
|
||||||
|
!strconcat(OpcodeStr, "_ps")) VR128:$src1,
|
||||||
|
VR128:$src2))]> {
|
||||||
|
// int_x86_sse_xxx_ps
|
||||||
|
let isCommutable = Commutable;
|
||||||
|
}
|
||||||
|
|
||||||
|
def PDrr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, VR128:$src2),
|
||||||
|
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse2_",
|
||||||
|
!strconcat(OpcodeStr, "_pd")) VR128:$src1,
|
||||||
|
VR128:$src2))]> {
|
||||||
|
// int_x86_sse2_xxx_pd
|
||||||
let isCommutable = Commutable;
|
let isCommutable = Commutable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vector intrinsic operation, reg+mem.
|
// Vector intrinsic operation, reg+mem.
|
||||||
def PSrm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst),
|
def PSrm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, f128mem:$src2),
|
(ins VR128:$src1, f128mem:$src2),
|
||||||
!strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set VR128:$dst, (V4F32Int VR128:$src1, (memopv4f32 addr:$src2)))]>;
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("int_x86_sse_",
|
||||||
|
!strconcat(OpcodeStr, "_ps")) VR128:$src1,
|
||||||
|
(memopv4f32 addr:$src2)))]>;
|
||||||
|
// int_x86_sse_xxx_ps
|
||||||
|
|
||||||
|
def PDrm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst),
|
||||||
|
(ins VR128:$src1, f128mem:$src2),
|
||||||
|
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
||||||
|
[(set VR128:$dst, (!nameconcat<Intrinsic>("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,
|
defm MAX : sse12_fp_binop_rm<0x5F, "max", X86fmax>;
|
||||||
int_x86_sse_max_ss, int_x86_sse_max_ps>;
|
defm MIN : sse12_fp_binop_rm<0x5D, "min", X86fmin>;
|
||||||
defm MIN : sse1_fp_binop_rm<0x5D, "min", X86fmin,
|
|
||||||
int_x86_sse_min_ss, int_x86_sse_min_ps>;
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// SSE packed FP Instructions
|
// 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<bits<8> opc, string OpcodeStr,
|
|
||||||
SDNode OpNode, Intrinsic F64Int,
|
|
||||||
bit Commutable = 0> {
|
|
||||||
// Scalar operation, reg+reg.
|
|
||||||
def SDrr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
|
|
||||||
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set FR64:$dst, (OpNode FR64:$src1, FR64:$src2))]> {
|
|
||||||
let isCommutable = Commutable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scalar operation, reg+mem.
|
|
||||||
def SDrm : SDI<opc, MRMSrcMem, (outs FR64:$dst),
|
|
||||||
(ins FR64:$src1, f64mem:$src2),
|
|
||||||
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set FR64:$dst, (OpNode FR64:$src1, (load addr:$src2)))]>;
|
|
||||||
|
|
||||||
// Vector operation, reg+reg.
|
|
||||||
def PDrr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, VR128:$src2),
|
|
||||||
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (v2f64 (OpNode VR128:$src1, VR128:$src2)))]> {
|
|
||||||
let isCommutable = Commutable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vector operation, reg+mem.
|
|
||||||
def PDrm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, f128mem:$src2),
|
|
||||||
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (OpNode VR128:$src1, (memopv2f64 addr:$src2)))]>;
|
|
||||||
|
|
||||||
// Intrinsic operation, reg+reg.
|
|
||||||
def SDrr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, VR128:$src2),
|
|
||||||
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2))]>;
|
|
||||||
|
|
||||||
// Intrinsic operation, reg+mem.
|
|
||||||
def SDrm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, sdmem:$src2),
|
|
||||||
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (F64Int VR128:$src1,
|
|
||||||
sse_load_f64:$src2))]>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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<bits<8> opc, string OpcodeStr,
|
|
||||||
SDNode OpNode,
|
|
||||||
Intrinsic F64Int,
|
|
||||||
Intrinsic V2F64Int,
|
|
||||||
bit Commutable = 0> {
|
|
||||||
|
|
||||||
// Scalar operation, reg+reg.
|
|
||||||
def SDrr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
|
|
||||||
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set FR64:$dst, (OpNode FR64:$src1, FR64:$src2))]> {
|
|
||||||
let isCommutable = Commutable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scalar operation, reg+mem.
|
|
||||||
def SDrm : SDI<opc, MRMSrcMem, (outs FR64:$dst),
|
|
||||||
(ins FR64:$src1, f64mem:$src2),
|
|
||||||
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set FR64:$dst, (OpNode FR64:$src1, (load addr:$src2)))]>;
|
|
||||||
|
|
||||||
// Vector operation, reg+reg.
|
|
||||||
def PDrr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, VR128:$src2),
|
|
||||||
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (v2f64 (OpNode VR128:$src1, VR128:$src2)))]> {
|
|
||||||
let isCommutable = Commutable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vector operation, reg+mem.
|
|
||||||
def PDrm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, f128mem:$src2),
|
|
||||||
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (OpNode VR128:$src1, (memopv2f64 addr:$src2)))]>;
|
|
||||||
|
|
||||||
// Intrinsic operation, reg+reg.
|
|
||||||
def SDrr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, VR128:$src2),
|
|
||||||
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2))]> {
|
|
||||||
let isCommutable = Commutable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intrinsic operation, reg+mem.
|
|
||||||
def SDrm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, sdmem:$src2),
|
|
||||||
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (F64Int VR128:$src1,
|
|
||||||
sse_load_f64:$src2))]>;
|
|
||||||
|
|
||||||
// Vector intrinsic operation, reg+reg.
|
|
||||||
def PDrr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, VR128:$src2),
|
|
||||||
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (V2F64Int VR128:$src1, VR128:$src2))]> {
|
|
||||||
let isCommutable = Commutable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vector intrinsic operation, reg+mem.
|
|
||||||
def PDrm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst),
|
|
||||||
(ins VR128:$src1, f128mem:$src2),
|
|
||||||
!strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
|
|
||||||
[(set VR128:$dst, (V2F64Int VR128:$src1,
|
|
||||||
(memopv2f64 addr:$src2)))]>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
// SSE packed FP Instructions
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user