Finish materialize for ints
authorReed Kotler <rkotler@mips.com>
Thu, 15 May 2014 21:54:15 +0000 (21:54 +0000)
committerReed Kotler <rkotler@mips.com>
Thu, 15 May 2014 21:54:15 +0000 (21:54 +0000)
Summary: We add code to materialize all integer literals.

Test Plan: simplestorei.ll

Reviewers: dsanders

Reviewed By: dsanders

Differential Revision: http://reviews.llvm.org/D3596

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208923 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsFastISel.cpp
test/CodeGen/Mips/Fast-ISel/simplestorei.ll [new file with mode: 0644]

index eed1f062a300f22a757a5951683cbbced59af855..268a0ed591c4bcbff38366c4e5c6c07903bf3101 100644 (file)
@@ -79,6 +79,7 @@ private:
   unsigned MaterializeFP(const ConstantFP *CFP, MVT VT);
   unsigned MaterializeGV(const GlobalValue *GV, MVT VT);
   unsigned MaterializeInt(const Constant *C, MVT VT);
+  unsigned Materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);
 };
 
 bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {
@@ -226,20 +227,52 @@ unsigned MipsFastISel::MaterializeGV(const GlobalValue *GV, MVT VT) {
   return DestReg;
 }
 unsigned MipsFastISel::MaterializeInt(const Constant *C, MVT VT) {
-  if (VT != MVT::i32)
+  if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
     return 0;
   const TargetRegisterClass *RC = &Mips::GPR32RegClass;
-  // If the constant is in range, use a load-immediate.
   const ConstantInt *CI = cast<ConstantInt>(C);
-  if (isInt<16>(CI->getSExtValue())) {
+  int64_t Imm;
+  if (CI->isNegative())
+    Imm = CI->getSExtValue();
+  else
+    Imm = CI->getZExtValue();
+  return Materialize32BitInt(Imm, RC);
+}
+
+unsigned MipsFastISel::Materialize32BitInt(int64_t Imm,
+                                           const TargetRegisterClass *RC) {
+  unsigned ResultReg = createResultReg(RC);
+
+  if (isInt<16>(Imm)) {
     unsigned Opc = Mips::ADDiu;
-    unsigned ImmReg = createResultReg(RC);
-    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ImmReg)
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
         .addReg(Mips::ZERO)
-        .addImm(CI->getSExtValue());
-    return ImmReg;
+        .addImm(Imm);
+    return ResultReg;
+  } else if (isUInt<16>(Imm)) {
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::ORi),
+            ResultReg)
+        .addReg(Mips::ZERO)
+        .addImm(Imm);
+    return ResultReg;
   }
-  return 0;
+  unsigned Lo = Imm & 0xFFFF;
+  unsigned Hi = (Imm >> 16) & 0xFFFF;
+  if (Lo) {
+    // Both Lo and Hi have nonzero bits.
+    unsigned TmpReg = createResultReg(RC);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::LUi),
+            TmpReg).addImm(Hi);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::ORi),
+            ResultReg)
+        .addReg(TmpReg)
+        .addImm(Lo);
+
+  } else {
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::LUi),
+            ResultReg).addImm(Hi);
+  }
+  return ResultReg;
 }
 
 namespace llvm {
diff --git a/test/CodeGen/Mips/Fast-ISel/simplestorei.ll b/test/CodeGen/Mips/Fast-ISel/simplestorei.ll
new file mode 100644 (file)
index 0000000..7d2c8e7
--- /dev/null
@@ -0,0 +1,65 @@
+; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \
+; RUN:     < %s | FileCheck %s
+
+@ijk = external global i32
+
+; Function Attrs: nounwind
+define void @si2_1() #0 {
+entry:
+  store i32 32767, i32* @ijk, align 4
+; CHECK:        .ent    si2_1
+; CHECK:        addiu   $[[REG1:[0-9]+]], $zero, 32767
+; CHECK:        lw      $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}})
+; CHECK:        sw      $[[REG1]], 0($[[REG2]])
+
+  ret void
+}
+
+; Function Attrs: nounwind
+define void @si2_2() #0 {
+entry:
+  store i32 -32768, i32* @ijk, align 4
+; CHECK:        .ent    si2_2
+; CHECK:        addiu   $[[REG1:[0-9]+]], $zero, -32768
+; CHECK:        lw      $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}})
+; CHECK:        sw      $[[REG1]], 0($[[REG2]])
+  ret void
+}
+
+; Function Attrs: nounwind
+define void @ui2_1() #0 {
+entry:
+  store i32 65535, i32* @ijk, align 4
+; CHECK:        .ent    ui2_1
+; CHECK:        ori     $[[REG1:[0-9]+]], $zero, 65535
+; CHECK:        lw      $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}})
+; CHECK:        sw      $[[REG1]], 0($[[REG2]])
+  ret void
+}
+
+; Function Attrs: nounwind
+define void @ui4_1() #0 {
+entry:
+  store i32 983040, i32* @ijk, align 4
+; CHECK:        .ent    ui4_1
+; CHECK:        lui     $[[REG1:[0-9]+]], 15
+; CHECK:        lw      $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}})
+; CHECK:        sw      $[[REG1]], 0($[[REG2]])
+  ret void
+}
+
+; Function Attrs: nounwind
+define void @ui4_2() #0 {
+entry:
+  store i32 719566, i32* @ijk, align 4
+; CHECK:        .ent    ui4_2
+; CHECK:        lui    $[[REG1:[0-9]+]], 10
+; CHECK:       ori     $[[REG1]], $[[REG1]], 64206
+; CHECK:       lw      $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}})
+; CHECK:       sw      $[[REG1]], 0($[[REG2]])
+  ret void
+}
+
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+