[llvm-commits] [llvm] r113453 - /llvm/trunk/lib/Target/ARM/ARMFastISel.cpp

Eric Christopher echristo at apple.com
Wed Sep 8 17:19:41 PDT 2010


Author: echristo
Date: Wed Sep  8 19:19:41 2010
New Revision: 113453

URL: http://llvm.org/viewvc/llvm-project?rev=113453&view=rev
Log:
Rewrite TargetMaterializeConstant splitting it out into two functions
for integer and fp constants. Implement todo to use vfp3 instructions
to materialize easy constants if we can.

Modified:
    llvm/trunk/lib/Target/ARM/ARMFastISel.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=113453&r1=113452&r2=113453&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Wed Sep  8 19:19:41 2010
@@ -124,6 +124,8 @@
     bool ARMLoadAlloca(const Instruction *I, EVT VT);
     bool ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT);
     bool ARMComputeRegOffset(const Value *Obj, unsigned &Reg, int &Offset);
+    unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT);
+    unsigned ARMMaterializeInt(const Constant *C);
     
     bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR);
     const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB);
@@ -323,18 +325,40 @@
   return ResultReg;
 }
 
-unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
-  EVT VT = TLI.getValueType(C->getType(), true);
-
-  // Only handle simple types.
-  if (!VT.isSimple()) return 0;
-
-  // Handle double width floating point?
-  if (VT.getSimpleVT().SimpleTy == MVT::f64) return 0;
+// For double width floating point we need to materialize two constants
+// (the high and the low) into integer registers then use a move to get
+// the combined constant into an FP reg.
+unsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, EVT VT) {
+  const APFloat Val = CFP->getValueAPF();
+  bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64;
+  
+  // This checks to see if we can use VFP3 instructions to materialize
+  // a constant, otherwise we have to go through the constant pool.
+  if (TLI.isFPImmLegal(Val, VT)) {
+    unsigned Opc = is64bit ? ARM::FCONSTD : ARM::FCONSTS;
+    unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
+    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
+                            DestReg)
+                    .addFPImm(CFP));
+    return DestReg;
+  }
+  
+  // No 64-bit at the moment.
+  if (is64bit) return 0;
   
-  // TODO: Theoretically we could materialize fp constants directly with
-  // instructions from VFP3.
+  // Load this from the constant pool.
+  unsigned DestReg = ARMMaterializeInt(cast<Constant>(CFP));
+
+  // If we have a floating point constant we expect it in a floating point
+  // register.
+  unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
+  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
+                          TII.get(ARM::VMOVRS), MoveReg)
+                  .addReg(DestReg));
+  return MoveReg;
+}
 
+unsigned ARMFastISel::ARMMaterializeInt(const Constant *C) {
   // MachineConstantPool wants an explicit alignment.
   unsigned Align = TD.getPrefTypeAlignment(C->getType());
   if (Align == 0) {
@@ -353,21 +377,21 @@
                             TII.get(ARM::LDRcp))
                             .addReg(DestReg).addConstantPoolIndex(Idx)
                     .addReg(0).addImm(0));
-                  
-  // If we have a floating point constant we expect it in a floating point
-  // register.
-  // TODO: Make this use ARMBaseInstrInfo::copyPhysReg.
-  if (C->getType()->isFloatTy()) {
-    unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
-    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
-                            TII.get(ARM::VMOVRS), MoveReg)
-                    .addReg(DestReg));
-    return MoveReg;
-  }
     
   return DestReg;
 }
 
+unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
+  EVT VT = TLI.getValueType(C->getType(), true);
+
+  // Only handle simple types.
+  if (!VT.isSimple()) return 0;
+
+  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
+    return ARMMaterializeFP(CFP, VT);
+  return ARMMaterializeInt(C);
+}
+
 bool ARMFastISel::isTypeLegal(const Type *Ty, EVT &VT) {
   VT = TLI.getValueType(Ty, true);
   





More information about the llvm-commits mailing list