OSDN Git Service

Subzero, MIPS32: lowerSelect for i1, i8, i16, i32, f32, f64
authorSrdjan Obucina <Srdjan.Obucina@imgtec.com>
Wed, 14 Sep 2016 13:06:24 +0000 (06:06 -0700)
committerJim Stichnoth <stichnot@chromium.org>
Wed, 14 Sep 2016 13:06:24 +0000 (06:06 -0700)
Implements lowerSelect for basic integer and float datatypes.
Support for i64 will be added as separate patch.
Crucial for running crosstests.

R=stichnot@chromium.org

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

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

src/IceInstMIPS32.cpp
src/IceInstMIPS32.h
src/IceTargetLoweringMIPS32.cpp
src/IceTargetLoweringMIPS32.h
tests_lit/llvm2ice_tests/fp.cmp.ll
tests_lit/llvm2ice_tests/select-opt.ll

index 85cf07b..c83267d 100644 (file)
@@ -104,7 +104,13 @@ template <> const char *InstMIPS32Mflo::Opcode = "mflo";
 template <> const char *InstMIPS32Mov_d::Opcode = "mov.d";
 template <> const char *InstMIPS32Mov_s::Opcode = "mov.s";
 template <> const char *InstMIPS32Movf::Opcode = "movf";
+template <> const char *InstMIPS32Movn::Opcode = "movn";
+template <> const char *InstMIPS32Movn_d::Opcode = "movn.d";
+template <> const char *InstMIPS32Movn_s::Opcode = "movn.s";
 template <> const char *InstMIPS32Movt::Opcode = "movt";
+template <> const char *InstMIPS32Movz::Opcode = "movz";
+template <> const char *InstMIPS32Movz_d::Opcode = "movz.d";
+template <> const char *InstMIPS32Movz_s::Opcode = "movz.s";
 template <> const char *InstMIPS32Mtc1::Opcode = "mtc1";
 template <> const char *InstMIPS32Mthi::Opcode = "mthi";
 template <> const char *InstMIPS32Mtlo::Opcode = "mtlo";
@@ -737,7 +743,8 @@ void InstMIPS32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
     const Type SrcType = Src->getType();
 
     // move GP to/from FP
-    if (DstType != SrcType) {
+    if ((isScalarIntegerType(DstType) && isScalarFloatingType(SrcType)) ||
+        (isScalarFloatingType(DstType) && isScalarIntegerType(SrcType))) {
       if (isScalarFloatingType(DstType)) {
         Str << "\t"
                "mtc1"
index f993800..a466059 100644 (file)
@@ -228,7 +228,13 @@ public:
     Mov_d,
     Mov_s,
     Movf,
+    Movn,
+    Movn_d,
+    Movn_s,
     Movt,
+    Movz,
+    Movz_d,
+    Movz_s,
     Mtc1,
     Mthi,
     Mtlo,
@@ -1078,7 +1084,13 @@ using InstMIPS32Mflo = InstMIPS32UnaryopGPR<InstMIPS32::Mflo>;
 using InstMIPS32Mov_d = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_d>;
 using InstMIPS32Mov_s = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_s>;
 using InstMIPS32Movf = InstMIPS32MovConditional<InstMIPS32::Movf>;
+using InstMIPS32Movn = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn>;
+using InstMIPS32Movn_d = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn_d>;
+using InstMIPS32Movn_s = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn_s>;
 using InstMIPS32Movt = InstMIPS32MovConditional<InstMIPS32::Movt>;
+using InstMIPS32Movz = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz>;
+using InstMIPS32Movz_d = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz_d>;
+using InstMIPS32Movz_s = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz_s>;
 using InstMIPS32Mtc1 = InstMIPS32TwoAddrGPR<InstMIPS32::Mtc1>;
 using InstMIPS32Mthi = InstMIPS32UnaryopGPR<InstMIPS32::Mthi>;
 using InstMIPS32Mtlo = InstMIPS32UnaryopGPR<InstMIPS32::Mtlo>;
index e4f2fd0..8db2276 100644 (file)
@@ -3209,12 +3209,23 @@ void TargetMIPS32::lowerRet(const InstRet *Instr) {
   if (Instr->hasRetValue()) {
     Operand *Src0 = Instr->getRetValue();
     switch (Src0->getType()) {
+    case IceType_f32: {
+      Operand *Src0F = legalizeToReg(Src0);
+      Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_F0);
+      _mov(Reg, Src0F);
+      break;
+    }
+    case IceType_f64: {
+      Operand *Src0F = legalizeToReg(Src0);
+      Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_F0F1);
+      _mov(Reg, Src0F);
+      break;
+    }
     case IceType_i1:
     case IceType_i8:
     case IceType_i16:
     case IceType_i32: {
-      // Reg = legalizeToReg(Src0, RegMIPS32::Reg_V0);
-      Operand *Src0F = legalize(Src0, Legal_Reg);
+      Operand *Src0F = legalizeToReg(Src0);
       Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_V0);
       _mov(Reg, Src0F);
       break;
@@ -3235,7 +3246,44 @@ void TargetMIPS32::lowerRet(const InstRet *Instr) {
 }
 
 void TargetMIPS32::lowerSelect(const InstSelect *Instr) {
-  UnimplementedLoweringError(this, Instr);
+  Variable *Dest = Instr->getDest();
+  const Type DestTy = Dest->getType();
+
+  if (DestTy == IceType_i64 || isVectorType(DestTy)) {
+    UnimplementedLoweringError(this, Instr);
+    return;
+  }
+
+  Variable *DestR = legalizeToReg(Dest);
+  Variable *SrcTR = legalizeToReg(Instr->getTrueOperand());
+  Variable *SrcFR = legalizeToReg(Instr->getFalseOperand());
+
+  Variable *ConditionR = legalizeToReg(Instr->getCondition());
+
+  assert(Instr->getCondition()->getType() == IceType_i1);
+
+  switch (DestTy) {
+  case IceType_i1:
+  case IceType_i8:
+  case IceType_i16:
+  case IceType_i32:
+    _movn(SrcFR, SrcTR, ConditionR);
+    _mov(DestR, SrcFR);
+    _mov(Dest, DestR);
+    break;
+  case IceType_f32:
+    _movn_s(SrcFR, SrcTR, ConditionR);
+    _mov(DestR, SrcFR);
+    _mov(Dest, DestR);
+    break;
+  case IceType_f64:
+    _movn_d(SrcFR, SrcTR, ConditionR);
+    _mov(DestR, SrcFR);
+    _mov(Dest, DestR);
+    break;
+  default:
+    UnimplementedLoweringError(this, Instr);
+  }
 }
 
 void TargetMIPS32::lowerShuffleVector(const InstShuffleVector *Instr) {
index 717b7d9..8029386 100644 (file)
@@ -319,6 +319,18 @@ public:
     Context.insert<InstMIPS32Lui>(Dest, Src, Reloc);
   }
 
+  void _mfc1(Variable *Dest, Variable *Src) {
+    Context.insert<InstMIPS32Mfc1>(Dest, Src);
+  }
+
+  void _mfhi(Variable *Dest, Operand *Src) {
+    Context.insert<InstMIPS32Mfhi>(Dest, Src);
+  }
+
+  void _mflo(Variable *Dest, Operand *Src) {
+    Context.insert<InstMIPS32Mflo>(Dest, Src);
+  }
+
   void _mov(Variable *Dest, Operand *Src0) {
     assert(Dest != nullptr);
     // Variable* Src0_ = llvm::dyn_cast<Variable>(Src0);
@@ -347,20 +359,32 @@ public:
     Context.insert<InstMIPS32Movf>(Src0, Src1, FCC);
   }
 
+  void _movn(Variable *Dest, Variable *Src0, Variable *Src1) {
+    Context.insert<InstMIPS32Movn>(Dest, Src0, Src1);
+  }
+
+  void _movn_d(Variable *Dest, Variable *Src0, Variable *Src1) {
+    Context.insert<InstMIPS32Movn_d>(Dest, Src0, Src1);
+  }
+
+  void _movn_s(Variable *Dest, Variable *Src0, Variable *Src1) {
+    Context.insert<InstMIPS32Movn_s>(Dest, Src0, Src1);
+  }
+
   void _movt(Variable *Src0, Variable *Src1, Operand *FCC) {
     Context.insert<InstMIPS32Movt>(Src0, Src1, FCC);
   }
 
-  void _mfc1(Variable *Dest, Variable *Src) {
-    Context.insert<InstMIPS32Mfc1>(Dest, Src);
+  void _movz(Variable *Dest, Variable *Src0, Variable *Src1) {
+    Context.insert<InstMIPS32Movz>(Dest, Src0, Src1);
   }
 
-  void _mfhi(Variable *Dest, Operand *Src) {
-    Context.insert<InstMIPS32Mfhi>(Dest, Src);
+  void _movz_d(Variable *Dest, Variable *Src0, Variable *Src1) {
+    Context.insert<InstMIPS32Movz_d>(Dest, Src0, Src1);
   }
 
-  void _mflo(Variable *Dest, Operand *Src) {
-    Context.insert<InstMIPS32Mflo>(Dest, Src);
+  void _movz_s(Variable *Dest, Variable *Src0, Variable *Src1) {
+    Context.insert<InstMIPS32Movz_s>(Dest, Src0, Src1);
   }
 
   void _mtc1(Variable *Dest, Variable *Src) {
index 39c1850..55aa701 100644 (file)
@@ -968,6 +968,9 @@ entry:
 ; ARM32-OM1: vmovne.f32 s{{[0-9]+}}
 ; ARM32-O2: vmovmi.f32 s{{[0-9]+}}
 ; ARM32: bx
+; MIPS32-LABEL: selectFloatVarVar
+; MIPS32: movn.s {{.*}}
+; MIPS32: mov.s {{.*}}
 
 define internal double @selectDoubleVarVar(double %a, double %b) {
 entry:
@@ -985,3 +988,6 @@ entry:
 ; ARM32-OM1: vmovne.f64 d{{[0-9]+}}
 ; ARM32-O2: vmovmi.f64 d{{[0-9]+}}
 ; ARM32: bx
+; MIPS32-LABEL: selectDoubleVarVar
+; MIPS32: movn.d {{.*}}
+; MIPS32: mov.d {{.*}}
index aa2c4d9..9620aad 100644 (file)
 ; RUN:   | %if --need=target_ARM32 --need=allow_dump \
 ; RUN:   --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OM1 %s
 
+; RUN: %if --need=target_MIPS32 --need=allow_dump \
+; RUN:   --command %p2i --filetype=asm --assemble \
+; RUN:   --disassemble --target mips32 -i %s --args -Om1 \
+; RUN:   -allow-externally-defined-symbols -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 \
+; RUN:   --disassemble --target mips32 -i %s --args -O2 \
+; RUN:   -allow-externally-defined-symbols -skip-unimplemented \
+; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
+; RUN:   --command FileCheck --check-prefix MIPS32 %s
+
 define internal void @testSelect(i32 %a, i32 %b) {
 entry:
   %cmp = icmp slt i32 %a, %b
@@ -61,6 +75,10 @@ declare void @useInt(i32 %x)
 ; ARM32: bl {{.*}} useInt
 ; ARM32: bl {{.*}} useInt
 ; ARM32: bx lr
+; MIPS32-LABEL: testSelect
+; MIPS32: slt {{.*}}
+; MIPS32: movn {{.*}}
+; MIPS32: move {{.*}}
 
 ; Check for valid addressing mode in the cmp instruction when the
 ; operand is an immediate.
@@ -73,6 +91,9 @@ entry:
 ; CHECK-NOT: cmp 0x{{[0-9a-f]+}},
 ; ARM32-LABEL: testSelectImm32
 ; ARM32-NOT: cmp #{{.*}},
+; MIPS32-LABEL: testSelectImm32
+; MIPS32: movn {{.*}}
+; MIPS32: move {{.*}}
 
 ; Check for valid addressing mode in the cmp instruction when the
 ; operand is an immediate.  There is a different x86-32 lowering
@@ -86,3 +107,4 @@ entry:
 ; CHECK-NOT: cmp 0x{{[0-9a-f]+}},
 ; ARM32-LABEL: testSelectImm64
 ; ARM32-NOT: cmp #{{.*}},
+; MIPS32-LABEL: testSelectImm64