1 //===-- ZPUISelLowering.cpp - ZPU 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 defines the interfaces that ZPU uses to lower LLVM code into a
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "ZPU-lower"
16 #include "ZPUISelLowering.h"
17 #include "ZPUTargetMachine.h"
18 #include "llvm/DerivedTypes.h"
19 #include "llvm/Function.h"
20 #include "llvm/GlobalVariable.h"
21 #include "llvm/Intrinsics.h"
22 #include "llvm/CallingConv.h"
23 #include "llvm/CodeGen/CallingConvLower.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineFunction.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/CodeGen/SelectionDAGISel.h"
29 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
30 #include "llvm/CodeGen/ValueTypes.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/ErrorHandling.h"
35 const char *ZPUTargetLowering::getTargetNodeName(unsigned Opcode
) const {
37 case ZPUISD::JmpLink
: return "ZPUISD::JmpLink";
38 case ZPUISD::Hi
: return "ZPUISD::Hi";
39 case ZPUISD::Lo
: return "ZPUISD::Lo";
40 case ZPUISD::GPRel
: return "ZPUISD::GPRel";
41 case ZPUISD::Ret
: return "ZPUISD::Ret";
42 case ZPUISD::CMov
: return "ZPUISD::CMov";
43 case ZPUISD::SelectCC
: return "ZPUISD::SelectCC";
44 case ZPUISD::FPSelectCC
: return "ZPUISD::FPSelectCC";
45 case ZPUISD::FPBrcond
: return "ZPUISD::FPBrcond";
46 case ZPUISD::FPCmp
: return "ZPUISD::FPCmp";
47 case ZPUISD::FPRound
: return "ZPUISD::FPRound";
48 default : return NULL
;
53 ZPUTargetLowering(ZPUTargetMachine
&TM
)
54 : TargetLowering(TM
, new TargetLoweringObjectFileELF()) {
56 // ZPU does not have i1 type, so use i32 for
57 // setcc operations results (slt, sgt, ...).
58 setBooleanContents(ZeroOrOneBooleanContent
);
60 // Set up the register classes
61 addRegisterClass(MVT::i32
, ZPU::CPURegsRegisterClass
);
63 setOperationAction(ISD::GlobalAddress
, MVT::i32
, Custom
);
65 // Load extented operations for i1 types must be promoted
66 setLoadExtAction(ISD::EXTLOAD
, MVT::i1
, Promote
);
67 setLoadExtAction(ISD::ZEXTLOAD
, MVT::i1
, Promote
);
68 setLoadExtAction(ISD::SEXTLOAD
, MVT::i1
, Promote
);
70 // ZPU doesn't have extending float->double load/store
71 setLoadExtAction(ISD::EXTLOAD
, MVT::f32
, Expand
);
72 setTruncStoreAction(MVT::f64
, MVT::f32
, Expand
);
74 // Used by legalize types to correctly generate the setcc result.
75 // Without this, every float setcc comes with a AND/OR with the result,
76 // we don't want this, since the fpcmp result goes to a flag register,
77 // which is used implicitly by brcond and select operations.
78 AddPromotedToType(ISD::SETCC
, MVT::i1
, MVT::i32
);
80 // Operations not directly supported by ZPU.
81 setOperationAction(ISD::BR_JT
, MVT::Other
, Expand
);
82 setOperationAction(ISD::BR_CC
, MVT::Other
, Expand
);
83 setOperationAction(ISD::SELECT_CC
, MVT::Other
, Expand
);
84 setOperationAction(ISD::UINT_TO_FP
, MVT::i32
, Expand
);
85 setOperationAction(ISD::FP_TO_UINT
, MVT::i32
, Expand
);
86 setOperationAction(ISD::SIGN_EXTEND_INREG
, MVT::i1
, Expand
);
87 setOperationAction(ISD::CTPOP
, MVT::i32
, Expand
);
88 setOperationAction(ISD::CTTZ
, MVT::i32
, Expand
);
89 setOperationAction(ISD::ROTL
, MVT::i32
, Expand
);
90 setOperationAction(ISD::ROTR
, MVT::i32
, Expand
);
91 setOperationAction(ISD::SHL_PARTS
, MVT::i32
, Expand
);
92 setOperationAction(ISD::SRA_PARTS
, MVT::i32
, Expand
);
93 setOperationAction(ISD::SRL_PARTS
, MVT::i32
, Expand
);
94 setOperationAction(ISD::FCOPYSIGN
, MVT::f32
, Expand
);
95 setOperationAction(ISD::FCOPYSIGN
, MVT::f64
, Expand
);
96 setOperationAction(ISD::FSIN
, MVT::f32
, Expand
);
97 setOperationAction(ISD::FCOS
, MVT::f32
, Expand
);
98 setOperationAction(ISD::FPOWI
, MVT::f32
, Expand
);
99 setOperationAction(ISD::FPOW
, MVT::f32
, Expand
);
100 setOperationAction(ISD::FLOG
, MVT::f32
, Expand
);
101 setOperationAction(ISD::FLOG2
, MVT::f32
, Expand
);
102 setOperationAction(ISD::FLOG10
, MVT::f32
, Expand
);
103 setOperationAction(ISD::FEXP
, MVT::f32
, Expand
);
105 setOperationAction(ISD::EH_LABEL
, MVT::Other
, Expand
);
107 // Use the default for now
108 setOperationAction(ISD::STACKSAVE
, MVT::Other
, Expand
);
109 setOperationAction(ISD::STACKRESTORE
, MVT::Other
, Expand
);
110 setOperationAction(ISD::MEMBARRIER
, MVT::Other
, Expand
);
112 setStackPointerRegisterToSaveRestore(ZPU::SP
);
113 computeRegisterProperties();
116 MVT::SimpleValueType
ZPUTargetLowering::getSetCCResultType(EVT VT
) const {
120 /// getFunctionAlignment - Return the Log2 alignment of this function.
121 unsigned ZPUTargetLowering::getFunctionAlignment(const Function
*) const {
125 SDValue
ZPUTargetLowering::
126 LowerOperation(SDValue Op
, SelectionDAG
&DAG
) const
128 switch (Op
.getOpcode()) {
129 default: llvm_unreachable("Wasn't expecting to be able to lower this!");
130 case ISD::GlobalAddress
: return LowerGlobalAddress(Op
, DAG
);
136 SDValue
ZPUTargetLowering::LowerGlobalAddress(SDValue Op
,
137 SelectionDAG
&DAG
) const {
138 DebugLoc DL
= Op
.getDebugLoc();
139 const GlobalValue
*GV
= cast
<GlobalAddressSDNode
>(Op
)->getGlobal();
141 return Op
= DAG
.getTargetGlobalAddress(GV
, DL
, MVT::i32
);
144 //===----------------------------------------------------------------------===//
145 // Lower helper functions
146 //===----------------------------------------------------------------------===//
148 // AddLiveIn - This helper function adds the specified physical register to the
149 // MachineFunction as a live in value. It also creates a corresponding
150 // virtual register for it.
152 AddLiveIn(MachineFunction
&MF
, unsigned PReg
, TargetRegisterClass
*RC
)
154 assert(RC
->contains(PReg
) && "Not the correct regclass!");
155 unsigned VReg
= MF
.getRegInfo().createVirtualRegister(RC
);
156 MF
.getRegInfo().addLiveIn(PReg
, VReg
);
161 ZPUTargetLowering::EmitInstrWithCustomInserter(MachineInstr
*MI
,
162 MachineBasicBlock
*BB
) const {
166 //===----------------------------------------------------------------------===//
167 // Calling Convention Implementation
168 //===----------------------------------------------------------------------===//
170 #include "ZPUGenCallingConv.inc"
172 //===----------------------------------------------------------------------===//
173 // TODO: Implement a generic logic using tblgen that can support this.
174 // ZPU O32 ABI rules:
176 // i32 - Passed in A0, A1, A2, A3 and stack
177 // f32 - Only passed in f32 registers if no int reg has been used yet to hold
178 // an argument. Otherwise, passed in A1, A2, A3 and stack.
179 // f64 - Only passed in two aliased f32 registers if no int reg has been used
180 // yet to hold an argument. Otherwise, use A2, A3 and stack. If A1 is
181 // not used, it must be shadowed. If only A3 is avaiable, shadow it and
183 //===----------------------------------------------------------------------===//
185 static bool CC_ZPUO32(unsigned ValNo
, EVT ValVT
,
186 MVT LocVT
, CCValAssign::LocInfo LocInfo
,
187 ISD::ArgFlagsTy ArgFlags
, CCState
&State
) {
189 return false; // CC must always match
192 static bool CC_ZPUO32_VarArgs(unsigned ValNo
, EVT ValVT
,
193 MVT LocVT
, CCValAssign::LocInfo LocInfo
,
194 ISD::ArgFlagsTy ArgFlags
, CCState
&State
) {
199 //===----------------------------------------------------------------------===//
200 // Call Calling Convention Implementation
201 //===----------------------------------------------------------------------===//
203 /// LowerCall - functions arguments are copied from virtual regs to
204 /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
205 /// TODO: isTailCall.
207 ZPUTargetLowering::LowerCall(SDValue Chain
, SDValue Callee
,
208 CallingConv::ID CallConv
, bool isVarArg
,
210 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
211 const SmallVectorImpl
<SDValue
> &OutVals
,
212 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
213 DebugLoc dl
, SelectionDAG
&DAG
,
214 SmallVectorImpl
<SDValue
> &InVals
) const {
218 /// LowerCallResult - Lower the result values of a call into the
219 /// appropriate copies out of appropriate physical registers.
221 ZPUTargetLowering::LowerCallResult(SDValue Chain
, SDValue InFlag
,
222 CallingConv::ID CallConv
, bool isVarArg
,
223 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
224 DebugLoc dl
, SelectionDAG
&DAG
,
225 SmallVectorImpl
<SDValue
> &InVals
) const {
227 // Assign locations to each value returned by this call.
228 SmallVector
<CCValAssign
, 16> RVLocs
;
229 CCState
CCInfo(CallConv
, isVarArg
, getTargetMachine(),
230 RVLocs
, *DAG
.getContext());
232 CCInfo
.AnalyzeCallResult(Ins
, RetCC_ZPU
);
234 // Copy all of the result registers out of their specified physreg.
235 for (unsigned i
= 0; i
!= RVLocs
.size(); ++i
) {
236 Chain
= DAG
.getCopyFromReg(Chain
, dl
, RVLocs
[i
].getLocReg(),
237 RVLocs
[i
].getValVT(), InFlag
).getValue(1);
238 InFlag
= Chain
.getValue(2);
239 InVals
.push_back(Chain
.getValue(0));
245 //===----------------------------------------------------------------------===//
246 // Formal Arguments Calling Convention Implementation
247 //===----------------------------------------------------------------------===//
249 /// LowerFormalArguments - transform physical registers into virtual registers
250 /// and generate load operations for arguments places on the stack.
252 ZPUTargetLowering::LowerFormalArguments(SDValue Chain
,
253 CallingConv::ID CallConv
, bool isVarArg
,
254 const SmallVectorImpl
<ISD::InputArg
>
256 DebugLoc dl
, SelectionDAG
&DAG
,
257 SmallVectorImpl
<SDValue
> &InVals
)
260 /* FIX! no arguments yet! */
264 //===----------------------------------------------------------------------===//
265 // Return Value Calling Convention Implementation
266 //===----------------------------------------------------------------------===//
269 ZPUTargetLowering::LowerReturn(SDValue Chain
,
270 CallingConv::ID CallConv
, bool isVarArg
,
271 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
272 const SmallVectorImpl
<SDValue
> &OutVals
,
273 DebugLoc dl
, SelectionDAG
&DAG
) const {
277 //===----------------------------------------------------------------------===//
278 // ZPU Inline Assembly Support
279 //===----------------------------------------------------------------------===//
281 /// getConstraintType - Given a constraint letter, return the type of
282 /// constraint it is for this target.
283 ZPUTargetLowering::ConstraintType
ZPUTargetLowering::
284 getConstraintType(const std::string
&Constraint
) const
286 return TargetLowering::getConstraintType(Constraint
);
289 /// Examine constraint type and operand type and determine a weight value.
290 /// This object must already have been set up with the operand type
291 /// and the current alternative constraint selected.
292 TargetLowering::ConstraintWeight
293 ZPUTargetLowering::getSingleConstraintMatchWeight(
294 AsmOperandInfo
&info
, const char *constraint
) const {
295 ConstraintWeight weight
= CW_Invalid
;
299 /// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),
300 /// return a list of registers that can be used to satisfy the constraint.
301 /// This should only be used for C_RegisterClass constraints.
302 std::pair
<unsigned, const TargetRegisterClass
*> ZPUTargetLowering::
303 getRegForInlineAsmConstraint(const std::string
&Constraint
, EVT VT
) const
305 return TargetLowering::getRegForInlineAsmConstraint(Constraint
, VT
);
308 /// Given a register class constraint, like 'r', if this corresponds directly
309 /// to an LLVM register class, return a register of 0 and the register class
311 std::vector
<unsigned> ZPUTargetLowering::
312 getRegClassForInlineAsmConstraint(const std::string
&Constraint
,
315 if (Constraint
.size() != 1)
316 return std::vector
<unsigned>();
318 return std::vector
<unsigned>();
322 ZPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode
*GA
) const {
323 // The ZPU target isn't yet aware of offsets.
327 bool ZPUTargetLowering::isFPImmLegal(const APFloat
&Imm
, EVT VT
) const {
328 if (VT
!= MVT::f32
&& VT
!= MVT::f64
)