MSP430ISelLowering.cpp revision c8fbb6ae2041f17285e4ba73d54d388e703b9689
1//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation ------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the MSP430TargetLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "msp430-lower" 15 16#include "MSP430ISelLowering.h" 17#include "MSP430.h" 18#include "MSP430TargetMachine.h" 19#include "MSP430Subtarget.h" 20#include "llvm/DerivedTypes.h" 21#include "llvm/Function.h" 22#include "llvm/Intrinsics.h" 23#include "llvm/CallingConv.h" 24#include "llvm/GlobalVariable.h" 25#include "llvm/GlobalAlias.h" 26#include "llvm/CodeGen/CallingConvLower.h" 27#include "llvm/CodeGen/MachineFrameInfo.h" 28#include "llvm/CodeGen/MachineFunction.h" 29#include "llvm/CodeGen/MachineInstrBuilder.h" 30#include "llvm/CodeGen/MachineRegisterInfo.h" 31#include "llvm/CodeGen/PseudoSourceValue.h" 32#include "llvm/CodeGen/SelectionDAGISel.h" 33#include "llvm/CodeGen/ValueTypes.h" 34#include "llvm/Support/Debug.h" 35#include "llvm/ADT/VectorExtras.h" 36using namespace llvm; 37 38MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : 39 TargetLowering(tm), Subtarget(*tm.getSubtargetImpl()), TM(tm) { 40 41 // Set up the register classes. 42 addRegisterClass(MVT::i16, MSP430::MSP430RegsRegisterClass); 43 44 // Compute derived properties from the register classes 45 computeRegisterProperties(); 46} 47 48SDValue MSP430TargetLowering:: 49LowerOperation(SDValue Op, SelectionDAG &DAG) { 50 switch (Op.getOpcode()) { 51 case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); 52 default: 53 assert(0 && "unimplemented operand"); 54 return SDValue(); 55 } 56} 57 58//===----------------------------------------------------------------------===// 59// Calling Convention Implementation 60//===----------------------------------------------------------------------===// 61 62#include "MSP430GenCallingConv.inc" 63 64SDValue MSP430TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, 65 SelectionDAG &DAG) { 66 unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 67 switch (CC) { 68 default: 69 assert(0 && "Unsupported calling convention"); 70 case CallingConv::C: 71 case CallingConv::Fast: 72 return LowerCCCArguments(Op, DAG); 73 } 74} 75 76/// LowerCCCArguments - transform physical registers into virtual registers and 77/// generate load operations for arguments places on the stack. 78// FIXME: struct return stuff 79// FIXME: varargs 80SDValue MSP430TargetLowering:: LowerCCCArguments(SDValue Op, 81 SelectionDAG &DAG) { 82 MachineFunction &MF = DAG.getMachineFunction(); 83 MachineFrameInfo *MFI = MF.getFrameInfo(); 84 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 85 SDValue Root = Op.getOperand(0); 86 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; 87 unsigned CC = MF.getFunction()->getCallingConv(); 88 DebugLoc dl = Op.getDebugLoc(); 89 90 // Assign locations to all of the incoming arguments. 91 SmallVector<CCValAssign, 16> ArgLocs; 92 CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); 93 CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_MSP430); 94 95 assert(!isVarArg && "Varargs not supported yet"); 96 97 SmallVector<SDValue, 16> ArgValues; 98 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 99 CCValAssign &VA = ArgLocs[i]; 100 if (VA.isRegLoc()) { 101 // Arguments passed in registers 102 MVT RegVT = VA.getLocVT(); 103 switch (RegVT.getSimpleVT()) { 104 default: 105 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 106 << RegVT.getSimpleVT() 107 << "\n"; 108 abort(); 109 case MVT::i16: 110 unsigned VReg = 111 RegInfo.createVirtualRegister(MSP430::MSP430RegsRegisterClass); 112 RegInfo.addLiveIn(VA.getLocReg(), VReg); 113 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT); 114 115 // If this is an 8-bit value, it is really passed promoted to 16 116 // bits. Insert an assert[sz]ext to capture this, then truncate to the 117 // right size. 118 if (VA.getLocInfo() == CCValAssign::SExt) 119 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 120 DAG.getValueType(VA.getValVT())); 121 else if (VA.getLocInfo() == CCValAssign::ZExt) 122 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 123 DAG.getValueType(VA.getValVT())); 124 125 if (VA.getLocInfo() != CCValAssign::Full) 126 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 127 128 ArgValues.push_back(ArgValue); 129 } 130 } else { 131 // Sanity check 132 assert(VA.isMemLoc()); 133 // Load the argument to a virtual register 134 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 135 if (ObjSize > 2) { 136 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 137 << VA.getLocVT().getSimpleVT() 138 << "\n"; 139 } 140 // Create the frame index object for this incoming parameter... 141 int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset()); 142 143 // Create the SelectionDAG nodes corresponding to a load 144 //from this parameter 145 SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 146 ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN, 147 PseudoSourceValue::getFixedStack(FI), 0)); 148 } 149 } 150 151 ArgValues.push_back(Root); 152 153 // Return the new list of results. 154 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), 155 &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); 156} 157