Add a first attempt at implementing stores for X86 fast isel using target hooks.
authorOwen Anderson <resistor@mac.com>
Thu, 4 Sep 2008 07:08:58 +0000 (07:08 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 4 Sep 2008 07:08:58 +0000 (07:08 +0000)
Dan or Evan, please review.

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

lib/Target/X86/X86FastISel.cpp
test/CodeGen/X86/fast-isel-mem.ll

index 38aa994a25172c5b9b67ba680dece7d2fedc11c3..51ef25a87c6f667996d83943f91a0fb7d5ba3d1d 100644 (file)
@@ -45,6 +45,8 @@ private:
   bool X86SelectConstAddr(Value *V, unsigned &Op0);
 
   bool X86SelectLoad(Instruction *I);
+  
+  bool X86SelectStore(Instruction *I);
 };
 
 /// X86SelectConstAddr - Select and emit code to materialize constant address.
@@ -77,6 +79,91 @@ bool X86FastISel::X86SelectConstAddr(Value *V,
   return true;
 }
 
+/// X86SelectStore - Select and emit code to implement store instructions.
+bool X86FastISel::X86SelectStore(Instruction* I) {
+  MVT VT = MVT::getMVT(I->getOperand(0)->getType());
+  if (VT == MVT::Other || !VT.isSimple())
+    // Unhandled type.  Halt "fast" selection and bail.
+    return false;
+  if (VT == MVT::iPTR)
+    // Use pointer type.
+    VT = TLI.getPointerTy();
+  // We only handle legal types. For example, on x86-32 the instruction
+  // selector contains all of the 64-bit instructions from x86-64,
+  // under the assumption that i64 won't be used if the target doesn't
+  // support it.
+  if (!TLI.isTypeLegal(VT))
+    return false;
+  unsigned Op0 = getRegForValue(I->getOperand(0));
+  if (Op0 == 0)
+    // Unhandled operand. Halt "fast" selection and bail.
+    return false;    
+
+  Value *V = I->getOperand(1);
+  unsigned Op1 = getRegForValue(V);
+  if (Op1 == 0) {
+    // Handle constant load address.
+    if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op1))
+      // Unhandled operand. Halt "fast" selection and bail.
+      return false;    
+  }
+  
+  // Get opcode and regclass of the output for the given load instruction.
+  unsigned Opc = 0;
+  const TargetRegisterClass *RC = NULL;
+  switch (VT.getSimpleVT()) {
+  default: return false;
+  case MVT::i8:
+    Opc = X86::MOV8mr;
+    RC  = X86::GR8RegisterClass;
+    break;
+  case MVT::i16:
+    Opc = X86::MOV16mr;
+    RC  = X86::GR16RegisterClass;
+    break;
+  case MVT::i32:
+    Opc = X86::MOV32mr;
+    RC  = X86::GR32RegisterClass;
+    break;
+  case MVT::i64:
+    // Must be in x86-64 mode.
+    Opc = X86::MOV64mr;
+    RC  = X86::GR64RegisterClass;
+    break;
+  case MVT::f32:
+    if (Subtarget->hasSSE1()) {
+      Opc = X86::MOVSSmr;
+      RC  = X86::FR32RegisterClass;
+    } else {
+      Opc = X86::ST_Fp32m;
+      RC  = X86::RFP32RegisterClass;
+    }
+    break;
+  case MVT::f64:
+    if (Subtarget->hasSSE2()) {
+      Opc = X86::MOVSDmr;
+      RC  = X86::FR64RegisterClass;
+    } else {
+      Opc = X86::ST_Fp64m;
+      RC  = X86::RFP64RegisterClass;
+    }
+    break;
+  case MVT::f80:
+    Opc = X86::ST_FP80m;
+    RC  = X86::RFP80RegisterClass;
+    break;
+  }
+
+  X86AddressMode AM;
+  if (Op1)
+    // Address is in register.
+    AM.Base.Reg = Op0;
+  else
+    AM.GV = cast<GlobalValue>(V);
+  addFullAddress(BuildMI(MBB, TII.get(Opc)), AM);
+  return true;
+}
+
 /// X86SelectLoad - Select and emit code to implement load instructions.
 ///
 bool X86FastISel::X86SelectLoad(Instruction *I)  {
index 81af0ab5a8f6347440413f01ab8436e990889834..5c39fb401707e72a5c41d12a634b42f61857e60f 100644 (file)
@@ -1,5 +1,5 @@
 ; RUN: llvm-as < %s | llc -fast-isel -mtriple=i386-apple-darwin -mattr=sse2 | \
-; RUN:   grep mov | grep lazy_ptr | count 1
+; RUN:   grep mov | grep lazy_ptr | count 2
 
 @src = external global i32
 
@@ -8,5 +8,6 @@ entry:
        %0 = load i32* @src, align 4
        %1 = load i32* @src, align 4
         %2 = add i32 %0, %1
+  store i32 %2, i32* @src
        ret i32 %2
 }