reduce indentation
[oota-llvm.git] / lib / Target / PIC16 / PIC16ISelLowering.h
index 503b72c42c44f8d4f035964eca8d2f63a7d8ffc4..b40ea12c15f6a7849aab9218113c8076cbe5c1e4 100644 (file)
@@ -19,6 +19,7 @@
 #include "PIC16Subtarget.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/Target/TargetLowering.h"
+#include <map>
 
 namespace llvm {
   namespace PIC16ISD {
@@ -29,19 +30,26 @@ namespace llvm {
       Lo,            // Low 8-bits of GlobalAddress.
       Hi,            // High 8-bits of GlobalAddress.
       PIC16Load,
+      PIC16LdArg,   // This is replica of PIC16Load but used to load function 
+                    // arguments and is being used for facilitating for some 
+                    // store removal optimizations. 
+
       PIC16LdWF,
       PIC16Store,
       PIC16StWF,
       Banksel,
-      MTLO,
-      MTHI,
+      MTLO,          // Move to low part of FSR
+      MTHI,          // Move to high part of FSR
+      MTPCLATH,      // Move to PCLATCH
+      PIC16Connect,  // General connector for PIC16 nodes
       BCF,
       LSLF,          // PIC16 Logical shift left
       LRLF,          // PIC16 Logical shift right
       RLF,           // Rotate left through carry
       RRF,           // Rotate right through carry
       CALL,          // PIC16 Call instruction 
-      SUBCC,        // Compare for equality or inequality.
+      CALLW,         // PIC16 CALLW instruction 
+      SUBCC,         // Compare for equality or inequality.
       SELECT_ICC,    // Psuedo to be caught in schedular and expanded to brcond.
       BRCOND,        // Conditional branch.
       Dummy
@@ -52,16 +60,11 @@ namespace llvm {
       RAM_SPACE = 0,   // RAM address space
       ROM_SPACE = 1    // ROM address space number is 1
     };
-    enum PIC16LibCall {
+    enum PIC16Libcall {
+      MUL_I8 = RTLIB::UNKNOWN_LIBCALL + 1,
       SRA_I8,
       SLL_I8,
       SRL_I8,
-      SRA_I16,
-      SLL_I16,
-      SRL_I16,
-      SRA_I32,
-      SLL_I32,
-      SRL_I32,
       PIC16UnknownCall
     };
   }
@@ -79,57 +82,83 @@ namespace llvm {
     virtual const char *getTargetNodeName(unsigned Opcode) const;
     /// getSetCCResultType - Return the ISD::SETCC ValueType
     virtual MVT getSetCCResultType(MVT ValType) const;
-    SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
     SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerShift(SDValue Op, SelectionDAG &DAG);
     SDValue LowerADD(SDValue Op, SelectionDAG &DAG);
     SDValue LowerSUB(SDValue Op, SelectionDAG &DAG);
     SDValue LowerBinOp(SDValue Op, SelectionDAG &DAG);
     SDValue LowerCALL(SDValue Op, SelectionDAG &DAG);
     SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
-    SDValue LowerCallReturn(SDValue Op, SDValue Chain, SDValue FrameAddress,
-                            SDValue InFlag, SelectionDAG &DAG);
-    SDValue LowerCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress,
-                               SDValue InFlag, SelectionDAG &DAG);
+    // Call returns
+    SDValue 
+    LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue FrameAddress, 
+                          SDValue InFlag, SelectionDAG &DAG);
+    SDValue 
+    LowerIndirectCallReturn(SDValue Op, SDValue Chain, SDValue InFlag,
+                            SDValue DataAddr_Lo, SDValue DataAddr_Hi,
+                            SelectionDAG &DAG);
+
+    // Call arguments
+    SDValue 
+    LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress, 
+                             SDValue InFlag, SelectionDAG &DAG);
+
+    SDValue 
+    LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, 
+                               SDValue DataAddr_Lo, SDValue DataAddr_Hi, 
+                               SelectionDAG &DAG);
+
     SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG);
     SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
     SDValue getPIC16Cmp(SDValue LHS, SDValue RHS, unsigned OrigCC, SDValue &CC,
-                        SelectionDAG &DAG);
+                        SelectionDAG &DAG, DebugLoc dl);
     virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
-                                                        MachineBasicBlock *MBB);
+                                                  MachineBasicBlock *MBB) const;
 
 
+    virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
     virtual void ReplaceNodeResults(SDNode *N,
                                     SmallVectorImpl<SDValue> &Results,
                                     SelectionDAG &DAG);
+    virtual void LowerOperationWrapper(SDNode *N,
+                                       SmallVectorImpl<SDValue> &Results,
+                                       SelectionDAG &DAG);
+
     SDValue ExpandStore(SDNode *N, SelectionDAG &DAG);
     SDValue ExpandLoad(SDNode *N, SelectionDAG &DAG);
-    //SDValue ExpandAdd(SDNode *N, SelectionDAG &DAG);
     SDValue ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG);
     SDValue ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG);
-    SDValue ExpandShift(SDNode *N, SelectionDAG &DAG);
     SDValue ExpandFrameIndex(SDNode *N, SelectionDAG &DAG);
 
     SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; 
     SDValue PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const; 
-
+    SDValue PerformStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const; 
+
+    // This function returns the Tmp Offset for FrameIndex. If any TmpOffset 
+    // already exists for the FI then it returns the same else it creates the 
+    // new offset and returns.
+    unsigned GetTmpOffsetForFI(unsigned FI, unsigned slot_size); 
+    void ResetTmpOffsetMap() { FiTmpOffsetMap.clear(); SetTmpSize(0); }
+    void InitReservedFrameCount(const Function *F); 
+
+    // Return the size of Tmp variable 
+    unsigned GetTmpSize() { return TmpSize; }
+    void SetTmpSize(unsigned Size) { TmpSize = Size; }
+
+    /// getFunctionAlignment - Return the Log2 alignment of this function.
+    virtual unsigned getFunctionAlignment(const Function *) const {
+      // FIXME: The function never seems to be aligned.
+      return 1;
+    }
   private:
-    // If the Node is a BUILD_PAIR representing representing an Address
-    // then this function will return true
+    // If the Node is a BUILD_PAIR representing a direct Address,
+    // then this function will return true.
     bool isDirectAddress(const SDValue &Op);
 
     // If the Node is a DirectAddress in ROM_SPACE then this 
     // function will return true
     bool isRomAddress(const SDValue &Op);
 
-    // To extract chain value from the SDValue Nodes
-    // This function will help to maintain the chain extracting
-    // code at one place. In case of any change in future it will
-    // help maintain the code
-    SDValue getChain(SDValue &Op);
-    
-    SDValue getOutFlag(SDValue &Op);
-
-
     // Extract the Lo and Hi component of Op. 
     void GetExpandedParts(SDValue Op, SelectionDAG &DAG, SDValue &Lo, 
                           SDValue &Hi); 
@@ -139,15 +168,28 @@ namespace llvm {
     // addresses need Banksel and Indirect addresses need to be loaded to
     // FSR first. Handle address specific cases here.
     void LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, SDValue &Chain, 
-                         SDValue &NewPtr, unsigned &Offset);
+                         SDValue &NewPtr, unsigned &Offset, DebugLoc dl);
 
     // FrameIndex should be broken down into ExternalSymbol and FrameOffset. 
     void LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG, SDValue &ES, 
                             int &Offset);
 
+
+    // CALL node should have all legal operands only. Legalize all non-legal
+    // operands of CALL node and then return the new call will all operands
+    // legal.
+    SDValue LegalizeCALL(SDValue Op, SelectionDAG &DAG);
+
+    // For indirect calls data address of the callee frame need to be
+    // extracted. This function fills the arguments DataAddr_Lo and 
+    // DataAddr_Hi with the address of the callee frame.
+    void GetDataAddress(DebugLoc dl, SDValue Callee, SDValue &Chain,
+                        SDValue &DataAddr_Lo, SDValue &DataAddr_Hi,
+                        SelectionDAG &DAG); 
+
     // We can not have both operands of a binary operation in W.
     // This function is used to put one operand on stack and generate a load.
-    SDValue ConvertToMemOperand(SDValue Op, SelectionDAG &DAG); 
+    SDValue ConvertToMemOperand(SDValue Op, SelectionDAG &DAG, DebugLoc dl); 
 
     // This function checks if we need to put an operand of an operation on
     // stack and generate a load or not.
@@ -159,26 +201,31 @@ namespace llvm {
 
 
     // Extending the LIB Call framework of LLVM
-    // To hold the names of PIC16LibCalls
-    const char *PIC16LibCallNames[PIC16ISD::PIC16UnknownCall]; 
+    // to hold the names of PIC16Libcalls.
+    const char *PIC16LibcallNames[PIC16ISD::PIC16UnknownCall]; 
 
-    // To set and retrieve the lib call names
-    void setPIC16LibCallName(PIC16ISD::PIC16LibCall Call, const char *Name);
-    const char *getPIC16LibCallName(PIC16ISD::PIC16LibCall Call);
+    // To set and retrieve the lib call names.
+    void setPIC16LibcallName(PIC16ISD::PIC16Libcall Call, const char *Name);
+    const char *getPIC16LibcallName(PIC16ISD::PIC16Libcall Call);
 
-    // Make PIC16 LibCall
-    SDValue MakePIC16LibCall(PIC16ISD::PIC16LibCall Call, MVT RetVT, 
+    // Make PIC16 Libcall.
+    SDValue MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, MVT RetVT, 
                              const SDValue *Ops, unsigned NumOps, bool isSigned,
-                             SelectionDAG &DAG);
+                             SelectionDAG &DAG, DebugLoc dl);
 
     // Check if operation has a direct load operand.
     inline bool isDirectLoad(const SDValue Op);
 
-    // Create the symbol and index for function frame
-    void getCurrentFrameIndex(SelectionDAG &DAG, SDValue &ES, 
-                              unsigned SlotSize, int &FI);
-
-    SDValue getCurrentFrame(SelectionDAG &DAG);
+  private:
+    // The frameindexes generated for spill/reload are stack based.
+    // This maps maintain zero based indexes for these FIs.
+    std::map<unsigned, unsigned> FiTmpOffsetMap;
+    unsigned TmpSize;
+
+    // These are the frames for return value and argument passing 
+    // These FrameIndices will be expanded to foo.frame external symbol
+    // and all others will be expanded to foo.tmp external symbol.
+    unsigned ReservedFrameCount; 
   };
 } // namespace llvm