diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86InstrFPStack.td')
-rw-r--r-- | llvm/lib/Target/X86/X86InstrFPStack.td | 103 |
1 files changed, 50 insertions, 53 deletions
diff --git a/llvm/lib/Target/X86/X86InstrFPStack.td b/llvm/lib/Target/X86/X86InstrFPStack.td index eaec18b4eca..b9148fef104 100644 --- a/llvm/lib/Target/X86/X86InstrFPStack.td +++ b/llvm/lib/Target/X86/X86InstrFPStack.td @@ -2,7 +2,7 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the Evan Cheng and is distributed under +// This file was developed by Evan Cheng and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// @@ -48,10 +48,6 @@ def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem, def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem, [SDNPHasChain]>; -def extloadf80f32 : PatFrag<(ops node:$ptr), (f80 (extloadf32 node:$ptr))>; -def extloadf80f64 : PatFrag<(ops node:$ptr), (f80 (extloadf64 node:$ptr))>; -def extloadf64f32 : PatFrag<(ops node:$ptr), (f64 (extloadf32 node:$ptr))>; - //===----------------------------------------------------------------------===// // FPStack pattern fragments //===----------------------------------------------------------------------===// @@ -116,18 +112,18 @@ let isTerminator = 1 in let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in def FP_REG_KILL : I<0, Pseudo, (outs), (ins), "#FP_REG_KILL", []>; -// All FP Stack operations are represented with three instructions here. The -// first two instructions, generated by the instruction selector, uses "RFP32" -// or "RFP64" registers: traditional register files to reference 32-bit or -// 64-bit floating point values. These sizes apply to the values, not the -// registers, which are always 64 bits; RFP32 and RFP64 can be copied to -// each other without losing information. These instructions are all psuedo -// instructions and use the "_Fp" suffix. -// In some cases there are additional variants with a mixture of 32-bit and -// 64-bit registers. +// All FP Stack operations are represented with four instructions here. The +// first three instructions, generated by the instruction selector, use "RFP32" +// "RFP64" or "RFP80" registers: traditional register files to reference 32-bit, +// 64-bit or 80-bit floating point values. These sizes apply to the values, +// not the registers, which are always 80 bits; RFP32, RFP64 and RFP80 can be +// copied to each other without losing information. These instructions are all +// pseudo instructions and use the "_Fp" suffix. +// In some cases there are additional variants with a mixture of different +// register sizes. // The second instruction is defined with FPI, which is the actual instruction // emitted by the assembler. These use "RST" registers, although frequently -// the actual register(s) used are implicit. These are always 64-bits. +// the actual register(s) used are implicit. These are always 80 bits. // The FP stackifier pass converts one to the other after register allocation // occurs. // @@ -135,7 +131,7 @@ let isTerminator = 1 in // a pattern) and the FPI instruction should have emission info (e.g. opcode // encoding and asm printing info). -// Random Pseudo Instructions. +// Pseudo Instructions for FP stack return values. def FpGETRESULT32 : FpI_<(outs RFP32:$dst), (ins), SpecialFP, [(set RFP32:$dst, X86fpget)]>; // FPR = ST(0) @@ -155,6 +151,8 @@ def FpSETRESULT80 : FpI_<(outs), (ins RFP80:$src), SpecialFP, [(X86fpset RFP80:$src)]>, Imp<[], [ST0]>;// ST(0) = FPR // FpI - Floating Point Psuedo Instruction template. Predicated on FPStack. +// Note that f80-only instructions are used even in SSE mode and use FpI_ +// not this predicate. class FpI<dag outs, dag ins, FPFormat fp, list<dag> pattern> : FpI_<outs, ins, fp, pattern>, Requires<[FPStack]>; @@ -167,7 +165,7 @@ def MOV_Fp8032 : FpI<(outs RFP32:$dst), (ins RFP80:$src), SpecialFP, []>; def MOV_Fp3280 : FpI<(outs RFP80:$dst), (ins RFP32:$src), SpecialFP, []>; def MOV_Fp8064 : FpI<(outs RFP64:$dst), (ins RFP80:$src), SpecialFP, []>; def MOV_Fp6480 : FpI<(outs RFP80:$dst), (ins RFP64:$src), SpecialFP, []>; -def MOV_Fp8080 : FpI<(outs RFP80:$dst), (ins RFP80:$src), SpecialFP, []>; +def MOV_Fp8080 : FpI_<(outs RFP80:$dst), (ins RFP80:$src), SpecialFP, []>; // Factoring for arithmetic. multiclass FPBinary_rr<SDNode OpNode> { @@ -177,7 +175,7 @@ def _Fp32 : FpI<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2), TwoArgFP, [(set RFP32:$dst, (OpNode RFP32:$src1, RFP32:$src2))]>; def _Fp64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), TwoArgFP, [(set RFP64:$dst, (OpNode RFP64:$src1, RFP64:$src2))]>; -def _Fp80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), TwoArgFP, +def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), TwoArgFP, [(set RFP80:$dst, (OpNode RFP80:$src1, RFP80:$src2))]>; } // The FopST0 series are not included here because of the irregularities @@ -193,13 +191,13 @@ def _Fp64m : FpI<(outs RFP64:$dst), (ins RFP64:$src1, f64mem:$src2), OneArgFPRW (OpNode RFP64:$src1, (loadf64 addr:$src2)))]>; def _Fp64m32: FpI<(outs RFP64:$dst), (ins RFP64:$src1, f32mem:$src2), OneArgFPRW, [(set RFP64:$dst, - (OpNode RFP64:$src1, (extloadf64f32 addr:$src2)))]>; -def _Fp80m32: FpI<(outs RFP80:$dst), (ins RFP80:$src1, f32mem:$src2), OneArgFPRW, + (OpNode RFP64:$src1, (f64 (extloadf32 addr:$src2))))]>; +def _Fp80m32: FpI_<(outs RFP80:$dst), (ins RFP80:$src1, f32mem:$src2), OneArgFPRW, [(set RFP80:$dst, - (OpNode RFP80:$src1, (extloadf80f32 addr:$src2)))]>; -def _Fp80m64: FpI<(outs RFP80:$dst), (ins RFP80:$src1, f64mem:$src2), OneArgFPRW, + (OpNode RFP80:$src1, (f80 (extloadf32 addr:$src2))))]>; +def _Fp80m64: FpI_<(outs RFP80:$dst), (ins RFP80:$src1, f64mem:$src2), OneArgFPRW, [(set RFP80:$dst, - (OpNode RFP80:$src1, (extloadf80f64 addr:$src2)))]>; + (OpNode RFP80:$src1, (f80 (extloadf64 addr:$src2))))]>; def _F32m : FPI<0xD8, fp, (outs), (ins f32mem:$src), !strconcat("f", !strconcat(asmstring, "{s}\t$src"))>; def _F64m : FPI<0xDC, fp, (outs), (ins f64mem:$src), @@ -217,10 +215,10 @@ def _FpI16m64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, i16mem:$src2), OneArgFP def _FpI32m64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, i32mem:$src2), OneArgFPRW, [(set RFP64:$dst, (OpNode RFP64:$src1, (X86fild addr:$src2, i32)))]>; -def _FpI16m80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, i16mem:$src2), OneArgFPRW, +def _FpI16m80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, i16mem:$src2), OneArgFPRW, [(set RFP80:$dst, (OpNode RFP80:$src1, (X86fild addr:$src2, i16)))]>; -def _FpI32m80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, i32mem:$src2), OneArgFPRW, +def _FpI32m80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, i32mem:$src2), OneArgFPRW, [(set RFP80:$dst, (OpNode RFP80:$src1, (X86fild addr:$src2, i32)))]>; def _FI16m : FPI<0xDE, fp, (outs), (ins i16mem:$src), @@ -275,7 +273,7 @@ def _Fp32 : FpI<(outs RFP32:$dst), (ins RFP32:$src), OneArgFPRW, [(set RFP32:$dst, (OpNode RFP32:$src))]>; def _Fp64 : FpI<(outs RFP64:$dst), (ins RFP64:$src), OneArgFPRW, [(set RFP64:$dst, (OpNode RFP64:$src))]>; -def _Fp80 : FpI<(outs RFP80:$dst), (ins RFP80:$src), OneArgFPRW, +def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src), OneArgFPRW, [(set RFP80:$dst, (OpNode RFP80:$src))]>; def _F : FPI<opcode, RawFrm, (outs), (ins), asmstring>, D9; } @@ -290,7 +288,7 @@ def TST_Fp32 : FpI<(outs), (ins RFP32:$src), OneArgFP, []>; def TST_Fp64 : FpI<(outs), (ins RFP64:$src), OneArgFP, []>; -def TST_Fp80 : FpI<(outs), (ins RFP80:$src), OneArgFP, +def TST_Fp80 : FpI_<(outs), (ins RFP80:$src), OneArgFP, []>; def TST_F : FPI<0xE4, RawFrm, (outs), (ins), "ftst">, D9; @@ -302,7 +300,7 @@ multiclass FPCMov<PatLeaf cc> { def _Fp64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), CondMovFP, [(set RFP64:$dst, (X86cmov RFP64:$src1, RFP64:$src2, cc))]>; - def _Fp80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), CondMovFP, + def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), CondMovFP, [(set RFP80:$dst, (X86cmov RFP80:$src1, RFP80:$src2, cc))]>; } @@ -340,8 +338,14 @@ def LD_Fp32m : FpI<(outs RFP32:$dst), (ins f32mem:$src), ZeroArgFP, [(set RFP32:$dst, (loadf32 addr:$src))]>; def LD_Fp64m : FpI<(outs RFP64:$dst), (ins f64mem:$src), ZeroArgFP, [(set RFP64:$dst, (loadf64 addr:$src))]>; -def LD_Fp80m : FpI<(outs RFP80:$dst), (ins f80mem:$src), ZeroArgFP, +def LD_Fp80m : FpI_<(outs RFP80:$dst), (ins f80mem:$src), ZeroArgFP, [(set RFP80:$dst, (loadf80 addr:$src))]>; +def LD_Fp32m64 : FpI<(outs RFP64:$dst), (ins f32mem:$src), ZeroArgFP, + [(set RFP64:$dst, (f64 (extloadf32 addr:$src)))]>; +def LD_Fp64m80 : FpI_<(outs RFP80:$dst), (ins f64mem:$src), ZeroArgFP, + [(set RFP80:$dst, (f80 (extloadf64 addr:$src)))]>; +def LD_Fp32m80 : FpI_<(outs RFP80:$dst), (ins f32mem:$src), ZeroArgFP, + [(set RFP80:$dst, (f80 (extloadf32 addr:$src)))]>; def ILD_Fp16m32: FpI<(outs RFP32:$dst), (ins i16mem:$src), ZeroArgFP, [(set RFP32:$dst, (X86fild addr:$src, i16))]>; def ILD_Fp32m32: FpI<(outs RFP32:$dst), (ins i32mem:$src), ZeroArgFP, @@ -354,11 +358,11 @@ def ILD_Fp32m64: FpI<(outs RFP64:$dst), (ins i32mem:$src), ZeroArgFP, [(set RFP64:$dst, (X86fild addr:$src, i32))]>; def ILD_Fp64m64: FpI<(outs RFP64:$dst), (ins i64mem:$src), ZeroArgFP, [(set RFP64:$dst, (X86fild addr:$src, i64))]>; -def ILD_Fp16m80: FpI<(outs RFP80:$dst), (ins i16mem:$src), ZeroArgFP, +def ILD_Fp16m80: FpI_<(outs RFP80:$dst), (ins i16mem:$src), ZeroArgFP, [(set RFP80:$dst, (X86fild addr:$src, i16))]>; -def ILD_Fp32m80: FpI<(outs RFP80:$dst), (ins i32mem:$src), ZeroArgFP, +def ILD_Fp32m80: FpI_<(outs RFP80:$dst), (ins i32mem:$src), ZeroArgFP, [(set RFP80:$dst, (X86fild addr:$src, i32))]>; -def ILD_Fp64m80: FpI<(outs RFP80:$dst), (ins i64mem:$src), ZeroArgFP, +def ILD_Fp64m80: FpI_<(outs RFP80:$dst), (ins i64mem:$src), ZeroArgFP, [(set RFP80:$dst, (X86fild addr:$src, i64))]>; def ST_Fp32m : FpI<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP, @@ -367,9 +371,9 @@ def ST_Fp64m32 : FpI<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, [(truncstoref32 RFP64:$src, addr:$op)]>; def ST_Fp64m : FpI<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, [(store RFP64:$src, addr:$op)]>; -def ST_Fp80m32 : FpI<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, +def ST_Fp80m32 : FpI_<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, [(truncstoref32 RFP80:$src, addr:$op)]>; -def ST_Fp80m64 : FpI<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, +def ST_Fp80m64 : FpI_<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, [(truncstoref64 RFP80:$src, addr:$op)]>; // FST does not support 80-bit memory target; FSTP must be used. @@ -378,7 +382,7 @@ def ST_FpP64m32 : FpI<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, []>; def ST_FpP64m : FpI<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, []>; def ST_FpP80m32 : FpI<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, []>; def ST_FpP80m64 : FpI<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, []>; -def ST_FpP80m : FpI<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP, +def ST_FpP80m : FpI_<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP, [(store RFP80:$src, addr:$op)]>; def IST_Fp16m32 : FpI<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, []>; def IST_Fp32m32 : FpI<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, []>; @@ -386,9 +390,9 @@ def IST_Fp64m32 : FpI<(outs), (ins i64mem:$op, RFP32:$src), OneArgFP, []>; def IST_Fp16m64 : FpI<(outs), (ins i16mem:$op, RFP64:$src), OneArgFP, []>; def IST_Fp32m64 : FpI<(outs), (ins i32mem:$op, RFP64:$src), OneArgFP, []>; def IST_Fp64m64 : FpI<(outs), (ins i64mem:$op, RFP64:$src), OneArgFP, []>; -def IST_Fp16m80 : FpI<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>; -def IST_Fp32m80 : FpI<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>; -def IST_Fp64m80 : FpI<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>; +def IST_Fp16m80 : FpI_<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>; +def IST_Fp32m80 : FpI_<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>; +def IST_Fp64m80 : FpI_<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>; def LD_F32m : FPI<0xD9, MRM0m, (outs), (ins f32mem:$src), "fld{s}\t$src">; def LD_F64m : FPI<0xDD, MRM0m, (outs), (ins f64mem:$src), "fld{l}\t$src">; @@ -456,9 +460,9 @@ def LD_Fp064 : FpI<(outs RFP64:$dst), (ins), ZeroArgFP, [(set RFP64:$dst, fpimm0)]>; def LD_Fp164 : FpI<(outs RFP64:$dst), (ins), ZeroArgFP, [(set RFP64:$dst, fpimm1)]>; -def LD_Fp080 : FpI<(outs RFP80:$dst), (ins), ZeroArgFP, +def LD_Fp080 : FpI_<(outs RFP80:$dst), (ins), ZeroArgFP, [(set RFP80:$dst, fpimm0)]>; -def LD_Fp180 : FpI<(outs RFP80:$dst), (ins), ZeroArgFP, +def LD_Fp180 : FpI_<(outs RFP80:$dst), (ins), ZeroArgFP, [(set RFP80:$dst, fpimm1)]>; } @@ -475,9 +479,9 @@ def UCOM_Fpr64 : FpI<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, []>; // FPSW = cmp ST(0) with ST(i) def UCOM_FpIr64: FpI<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, [(X86cmp RFP64:$lhs, RFP64:$rhs)]>; // CC = ST(0) cmp ST(i) -def UCOM_Fpr80 : FpI<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, +def UCOM_Fpr80 : FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, []>; // FPSW = cmp ST(0) with ST(i) -def UCOM_FpIr80: FpI<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, +def UCOM_FpIr80: FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, [(X86cmp RFP80:$lhs, RFP80:$rhs)]>; // CC = ST(0) cmp ST(i) def UCOM_Fr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i) @@ -510,12 +514,12 @@ def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16] // Non-Instruction Patterns //===----------------------------------------------------------------------===// -// Required for RET of f32 / f64 values. +// Required for RET of f32 / f64 / f80 values. def : Pat<(X86fld addr:$src, f32), (LD_Fp32m addr:$src)>; def : Pat<(X86fld addr:$src, f64), (LD_Fp64m addr:$src)>; def : Pat<(X86fld addr:$src, f80), (LD_Fp80m addr:$src)>; -// Required for CALL which return f32 / f64 values. +// Required for CALL which return f32 / f64 / f80 values. def : Pat<(X86fst RFP32:$src, addr:$op, f32), (ST_Fp32m addr:$op, RFP32:$src)>; def : Pat<(X86fst RFP64:$src, addr:$op, f32), (ST_Fp64m32 addr:$op, RFP64:$src)>; def : Pat<(X86fst RFP64:$src, addr:$op, f64), (ST_Fp64m addr:$op, RFP64:$src)>; @@ -528,19 +532,12 @@ def : Pat<(f32 fpimmneg0), (CHS_Fp32 (LD_Fp032))>, Requires<[FPStack]>; def : Pat<(f32 fpimmneg1), (CHS_Fp32 (LD_Fp132))>, Requires<[FPStack]>; def : Pat<(f64 fpimmneg0), (CHS_Fp64 (LD_Fp064))>, Requires<[FPStack]>; def : Pat<(f64 fpimmneg1), (CHS_Fp64 (LD_Fp164))>, Requires<[FPStack]>; -def : Pat<(f80 fpimmneg0), (CHS_Fp80 (LD_Fp080))>, Requires<[FPStack]>; -def : Pat<(f80 fpimmneg1), (CHS_Fp80 (LD_Fp180))>, Requires<[FPStack]>; +def : Pat<(f80 fpimmneg0), (CHS_Fp80 (LD_Fp080))>; +def : Pat<(f80 fpimmneg1), (CHS_Fp80 (LD_Fp180))>; // Used to conv. i64 to f64 since there isn't a SSE version. def : Pat<(X86fildflag addr:$src, i64), (ILD_Fp64m64 addr:$src)>; -def : Pat<(extloadf80f32 addr:$src), - (MOV_Fp3280 (LD_Fp32m addr:$src))>, Requires<[FPStack]>; -def : Pat<(extloadf80f64 addr:$src), - (MOV_Fp6480 (LD_Fp64m addr:$src))>, Requires<[FPStack]>; -def : Pat<(extloadf64f32 addr:$src), - (MOV_Fp3264 (LD_Fp32m addr:$src))>, Requires<[FPStack]>; - def : Pat<(f64 (fextend RFP32:$src)), (MOV_Fp3264 RFP32:$src)>, Requires<[FPStack]>; def : Pat<(f80 (fextend RFP32:$src)), (MOV_Fp3280 RFP32:$src)>, Requires<[FPStack]>; def : Pat<(f80 (fextend RFP64:$src)), (MOV_Fp6480 RFP64:$src)>, Requires<[FPStack]>; |