Fixed some bugs in register stack pass.
[llvm/zpu.git] / lib / Target / ZPU / ZPUISelLowering.cpp
blobe0215b60b1f28c85ac4dba99f1285506843b992b
1 //===-- ZPUISelLowering.cpp - ZPU 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 defines the interfaces that ZPU uses to lower LLVM code into a
11 // selection DAG.
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"
33 using namespace llvm;
35 const char *ZPUTargetLowering::getTargetNodeName(unsigned Opcode) const {
36 switch (Opcode) {
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;
52 ZPUTargetLowering::
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);
81 //setOperationAction(ISD::SETCC, MVT::i32, Custom);
83 // Operations not directly supported by ZPU.
84 //setOperationAction(ISD::BR_JT, MVT::Other, Expand);
85 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
86 //setOperationAction(ISD::BRCOND, MVT::Other, Expand);
87 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
88 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
89 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
90 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
91 setOperationAction(ISD::CTPOP, MVT::i32, Expand);
92 setOperationAction(ISD::CTTZ, MVT::i32, Expand);
93 setOperationAction(ISD::ROTL, MVT::i32, Expand);
94 setOperationAction(ISD::ROTR, MVT::i32, Expand);
95 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
96 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
97 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
98 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
99 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
100 setOperationAction(ISD::FSIN, MVT::f32, Expand);
101 setOperationAction(ISD::FCOS, MVT::f32, Expand);
102 setOperationAction(ISD::FPOWI, MVT::f32, Expand);
103 setOperationAction(ISD::FPOW, MVT::f32, Expand);
104 setOperationAction(ISD::FLOG, MVT::f32, Expand);
105 setOperationAction(ISD::FLOG2, MVT::f32, Expand);
106 setOperationAction(ISD::FLOG10, MVT::f32, Expand);
107 setOperationAction(ISD::FEXP, MVT::f32, Expand);
109 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
111 // Use the default for now
112 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
113 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
114 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
116 setStackPointerRegisterToSaveRestore(ZPU::SP);
117 computeRegisterProperties();
120 MVT::SimpleValueType ZPUTargetLowering::getSetCCResultType(EVT VT) const {
121 return MVT::i32;
124 /// getFunctionAlignment - Return the Log2 alignment of this function.
125 unsigned ZPUTargetLowering::getFunctionAlignment(const Function *) const {
126 return 2;
129 SDValue ZPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
131 switch (Op.getOpcode())
133 default: llvm_unreachable("Wasn't expecting to be able to lower this!");
134 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
135 case ISD::SETCC: return LowerSETCC(Op, DAG);
137 return SDValue();
140 SDValue ZPUTargetLowering::LowerGlobalAddress(SDValue Op,
141 SelectionDAG &DAG) const {
142 DebugLoc DL = Op.getDebugLoc();
143 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
145 return Op = DAG.getTargetGlobalAddress(GV, DL, MVT::i32);
148 //===----------------------------------------------------------------------===//
149 // Lower helper functions
150 //===----------------------------------------------------------------------===//
152 // AddLiveIn - This helper function adds the specified physical register to the
153 // MachineFunction as a live in value. It also creates a corresponding
154 // virtual register for it.
155 static unsigned
156 AddLiveIn(MachineFunction &MF, unsigned PReg, TargetRegisterClass *RC)
158 assert(RC->contains(PReg) && "Not the correct regclass!");
159 unsigned VReg = MF.getRegInfo().createVirtualRegister(RC);
160 MF.getRegInfo().addLiveIn(PReg, VReg);
161 return VReg;
164 MachineBasicBlock *
165 ZPUTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
166 MachineBasicBlock *BB) const {
167 return BB;
170 //===----------------------------------------------------------------------===//
171 // Calling Convention Implementation
172 //===----------------------------------------------------------------------===//
174 #include "ZPUGenCallingConv.inc"
176 //===----------------------------------------------------------------------===//
177 // TODO: Implement a generic logic using tblgen that can support this.
178 // ZPU O32 ABI rules:
179 // ---
180 // i32 - Passed in A0, A1, A2, A3 and stack
181 // f32 - Only passed in f32 registers if no int reg has been used yet to hold
182 // an argument. Otherwise, passed in A1, A2, A3 and stack.
183 // f64 - Only passed in two aliased f32 registers if no int reg has been used
184 // yet to hold an argument. Otherwise, use A2, A3 and stack. If A1 is
185 // not used, it must be shadowed. If only A3 is avaiable, shadow it and
186 // go to stack.
187 //===----------------------------------------------------------------------===//
189 static bool CC_ZPUO32(unsigned ValNo, EVT ValVT,
190 MVT LocVT, CCValAssign::LocInfo LocInfo,
191 ISD::ArgFlagsTy ArgFlags, CCState &State) {
193 return false; // CC must always match
196 static bool CC_ZPUO32_VarArgs(unsigned ValNo, EVT ValVT,
197 MVT LocVT, CCValAssign::LocInfo LocInfo,
198 ISD::ArgFlagsTy ArgFlags, CCState &State) {
200 return false;
203 //===----------------------------------------------------------------------===//
204 // Call Calling Convention Implementation
205 //===----------------------------------------------------------------------===//
207 /// LowerCall - functions arguments are copied from virtual regs to
208 /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
209 /// TODO: isTailCall.
210 SDValue
211 ZPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
212 CallingConv::ID CallConv, bool isVarArg,
213 bool &isTailCall,
214 const SmallVectorImpl<ISD::OutputArg> &Outs,
215 const SmallVectorImpl<SDValue> &OutVals,
216 const SmallVectorImpl<ISD::InputArg> &Ins,
217 DebugLoc dl, SelectionDAG &DAG,
218 SmallVectorImpl<SDValue> &InVals) const {
219 return Chain;
222 /// LowerCallResult - Lower the result values of a call into the
223 /// appropriate copies out of appropriate physical registers.
224 SDValue
225 ZPUTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
226 CallingConv::ID CallConv, bool isVarArg,
227 const SmallVectorImpl<ISD::InputArg> &Ins,
228 DebugLoc dl, SelectionDAG &DAG,
229 SmallVectorImpl<SDValue> &InVals) const {
231 // Assign locations to each value returned by this call.
232 SmallVector<CCValAssign, 16> RVLocs;
233 CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
234 RVLocs, *DAG.getContext());
236 CCInfo.AnalyzeCallResult(Ins, RetCC_ZPU);
238 // Copy all of the result registers out of their specified physreg.
239 for (unsigned i = 0; i != RVLocs.size(); ++i) {
240 Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
241 RVLocs[i].getValVT(), InFlag).getValue(1);
242 InFlag = Chain.getValue(2);
243 InVals.push_back(Chain.getValue(0));
246 return Chain;
249 //===----------------------------------------------------------------------===//
250 // Formal Arguments Calling Convention Implementation
251 //===----------------------------------------------------------------------===//
253 /// LowerFormalArguments - transform physical registers into virtual registers
254 /// and generate load operations for arguments places on the stack.
255 SDValue
256 ZPUTargetLowering::LowerFormalArguments(SDValue Chain,
257 CallingConv::ID CallConv, bool isVarArg,
258 const SmallVectorImpl<ISD::InputArg>
259 &Ins,
260 DebugLoc dl, SelectionDAG &DAG,
261 SmallVectorImpl<SDValue> &InVals)
262 const {
264 /* FIX! no arguments yet! */
265 return Chain;
268 //===----------------------------------------------------------------------===//
269 // Return Value Calling Convention Implementation
270 //===----------------------------------------------------------------------===//
272 SDValue
273 ZPUTargetLowering::LowerReturn(SDValue Chain,
274 CallingConv::ID CallConv, bool isVarArg,
275 const SmallVectorImpl<ISD::OutputArg> &Outs,
276 const SmallVectorImpl<SDValue> &OutVals,
277 DebugLoc dl, SelectionDAG &DAG) const {
278 return Chain;
281 //===----------------------------------------------------------------------===//
282 // ZPU Inline Assembly Support
283 //===----------------------------------------------------------------------===//
285 /// getConstraintType - Given a constraint letter, return the type of
286 /// constraint it is for this target.
287 ZPUTargetLowering::ConstraintType ZPUTargetLowering::
288 getConstraintType(const std::string &Constraint) const
290 return TargetLowering::getConstraintType(Constraint);
293 /// Examine constraint type and operand type and determine a weight value.
294 /// This object must already have been set up with the operand type
295 /// and the current alternative constraint selected.
296 TargetLowering::ConstraintWeight
297 ZPUTargetLowering::getSingleConstraintMatchWeight(
298 AsmOperandInfo &info, const char *constraint) const {
299 ConstraintWeight weight = CW_Invalid;
300 return weight;
303 /// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),
304 /// return a list of registers that can be used to satisfy the constraint.
305 /// This should only be used for C_RegisterClass constraints.
306 std::pair<unsigned, const TargetRegisterClass*> ZPUTargetLowering::
307 getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const
309 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
312 /// Given a register class constraint, like 'r', if this corresponds directly
313 /// to an LLVM register class, return a register of 0 and the register class
314 /// pointer.
315 std::vector<unsigned> ZPUTargetLowering::
316 getRegClassForInlineAsmConstraint(const std::string &Constraint,
317 EVT VT) const
319 if (Constraint.size() != 1)
320 return std::vector<unsigned>();
322 return std::vector<unsigned>();
325 bool
326 ZPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
327 // The ZPU target isn't yet aware of offsets.
328 return true;
331 bool ZPUTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
332 if (VT != MVT::f32 && VT != MVT::f64)
333 return false;
334 return Imm.isZero();
336 #include <stdio.h>
337 static SDValue EmitConditionFunc(SDValue LHS,SDValue RHS,ISD::CondCode CC,
338 DebugLoc dl, SelectionDAG &DAG)
340 bool unsign=false;
341 bool swap=false;
342 bool emit_equal = false;
343 printf("opcode is %d \n",CC);
344 switch(CC)
346 case ISD::SETFALSE: // Always false (always folded)
347 case ISD::SETOEQ: // True if ordered and equal
348 case ISD::SETOGT: // True if ordered and greater than
349 case ISD::SETOGE: // True if ordered and greater than or equal
350 case ISD::SETOLT: // True if ordered and less than
351 case ISD::SETOLE: // True if ordered and less than or equal
352 case ISD::SETONE: // True if ordered and operands are unequal
353 case ISD::SETO: // True if ordered (no nans)
354 case ISD::SETUO: // True if unordered: isnan(X) | isnan(Y)
355 case ISD::SETUEQ: // True if unordered or equal
356 case ISD::SETUGT: // True if unordered or greater than
357 case ISD::SETUGE: // True if unordered, greater than, or equal
358 case ISD::SETULT: // True if unordered or less than
359 case ISD::SETULE: // True if unordered, less than, or equal
360 case ISD::SETUNE: // True if unordered or not equal
361 case ISD::SETTRUE: // Always true (always folded)
362 case ISD::SETTRUE2: // Always true (always folded)
363 case ISD::SETFALSE2: // Always false (always folded)
364 llvm_unreachable("Unkown cmp instruction");
365 break;
366 case ISD::SETEQ: // True if equal
367 return DAG.getNode(ZPUISD::EQ, dl,MVT::i32, LHS,RHS);
368 case ISD::SETNE: // True if not equal
369 return DAG.getNode(ZPUISD::NEQ, dl,MVT::i32, LHS,RHS);
370 case ISD::SETLT: // True if less than
371 swap=false;
372 emit_equal=false;
373 break;
374 case ISD::SETLE: // True if less than or equal
375 swap=false;
376 emit_equal=true;
377 break;
378 case ISD::SETCC_INVALID:
379 llvm_unreachable("Invalid CC");
380 break;
381 case ISD::SETGE: // True if greater than or equal
382 swap=true;
383 emit_equal=true;
384 break;
385 case ISD::SETGT: // True if greater than
386 swap=true;
387 emit_equal=false;
388 break;
389 default:
390 llvm_unreachable("unimplemented operand");
392 SDValue cmp_node;
393 unsigned opcode=0;
394 if(emit_equal)
396 if(unsign)
398 opcode = ZPUISD::ULESSTHANEQ;
400 else
402 opcode = ZPUISD::LESSTHANEQ;
405 else
407 if(unsign)
409 opcode = ZPUISD::ULESSTHAN;
411 else
413 opcode = ZPUISD::LESSTHAN;
418 if(swap)
420 return DAG.getNode(opcode, dl,MVT::i32, RHS,LHS);
422 else
424 return DAG.getNode(opcode, dl,MVT::i32, LHS,RHS);
427 if(negate)
429 SDValue cmp_res = DAG.getCopyFromReg(DAG.getEntryNode(), dl, , MVT::i32);
431 SDValue minus1 = DAG.getConstant(-1, MVT::i32);
434 return DAG.getNode(ISD::XOR,dl,MVT::i32,cmp_node,minus1);
436 else
438 return cmp_node;
442 SDValue ZPUTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
443 SDValue LHS = Op.getOperand(0);
444 SDValue RHS = Op.getOperand(1);
445 DebugLoc dl = Op.getDebugLoc();
447 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
449 return EmitConditionFunc(LHS,RHS, CC,dl,DAG);