diff options
| author | Akira Hatanaka <ahatanaka@mips.com> | 2012-02-25 00:21:52 +0000 |
|---|---|---|
| committer | Akira Hatanaka <ahatanaka@mips.com> | 2012-02-25 00:21:52 +0000 |
| commit | 60f7a8e710d35cafd085c99f205b880cdfcc4513 (patch) | |
| tree | 55677e8262ca6a22a11980756d3e3d6efbbcdb8c /llvm | |
| parent | 4a71b12a4ed73694d7d9aa3f4e0c0d5a5141cdd5 (diff) | |
| download | bcm5719-llvm-60f7a8e710d35cafd085c99f205b880cdfcc4513.tar.gz bcm5719-llvm-60f7a8e710d35cafd085c99f205b880cdfcc4513.zip | |
Add definitions of floating point multiply add/sub and negative multiply
add/sub instructions.
llvm-svn: 151415
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrFPU.td | 60 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrFormats.td | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 1 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Mips/fmadd1.ll | 88 |
4 files changed, 159 insertions, 8 deletions
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td index 568cfa57083..f7af99dd408 100644 --- a/llvm/lib/Target/Mips/MipsInstrFPU.td +++ b/llvm/lib/Target/Mips/MipsInstrFPU.td @@ -59,6 +59,15 @@ def NotFP64bit : Predicate<"!Subtarget.isFP64bit()">; def IsSingleFloat : Predicate<"Subtarget.isSingleFloat()">; def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">; +// FP immediate patterns. +def fpimm0 : PatLeaf<(fpimm), [{ + return N->isExactlyValue(+0.0); +}]>; + +def fpimm0neg : PatLeaf<(fpimm), [{ + return N->isExactlyValue(-0.0); +}]>; + //===----------------------------------------------------------------------===// // Instruction Class Templates // @@ -122,6 +131,19 @@ multiclass FFR2P_M<bits<6> funct, string opstr, SDNode OpNode, bit isComm = 0> { } } +// FP madd/msub/nmadd/nmsub instruction classes. +class FMADDSUB<bits<3> funct, bits<3> fmt, string opstr, string fmtstr, + SDNode OpNode, RegisterClass RC> : + FFMADDSUB<funct, fmt, (outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft), + !strconcat(opstr, ".", fmtstr, "\t$fd, $fr, $fs, $ft"), + [(set RC:$fd, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr))]>; + +class FNMADDSUB<bits<3> funct, bits<3> fmt, string opstr, string fmtstr, + SDNode OpNode, RegisterClass RC> : + FFMADDSUB<funct, fmt, (outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft), + !strconcat(opstr, ".", fmtstr, "\t$fd, $fr, $fs, $ft"), + [(set RC:$fd, (fsub fpimm0, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr)))]>; + //===----------------------------------------------------------------------===// // Floating Point Instructions //===----------------------------------------------------------------------===// @@ -224,6 +246,36 @@ defm FDIV : FFR2P_M<0x03, "div", fdiv>; defm FMUL : FFR2P_M<0x02, "mul", fmul, 1>; defm FSUB : FFR2P_M<0x01, "sub", fsub>; +let Predicates = [HasMips32r2] in { + def MADD_S : FMADDSUB<0x4, 0, "madd", "s", fadd, FGR32>; + def MSUB_S : FMADDSUB<0x5, 0, "msub", "s", fsub, FGR32>; +} + +let Predicates = [HasMips32r2, NoNaNsFPMath] in { + def NMADD_S : FNMADDSUB<0x6, 0, "nmadd", "s", fadd, FGR32>; + def NMSUB_S : FNMADDSUB<0x7, 0, "nmsub", "s", fsub, FGR32>; +} + +let Predicates = [HasMips32r2, NotFP64bit] in { + def MADD_D32 : FMADDSUB<0x4, 1, "madd", "d", fadd, AFGR64>; + def MSUB_D32 : FMADDSUB<0x5, 1, "msub", "d", fsub, AFGR64>; +} + +let Predicates = [HasMips32r2, NotFP64bit, NoNaNsFPMath] in { + def NMADD_D32 : FNMADDSUB<0x6, 1, "nmadd", "d", fadd, AFGR64>; + def NMSUB_D32 : FNMADDSUB<0x7, 1, "nmsub", "d", fsub, AFGR64>; +} + +let Predicates = [HasMips32r2, IsFP64bit] in { + def MADD_D64 : FMADDSUB<0x4, 1, "madd", "d", fadd, FGR64>; + def MSUB_D64 : FMADDSUB<0x5, 1, "msub", "d", fsub, FGR64>; +} + +let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath] in { + def NMADD_D64 : FNMADDSUB<0x6, 1, "nmadd", "d", fadd, FGR64>; + def NMSUB_D64 : FNMADDSUB<0x7, 1, "nmsub", "d", fsub, FGR64>; +} + //===----------------------------------------------------------------------===// // Floating Point Branch Codes //===----------------------------------------------------------------------===// @@ -305,14 +357,6 @@ def ExtractElementF64 : //===----------------------------------------------------------------------===// // Floating Point Patterns //===----------------------------------------------------------------------===// -def fpimm0 : PatLeaf<(fpimm), [{ - return N->isExactlyValue(+0.0); -}]>; - -def fpimm0neg : PatLeaf<(fpimm), [{ - return N->isExactlyValue(-0.0); -}]>; - def : Pat<(f32 fpimm0), (MTC1 ZERO)>; def : Pat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>; diff --git a/llvm/lib/Target/Mips/MipsInstrFormats.td b/llvm/lib/Target/Mips/MipsInstrFormats.td index 21a1862d2fb..6bf8668fca0 100644 --- a/llvm/lib/Target/Mips/MipsInstrFormats.td +++ b/llvm/lib/Target/Mips/MipsInstrFormats.td @@ -290,3 +290,21 @@ class FFR2P<bits<6> funct, bits<5> fmt, string opstr, FFR<0x11, funct, fmt, (outs RC:$fd), (ins RC:$fs, RC:$ft), !strconcat(opstr, ".", fmtstr, "\t$fd, $fs, $ft"), [(set RC:$fd, (OpNode RC:$fs, RC:$ft))]>; + +// Floating point madd/msub/nmadd/nmsub. +class FFMADDSUB<bits<3> funct, bits<3> fmt, dag outs, dag ins, string asmstr, + list<dag> pattern> + : MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther> { + bits<5> fd; + bits<5> fr; + bits<5> fs; + bits<5> ft; + + let Opcode = 0x13; + let Inst{25-21} = fr; + let Inst{20-16} = ft; + let Inst{15-11} = fs; + let Inst{10-6} = fd; + let Inst{5-3} = funct; + let Inst{2-0} = fmt; +} diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index ac1261068c4..3d58030c024 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -134,6 +134,7 @@ def IsN64 : Predicate<"Subtarget.isABI_N64()">; def NotN64 : Predicate<"!Subtarget.isABI_N64()">; def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">; def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">; +def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">; //===----------------------------------------------------------------------===// // Mips Operand, Complex Patterns and Transformations Definitions. diff --git a/llvm/test/CodeGen/Mips/fmadd1.ll b/llvm/test/CodeGen/Mips/fmadd1.ll new file mode 100644 index 00000000000..435b419368b --- /dev/null +++ b/llvm/test/CodeGen/Mips/fmadd1.ll @@ -0,0 +1,88 @@ +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -enable-no-nans-fp-math | FileCheck %s -check-prefix=32R2 +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -mattr=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefix=64R2 +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=32R2NAN +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -mattr=n64 | FileCheck %s -check-prefix=64R2NAN + +define float @FOO0float(float %a, float %b, float %c) nounwind readnone { +entry: +; CHECK: madd.s + %mul = fmul float %a, %b + %add = fadd float %mul, %c + %add1 = fadd float %add, 0.000000e+00 + ret float %add1 +} + +define float @FOO1float(float %a, float %b, float %c) nounwind readnone { +entry: +; CHECK: msub.s + %mul = fmul float %a, %b + %sub = fsub float %mul, %c + %add = fadd float %sub, 0.000000e+00 + ret float %add +} + +define float @FOO2float(float %a, float %b, float %c) nounwind readnone { +entry: +; 32R2: nmadd.s +; 64R2: nmadd.s +; 32R2NAN: madd.s +; 64R2NAN: madd.s + %mul = fmul float %a, %b + %add = fadd float %mul, %c + %sub = fsub float 0.000000e+00, %add + ret float %sub +} + +define float @FOO3float(float %a, float %b, float %c) nounwind readnone { +entry: +; 32R2: nmsub.s +; 64R2: nmsub.s +; 32R2NAN: msub.s +; 64R2NAN: msub.s + %mul = fmul float %a, %b + %sub = fsub float %mul, %c + %sub1 = fsub float 0.000000e+00, %sub + ret float %sub1 +} + +define double @FOO10double(double %a, double %b, double %c) nounwind readnone { +entry: +; CHECK: madd.d + %mul = fmul double %a, %b + %add = fadd double %mul, %c + %add1 = fadd double %add, 0.000000e+00 + ret double %add1 +} + +define double @FOO11double(double %a, double %b, double %c) nounwind readnone { +entry: +; CHECK: msub.d + %mul = fmul double %a, %b + %sub = fsub double %mul, %c + %add = fadd double %sub, 0.000000e+00 + ret double %add +} + +define double @FOO12double(double %a, double %b, double %c) nounwind readnone { +entry: +; 32R2: nmadd.d +; 64R2: nmadd.d +; 32R2NAN: madd.d +; 64R2NAN: madd.d + %mul = fmul double %a, %b + %add = fadd double %mul, %c + %sub = fsub double 0.000000e+00, %add + ret double %sub +} + +define double @FOO13double(double %a, double %b, double %c) nounwind readnone { +entry: +; 32R2: nmsub.d +; 64R2: nmsub.d +; 32R2NAN: msub.d +; 64R2NAN: msub.d + %mul = fmul double %a, %b + %sub = fsub double %mul, %c + %sub1 = fsub double 0.000000e+00, %sub + ret double %sub1 +} |

