Skip to content
X86ISelLowering.cpp 74.7 KiB
Newer Older
//===-- X86ISelLowering.h - X86 DAG Lowering Interface ----------*- C++ -*-===//
//
//                     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 defines the interfaces that X86 uses to lower LLVM code into a
// selection DAG.
//
//===----------------------------------------------------------------------===//

#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86ISelLowering.h"
#include "X86TargetMachine.h"
#include "llvm/CallingConv.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
Evan Cheng's avatar
Evan Cheng committed
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/VectorExtras.h"
using namespace llvm;

// FIXME: temporary.
#include "llvm/Support/CommandLine.h"
static cl::opt<bool> EnableFastCC("enable-x86-fastcc", cl::Hidden,
                                  cl::desc("Enable fastcc on X86"));

X86TargetLowering::X86TargetLowering(TargetMachine &TM)
  : TargetLowering(TM) {
  Subtarget = &TM.getSubtarget<X86Subtarget>();
  X86ScalarSSE = Subtarget->hasSSE2();

  // Set up the TargetLowering object.

  // X86 is weird, it always uses i8 for shift amounts and setcc results.
  setShiftAmountType(MVT::i8);
  setSetCCResultType(MVT::i8);
  setSetCCResultContents(ZeroOrOneSetCCResult);
  setSchedulingPreference(SchedulingForRegPressure);
  setShiftAmountFlavor(Mask);   // shl X, 32 == shl X, 0
  setStackPointerRegisterToSaveRestore(X86::ESP);
  // Set up the register classes.
  addRegisterClass(MVT::i8, X86::R8RegisterClass);
  addRegisterClass(MVT::i16, X86::R16RegisterClass);
  addRegisterClass(MVT::i32, X86::R32RegisterClass);

  // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
  // operation.
  setOperationAction(ISD::UINT_TO_FP       , MVT::i1   , Promote);
  setOperationAction(ISD::UINT_TO_FP       , MVT::i8   , Promote);
  setOperationAction(ISD::UINT_TO_FP       , MVT::i16  , Promote);

  if (X86ScalarSSE)
    // No SSE i64 SINT_TO_FP, so expand i32 UINT_TO_FP instead.
    setOperationAction(ISD::UINT_TO_FP     , MVT::i32  , Expand);
  else
    setOperationAction(ISD::UINT_TO_FP     , MVT::i32  , Promote);

  // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have
  // this operation.
  setOperationAction(ISD::SINT_TO_FP       , MVT::i1   , Promote);
  setOperationAction(ISD::SINT_TO_FP       , MVT::i8   , Promote);
  // SSE has no i16 to fp conversion, only i32
  if (X86ScalarSSE)
    setOperationAction(ISD::SINT_TO_FP     , MVT::i16  , Promote);
Evan Cheng's avatar
Evan Cheng committed
  else {
    setOperationAction(ISD::SINT_TO_FP     , MVT::i16  , Custom);
    setOperationAction(ISD::SINT_TO_FP     , MVT::i32  , Custom);
  }
  // We can handle SINT_TO_FP and FP_TO_SINT from/to i64 even though i64
  // isn't legal.
  setOperationAction(ISD::SINT_TO_FP       , MVT::i64  , Custom);
  setOperationAction(ISD::FP_TO_SINT       , MVT::i64  , Custom);

  // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have
  // this operation.
  setOperationAction(ISD::FP_TO_SINT       , MVT::i1   , Promote);
  setOperationAction(ISD::FP_TO_SINT       , MVT::i8   , Promote);

  if (X86ScalarSSE) {
    setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Promote);
  } else {
    setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Custom);
    setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Custom);
  }

  // Handle FP_TO_UINT by promoting the destination to a larger signed
  // conversion.
  setOperationAction(ISD::FP_TO_UINT       , MVT::i1   , Promote);
  setOperationAction(ISD::FP_TO_UINT       , MVT::i8   , Promote);
  setOperationAction(ISD::FP_TO_UINT       , MVT::i16  , Promote);

  if (X86ScalarSSE && !Subtarget->hasSSE3())
    // Expand FP_TO_UINT into a select.
    // FIXME: We would like to use a Custom expander here eventually to do
    // the optimal thing for SSE vs. the default expansion in the legalizer.
    setOperationAction(ISD::FP_TO_UINT     , MVT::i32  , Expand);
  else
    // With SSE3 we can use fisttpll to convert to a signed i64.
    setOperationAction(ISD::FP_TO_UINT     , MVT::i32  , Promote);

  setOperationAction(ISD::BIT_CONVERT      , MVT::f32  , Expand);
  setOperationAction(ISD::BIT_CONVERT      , MVT::i32  , Expand);
Evan Cheng's avatar
Evan Cheng committed
  setOperationAction(ISD::BRCOND           , MVT::Other, Custom);
  setOperationAction(ISD::BRCONDTWOWAY     , MVT::Other, Expand);
  setOperationAction(ISD::BRTWOWAY_CC      , MVT::Other, Expand);
  setOperationAction(ISD::BR_CC            , MVT::Other, Expand);
  setOperationAction(ISD::SELECT_CC        , MVT::Other, Expand);
  setOperationAction(ISD::MEMMOVE          , MVT::Other, Expand);
  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Expand);
  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8   , Expand);
  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
  setOperationAction(ISD::FP_ROUND_INREG   , MVT::f32  , Expand);
  setOperationAction(ISD::SEXTLOAD         , MVT::i1   , Expand);
  setOperationAction(ISD::FREM             , MVT::f64  , Expand);
  setOperationAction(ISD::CTPOP            , MVT::i8   , Expand);
  setOperationAction(ISD::CTTZ             , MVT::i8   , Expand);
  setOperationAction(ISD::CTLZ             , MVT::i8   , Expand);
  setOperationAction(ISD::CTPOP            , MVT::i16  , Expand);
  setOperationAction(ISD::CTTZ             , MVT::i16  , Expand);
  setOperationAction(ISD::CTLZ             , MVT::i16  , Expand);
  setOperationAction(ISD::CTPOP            , MVT::i32  , Expand);
  setOperationAction(ISD::CTTZ             , MVT::i32  , Expand);
  setOperationAction(ISD::CTLZ             , MVT::i32  , Expand);
  setOperationAction(ISD::READCYCLECOUNTER , MVT::i64  , Custom);
Nate Begeman's avatar
Nate Begeman committed
  setOperationAction(ISD::BSWAP            , MVT::i16  , Expand);
  setOperationAction(ISD::READIO           , MVT::i1   , Expand);
  setOperationAction(ISD::READIO           , MVT::i8   , Expand);
  setOperationAction(ISD::READIO           , MVT::i16  , Expand);
  setOperationAction(ISD::READIO           , MVT::i32  , Expand);
  setOperationAction(ISD::WRITEIO          , MVT::i1   , Expand);
  setOperationAction(ISD::WRITEIO          , MVT::i8   , Expand);
  setOperationAction(ISD::WRITEIO          , MVT::i16  , Expand);
  setOperationAction(ISD::WRITEIO          , MVT::i32  , Expand);

  // These should be promoted to a larger select which is supported.
  setOperationAction(ISD::SELECT           , MVT::i1   , Promote);
  setOperationAction(ISD::SELECT           , MVT::i8   , Promote);

  // X86 wants to expand cmov itself.
Evan Cheng's avatar
Evan Cheng committed
  setOperationAction(ISD::SELECT          , MVT::i16  , Custom);
  setOperationAction(ISD::SELECT          , MVT::i32  , Custom);
  setOperationAction(ISD::SELECT          , MVT::f32  , Custom);
  setOperationAction(ISD::SELECT          , MVT::f64  , Custom);
  setOperationAction(ISD::SETCC           , MVT::i8   , Custom);
  setOperationAction(ISD::SETCC           , MVT::i16  , Custom);
  setOperationAction(ISD::SETCC           , MVT::i32  , Custom);
  setOperationAction(ISD::SETCC           , MVT::f32  , Custom);
  setOperationAction(ISD::SETCC           , MVT::f64  , Custom);
  // X86 ret instruction may pop stack.
Evan Cheng's avatar
Evan Cheng committed
  setOperationAction(ISD::RET             , MVT::Other, Custom);
  // Darwin ABI issue.
Evan Cheng's avatar
Evan Cheng committed
  setOperationAction(ISD::ConstantPool    , MVT::i32  , Custom);
Evan Cheng's avatar
Evan Cheng committed
  setOperationAction(ISD::GlobalAddress   , MVT::i32  , Custom);
  // 64-bit addm sub, shl, sra, srl (iff 32-bit x86)
Evan Cheng's avatar
Evan Cheng committed
  setOperationAction(ISD::SHL_PARTS       , MVT::i32  , Custom);
  setOperationAction(ISD::SRA_PARTS       , MVT::i32  , Custom);
  setOperationAction(ISD::SRL_PARTS       , MVT::i32  , Custom);
  // X86 wants to expand memset / memcpy itself.
Evan Cheng's avatar
Evan Cheng committed
  setOperationAction(ISD::MEMSET          , MVT::Other, Custom);
  setOperationAction(ISD::MEMCPY          , MVT::Other, Custom);
  // We don't have line number support yet.
  setOperationAction(ISD::LOCATION, MVT::Other, Expand);
Jim Laskey's avatar
Jim Laskey committed
  setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
  setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
Nate Begeman's avatar
Nate Begeman committed
  // VASTART needs to be custom lowered to use the VarArgsFrameIndex
  setOperationAction(ISD::VASTART           , MVT::Other, Custom);
  
  // Use the default implementation.
  setOperationAction(ISD::VAARG             , MVT::Other, Expand);
  setOperationAction(ISD::VACOPY            , MVT::Other, Expand);
  setOperationAction(ISD::VAEND             , MVT::Other, Expand);
  setOperationAction(ISD::STACKSAVE,          MVT::Other, Expand); 
  setOperationAction(ISD::STACKRESTORE,       MVT::Other, Expand);
  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Expand);
  if (X86ScalarSSE) {
    // Set up the FP register classes.
    addRegisterClass(MVT::f32, X86::FR32RegisterClass);
    addRegisterClass(MVT::f64, X86::FR64RegisterClass);

    // SSE has no load+extend ops
    setOperationAction(ISD::EXTLOAD,  MVT::f32, Expand);
    setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand);

Loading
Loading full blame...