• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- Nios2ISelLowering.cpp - Nios2 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 interfaces that Nios2 uses to lower LLVM code into a
11 // selection DAG.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "Nios2ISelLowering.h"
16 #include "Nios2MachineFunction.h"
17 #include "Nios2TargetMachine.h"
18 #include "llvm/CodeGen/CallingConvLower.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 
21 using namespace llvm;
22 
23 //===----------------------------------------------------------------------===//
24 // Calling Convention Implementation
25 //===----------------------------------------------------------------------===//
26 
27 #include "Nios2GenCallingConv.inc"
28 
29 SDValue
LowerReturn(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,const SmallVectorImpl<SDValue> & OutVals,const SDLoc & DL,SelectionDAG & DAG) const30 Nios2TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
31                                  bool IsVarArg,
32                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
33                                  const SmallVectorImpl<SDValue> &OutVals,
34                                  const SDLoc &DL, SelectionDAG &DAG) const {
35   // CCValAssign - represent the assignment of
36   // the return value to a location
37   SmallVector<CCValAssign, 16> RVLocs;
38   MachineFunction &MF = DAG.getMachineFunction();
39 
40   // CCState - Info about the registers and stack slot.
41   CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
42   // Analyze return values.
43   CCInfo.CheckReturn(Outs, RetCC_Nios2EABI);
44 
45   SDValue Flag;
46   SmallVector<SDValue, 4> RetOps(1, Chain);
47 
48   // Copy the result values into the output registers.
49   for (unsigned i = 0; i != RVLocs.size(); ++i) {
50     SDValue Val = OutVals[i];
51     CCValAssign &VA = RVLocs[i];
52     assert(VA.isRegLoc() && "Can only return in registers!");
53 
54     if (RVLocs[i].getValVT() != RVLocs[i].getLocVT())
55       Val = DAG.getNode(ISD::BITCAST, DL, RVLocs[i].getLocVT(), Val);
56 
57     Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Flag);
58 
59     // Guarantee that all emitted copies are stuck together with flags.
60     Flag = Chain.getValue(1);
61     RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
62   }
63 
64   if (Flag.getNode())
65     RetOps.push_back(Flag);
66 
67   return DAG.getNode(Nios2ISD::Ret, DL, MVT::Other, RetOps);
68 }
69 
70 // addLiveIn - This helper function adds the specified physical register to the
71 // MachineFunction as a live in value.  It also creates a corresponding
72 // virtual register for it.
addLiveIn(MachineFunction & MF,unsigned PReg,const TargetRegisterClass * RC)73 static unsigned addLiveIn(MachineFunction &MF, unsigned PReg,
74                           const TargetRegisterClass *RC) {
75   unsigned VReg = MF.getRegInfo().createVirtualRegister(RC);
76   MF.getRegInfo().addLiveIn(PReg, VReg);
77   return VReg;
78 }
79 
80 //===----------------------------------------------------------------------===//
81 //            Formal Arguments Calling Convention Implementation
82 //===----------------------------------------------------------------------===//
83 
84 // LowerFormalArguments - transform physical registers into virtual registers
85 // and generate load operations for arguments places on the stack.
LowerFormalArguments(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,const SDLoc & DL,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const86 SDValue Nios2TargetLowering::LowerFormalArguments(
87     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
88     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
89     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
90   MachineFunction &MF = DAG.getMachineFunction();
91   MachineFrameInfo &MFI = MF.getFrameInfo();
92 
93   // Assign locations to all of the incoming arguments.
94   SmallVector<CCValAssign, 16> ArgLocs;
95   CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
96                  *DAG.getContext());
97 
98   CCInfo.AnalyzeFormalArguments(Ins, CC_Nios2);
99 
100   // Used with vargs to acumulate store chains.
101   std::vector<SDValue> OutChains;
102 
103   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
104     CCValAssign &VA = ArgLocs[i];
105 
106     EVT ValVT = VA.getValVT();
107 
108     // Arguments stored on registers
109     if (VA.isRegLoc()) {
110       MVT RegVT = VA.getLocVT();
111       unsigned ArgReg = VA.getLocReg();
112       const TargetRegisterClass *RC = getRegClassFor(RegVT);
113 
114       // Transform the arguments stored on
115       // physical registers into virtual ones
116       unsigned Reg = addLiveIn(MF, ArgReg, RC);
117       SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT);
118 
119       // If this is an 8 or 16-bit value, it has been passed promoted
120       // to 32 bits.  Insert an assert[sz]ext to capture this, then
121       // truncate to the right size.
122       if (VA.getLocInfo() != CCValAssign::Full) {
123         unsigned Opcode = 0;
124         if (VA.getLocInfo() == CCValAssign::SExt)
125           Opcode = ISD::AssertSext;
126         else if (VA.getLocInfo() == CCValAssign::ZExt)
127           Opcode = ISD::AssertZext;
128         if (Opcode)
129           ArgValue =
130               DAG.getNode(Opcode, DL, RegVT, ArgValue, DAG.getValueType(ValVT));
131         ArgValue = DAG.getNode(ISD::TRUNCATE, DL, ValVT, ArgValue);
132       }
133 
134       // Handle floating point arguments passed in integer registers.
135       if ((RegVT == MVT::i32 && ValVT == MVT::f32) ||
136           (RegVT == MVT::i64 && ValVT == MVT::f64))
137         ArgValue = DAG.getNode(ISD::BITCAST, DL, ValVT, ArgValue);
138       InVals.push_back(ArgValue);
139     } else { // VA.isRegLoc()
140       MVT LocVT = VA.getLocVT();
141 
142       // sanity check
143       assert(VA.isMemLoc());
144 
145       // The stack pointer offset is relative to the caller stack frame.
146       int FI = MFI.CreateFixedObject(ValVT.getSizeInBits() / 8,
147                                      VA.getLocMemOffset(), true);
148 
149       // Create load nodes to retrieve arguments from the stack
150       SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
151       SDValue Load = DAG.getLoad(
152           LocVT, DL, Chain, FIN,
153           MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI));
154       InVals.push_back(Load);
155       OutChains.push_back(Load.getValue(1));
156     }
157   }
158   if (!OutChains.empty()) {
159     OutChains.push_back(Chain);
160     Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
161   }
162 
163   return Chain;
164 }
165 
166 //===----------------------------------------------------------------------===//
167 // TargetLowering Implementation
168 //===----------------------------------------------------------------------===//
169 
Nios2TargetLowering(const TargetMachine & TM,const Nios2Subtarget & STI)170 Nios2TargetLowering::Nios2TargetLowering(const TargetMachine &TM,
171                                          const Nios2Subtarget &STI)
172     : TargetLowering(TM), Subtarget(&STI) {
173 
174   addRegisterClass(MVT::i32, &Nios2::CPURegsRegClass);
175   computeRegisterProperties(Subtarget->getRegisterInfo());
176 }
177 
getTargetNodeName(unsigned Opcode) const178 const char *Nios2TargetLowering::getTargetNodeName(unsigned Opcode) const {
179   switch (Opcode) {
180   case Nios2ISD::Hi:
181     return "Nios2ISD::Hi";
182   case Nios2ISD::Lo:
183     return "Nios2ISD::Lo";
184   case Nios2ISD::Ret:
185     return "Nios2ISD::Ret";
186   }
187   return nullptr;
188 }
189