1 //===-- Nios2ISelLowering.cpp - Nios2 DAG Lowering Implementation ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the interfaces that Nios2 uses to lower LLVM code into a
13 //===----------------------------------------------------------------------===//
15 #include "Nios2ISelLowering.h"
16 #include "Nios2MachineFunction.h"
17 #include "Nios2TargetMachine.h"
18 #include "llvm/CodeGen/CallingConvLower.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 //===----------------------------------------------------------------------===//
24 // Calling Convention Implementation
25 //===----------------------------------------------------------------------===//
27 #include "Nios2GenCallingConv.inc"
30 Nios2TargetLowering::LowerReturn(SDValue Chain
, CallingConv::ID CallConv
,
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();
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
);
46 SmallVector
<SDValue
, 4> RetOps(1, Chain
);
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!");
54 if (RVLocs
[i
].getValVT() != RVLocs
[i
].getLocVT())
55 Val
= DAG
.getNode(ISD::BITCAST
, DL
, RVLocs
[i
].getLocVT(), Val
);
57 Chain
= DAG
.getCopyToReg(Chain
, DL
, VA
.getLocReg(), Val
, Flag
);
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()));
65 RetOps
.push_back(Flag
);
67 return DAG
.getNode(Nios2ISD::Ret
, DL
, MVT::Other
, RetOps
);
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.
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
);
80 //===----------------------------------------------------------------------===//
81 // Formal Arguments Calling Convention Implementation
82 //===----------------------------------------------------------------------===//
84 // LowerFormalArguments - transform physical registers into virtual registers
85 // and generate load operations for arguments places on the stack.
86 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();
93 // Assign locations to all of the incoming arguments.
94 SmallVector
<CCValAssign
, 16> ArgLocs
;
95 CCState
CCInfo(CallConv
, IsVarArg
, DAG
.getMachineFunction(), ArgLocs
,
98 CCInfo
.AnalyzeFormalArguments(Ins
, CC_Nios2
);
100 // Used with vargs to acumulate store chains.
101 std::vector
<SDValue
> OutChains
;
103 for (unsigned i
= 0, e
= ArgLocs
.size(); i
!= e
; ++i
) {
104 CCValAssign
&VA
= ArgLocs
[i
];
106 EVT ValVT
= VA
.getValVT();
108 // Arguments stored on registers
110 MVT RegVT
= VA
.getLocVT();
111 unsigned ArgReg
= VA
.getLocReg();
112 const TargetRegisterClass
*RC
= getRegClassFor(RegVT
);
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
);
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
) {
124 if (VA
.getLocInfo() == CCValAssign::SExt
)
125 Opcode
= ISD::AssertSext
;
126 else if (VA
.getLocInfo() == CCValAssign::ZExt
)
127 Opcode
= ISD::AssertZext
;
130 DAG
.getNode(Opcode
, DL
, RegVT
, ArgValue
, DAG
.getValueType(ValVT
));
131 ArgValue
= DAG
.getNode(ISD::TRUNCATE
, DL
, ValVT
, ArgValue
);
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();
143 assert(VA
.isMemLoc());
145 // The stack pointer offset is relative to the caller stack frame.
146 int FI
= MFI
.CreateFixedObject(ValVT
.getSizeInBits() / 8,
147 VA
.getLocMemOffset(), true);
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));
158 if (!OutChains
.empty()) {
159 OutChains
.push_back(Chain
);
160 Chain
= DAG
.getNode(ISD::TokenFactor
, DL
, MVT::Other
, OutChains
);
166 //===----------------------------------------------------------------------===//
167 // TargetLowering Implementation
168 //===----------------------------------------------------------------------===//
170 Nios2TargetLowering::Nios2TargetLowering(const TargetMachine
&TM
,
171 const Nios2Subtarget
&STI
)
172 : TargetLowering(TM
), Subtarget(&STI
) {
174 addRegisterClass(MVT::i32
, &Nios2::CPURegsRegClass
);
175 computeRegisterProperties(Subtarget
->getRegisterInfo());
178 const char *Nios2TargetLowering::getTargetNodeName(unsigned Opcode
) const {
181 return "Nios2ISD::Hi";
183 return "Nios2ISD::Lo";
185 return "Nios2ISD::Ret";