Implement vector shift up / down and insert zero with ps{rl}lq / ps{rl}ldq.
[oota-llvm.git] / lib / Target / X86 / X86ISelLowering.h
index 6bf76afd642eef7a7c143bee8852f936eb09c792..0c67794c932989e8bbebd5ded9bc3e7e8d7530de 100644 (file)
@@ -84,20 +84,6 @@ namespace llvm {
       /// as.
       FST,
 
-      /// FP_GET_RESULT - This corresponds to FpGETRESULT pseudo instruction
-      /// which copies from ST(0) to the destination. It takes a chain and
-      /// writes a RFP result and a chain.
-      FP_GET_RESULT,
-
-      /// FP_GET_RESULT2 - Same as FP_GET_RESULT except it copies two values
-      /// ST(0) and ST(1).
-      FP_GET_RESULT2,
-
-      /// FP_SET_RESULT - This corresponds to FpSETRESULT pseudo instruction
-      /// which copies the source operand to ST(0). It takes a chain+value and
-      /// returns a chain and a flag.
-      FP_SET_RESULT,
-
       /// CALL/TAILCALL - These operations represent an abstract X86 call
       /// instruction, which includes a bunch of information.  In particular the
       /// operands of these node are:
@@ -166,14 +152,22 @@ namespace llvm {
       /// relative displacements.
       WrapperRIP,
 
-      /// S2VEC - X86 version of SCALAR_TO_VECTOR. The destination base does not
-      /// have to match the operand type.
-      S2VEC,
+      /// PEXTRB - Extract an 8-bit value from a vector and zero extend it to
+      /// i32, corresponds to X86::PEXTRB.
+      PEXTRB,
 
       /// PEXTRW - Extract a 16-bit value from a vector and zero extend it to
       /// i32, corresponds to X86::PEXTRW.
       PEXTRW,
 
+      /// INSERTPS - Insert any element of a 4 x float vector into any element
+      /// of a destination 4 x floatvector.
+      INSERTPS,
+
+      /// PINSRB - Insert the lower 8-bits of a 32-bit value to a vector,
+      /// corresponds to X86::PINSRB.
+      PINSRB,
+
       /// PINSRW - Insert the lower 16-bits of a 32-bit value to a vector,
       /// corresponds to X86::PINSRW.
       PINSRW,
@@ -187,21 +181,34 @@ namespace llvm {
       /// in order to obtain suitable precision.
       FRSQRT, FRCP,
 
-      // Thread Local Storage
+      // TLSADDR, THREAThread - Thread Local Storage.
       TLSADDR, THREAD_POINTER,
 
-      // Exception Handling helpers
+      // EH_RETURN - Exception Handling helpers.
       EH_RETURN,
       
-      // tail call return 
-      //   oeprand #0 chain
-      //   operand #1 callee (register or absolute)
-      //   operand #2 stack adjustment
-      //   operand #3 optional in flag
+      /// TC_RETURN - Tail call return.
+      ///   operand #0 chain
+      ///   operand #1 callee (register or absolute)
+      ///   operand #2 stack adjustment
+      ///   operand #3 optional in flag
       TC_RETURN,
 
-      // Store FP control world into i16 memory
-      FNSTCW16m
+      // LCMPXCHG_DAG, LCMPXCHG8_DAG - Compare and swap.
+      LCMPXCHG_DAG,
+      LCMPXCHG8_DAG,
+
+      // FNSTCW16m - Store FP control world into i16 memory.
+      FNSTCW16m,
+
+      // VZEXT_MOVL - Vector move low and zero extend.
+      VZEXT_MOVL,
+
+      // VZEXT_LOAD - Load, scalar_to_vector, and zero extend.
+      VZEXT_LOAD,
+
+      // VSHL, VSRL - Vector logical left / right shift.
+      VSHL, VSRL
     };
   }
 
@@ -296,17 +303,6 @@ namespace llvm {
     unsigned getShufflePSHUFLWImmediate(SDNode *N);
   }
 
-  namespace X86 {
-   /// X86_64SRet - These represent different ways to implement x86_64 struct
-   /// returns call results.
-   enum X86_64SRet {
-     InMemory,    // Really is sret, returns in memory.
-     InGPR64,     // Returns in a pair of 64-bit integer registers.
-     InSSE,       // Returns in a pair of SSE registers.
-     InX87        // Returns in a pair of f80 X87 registers.
-   };
-  }
-
   //===--------------------------------------------------------------------===//
   //  X86TargetLowering - X86 Implementation of the TargetLowering interface
   class X86TargetLowering : public TargetLowering {
@@ -318,7 +314,7 @@ namespace llvm {
     int BytesCallerReserves;          // Number of arg bytes caller makes.
 
   public:
-    explicit X86TargetLowering(TargetMachine &TM);
+    explicit X86TargetLowering(X86TargetMachine &TM);
 
     /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
     /// jumptable.
@@ -343,6 +339,14 @@ namespace llvm {
     /// that contains are placed at 16-byte boundaries while the rest are at
     /// 4-byte boundaries.
     virtual unsigned getByValTypeAlignment(const Type *Ty) const;
+
+    /// getOptimalMemOpType - Returns the target specific optimal type for load
+    /// and store operations as a result of memset, memcpy, and memmove
+    /// lowering. It returns MVT::iAny if SelectionDAG should be responsible for
+    /// determining it.
+    virtual
+    MVT::ValueType getOptimalMemOpType(uint64_t Size, unsigned Align,
+                                       bool isSrcConst, bool isSrcStr) const;
     
     /// LowerOperation - Provide custom lowering hooks for some operations.
     ///
@@ -359,19 +363,26 @@ namespace llvm {
     virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
                                                         MachineBasicBlock *MBB);
 
     /// getTargetNodeName - This method returns the name of a target specific
     /// DAG node.
     virtual const char *getTargetNodeName(unsigned Opcode) const;
 
+    /// getSetCCResultType - Return the ISD::SETCC ValueType
+    virtual MVT::ValueType getSetCCResultType(const SDOperand &) const;
+
     /// computeMaskedBitsForTargetNode - Determine which of the bits specified 
     /// in Mask are known to be either zero or one and return them in the 
     /// KnownZero/KnownOne bitsets.
     virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
-                                                uint64_t Mask,
-                                                uint64_t &KnownZero, 
-                                                uint64_t &KnownOne,
+                                                const APInt &Mask,
+                                                APInt &KnownZero, 
+                                                APInt &KnownOne,
                                                 const SelectionDAG &DAG,
                                                 unsigned Depth = 0) const;
+
+    virtual bool
+    isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) const;
     
     SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG);
 
@@ -381,15 +392,14 @@ namespace llvm {
       getRegClassForInlineAsmConstraint(const std::string &Constraint,
                                         MVT::ValueType VT) const;
 
-    virtual void lowerXConstraint(MVT::ValueType ConstraintVT, 
-                                  std::string&) const;
+    virtual const char *LowerXConstraint(MVT::ValueType ConstraintVT) const;
 
     /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
     /// vector.  If it is invalid, don't add anything to Ops.
     virtual void LowerAsmOperandForConstraint(SDOperand Op,
                                               char ConstraintLetter,
                                               std::vector<SDOperand> &Ops,
-                                              SelectionDAG &DAG);
+                                              SelectionDAG &DAG) const;
     
     /// getRegForInlineAsmConstraint - Given a physical register constraint
     /// (e.g. {edx}), return the register number and the register class for the
@@ -419,9 +429,19 @@ namespace llvm {
     /// used by Targets can use this to indicate if there is a suitable
     /// VECTOR_SHUFFLE that can be used to replace a VAND with a constant
     /// pool entry.
-    virtual bool isVectorClearMaskLegal(std::vector<SDOperand> &BVOps,
+    virtual bool isVectorClearMaskLegal(const std::vector<SDOperand> &BVOps,
                                         MVT::ValueType EVT,
                                         SelectionDAG &DAG) const;
+
+    /// ShouldShrinkFPConstant - If true, then instruction selection should
+    /// seek to shrink the FP constant of the specified type to a smaller type
+    /// in order to save space and / or reduce runtime.
+    virtual bool ShouldShrinkFPConstant(MVT::ValueType VT) const {
+      // Don't shrink FP constpool if SSE2 is available since cvtss2sd is more
+      // expensive than a straight movsd. On the other hand, it's important to
+      // shrink long double fp constant since fldt is very slow.
+      return !X86ScalarSSEf64 || VT == MVT::f80;
+    }
     
     /// IsEligibleForTailCallOptimization - Check whether the call is eligible
     /// for tail call optimization. Target which want to do tail call
@@ -430,8 +450,8 @@ namespace llvm {
                                                    SDOperand Ret, 
                                                    SelectionDAG &DAG) const;
 
-    virtual const TargetSubtarget* getSubtarget() {
-      return static_cast<const TargetSubtarget*>(Subtarget);
+    virtual const X86Subtarget* getSubtarget() {
+      return Subtarget;
     }
 
     /// isScalarFPTypeInSSEReg - Return true if the specified scalar FP type is
@@ -445,7 +465,7 @@ namespace llvm {
     /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
     /// make the right decision when generating code for different targets.
     const X86Subtarget *Subtarget;
-    const MRegisterInfo *RegInfo;
+    const X86RegisterInfo *RegInfo;
 
     /// X86StackPtr - X86 physical register used as stack ptr.
     unsigned X86StackPtr;
@@ -457,24 +477,12 @@ namespace llvm {
     bool X86ScalarSSEf32;
     bool X86ScalarSSEf64;
 
-    X86::X86_64SRet ClassifyX86_64SRetCallReturn(const Function *Fn);
-
-    void X86_64AnalyzeSRetCallOperands(SDNode*, CCAssignFn*, CCState&);
-
     SDNode *LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode*TheCall,
                             unsigned CallingConv, SelectionDAG &DAG);
 
-    SDNode *LowerCallResultToTwo64BitRegs(SDOperand Chain, SDOperand InFlag,
-                                          SDNode *TheCall, unsigned Reg1,
-                                          unsigned Reg2, MVT::ValueType VT,
-                                          SelectionDAG &DAG);        
-
-    SDNode *LowerCallResultToTwoX87Regs(SDOperand Chain, SDOperand InFlag,
-                                        SDNode *TheCall, SelectionDAG &DAG);        
-
     SDOperand LowerMemArgument(SDOperand Op, SelectionDAG &DAG,
                                const CCValAssign &VA,  MachineFrameInfo *MFI,
-                               SDOperand Root, unsigned i);
+                               unsigned CC, SDOperand Root, unsigned i);
 
     SDOperand LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
                                const SDOperand &StackPtr,
@@ -483,6 +491,12 @@ namespace llvm {
 
     // Call lowering helpers.
     bool IsCalleePop(SDOperand Op);
+    bool CallRequiresGOTPtrInReg(bool Is64Bit, bool IsTailCall);
+    bool CallRequiresFnAddressInReg(bool Is64Bit, bool IsTailCall);
+    SDOperand EmitTailCallLoadRetAddr(SelectionDAG &DAG, SDOperand &OutRetAddr,
+                                SDOperand Chain, bool IsTailCall, bool Is64Bit,
+                                int FPDiff);
+
     CCAssignFn *CCAssignFnForNode(SDOperand Op) const;
     NameDecorationStyle NameDecorationForFORMAL_ARGUMENTS(SDOperand Op);
     unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG);
@@ -493,7 +507,9 @@ namespace llvm {
     SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerEXTRACT_VECTOR_ELT_SSE4(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerINSERT_VECTOR_ELT_SSE4(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG);
@@ -509,15 +525,13 @@ namespace llvm {
     SDOperand LowerSELECT(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerBRCOND(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerMEMSET(SDOperand Op, SelectionDAG &DAG);
-    SDOperand LowerMEMCPYInline(SDOperand Dest, SDOperand Source,
-                                SDOperand Chain, unsigned Size, unsigned Align,
-                                SelectionDAG &DAG);
     SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerDYNAMIC_STACKALLOC(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerVAARG(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerVACOPY(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG);
@@ -528,8 +542,40 @@ namespace llvm {
     SDOperand LowerFLT_ROUNDS_(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerCTLZ(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerCTTZ(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerLCS(SDOperand Op, SelectionDAG &DAG);
     SDNode *ExpandFP_TO_SINT(SDNode *N, SelectionDAG &DAG);
     SDNode *ExpandREADCYCLECOUNTER(SDNode *N, SelectionDAG &DAG);
+    SDNode *ExpandATOMIC_LCS(SDNode *N, SelectionDAG &DAG);
+    SDNode *ExpandATOMIC_LSS(SDNode *N, SelectionDAG &DAG);
+    
+    SDOperand EmitTargetCodeForMemset(SelectionDAG &DAG,
+                                      SDOperand Chain,
+                                      SDOperand Dst, SDOperand Src,
+                                      SDOperand Size, unsigned Align,
+                                      const Value *DstSV, uint64_t DstSVOff);
+    SDOperand EmitTargetCodeForMemcpy(SelectionDAG &DAG,
+                                      SDOperand Chain,
+                                      SDOperand Dst, SDOperand Src,
+                                      SDOperand Size, unsigned Align,
+                                      bool AlwaysInline,
+                                      const Value *DstSV, uint64_t DstSVOff,
+                                      const Value *SrcSV, uint64_t SrcSVOff);
+    
+    /// Utility function to emit atomic bitwise operations (and, or, xor).
+    // It takes the bitwise instruction to expand, the associated machine basic
+    // block, and the associated X86 opcodes for reg/reg and reg/imm.
+    MachineBasicBlock *EmitAtomicBitwiseWithCustomInserter(
+                                                    MachineInstr *BInstr,
+                                                    MachineBasicBlock *BB,
+                                                    unsigned regOpc,
+                                                    unsigned immOpc);
+    
+    /// Utility function to emit atomic min and max.  It takes the min/max
+    // instruction to expand, the associated basic block, and the associated
+    // cmov opcode for moving the min or max value.
+    MachineBasicBlock *EmitAtomicMinMaxWithCustomInserter(MachineInstr *BInstr,
+                                                          MachineBasicBlock *BB,
+                                                          unsigned cmovOpc);
   };
 }