X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSystemZ%2FSystemZInstrFP.td;h=f46840c46c6a565f081f4a43b21db55ddd20a3e6;hb=bc9d98b52d008d857c7423d7b43fb32022b926a2;hp=ce704cbb0977337eb41ef10d5502065a583f12ea;hpb=55e96fb1c67316cd5e28ebb16075fe6c9adbe0de;p=oota-llvm.git diff --git a/lib/Target/SystemZ/SystemZInstrFP.td b/lib/Target/SystemZ/SystemZInstrFP.td index ce704cbb097..f46840c46c6 100644 --- a/lib/Target/SystemZ/SystemZInstrFP.td +++ b/lib/Target/SystemZ/SystemZInstrFP.td @@ -14,9 +14,41 @@ // FIXME: multiclassify! +//===----------------------------------------------------------------------===// +// FP Pattern fragments + +def fpimm0 : PatLeaf<(fpimm), [{ + return N->isExactlyValue(+0.0); +}]>; + +def fpimmneg0 : PatLeaf<(fpimm), [{ + return N->isExactlyValue(-0.0); +}]>; + +let Uses = [PSW], usesCustomInserter = 1 in { + def SelectF32 : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, i8imm:$cc), + "# SelectF32 PSEUDO", + [(set FP32:$dst, + (SystemZselect FP32:$src1, FP32:$src2, imm:$cc, PSW))]>; + def SelectF64 : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, i8imm:$cc), + "# SelectF64 PSEUDO", + [(set FP64:$dst, + (SystemZselect FP64:$src1, FP64:$src2, imm:$cc, PSW))]>; +} + //===----------------------------------------------------------------------===// // Move Instructions +// Floating point constant loads. +let isReMaterializable = 1, isAsCheapAsAMove = 1 in { +def LD_Fp032 : Pseudo<(outs FP32:$dst), (ins), + "lzer\t{$dst}", + [(set FP32:$dst, fpimm0)]>; +def LD_Fp064 : Pseudo<(outs FP64:$dst), (ins), + "lzdr\t{$dst}", + [(set FP64:$dst, fpimm0)]>; +} + let neverHasSideEffects = 1 in { def FMOV32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src), "ler\t{$dst, $src}", @@ -26,7 +58,7 @@ def FMOV64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src), []>; } -let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { +let canFoldAsLoad = 1, isReMaterializable = 1 in { def FMOV32rm : Pseudo<(outs FP32:$dst), (ins rriaddr12:$src), "le\t{$dst, $src}", [(set FP32:$dst, (load rriaddr12:$src))]>; @@ -54,57 +86,86 @@ def FMOV64mry : Pseudo<(outs), (ins rriaddr:$dst, FP64:$src), "stdy\t{$src, $dst}", [(store FP64:$src, rriaddr:$dst)]>; +def FCOPYSIGN32 : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2), + "cpsdr\t{$dst, $src2, $src1}", + [(set FP32:$dst, (fcopysign FP32:$src1, FP32:$src2))]>; +def FCOPYSIGN64 : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2), + "cpsdr\t{$dst, $src2, $src1}", + [(set FP64:$dst, (fcopysign FP64:$src1, FP64:$src2))]>; + //===----------------------------------------------------------------------===// // Arithmetic Instructions - -let isTwoAddress = 1 in { +let Defs = [PSW] in { def FNEG32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src), - "lcebr\t{$dst}", - [(set FP32:$dst, (fneg FP32:$src))]>; + "lcebr\t{$dst, $src}", + [(set FP32:$dst, (fneg FP32:$src)), + (implicit PSW)]>; def FNEG64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src), - "lcdbr\t{$dst}", - [(set FP64:$dst, (fneg FP64:$src))]>; - -// FIXME: Add peephole for fneg(fabs) => load negative + "lcdbr\t{$dst, $src}", + [(set FP64:$dst, (fneg FP64:$src)), + (implicit PSW)]>; def FABS32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src), - "lpebr\t{$dst}", - [(set FP32:$dst, (fabs FP32:$src))]>; + "lpebr\t{$dst, $src}", + [(set FP32:$dst, (fabs FP32:$src)), + (implicit PSW)]>; def FABS64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src), - "lpdbr\t{$dst}", - [(set FP64:$dst, (fabs FP64:$src))]>; + "lpdbr\t{$dst, $src}", + [(set FP64:$dst, (fabs FP64:$src)), + (implicit PSW)]>; + +def FNABS32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src), + "lnebr\t{$dst, $src}", + [(set FP32:$dst, (fneg(fabs FP32:$src))), + (implicit PSW)]>; +def FNABS64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src), + "lndbr\t{$dst, $src}", + [(set FP64:$dst, (fneg(fabs FP64:$src))), + (implicit PSW)]>; +} +let isTwoAddress = 1 in { +let Defs = [PSW] in { let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y def FADD32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2), "aebr\t{$dst, $src2}", - [(set FP32:$dst, (fadd FP32:$src1, FP32:$src2))]>; + [(set FP32:$dst, (fadd FP32:$src1, FP32:$src2)), + (implicit PSW)]>; def FADD64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2), "adbr\t{$dst, $src2}", - [(set FP64:$dst, (fadd FP64:$src1, FP64:$src2))]>; + [(set FP64:$dst, (fadd FP64:$src1, FP64:$src2)), + (implicit PSW)]>; } -def FADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2), +def FADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2), "aeb\t{$dst, $src2}", - [(set FP32:$dst, (fadd FP32:$src1, (load rriaddr:$src2)))]>; -def FADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2), + [(set FP32:$dst, (fadd FP32:$src1, (load rriaddr12:$src2))), + (implicit PSW)]>; +def FADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2), "adb\t{$dst, $src2}", - [(set FP64:$dst, (fadd FP64:$src1, (load rriaddr:$src2)))]>; + [(set FP64:$dst, (fadd FP64:$src1, (load rriaddr12:$src2))), + (implicit PSW)]>; def FSUB32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2), "sebr\t{$dst, $src2}", - [(set FP32:$dst, (fsub FP32:$src1, FP32:$src2))]>; + [(set FP32:$dst, (fsub FP32:$src1, FP32:$src2)), + (implicit PSW)]>; def FSUB64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2), "sdbr\t{$dst, $src2}", - [(set FP64:$dst, (fsub FP64:$src1, FP64:$src2))]>; + [(set FP64:$dst, (fsub FP64:$src1, FP64:$src2)), + (implicit PSW)]>; -def FSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2), +def FSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2), "seb\t{$dst, $src2}", - [(set FP32:$dst, (fsub FP32:$src1, (load rriaddr:$src2)))]>; -def FSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2), + [(set FP32:$dst, (fsub FP32:$src1, (load rriaddr12:$src2))), + (implicit PSW)]>; +def FSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2), "sdb\t{$dst, $src2}", - [(set FP64:$dst, (fsub FP64:$src1, (load rriaddr:$src2)))]>; + [(set FP64:$dst, (fsub FP64:$src1, (load rriaddr12:$src2))), + (implicit PSW)]>; +} // Defs = [PSW] let isCommutable = 1 in { // X = MUL Y, Z == X = MUL Z, Y def FMUL32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2), @@ -115,12 +176,52 @@ def FMUL64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2), [(set FP64:$dst, (fmul FP64:$src1, FP64:$src2))]>; } -def FMUL32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2), +def FMUL32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2), "meeb\t{$dst, $src2}", - [(set FP32:$dst, (fmul FP32:$src1, (load rriaddr:$src2)))]>; -def FMUL64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2), + [(set FP32:$dst, (fmul FP32:$src1, (load rriaddr12:$src2)))]>; +def FMUL64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2), "mdb\t{$dst, $src2}", - [(set FP64:$dst, (fmul FP64:$src1, (load rriaddr:$src2)))]>; + [(set FP64:$dst, (fmul FP64:$src1, (load rriaddr12:$src2)))]>; + +def FMADD32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, FP32:$src3), + "maebr\t{$dst, $src3, $src2}", + [(set FP32:$dst, (fadd (fmul FP32:$src2, FP32:$src3), + FP32:$src1))]>; +def FMADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2, FP32:$src3), + "maeb\t{$dst, $src3, $src2}", + [(set FP32:$dst, (fadd (fmul (load rriaddr12:$src2), + FP32:$src3), + FP32:$src1))]>; + +def FMADD64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, FP64:$src3), + "madbr\t{$dst, $src3, $src2}", + [(set FP64:$dst, (fadd (fmul FP64:$src2, FP64:$src3), + FP64:$src1))]>; +def FMADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2, FP64:$src3), + "madb\t{$dst, $src3, $src2}", + [(set FP64:$dst, (fadd (fmul (load rriaddr12:$src2), + FP64:$src3), + FP64:$src1))]>; + +def FMSUB32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, FP32:$src3), + "msebr\t{$dst, $src3, $src2}", + [(set FP32:$dst, (fsub (fmul FP32:$src2, FP32:$src3), + FP32:$src1))]>; +def FMSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2, FP32:$src3), + "mseb\t{$dst, $src3, $src2}", + [(set FP32:$dst, (fsub (fmul (load rriaddr12:$src2), + FP32:$src3), + FP32:$src1))]>; + +def FMSUB64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, FP64:$src3), + "msdbr\t{$dst, $src3, $src2}", + [(set FP64:$dst, (fsub (fmul FP64:$src2, FP64:$src3), + FP64:$src1))]>; +def FMSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2, FP64:$src3), + "msdb\t{$dst, $src3, $src2}", + [(set FP64:$dst, (fsub (fmul (load rriaddr12:$src2), + FP64:$src3), + FP64:$src1))]>; def FDIV32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2), "debr\t{$dst, $src2}", @@ -129,46 +230,84 @@ def FDIV64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2), "ddbr\t{$dst, $src2}", [(set FP64:$dst, (fdiv FP64:$src1, FP64:$src2))]>; -def FDIV32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr:$src2), +def FDIV32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2), "deb\t{$dst, $src2}", - [(set FP32:$dst, (fdiv FP32:$src1, (load rriaddr:$src2)))]>; -def FDIV64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr:$src2), + [(set FP32:$dst, (fdiv FP32:$src1, (load rriaddr12:$src2)))]>; +def FDIV64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2), "ddb\t{$dst, $src2}", - [(set FP64:$dst, (fdiv FP64:$src1, (load rriaddr:$src2)))]>; + [(set FP64:$dst, (fdiv FP64:$src1, (load rriaddr12:$src2)))]>; } // isTwoAddress = 1 +def FSQRT32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src), + "sqebr\t{$dst, $src}", + [(set FP32:$dst, (fsqrt FP32:$src))]>; +def FSQRT64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src), + "sqdbr\t{$dst, $src}", + [(set FP64:$dst, (fsqrt FP64:$src))]>; + +def FSQRT32rm : Pseudo<(outs FP32:$dst), (ins rriaddr12:$src), + "sqeb\t{$dst, $src}", + [(set FP32:$dst, (fsqrt (load rriaddr12:$src)))]>; +def FSQRT64rm : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src), + "sqdb\t{$dst, $src}", + [(set FP64:$dst, (fsqrt (load rriaddr12:$src)))]>; + def FROUND64r32 : Pseudo<(outs FP32:$dst), (ins FP64:$src), "ledbr\t{$dst, $src}", [(set FP32:$dst, (fround FP64:$src))]>; +def FEXT32r64 : Pseudo<(outs FP64:$dst), (ins FP32:$src), + "ldebr\t{$dst, $src}", + [(set FP64:$dst, (fextend FP32:$src))]>; +def FEXT32m64 : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src), + "ldeb\t{$dst, $src}", + [(set FP64:$dst, (fextend (load rriaddr12:$src)))]>; + +let Defs = [PSW] in { def FCONVFP32 : Pseudo<(outs FP32:$dst), (ins GR32:$src), "cefbr\t{$dst, $src}", - [(set FP32:$dst, (sint_to_fp GR32:$src))]>; + [(set FP32:$dst, (sint_to_fp GR32:$src)), + (implicit PSW)]>; def FCONVFP32r64: Pseudo<(outs FP32:$dst), (ins GR64:$src), "cegbr\t{$dst, $src}", - [(set FP32:$dst, (sint_to_fp GR64:$src))]>; + [(set FP32:$dst, (sint_to_fp GR64:$src)), + (implicit PSW)]>; def FCONVFP64r32: Pseudo<(outs FP64:$dst), (ins GR32:$src), "cdfbr\t{$dst, $src}", - [(set FP64:$dst, (sint_to_fp GR32:$src))]>; + [(set FP64:$dst, (sint_to_fp GR32:$src)), + (implicit PSW)]>; def FCONVFP64 : Pseudo<(outs FP64:$dst), (ins GR64:$src), "cdgbr\t{$dst, $src}", - [(set FP64:$dst, (sint_to_fp GR64:$src))]>; + [(set FP64:$dst, (sint_to_fp GR64:$src)), + (implicit PSW)]>; def FCONVGR32 : Pseudo<(outs GR32:$dst), (ins FP32:$src), - "cfebr\t{$dst, $src}", - [(set GR32:$dst, (fp_to_sint FP32:$src))]>; + "cfebr\t{$dst, 5, $src}", + [(set GR32:$dst, (fp_to_sint FP32:$src)), + (implicit PSW)]>; def FCONVGR32r64: Pseudo<(outs GR32:$dst), (ins FP64:$src), - "cgebr\t{$dst, $src}", - [(set GR32:$dst, (fp_to_sint FP64:$src))]>; + "cfdbr\t{$dst, 5, $src}", + [(set GR32:$dst, (fp_to_sint FP64:$src)), + (implicit PSW)]>; def FCONVGR64r32: Pseudo<(outs GR64:$dst), (ins FP32:$src), - "cfdbr\t{$dst, $src}", - [(set GR64:$dst, (fp_to_sint FP32:$src))]>; + "cgebr\t{$dst, 5, $src}", + [(set GR64:$dst, (fp_to_sint FP32:$src)), + (implicit PSW)]>; def FCONVGR64 : Pseudo<(outs GR64:$dst), (ins FP64:$src), - "cgdbr\t{$dst, $src}", - [(set GR64:$dst, (fp_to_sint FP64:$src))]>; + "cgdbr\t{$dst, 5, $src}", + [(set GR64:$dst, (fp_to_sint FP64:$src)), + (implicit PSW)]>; +} // Defs = [PSW] + +def FBCONVG64 : Pseudo<(outs GR64:$dst), (ins FP64:$src), + "lgdr\t{$dst, $src}", + [(set GR64:$dst, (bitconvert FP64:$src))]>; +def FBCONVF64 : Pseudo<(outs FP64:$dst), (ins GR64:$src), + "ldgr\t{$dst, $src}", + [(set FP64:$dst, (bitconvert GR64:$src))]>; //===----------------------------------------------------------------------===// // Test instructions (like AND but do not produce any result) @@ -182,12 +321,20 @@ def FCMP64rr : Pseudo<(outs), (ins FP64:$src1, FP64:$src2), "cdbr\t$src1, $src2", [(SystemZcmp FP64:$src1, FP64:$src2), (implicit PSW)]>; -def FCMP32rm : Pseudo<(outs), (ins FP32:$src1, rriaddr:$src2), +def FCMP32rm : Pseudo<(outs), (ins FP32:$src1, rriaddr12:$src2), "ceb\t$src1, $src2", - [(SystemZcmp FP32:$src1, (load rriaddr:$src2)), + [(SystemZcmp FP32:$src1, (load rriaddr12:$src2)), (implicit PSW)]>; -def FCMP64rm : Pseudo<(outs), (ins FP64:$src1, rriaddr:$src2), +def FCMP64rm : Pseudo<(outs), (ins FP64:$src1, rriaddr12:$src2), "cdb\t$src1, $src2", - [(SystemZcmp FP64:$src1, (load rriaddr:$src2)), + [(SystemZcmp FP64:$src1, (load rriaddr12:$src2)), (implicit PSW)]>; } // Defs = [PSW] + +//===----------------------------------------------------------------------===// +// Non-Instruction Patterns +//===----------------------------------------------------------------------===// + +// Floating point constant -0.0 +def : Pat<(f32 fpimmneg0), (FNEG32rr (LD_Fp032))>; +def : Pat<(f64 fpimmneg0), (FNEG64rr (LD_Fp064))>;