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