[MIPS GlobalISel] Select float and double load and store

Select float and double load and store for MIPS32.

Differential Revision: https://reviews.llvm.org/D64419

llvm-svn: 365626
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 8e597dc..b7a9955 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -139,30 +139,49 @@
 }
 
 /// Returning Opc indicates that we failed to select MIPS instruction opcode.
-static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned MemSizeInBytes) {
-  if (Opc == TargetOpcode::G_STORE)
+static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned MemSizeInBytes,
+                                      unsigned RegBank, bool isFP64) {
+  bool isStore = Opc == TargetOpcode::G_STORE;
+  if (RegBank == Mips::GPRBRegBankID) {
+    if (isStore)
+      switch (MemSizeInBytes) {
+      case 4:
+        return Mips::SW;
+      case 2:
+        return Mips::SH;
+      case 1:
+        return Mips::SB;
+      default:
+        return Opc;
+      }
+    else
+      // Unspecified extending load is selected into zeroExtending load.
+      switch (MemSizeInBytes) {
+      case 4:
+        return Mips::LW;
+      case 2:
+        return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LH : Mips::LHu;
+      case 1:
+        return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LB : Mips::LBu;
+      default:
+        return Opc;
+      }
+  }
+
+  if (RegBank == Mips::FPRBRegBankID) {
     switch (MemSizeInBytes) {
     case 4:
-      return Mips::SW;
-    case 2:
-      return Mips::SH;
-    case 1:
-      return Mips::SB;
+      return isStore ? Mips::SWC1 : Mips::LWC1;
+    case 8:
+      if (isFP64)
+        return isStore ? Mips::SDC164 : Mips::LDC164;
+      else
+        return isStore ? Mips::SDC1 : Mips::LDC1;
     default:
       return Opc;
     }
-  else
-    // Unspecified extending load is selected into zeroExtending load.
-    switch (MemSizeInBytes) {
-    case 4:
-      return Mips::LW;
-    case 2:
-      return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LH : Mips::LHu;
-    case 1:
-      return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LB : Mips::LBu;
-    default:
-      return Opc;
-    }
+  }
+  return Opc;
 }
 
 bool MipsInstructionSelector::select(MachineInstr &I,
@@ -262,11 +281,14 @@
     const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
     const unsigned OpMemSizeInBytes = (*I.memoperands_begin())->getSize();
 
-    if (DestRegBank != Mips::GPRBRegBankID || OpSize != 32)
+    if (DestRegBank == Mips::GPRBRegBankID && OpSize != 32)
       return false;
 
-    const unsigned NewOpc =
-        selectLoadStoreOpCode(I.getOpcode(), OpMemSizeInBytes);
+    if (DestRegBank == Mips::FPRBRegBankID && OpSize != 32 && OpSize != 64)
+      return false;
+
+    const unsigned NewOpc = selectLoadStoreOpCode(
+        I.getOpcode(), OpMemSizeInBytes, DestRegBank, STI.isFP64bit());
     if (NewOpc == I.getOpcode())
       return false;