zpu: wip eke out some simple instructions for load/store/add
[llvm/zpu.git] / lib / Target / ZPU / ZPUISelLowering.cpp
blobe5fbff9e34294bf5653f6815c416610ad076a990
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);
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 {
117 return MVT::i32;
120 /// getFunctionAlignment - Return the Log2 alignment of this function.
121 unsigned ZPUTargetLowering::getFunctionAlignment(const Function *) const {
122 return 2;
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);
133 return SDValue();
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.
151 static unsigned
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);
157 return VReg;
160 MachineBasicBlock *
161 ZPUTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
162 MachineBasicBlock *BB) const {
163 return BB;
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:
175 // ---
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
182 // go to stack.
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) {
196 return false;
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.
206 SDValue
207 ZPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
208 CallingConv::ID CallConv, bool isVarArg,
209 bool &isTailCall,
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 {
215 return Chain;
218 /// LowerCallResult - Lower the result values of a call into the
219 /// appropriate copies out of appropriate physical registers.
220 SDValue
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));
242 return Chain;
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.
251 SDValue
252 ZPUTargetLowering::LowerFormalArguments(SDValue Chain,
253 CallingConv::ID CallConv, bool isVarArg,
254 const SmallVectorImpl<ISD::InputArg>
255 &Ins,
256 DebugLoc dl, SelectionDAG &DAG,
257 SmallVectorImpl<SDValue> &InVals)
258 const {
260 /* FIX! no arguments yet! */
261 return Chain;
264 //===----------------------------------------------------------------------===//
265 // Return Value Calling Convention Implementation
266 //===----------------------------------------------------------------------===//
268 SDValue
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 {
274 return Chain;
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;
296 return weight;
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
310 /// pointer.
311 std::vector<unsigned> ZPUTargetLowering::
312 getRegClassForInlineAsmConstraint(const std::string &Constraint,
313 EVT VT) const
315 if (Constraint.size() != 1)
316 return std::vector<unsigned>();
318 return std::vector<unsigned>();
321 bool
322 ZPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
323 // The ZPU target isn't yet aware of offsets.
324 return true;
327 bool ZPUTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
328 if (VT != MVT::f32 && VT != MVT::f64)
329 return false;
330 return Imm.isZero();