//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation ------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the MSP430TargetLowering class.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "msp430-lower"
#include "MSP430ISelLowering.h"
#include "MSP430.h"
#include "MSP430MachineFunctionInfo.h"
#include "MSP430Subtarget.h"
#include "MSP430TargetMachine.h"
#include "llvm/CallingConv.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/GlobalAlias.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Intrinsics.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
typedef enum {
NoHWMult,
HWMultIntr,
HWMultNoIntr
} HWMultUseMode;
static cl::opt<HWMultUseMode>
HWMultMode("msp430-hwmult-mode",
cl::desc("Hardware multiplier use mode"),
cl::init(HWMultNoIntr),
cl::values(
clEnumValN(NoHWMult, "no",
"Do not use hardware multiplier"),
clEnumValN(HWMultIntr, "interrupts",
"Assume hardware multiplier can be used inside interrupts"),
clEnumValN(HWMultNoIntr, "use",
"Assume hardware multiplier cannot be used inside interrupts"),
clEnumValEnd));
MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
TargetLowering(tm, new TargetLoweringObjectFileELF()),
Subtarget(*tm.getSubtargetImpl()) {
TD = getDataLayout();
// Set up the register classes.
addRegisterClass(MVT::i8, &MSP430::GR8RegClass);
addRegisterClass(MVT::i16, &MSP430::GR16RegClass);
// Compute derived properties from the register classes
computeRegisterProperties();
// Provide all sorts of operation actions
// Division is expensive
setIntDivIsCheap(false);
setStackPointerRegisterToSaveRestore(MSP430::SPW);
setBooleanContents(ZeroOrOneBooleanContent);
setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
// We have post-incremented loads / stores.
setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand);
setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
// We don't have any truncstores
setTruncStoreAction(MVT::i16, MVT::i8, Expand);
setOperationAction(ISD::SRA, MVT::i8, Custom);
setOperationAction(ISD::SHL, MVT::i8, Custom);
setOperationAction(ISD