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 | c8fbb6ae2041f17285e4ba73d54d388e703b9689 (patch) | |
tree | 3d7cb4c2733f6bd89e106881361a0f72da62ab0d | |
parent | 2dd6cdc9204eaca42923509d227ef67974784aae (diff) | |
download | llvm-c8fbb6ae2041f17285e4ba73d54d388e703b9689.tar.gz llvm-c8fbb6ae2041f17285e4ba73d54d388e703b9689.tar.bz2 llvm-c8fbb6ae2041f17285e4ba73d54d388e703b9689.tar.xz |
Add first draft of MSP430 calling convention stuff and draft of ISD::FORMAL_ARGUMENTS node lowering.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70702 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/MSP430/MSP430.td | 6 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430CallingConv.td | 34 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelLowering.cpp | 100 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelLowering.h | 2 |
4 files changed, 142 insertions, 0 deletions
diff --git a/lib/Target/MSP430/MSP430.td b/lib/Target/MSP430/MSP430.td index 99dc62dbc7..89313ab59c 100644 --- a/lib/Target/MSP430/MSP430.td +++ b/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/lib/Target/MSP430/MSP430CallingConv.td b/lib/Target/MSP430/MSP430CallingConv.td new file mode 100644 index 0000000000..e60a3de13f --- /dev/null +++ b/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/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index 99a5673785..99996bbb84 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/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/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h index 8acfd26dce..0d17ddc574 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.h +++ b/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; |