OSDN Git Service

Subzero, MIPS32: Handling floating point instructions fadd, fsub, fmul, fdiv
authorSrdjan Obucina <Srdjan.Obucina@imgtec.com>
Tue, 12 Jul 2016 03:23:50 +0000 (20:23 -0700)
committerJim Stichnoth <stichnot@chromium.org>
Tue, 12 Jul 2016 03:23:50 +0000 (20:23 -0700)
This patch adds handling of floating point instructions
fadd, fsub, fmul and fdiv. Regarding frem, Mips32 does not have
instruction that calculates partial reminder, so it has to be
emulated with a set of instructions. Emulating frem will be addressed
in separate patch, when floating point format conversion instructions
are fully implemented.

BUG=
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/2027773002 .

Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.

src/IceTargetLoweringMIPS32.cpp
tests_lit/llvm2ice_tests/fp.arith.ll

index fbfbe92..6f9df19 100644 (file)
@@ -1255,10 +1255,6 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
   switch (Instr->getOp()) {
   default:
     break;
-  case InstArithmetic::Fadd:
-  case InstArithmetic::Fsub:
-  case InstArithmetic::Fmul:
-  case InstArithmetic::Fdiv:
   case InstArithmetic::Frem:
     UnimplementedLoweringError(this, Instr);
     return;
@@ -1341,13 +1337,54 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
     _mov(Dest, T);
     return;
   }
-  case InstArithmetic::Fadd:
+  case InstArithmetic::Fadd: {
+    if (DestTy == IceType_f32) {
+      _add_s(T, Src0R, Src1R);
+      _mov(Dest, T);
+      return;
+    }
+    if (DestTy == IceType_f64) {
+      _add_d(T, Src0R, Src1R);
+      _mov(Dest, T);
+      return;
+    }
     break;
+  }
   case InstArithmetic::Fsub:
+    if (DestTy == IceType_f32) {
+      _sub_s(T, Src0R, Src1R);
+      _mov(Dest, T);
+      return;
+    }
+    if (DestTy == IceType_f64) {
+      _sub_d(T, Src0R, Src1R);
+      _mov(Dest, T);
+      return;
+    }
     break;
   case InstArithmetic::Fmul:
+    if (DestTy == IceType_f32) {
+      _mul_s(T, Src0R, Src1R);
+      _mov(Dest, T);
+      return;
+    }
+    if (DestTy == IceType_f64) {
+      _mul_d(T, Src0R, Src1R);
+      _mov(Dest, T);
+      return;
+    }
     break;
   case InstArithmetic::Fdiv:
+    if (DestTy == IceType_f32) {
+      _div_s(T, Src0R, Src1R);
+      _mov(Dest, T);
+      return;
+    }
+    if (DestTy == IceType_f64) {
+      _div_d(T, Src0R, Src1R);
+      _mov(Dest, T);
+      return;
+    }
     break;
   case InstArithmetic::Frem:
     break;
@@ -2069,7 +2106,6 @@ void TargetMIPS32::lowerRet(const InstRet *Instr) {
       Context.insert<InstFakeUse>(R1);
       break;
     }
-
     default:
       UnimplementedLoweringError(this, Instr);
     }
@@ -2192,9 +2228,6 @@ Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) {
   Variable *Reg = makeReg(Ty, RegNum);
   if (isVectorType(Ty)) {
     UnimplementedError(getFlags());
-  } else if (isFloatingType(Ty)) {
-    (Ty == IceType_f32) ? _mov_s(Reg, llvm::dyn_cast<Variable>(Src))
-                        : _mov_d(Reg, llvm::dyn_cast<Variable>(Src));
   } else {
     // Mov's Src operand can really only be the flexible second operand type
     // or a register. Users should guarantee that.
index c57045a..22d41fc 100644 (file)
 ; RUN:   | %if --need=target_ARM32 --need=allow_dump \
 ; RUN:   --command FileCheck --check-prefix ARM32 %s
 
+; RUN: %if --need=target_MIPS32 --need=allow_dump \
+; RUN:   --command %p2i --filetype=asm --assemble --disassemble --target \
+; RUN:   mips32 -i %s --args -O2 --skip-unimplemented \
+; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
+; RUN:   --command FileCheck --check-prefix MIPS32 %s
+; RUN: %if --need=target_MIPS32 --need=allow_dump \
+; RUN:   --command %p2i --filetype=asm --assemble --disassemble --target \
+; RUN:   mips32 -i %s --args -Om1 --skip-unimplemented \
+; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
+; RUN:   --command FileCheck --check-prefix MIPS32 %s
+
 define internal float @addFloat(float %a, float %b) {
 entry:
   %add = fadd float %a, %b
@@ -31,6 +42,8 @@ entry:
 ; CHECK: fld
 ; ARM32-LABEL: addFloat
 ; ARM32: vadd.f32 s{{[0-9]+}}, s
+; MIPS32-LABEL: addFloat
+; MIPS32: add.s
 
 define internal double @addDouble(double %a, double %b) {
 entry:
@@ -42,6 +55,8 @@ entry:
 ; CHECK: fld
 ; ARM32-LABEL: addDouble
 ; ARM32: vadd.f64 d{{[0-9]+}}, d
+; MIPS32-LABEL: addDouble
+; MIPS32: add.d
 
 define internal float @subFloat(float %a, float %b) {
 entry:
@@ -53,6 +68,8 @@ entry:
 ; CHECK: fld
 ; ARM32-LABEL: subFloat
 ; ARM32: vsub.f32 s{{[0-9]+}}, s
+; MIPS32-LABEL: subFloat
+; MIPS32: sub.s
 
 define internal double @subDouble(double %a, double %b) {
 entry:
@@ -64,6 +81,8 @@ entry:
 ; CHECK: fld
 ; ARM32-LABEL: subDouble
 ; ARM32: vsub.f64 d{{[0-9]+}}, d
+; MIPS32-LABEL: subDouble
+; MIPS32: sub.d
 
 define internal float @mulFloat(float %a, float %b) {
 entry:
@@ -75,6 +94,8 @@ entry:
 ; CHECK: fld
 ; ARM32-LABEL: mulFloat
 ; ARM32: vmul.f32 s{{[0-9]+}}, s
+; MIPS32-LABEL: mulFloat
+; MIPS32: mul.s
 
 define internal double @mulDouble(double %a, double %b) {
 entry:
@@ -86,6 +107,8 @@ entry:
 ; CHECK: fld
 ; ARM32-LABEL: mulDouble
 ; ARM32: vmul.f64 d{{[0-9]+}}, d
+; MIPS32-LABEL: mulDouble
+; MIPS32: mul.d
 
 define internal float @divFloat(float %a, float %b) {
 entry:
@@ -97,6 +120,8 @@ entry:
 ; CHECK: fld
 ; ARM32-LABEL: divFloat
 ; ARM32: vdiv.f32 s{{[0-9]+}}, s
+; MIPS32-LABEL: divFloat
+; MIPS32: div.s
 
 define internal double @divDouble(double %a, double %b) {
 entry:
@@ -108,6 +133,8 @@ entry:
 ; CHECK: fld
 ; ARM32-LABEL: divDouble
 ; ARM32: vdiv.f64 d{{[0-9]+}}, d
+; MIPS32-LABEL: divDouble
+; MIPS32: div.d
 
 define internal float @remFloat(float %a, float %b) {
 entry: