//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Chris Lattner 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.
//
//===----------------------------------------------------------------------===//
//
#include "X86RegisterInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/CallingConvLower.h"
namespace llvm {
namespace X86ISD {
// Start the numbering where the builtin ops leave off.
FIRST_NUMBER = ISD::BUILTIN_OP_END+X86::INSTRUCTION_LIST_END,
+ /// BSF - Bit scan forward.
+ /// BSR - Bit scan reverse.
+ BSF,
+ BSR,
+
/// SHLD, SHRD - Double shift instructions. These correspond to
/// X86::SHLDxx and X86::SHRDxx instructions.
SHLD,
RDTSC_DAG,
/// X86 compare and logical compare instructions.
- CMP, TEST, COMI, UCOMI,
+ CMP, COMI, UCOMI,
/// X86 SetCC. Operand 1 is condition code, and operand 2 is the flag
/// operand produced by a CMP instruction.
TLSADDR, THREAD_POINTER,
// Exception Handling helpers
- EH_RETURN
+ 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,
+
+ // Store FP control world into i16 memory
+ FNSTCW16m
};
}
int RegSaveFrameIndex; // X86-64 vararg func register save area.
unsigned VarArgsGPOffset; // X86-64 vararg func int reg offset.
unsigned VarArgsFPOffset; // X86-64 vararg func fp reg offset.
- int ReturnAddrIndex; // FrameIndex for return slot.
int BytesToPopOnReturn; // Number of arg bytes ret should pop.
int BytesCallerReserves; // Number of arg bytes caller makes.
+
public:
- X86TargetLowering(TargetMachine &TM);
+ explicit X86TargetLowering(TargetMachine &TM);
+
+ /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
+ /// jumptable.
+ SDOperand getPICJumpTableRelocBase(SDOperand Table,
+ SelectionDAG &DAG) const;
// Return the number of bytes that a function should pop when it returns (in
// addition to the space used by the return address).
///
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+ /// ExpandOperation - Custom lower the specified operation, splitting the
+ /// value into two pieces.
+ ///
+ virtual SDNode *ExpandOperationResult(SDNode *N, SelectionDAG &DAG);
+
+
virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
std::vector<unsigned>
getRegClassForInlineAsmConstraint(const std::string &Constraint,
MVT::ValueType VT) const;
- /// isOperandValidForConstraint - Return the specified operand (possibly
- /// modified) if the specified SDOperand is valid for the specified target
- /// constraint letter, otherwise return null.
- SDOperand isOperandValidForConstraint(SDOperand Op, char ConstraintLetter,
- SelectionDAG &DAG);
+
+ /// 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);
/// getRegForInlineAsmConstraint - Given a physical register constraint
/// (e.g. {edx}), return the register number and the register class for the
/// 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;
+ /// isTruncateFree - Return true if it's free to truncate a value of
+ /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in
+ /// register EAX to i16 by referencing its sub-register AX.
+ virtual bool isTruncateFree(const Type *Ty1, const Type *Ty2) const;
+ virtual bool isTruncateFree(MVT::ValueType VT1, MVT::ValueType VT2) const;
+
/// isShuffleMaskLegal - Targets can use this to indicate that they only
/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
/// By default, if a target supports the VECTOR_SHUFFLE node, all mask
virtual bool isVectorClearMaskLegal(std::vector<SDOperand> &BVOps,
MVT::ValueType EVT,
SelectionDAG &DAG) const;
+
+ /// IsEligibleForTailCallOptimization - Check whether the call is eligible
+ /// for tail call optimization. Target which want to do tail call
+ /// optimization should implement this function.
+ virtual bool IsEligibleForTailCallOptimization(SDOperand Call,
+ SDOperand Ret,
+ SelectionDAG &DAG) const;
+
+ virtual const TargetSubtarget* getSubtarget() {
+ return static_cast<const TargetSubtarget*>(Subtarget);
+ }
+
private:
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
/// make the right decision when generating code for different targets.
/// X86StackPtr - X86 physical register used as stack ptr.
unsigned X86StackPtr;
-
- /// X86ScalarSSE - Select between SSE2 or x87 floating point ops.
- bool X86ScalarSSE;
+
+ /// X86ScalarSSEf32, X86ScalarSSEf64 - Select between SSE or x87
+ /// floating point ops.
+ /// When SSE is available, use it for f32 operations.
+ /// When SSE2 is available, use it for f64 operations.
+ bool X86ScalarSSEf32;
+ bool X86ScalarSSEf64;
SDNode *LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode*TheCall,
unsigned CallingConv, SelectionDAG &DAG);
+
+ SDOperand LowerMemArgument(SDOperand Op, SelectionDAG &DAG,
+ const CCValAssign &VA, MachineFrameInfo *MFI,
+ SDOperand Root, unsigned i);
+
+ SDOperand LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
+ const SDOperand &StackPtr,
+ const CCValAssign &VA, SDOperand Chain,
+ SDOperand Arg);
+
// C and StdCall Calling Convention implementation.
SDOperand LowerCCCArguments(SDOperand Op, SelectionDAG &DAG,
bool isStdCall = false);
SDOperand LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG,unsigned CC);
+ // fast calling convention (tail call) implementation for 32/64bit
+ SDOperand LowerX86_TailCallTo(SDOperand Op,
+ SelectionDAG & DAG, unsigned CC);
+ unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG);
// Fast and FastCall Calling Convention implementation.
SDOperand LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC);
+ std::pair<SDOperand,SDOperand> FP_TO_SINTHelper(SDOperand Op,
+ SelectionDAG &DAG);
+
SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerFABS(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerFNEG(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG);
- SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG, SDOperand Chain);
+ SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerSELECT(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerBRCOND(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerMEMSET(SDOperand Op, SelectionDAG &DAG);
- SDOperand LowerMEMCPY(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 LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerVACOPY(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerFRAME_TO_ARGS_OFFSET(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerTRAMPOLINE(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerFLT_ROUNDS(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerCTLZ(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerCTTZ(SDOperand Op, SelectionDAG &DAG);
+ SDNode *ExpandFP_TO_SINT(SDNode *N, SelectionDAG &DAG);
+ SDNode *ExpandREADCYCLECOUNTER(SDNode *N, SelectionDAG &DAG);
};
}