Fix pre- and post-indexed load / store encoding bugs.
[oota-llvm.git] / lib / Target / ARM / ARMISelLowering.h
index 71a115e1fcd9efc8d15c4888a89dcd5df444c54b..8408cc527abc9254c60d4e0fec1715e2dce5bdb2 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Evan Cheng and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #ifndef ARMISELLOWERING_H
 #define ARMISELLOWERING_H
 
+#include "ARMSubtarget.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include <vector>
 
 namespace llvm {
   class ARMConstantPoolValue;
-  class ARMSubtarget;
 
   namespace ARMISD {
     // ARM Specific DAG Nodes
     enum NodeType {
       // Start the numbering where the builting ops and target ops leave off.
-      FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END,
+      FIRST_NUMBER = ISD::BUILTIN_OP_END,
 
       Wrapper,      // Wrapper - A wrapper node for TargetConstantPool,
                     // TargetExternalSymbol, and TargetGlobalAddress.
       WrapperJT,    // WrapperJT - A wrapper node for TargetJumpTable
       
       CALL,         // Function call.
+      CALL_PRED,    // Function call that's predicable.
       CALL_NOLINK,  // Function call with branch not branch-and-link.
       tCALL,        // Thumb function call.
       BRCOND,       // Conditional branch.
@@ -55,15 +56,14 @@ namespace llvm {
       SITOF,        // sint to FP within a FP register.
       UITOF,        // uint to FP within a FP register.
 
-      MULHILOU,     // Lo,Hi = umul LHS, RHS.
-      MULHILOS,     // Lo,Hi = smul LHS, RHS.
-      
       SRL_FLAG,     // V,Flag = srl_flag X -> srl X, 1 + save carry out.
       SRA_FLAG,     // V,Flag = sra_flag X -> sra X, 1 + save carry out.
       RRX,          // V = RRX X, Flag     -> srl X, 1 + shift in carry flag.
       
       FMRRD,        // double to two gprs.
-      FMDRR         // Two gprs to double.
+      FMDRR,         // Two gprs to double.
+
+      THREAD_POINTER
     };
   }
 
@@ -73,37 +73,27 @@ namespace llvm {
   class ARMTargetLowering : public TargetLowering {
     int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
   public:
-    ARMTargetLowering(TargetMachine &TM);
+    explicit ARMTargetLowering(TargetMachine &TM);
 
-    virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+    virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
+    virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG);
+        
+    virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
+    
     virtual const char *getTargetNodeName(unsigned Opcode) const;
 
-    virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
+    virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
                                                        MachineBasicBlock *MBB);
 
     /// isLegalAddressingMode - Return true if the addressing mode represented
     /// by AM is legal for this target, for a load/store of the specified type.
     virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty)const;
     
-    /// isLegalAddressImmediate - Return true if the integer value can be used
-    /// as the offset of the target addressing mode for load / store of the
-    /// given type.
-    virtual bool isLegalAddressImmediate(int64_t V, const Type *Ty) const;
-
-    /// isLegalAddressImmediate - Return true if the GlobalValue can be used as
-    /// the offset of the target addressing mode.
-    virtual bool isLegalAddressImmediate(GlobalValue *GV) const;
-
-    /// isLegalAddressScale - Return true if the integer value can be used as
-    /// the scale of the target addressing mode for load / store of the given
-    /// type.
-    virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const;
-
     /// getPreIndexedAddressParts - returns true by value, base pointer and
     /// offset pointer and addressing mode by reference if the node's address
     /// can be legally represented as pre-indexed load / store address.
-    virtual bool getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
-                                           SDOperand &Offset,
+    virtual bool getPreIndexedAddressParts(SDNode *N, SDValue &Base,
+                                           SDValue &Offset,
                                            ISD::MemIndexedMode &AM,
                                            SelectionDAG &DAG);
 
@@ -111,22 +101,28 @@ namespace llvm {
     /// offset pointer and addressing mode by reference if this node can be
     /// combined with a load / store to form a post-indexed load / store.
     virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
-                                            SDOperand &Base, SDOperand &Offset,
+                                            SDValue &Base, SDValue &Offset,
                                             ISD::MemIndexedMode &AM,
                                             SelectionDAG &DAG);
 
-    virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
-                                                uint64_t Mask,
-                                                uint64_t &KnownZero, 
-                                                uint64_t &KnownOne,
+    virtual void computeMaskedBitsForTargetNode(const SDValue Op,
+                                                const APInt &Mask,
+                                                APInt &KnownZero, 
+                                                APInt &KnownOne,
+                                                const SelectionDAG &DAG,
                                                 unsigned Depth) const;
     ConstraintType getConstraintType(const std::string &Constraint) const;
     std::pair<unsigned, const TargetRegisterClass*> 
       getRegForInlineAsmConstraint(const std::string &Constraint,
-                                   MVT::ValueType VT) const;
+                                   MVT VT) const;
     std::vector<unsigned>
     getRegClassForInlineAsmConstraint(const std::string &Constraint,
-                                      MVT::ValueType VT) const;
+                                      MVT VT) const;
+
+    virtual const ARMSubtarget* getSubtarget() {
+      return Subtarget;
+    }
+
   private:
     /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
     /// make the right decision when generating code for different targets.
@@ -136,10 +132,25 @@ namespace llvm {
     ///
     unsigned ARMPCLabelIndex;
 
-    SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
-    SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG);
-    SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
-    SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG);
+    SDValue LowerCALL(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
+                                            SelectionDAG &DAG);
+    SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA,
+                                   SelectionDAG &DAG);
+    SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG);
+
+    SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG,
+                                      SDValue Chain,
+                                      SDValue Dst, SDValue Src,
+                                      SDValue Size, unsigned Align,
+                                      bool AlwaysInline,
+                                      const Value *DstSV, uint64_t DstSVOff,
+                                      const Value *SrcSV, uint64_t SrcSVOff);
   };
 }