diff options
| author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-05-03 12:59:33 +0000 | 
|---|---|---|
| committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-05-03 12:59:33 +0000 | 
| commit | 3849be6ca1e66c79248ff901d5a1429a2fa9b1d1 (patch) | |
| tree | 17f33dc45ff18fc09d461c5186528a02e1795582 /llvm/lib/Target/MSP430 | |
| parent | 77e5a11ec26cafa57f7a9b1715fbd31d545383f4 (diff) | |
| download | bcm5719-llvm-3849be6ca1e66c79248ff901d5a1429a2fa9b1d1.tar.gz bcm5719-llvm-3849be6ca1e66c79248ff901d5a1429a2fa9b1d1.zip  | |
Add first draft of MSP430 calling convention stuff and draft of ISD::FORMAL_ARGUMENTS node lowering.
llvm-svn: 70702
Diffstat (limited to 'llvm/lib/Target/MSP430')
| -rw-r--r-- | llvm/lib/Target/MSP430/MSP430.td | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/MSP430/MSP430CallingConv.td | 34 | ||||
| -rw-r--r-- | llvm/lib/Target/MSP430/MSP430ISelLowering.cpp | 100 | ||||
| -rw-r--r-- | llvm/lib/Target/MSP430/MSP430ISelLowering.h | 2 | 
4 files changed, 142 insertions, 0 deletions
diff --git a/llvm/lib/Target/MSP430/MSP430.td b/llvm/lib/Target/MSP430/MSP430.td index 99dc62dbc7e..89313ab59c1 100644 --- a/llvm/lib/Target/MSP430/MSP430.td +++ b/llvm/lib/Target/MSP430/MSP430.td @@ -37,6 +37,12 @@ def : Proc<"generic",         []>;  include "MSP430RegisterInfo.td"  //===----------------------------------------------------------------------===// +// Calling Convention Description +//===----------------------------------------------------------------------===// + +include "MSP430CallingConv.td" + +//===----------------------------------------------------------------------===//  // Instruction Descriptions  //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/MSP430/MSP430CallingConv.td b/llvm/lib/Target/MSP430/MSP430CallingConv.td new file mode 100644 index 00000000000..e60a3de13f3 --- /dev/null +++ b/llvm/lib/Target/MSP430/MSP430CallingConv.td @@ -0,0 +1,34 @@ +//==- MSP430CallingConv.td - Calling Conventions for MSP430 -*- tablegen -*-==// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This describes the calling conventions for MSP430 architecture. +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// MSP430 Return Value Calling Convention +//===----------------------------------------------------------------------===// +def RetCC_MSP430 : CallingConv<[ +  // i16 are returned in registers R15, R14, R13, R12 +  CCIfType<[i16], CCAssignToReg<[R15, R14, R13, R12]>> +]>; + +//===----------------------------------------------------------------------===// +// MSP430 Argument Calling Conventions +//===----------------------------------------------------------------------===// +def CC_MSP430 : CallingConv<[ +  // Promote i8 arguments to i16. +  CCIfType<[i8], CCPromoteToType<i16>>, + +  // The first 4 integer arguments of non-varargs functions are passed in +  // integer registers. +  CCIfNotVarArg<CCIfType<[i16], CCAssignToReg<[R15, R14, R13, R12]>>>, + +  // Integer values get stored in stack slots that are 2 bytes in +  // size and 2-byte aligned. +  CCIfType<[i16], CCAssignToStack<2, 2>> +]>; diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp index 99a5673785d..99996bbb848 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -28,6 +28,7 @@  #include "llvm/CodeGen/MachineFunction.h"  #include "llvm/CodeGen/MachineInstrBuilder.h"  #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h"  #include "llvm/CodeGen/SelectionDAGISel.h"  #include "llvm/CodeGen/ValueTypes.h"  #include "llvm/Support/Debug.h" @@ -47,10 +48,109 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :  SDValue MSP430TargetLowering::  LowerOperation(SDValue Op, SelectionDAG &DAG) {    switch (Op.getOpcode()) { +  case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);    default:      assert(0 && "unimplemented operand");      return SDValue();    }  } +//===----------------------------------------------------------------------===// +//                      Calling Convention Implementation +//===----------------------------------------------------------------------===// +  #include "MSP430GenCallingConv.inc" + +SDValue MSP430TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, +                                                    SelectionDAG &DAG) { +  unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); +  switch (CC) { +  default: +    assert(0 && "Unsupported calling convention"); +  case CallingConv::C: +  case CallingConv::Fast: +    return LowerCCCArguments(Op, DAG); +  } +} + +/// LowerCCCArguments - transform physical registers into virtual registers and +/// generate load operations for arguments places on the stack. +// FIXME: struct return stuff +// FIXME: varargs +SDValue MSP430TargetLowering:: LowerCCCArguments(SDValue Op, +                                                 SelectionDAG &DAG) { +  MachineFunction &MF = DAG.getMachineFunction(); +  MachineFrameInfo *MFI = MF.getFrameInfo(); +  MachineRegisterInfo &RegInfo = MF.getRegInfo(); +  SDValue Root = Op.getOperand(0); +  bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; +  unsigned CC = MF.getFunction()->getCallingConv(); +  DebugLoc dl = Op.getDebugLoc(); + +  // Assign locations to all of the incoming arguments. +  SmallVector<CCValAssign, 16> ArgLocs; +  CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); +  CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_MSP430); + +  assert(!isVarArg && "Varargs not supported yet"); + +  SmallVector<SDValue, 16> ArgValues; +  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { +    CCValAssign &VA = ArgLocs[i]; +    if (VA.isRegLoc()) { +      // Arguments passed in registers +      MVT RegVT = VA.getLocVT(); +      switch (RegVT.getSimpleVT()) { +      default: +        cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " +             << RegVT.getSimpleVT() +             << "\n"; +        abort(); +      case MVT::i16: +        unsigned VReg = +          RegInfo.createVirtualRegister(MSP430::MSP430RegsRegisterClass); +        RegInfo.addLiveIn(VA.getLocReg(), VReg); +        SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT); + +        // If this is an 8-bit value, it is really passed promoted to 16 +        // bits. Insert an assert[sz]ext to capture this, then truncate to the +        // right size. +        if (VA.getLocInfo() == CCValAssign::SExt) +          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, +                                 DAG.getValueType(VA.getValVT())); +        else if (VA.getLocInfo() == CCValAssign::ZExt) +          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, +                                 DAG.getValueType(VA.getValVT())); + +        if (VA.getLocInfo() != CCValAssign::Full) +          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); + +        ArgValues.push_back(ArgValue); +      } +    } else { +      // Sanity check +      assert(VA.isMemLoc()); +      // Load the argument to a virtual register +      unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; +      if (ObjSize > 2) { +        cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " +             << VA.getLocVT().getSimpleVT() +             << "\n"; +      } +      // Create the frame index object for this incoming parameter... +      int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset()); + +      // Create the SelectionDAG nodes corresponding to a load +      //from this parameter +      SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); +      ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN, +                                      PseudoSourceValue::getFixedStack(FI), 0)); +    } +  } + +  ArgValues.push_back(Root); + +  // Return the new list of results. +  return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), +                     &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); +} diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.h b/llvm/lib/Target/MSP430/MSP430ISelLowering.h index 8acfd26dced..0d17ddc5741 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.h +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.h @@ -30,6 +30,8 @@ namespace llvm {      /// LowerOperation - Provide custom lowering hooks for some operations.      virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); +    SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); +    SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG);    private:      const MSP430Subtarget &Subtarget;  | 

