SystemZISelLowering.cpp revision c7b71bede49dc1eae107c79a74b5c618c39506ac
1//===-- SystemZISelLowering.cpp - SystemZ 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 SystemZTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "systemz-lower"
15
16#include "SystemZISelLowering.h"
17#include "SystemZ.h"
18#include "SystemZTargetMachine.h"
19#include "SystemZSubtarget.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
38SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) :
39  TargetLowering(tm), Subtarget(*tm.getSubtargetImpl()), TM(tm) {
40
41  RegInfo = TM.getRegisterInfo();
42
43  // Set up the register classes.
44  addRegisterClass(MVT::i32, SystemZ::GR32RegisterClass);
45  addRegisterClass(MVT::i64, SystemZ::GR64RegisterClass);
46
47  // Compute derived properties from the register classes
48  computeRegisterProperties();
49
50  // Set shifts properties
51  setShiftAmountFlavor(Extend);
52  setShiftAmountType(MVT::i32);
53
54  // Provide all sorts of operation actions
55
56  setStackPointerRegisterToSaveRestore(SystemZ::R15D);
57  setSchedulingPreference(SchedulingForLatency);
58
59  setOperationAction(ISD::RET,              MVT::Other, Custom);
60}
61
62SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
63  switch (Op.getOpcode()) {
64  case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
65  case ISD::RET:              return LowerRET(Op, DAG);
66  case ISD::CALL:             return LowerCALL(Op, DAG);
67  default:
68    assert(0 && "unimplemented operand");
69    return SDValue();
70  }
71}
72
73//===----------------------------------------------------------------------===//
74//                      Calling Convention Implementation
75//===----------------------------------------------------------------------===//
76
77#include "SystemZGenCallingConv.inc"
78
79SDValue SystemZTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op,
80                                                     SelectionDAG &DAG) {
81  unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
82  switch (CC) {
83  default:
84    assert(0 && "Unsupported calling convention");
85  case CallingConv::C:
86  case CallingConv::Fast:
87    return LowerCCCArguments(Op, DAG);
88  }
89}
90
91SDValue SystemZTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
92  CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
93  unsigned CallingConv = TheCall->getCallingConv();
94  switch (CallingConv) {
95  default:
96    assert(0 && "Unsupported calling convention");
97  case CallingConv::Fast:
98  case CallingConv::C:
99    return LowerCCCCallTo(Op, DAG, CallingConv);
100  }
101}
102
103/// LowerCCCArguments - transform physical registers into virtual registers and
104/// generate load operations for arguments places on the stack.
105// FIXME: struct return stuff
106// FIXME: varargs
107SDValue SystemZTargetLowering::LowerCCCArguments(SDValue Op,
108                                                 SelectionDAG &DAG) {
109  MachineFunction &MF = DAG.getMachineFunction();
110  MachineFrameInfo *MFI = MF.getFrameInfo();
111  MachineRegisterInfo &RegInfo = MF.getRegInfo();
112  SDValue Root = Op.getOperand(0);
113  bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
114  unsigned CC = MF.getFunction()->getCallingConv();
115  DebugLoc dl = Op.getDebugLoc();
116
117  // Assign locations to all of the incoming arguments.
118  SmallVector<CCValAssign, 16> ArgLocs;
119  CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
120  CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_SystemZ);
121
122  assert(!isVarArg && "Varargs not supported yet");
123
124  SmallVector<SDValue, 16> ArgValues;
125  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
126    CCValAssign &VA = ArgLocs[i];
127    if (VA.isRegLoc()) {
128      // Arguments passed in registers
129      MVT RegVT = VA.getLocVT();
130      switch (RegVT.getSimpleVT()) {
131      default:
132        cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
133             << RegVT.getSimpleVT()
134             << "\n";
135        abort();
136      case MVT::i64:
137        unsigned VReg =
138          RegInfo.createVirtualRegister(SystemZ::GR64RegisterClass);
139        RegInfo.addLiveIn(VA.getLocReg(), VReg);
140        SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT);
141
142        // If this is an 8/16/32-bit value, it is really passed promoted to 64
143        // bits. Insert an assert[sz]ext to capture this, then truncate to the
144        // right size.
145        if (VA.getLocInfo() == CCValAssign::SExt)
146          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
147                                 DAG.getValueType(VA.getValVT()));
148        else if (VA.getLocInfo() == CCValAssign::ZExt)
149          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
150                                 DAG.getValueType(VA.getValVT()));
151
152        if (VA.getLocInfo() != CCValAssign::Full)
153          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
154
155        ArgValues.push_back(ArgValue);
156      }
157    } else {
158      // Sanity check
159      assert(VA.isMemLoc());
160      // Load the argument to a virtual register
161      unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
162      if (ObjSize > 8) {
163        cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
164             << VA.getLocVT().getSimpleVT()
165             << "\n";
166      }
167      // Create the frame index object for this incoming parameter...
168      int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset());
169
170      // Create the SelectionDAG nodes corresponding to a load
171      //from this parameter
172      SDValue FIN = DAG.getFrameIndex(FI, MVT::i64);
173      ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN,
174                                      PseudoSourceValue::getFixedStack(FI), 0));
175    }
176  }
177
178  ArgValues.push_back(Root);
179
180  // Return the new list of results.
181  return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(),
182                     &ArgValues[0], ArgValues.size()).getValue(Op.getResNo());
183}
184
185/// LowerCCCCallTo - functions arguments are copied from virtual regs to
186/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
187/// TODO: sret.
188SDValue SystemZTargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG,
189                                              unsigned CC) {
190  CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
191  SDValue Chain  = TheCall->getChain();
192  SDValue Callee = TheCall->getCallee();
193  bool isVarArg  = TheCall->isVarArg();
194  DebugLoc dl = Op.getDebugLoc();
195  MachineFunction &MF = DAG.getMachineFunction();
196
197  // Offset to first argument stack slot.
198  const unsigned FirstArgOffset = 160;
199
200  // Analyze operands of the call, assigning locations to each operand.
201  SmallVector<CCValAssign, 16> ArgLocs;
202  CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
203
204  CCInfo.AnalyzeCallOperands(TheCall, CC_SystemZ);
205
206  // Get a count of how many bytes are to be pushed on the stack.
207  unsigned NumBytes = CCInfo.getNextStackOffset();
208
209  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
210                                                      getPointerTy(), true));
211
212  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
213  SmallVector<SDValue, 12> MemOpChains;
214  SDValue StackPtr;
215
216  // Walk the register/memloc assignments, inserting copies/loads.
217  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
218    CCValAssign &VA = ArgLocs[i];
219
220    // Arguments start after the 5 first operands of ISD::CALL
221    SDValue Arg = TheCall->getArg(i);
222
223    // Promote the value if needed.
224    switch (VA.getLocInfo()) {
225      default: assert(0 && "Unknown loc info!");
226      case CCValAssign::Full: break;
227      case CCValAssign::SExt:
228        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
229        break;
230      case CCValAssign::ZExt:
231        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
232        break;
233      case CCValAssign::AExt:
234        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
235        break;
236    }
237
238    // Arguments that can be passed on register must be kept at RegsToPass
239    // vector
240    if (VA.isRegLoc()) {
241      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
242    } else {
243      assert(VA.isMemLoc());
244
245      if (StackPtr.getNode() == 0)
246        StackPtr =
247          DAG.getCopyFromReg(Chain, dl,
248                             (RegInfo->hasFP(MF) ?
249                              SystemZ::R11D : SystemZ::R15D),
250                             getPointerTy());
251
252      unsigned Offset = FirstArgOffset + VA.getLocMemOffset();
253      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
254                                   StackPtr,
255                                   DAG.getIntPtrConstant(Offset));
256
257      MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
258                                         PseudoSourceValue::getStack(), Offset));
259    }
260  }
261
262  // Transform all store nodes into one single node because all store nodes are
263  // independent of each other.
264  if (!MemOpChains.empty())
265    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
266                        &MemOpChains[0], MemOpChains.size());
267
268  // Build a sequence of copy-to-reg nodes chained together with token chain and
269  // flag operands which copy the outgoing args into registers.  The InFlag in
270  // necessary since all emited instructions must be stuck together.
271  SDValue InFlag;
272  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
273    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
274                             RegsToPass[i].second, InFlag);
275    InFlag = Chain.getValue(1);
276  }
277
278  // If the callee is a GlobalAddress node (quite common, every direct call is)
279  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
280  // Likewise ExternalSymbol -> TargetExternalSymbol.
281  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
282    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
283  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
284    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy());
285
286  // Returns a chain & a flag for retval copy to use.
287  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
288  SmallVector<SDValue, 8> Ops;
289  Ops.push_back(Chain);
290  Ops.push_back(Callee);
291
292  // Add argument registers to the end of the list so that they are
293  // known live into the call.
294  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
295    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
296                                  RegsToPass[i].second.getValueType()));
297
298  if (InFlag.getNode())
299    Ops.push_back(InFlag);
300
301  Chain = DAG.getNode(SystemZISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
302  InFlag = Chain.getValue(1);
303
304  // Create the CALLSEQ_END node.
305  Chain = DAG.getCALLSEQ_END(Chain,
306                             DAG.getConstant(NumBytes, getPointerTy(), true),
307                             DAG.getConstant(0, getPointerTy(), true),
308                             InFlag);
309  InFlag = Chain.getValue(1);
310
311  // Handle result values, copying them out of physregs into vregs that we
312  // return.
313  return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG),
314                 Op.getResNo());
315}
316
317/// LowerCallResult - Lower the result values of an ISD::CALL into the
318/// appropriate copies out of appropriate physical registers.  This assumes that
319/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call
320/// being lowered. Returns a SDNode with the same number of values as the
321/// ISD::CALL.
322SDNode*
323SystemZTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
324                                       CallSDNode *TheCall,
325                                       unsigned CallingConv,
326                                       SelectionDAG &DAG) {
327  bool isVarArg = TheCall->isVarArg();
328  DebugLoc dl = TheCall->getDebugLoc();
329
330  // Assign locations to each value returned by this call.
331  SmallVector<CCValAssign, 16> RVLocs;
332  CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs);
333
334  CCInfo.AnalyzeCallResult(TheCall, RetCC_SystemZ);
335  SmallVector<SDValue, 8> ResultVals;
336
337  // Copy all of the result registers out of their specified physreg.
338  for (unsigned i = 0; i != RVLocs.size(); ++i) {
339    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
340                               RVLocs[i].getValVT(), InFlag).getValue(1);
341    InFlag = Chain.getValue(2);
342    ResultVals.push_back(Chain.getValue(0));
343  }
344
345  ResultVals.push_back(Chain);
346
347  // Merge everything together with a MERGE_VALUES node.
348  return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(),
349                     &ResultVals[0], ResultVals.size()).getNode();
350}
351
352
353SDValue SystemZTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
354  // CCValAssign - represent the assignment of the return value to a location
355  SmallVector<CCValAssign, 16> RVLocs;
356  unsigned CC   = DAG.getMachineFunction().getFunction()->getCallingConv();
357  bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
358  DebugLoc dl = Op.getDebugLoc();
359
360  // CCState - Info about the registers and stack slot.
361  CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs);
362
363  // Analize return values of ISD::RET
364  CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SystemZ);
365
366  // If this is the first return lowered for this function, add the regs to the
367  // liveout set for the function.
368  if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
369    for (unsigned i = 0; i != RVLocs.size(); ++i)
370      if (RVLocs[i].isRegLoc())
371        DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
372  }
373
374  // The chain is always operand #0
375  SDValue Chain = Op.getOperand(0);
376  SDValue Flag;
377
378  // Copy the result values into the output registers.
379  for (unsigned i = 0; i != RVLocs.size(); ++i) {
380    CCValAssign &VA = RVLocs[i];
381    SDValue ResValue = Op.getOperand(i*2+1);
382    assert(VA.isRegLoc() && "Can only return in registers!");
383
384    // If this is an 8/16/32-bit value, it is really should be passed promoted
385    // to 64 bits.
386    if (VA.getLocInfo() == CCValAssign::SExt)
387      ResValue = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), ResValue);
388    else if (VA.getLocInfo() == CCValAssign::ZExt)
389      ResValue = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), ResValue);
390    else if (VA.getLocInfo() == CCValAssign::AExt)
391      ResValue = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), ResValue);
392
393    // ISD::RET => ret chain, (regnum1,val1), ...
394    // So i*2+1 index only the regnums
395    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), ResValue, Flag);
396
397    // Guarantee that all emitted copies are stuck together,
398    // avoiding something bad.
399    Flag = Chain.getValue(1);
400  }
401
402  if (Flag.getNode())
403    return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
404
405  // Return Void
406  return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain);
407}
408
409const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
410  switch (Opcode) {
411  case SystemZISD::RET_FLAG:           return "SystemZISD::RET_FLAG";
412  case SystemZISD::CALL:               return "SystemZISD::CALL";
413  default: return NULL;
414  }
415}
416
417