1 //===-- AlphaISelLowering.cpp - Alpha 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 AlphaISelLowering class.
12 //===----------------------------------------------------------------------===//
14 #include "AlphaISelLowering.h"
15 #include "AlphaTargetMachine.h"
16 #include "AlphaMachineFunctionInfo.h"
17 #include "llvm/CodeGen/CallingConvLower.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 #include "llvm/CodeGen/SelectionDAG.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/PseudoSourceValue.h"
25 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
26 #include "llvm/Constants.h"
27 #include "llvm/Function.h"
28 #include "llvm/Module.h"
29 #include "llvm/Intrinsics.h"
30 #include "llvm/Type.h"
31 #include "llvm/Support/CommandLine.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/raw_ostream.h"
36 /// AddLiveIn - This helper function adds the specified physical register to the
37 /// MachineFunction as a live in value. It also creates a corresponding virtual
39 static unsigned AddLiveIn(MachineFunction
&MF
, unsigned PReg
,
40 TargetRegisterClass
*RC
) {
41 assert(RC
->contains(PReg
) && "Not the correct regclass!");
42 unsigned VReg
= MF
.getRegInfo().createVirtualRegister(RC
);
43 MF
.getRegInfo().addLiveIn(PReg
, VReg
);
47 AlphaTargetLowering::AlphaTargetLowering(TargetMachine
&TM
)
48 : TargetLowering(TM
, new TargetLoweringObjectFileELF()) {
49 // Set up the TargetLowering object.
50 //I am having problems with shr n i8 1
51 setShiftAmountType(MVT::i64
);
52 setBooleanContents(ZeroOrOneBooleanContent
);
54 addRegisterClass(MVT::i64
, Alpha::GPRCRegisterClass
);
55 addRegisterClass(MVT::f64
, Alpha::F8RCRegisterClass
);
56 addRegisterClass(MVT::f32
, Alpha::F4RCRegisterClass
);
58 // We want to custom lower some of our intrinsics.
59 setOperationAction(ISD::INTRINSIC_WO_CHAIN
, MVT::Other
, Custom
);
61 setLoadExtAction(ISD::EXTLOAD
, MVT::i1
, Promote
);
62 setLoadExtAction(ISD::EXTLOAD
, MVT::f32
, Expand
);
64 setLoadExtAction(ISD::ZEXTLOAD
, MVT::i1
, Promote
);
65 setLoadExtAction(ISD::ZEXTLOAD
, MVT::i32
, Expand
);
67 setLoadExtAction(ISD::SEXTLOAD
, MVT::i1
, Promote
);
68 setLoadExtAction(ISD::SEXTLOAD
, MVT::i8
, Expand
);
69 setLoadExtAction(ISD::SEXTLOAD
, MVT::i16
, Expand
);
71 setTruncStoreAction(MVT::f64
, MVT::f32
, Expand
);
73 // setOperationAction(ISD::BRIND, MVT::Other, Expand);
74 setOperationAction(ISD::BR_JT
, MVT::Other
, Expand
);
75 setOperationAction(ISD::BR_CC
, MVT::Other
, Expand
);
76 setOperationAction(ISD::SELECT_CC
, MVT::Other
, Expand
);
78 setOperationAction(ISD::SIGN_EXTEND_INREG
, MVT::i1
, Expand
);
80 setOperationAction(ISD::FREM
, MVT::f32
, Expand
);
81 setOperationAction(ISD::FREM
, MVT::f64
, Expand
);
83 setOperationAction(ISD::UINT_TO_FP
, MVT::i64
, Expand
);
84 setOperationAction(ISD::SINT_TO_FP
, MVT::i64
, Custom
);
85 setOperationAction(ISD::FP_TO_UINT
, MVT::i64
, Expand
);
86 setOperationAction(ISD::FP_TO_SINT
, MVT::i64
, Custom
);
88 if (!TM
.getSubtarget
<AlphaSubtarget
>().hasCT()) {
89 setOperationAction(ISD::CTPOP
, MVT::i64
, Expand
);
90 setOperationAction(ISD::CTTZ
, MVT::i64
, Expand
);
91 setOperationAction(ISD::CTLZ
, MVT::i64
, Expand
);
93 setOperationAction(ISD::BSWAP
, MVT::i64
, Expand
);
94 setOperationAction(ISD::ROTL
, MVT::i64
, Expand
);
95 setOperationAction(ISD::ROTR
, MVT::i64
, Expand
);
97 setOperationAction(ISD::SREM
, MVT::i64
, Custom
);
98 setOperationAction(ISD::UREM
, MVT::i64
, Custom
);
99 setOperationAction(ISD::SDIV
, MVT::i64
, Custom
);
100 setOperationAction(ISD::UDIV
, MVT::i64
, Custom
);
102 setOperationAction(ISD::ADDC
, MVT::i64
, Expand
);
103 setOperationAction(ISD::ADDE
, MVT::i64
, Expand
);
104 setOperationAction(ISD::SUBC
, MVT::i64
, Expand
);
105 setOperationAction(ISD::SUBE
, MVT::i64
, Expand
);
107 setOperationAction(ISD::UMUL_LOHI
, MVT::i64
, Expand
);
108 setOperationAction(ISD::SMUL_LOHI
, MVT::i64
, Expand
);
110 setOperationAction(ISD::SRL_PARTS
, MVT::i64
, Custom
);
111 setOperationAction(ISD::SRA_PARTS
, MVT::i64
, Expand
);
112 setOperationAction(ISD::SHL_PARTS
, MVT::i64
, Expand
);
114 // We don't support sin/cos/sqrt/pow
115 setOperationAction(ISD::FSIN
, MVT::f64
, Expand
);
116 setOperationAction(ISD::FCOS
, MVT::f64
, Expand
);
117 setOperationAction(ISD::FSIN
, MVT::f32
, Expand
);
118 setOperationAction(ISD::FCOS
, MVT::f32
, Expand
);
120 setOperationAction(ISD::FSQRT
, MVT::f64
, Expand
);
121 setOperationAction(ISD::FSQRT
, MVT::f32
, Expand
);
123 setOperationAction(ISD::FPOW
, MVT::f32
, Expand
);
124 setOperationAction(ISD::FPOW
, MVT::f64
, Expand
);
126 setOperationAction(ISD::SETCC
, MVT::f32
, Promote
);
128 setOperationAction(ISD::BIT_CONVERT
, MVT::f32
, Promote
);
130 setOperationAction(ISD::EH_LABEL
, MVT::Other
, Expand
);
132 // Not implemented yet.
133 setOperationAction(ISD::STACKSAVE
, MVT::Other
, Expand
);
134 setOperationAction(ISD::STACKRESTORE
, MVT::Other
, Expand
);
135 setOperationAction(ISD::DYNAMIC_STACKALLOC
, MVT::i64
, Expand
);
137 // We want to legalize GlobalAddress and ConstantPool and
138 // ExternalSymbols nodes into the appropriate instructions to
139 // materialize the address.
140 setOperationAction(ISD::GlobalAddress
, MVT::i64
, Custom
);
141 setOperationAction(ISD::ConstantPool
, MVT::i64
, Custom
);
142 setOperationAction(ISD::ExternalSymbol
, MVT::i64
, Custom
);
143 setOperationAction(ISD::GlobalTLSAddress
, MVT::i64
, Custom
);
145 setOperationAction(ISD::VASTART
, MVT::Other
, Custom
);
146 setOperationAction(ISD::VAEND
, MVT::Other
, Expand
);
147 setOperationAction(ISD::VACOPY
, MVT::Other
, Custom
);
148 setOperationAction(ISD::VAARG
, MVT::Other
, Custom
);
149 setOperationAction(ISD::VAARG
, MVT::i32
, Custom
);
151 setOperationAction(ISD::JumpTable
, MVT::i64
, Custom
);
152 setOperationAction(ISD::JumpTable
, MVT::i32
, Custom
);
154 setStackPointerRegisterToSaveRestore(Alpha::R30
);
157 setJumpBufAlignment(16);
159 computeRegisterProperties();
162 MVT::SimpleValueType
AlphaTargetLowering::getSetCCResultType(EVT VT
) const {
166 const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode
) const {
169 case AlphaISD::CVTQT_
: return "Alpha::CVTQT_";
170 case AlphaISD::CVTQS_
: return "Alpha::CVTQS_";
171 case AlphaISD::CVTTQ_
: return "Alpha::CVTTQ_";
172 case AlphaISD::GPRelHi
: return "Alpha::GPRelHi";
173 case AlphaISD::GPRelLo
: return "Alpha::GPRelLo";
174 case AlphaISD::RelLit
: return "Alpha::RelLit";
175 case AlphaISD::GlobalRetAddr
: return "Alpha::GlobalRetAddr";
176 case AlphaISD::CALL
: return "Alpha::CALL";
177 case AlphaISD::DivCall
: return "Alpha::DivCall";
178 case AlphaISD::RET_FLAG
: return "Alpha::RET_FLAG";
179 case AlphaISD::COND_BRANCH_I
: return "Alpha::COND_BRANCH_I";
180 case AlphaISD::COND_BRANCH_F
: return "Alpha::COND_BRANCH_F";
184 /// getFunctionAlignment - Return the Log2 alignment of this function.
185 unsigned AlphaTargetLowering::getFunctionAlignment(const Function
*F
) const {
189 static SDValue
LowerJumpTable(SDValue Op
, SelectionDAG
&DAG
) {
190 EVT PtrVT
= Op
.getValueType();
191 JumpTableSDNode
*JT
= cast
<JumpTableSDNode
>(Op
);
192 SDValue JTI
= DAG
.getTargetJumpTable(JT
->getIndex(), PtrVT
);
193 // FIXME there isn't really any debug info here
194 DebugLoc dl
= Op
.getDebugLoc();
196 SDValue Hi
= DAG
.getNode(AlphaISD::GPRelHi
, dl
, MVT::i64
, JTI
,
197 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
198 SDValue Lo
= DAG
.getNode(AlphaISD::GPRelLo
, dl
, MVT::i64
, JTI
, Hi
);
202 //http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/
203 //AA-PY8AC-TET1_html/callCH3.html#BLOCK21
205 //For now, just use variable size stack frame format
207 //In a standard call, the first six items are passed in registers $16
208 //- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
209 //of argument-to-register correspondence.) The remaining items are
210 //collected in a memory argument list that is a naturally aligned
211 //array of quadwords. In a standard call, this list, if present, must
212 //be passed at 0(SP).
213 //7 ... n 0(SP) ... (n-7)*8(SP)
221 #include "AlphaGenCallingConv.inc"
224 AlphaTargetLowering::LowerCall(SDValue Chain
, SDValue Callee
,
225 CallingConv::ID CallConv
, bool isVarArg
,
227 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
228 const SmallVectorImpl
<SDValue
> &OutVals
,
229 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
230 DebugLoc dl
, SelectionDAG
&DAG
,
231 SmallVectorImpl
<SDValue
> &InVals
) const {
232 // Alpha target does not yet support tail call optimization.
235 // Analyze operands of the call, assigning locations to each operand.
236 SmallVector
<CCValAssign
, 16> ArgLocs
;
237 CCState
CCInfo(CallConv
, isVarArg
, getTargetMachine(),
238 ArgLocs
, *DAG
.getContext());
240 CCInfo
.AnalyzeCallOperands(Outs
, CC_Alpha
);
242 // Get a count of how many bytes are to be pushed on the stack.
243 unsigned NumBytes
= CCInfo
.getNextStackOffset();
245 Chain
= DAG
.getCALLSEQ_START(Chain
, DAG
.getConstant(NumBytes
,
246 getPointerTy(), true));
248 SmallVector
<std::pair
<unsigned, SDValue
>, 4> RegsToPass
;
249 SmallVector
<SDValue
, 12> MemOpChains
;
252 // Walk the register/memloc assignments, inserting copies/loads.
253 for (unsigned i
= 0, e
= ArgLocs
.size(); i
!= e
; ++i
) {
254 CCValAssign
&VA
= ArgLocs
[i
];
256 SDValue Arg
= OutVals
[i
];
258 // Promote the value if needed.
259 switch (VA
.getLocInfo()) {
260 default: assert(0 && "Unknown loc info!");
261 case CCValAssign::Full
: break;
262 case CCValAssign::SExt
:
263 Arg
= DAG
.getNode(ISD::SIGN_EXTEND
, dl
, VA
.getLocVT(), Arg
);
265 case CCValAssign::ZExt
:
266 Arg
= DAG
.getNode(ISD::ZERO_EXTEND
, dl
, VA
.getLocVT(), Arg
);
268 case CCValAssign::AExt
:
269 Arg
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, VA
.getLocVT(), Arg
);
273 // Arguments that can be passed on register must be kept at RegsToPass
276 RegsToPass
.push_back(std::make_pair(VA
.getLocReg(), Arg
));
278 assert(VA
.isMemLoc());
280 if (StackPtr
.getNode() == 0)
281 StackPtr
= DAG
.getCopyFromReg(Chain
, dl
, Alpha::R30
, MVT::i64
);
283 SDValue PtrOff
= DAG
.getNode(ISD::ADD
, dl
, getPointerTy(),
285 DAG
.getIntPtrConstant(VA
.getLocMemOffset()));
287 MemOpChains
.push_back(DAG
.getStore(Chain
, dl
, Arg
, PtrOff
,
288 MachinePointerInfo(),false, false, 0));
292 // Transform all store nodes into one single node because all store nodes are
293 // independent of each other.
294 if (!MemOpChains
.empty())
295 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
296 &MemOpChains
[0], MemOpChains
.size());
298 // Build a sequence of copy-to-reg nodes chained together with token chain and
299 // flag operands which copy the outgoing args into registers. The InFlag in
300 // necessary since all emited instructions must be stuck together.
302 for (unsigned i
= 0, e
= RegsToPass
.size(); i
!= e
; ++i
) {
303 Chain
= DAG
.getCopyToReg(Chain
, dl
, RegsToPass
[i
].first
,
304 RegsToPass
[i
].second
, InFlag
);
305 InFlag
= Chain
.getValue(1);
308 // Returns a chain & a flag for retval copy to use.
309 SDVTList NodeTys
= DAG
.getVTList(MVT::Other
, MVT::Flag
);
310 SmallVector
<SDValue
, 8> Ops
;
311 Ops
.push_back(Chain
);
312 Ops
.push_back(Callee
);
314 // Add argument registers to the end of the list so that they are
315 // known live into the call.
316 for (unsigned i
= 0, e
= RegsToPass
.size(); i
!= e
; ++i
)
317 Ops
.push_back(DAG
.getRegister(RegsToPass
[i
].first
,
318 RegsToPass
[i
].second
.getValueType()));
320 if (InFlag
.getNode())
321 Ops
.push_back(InFlag
);
323 Chain
= DAG
.getNode(AlphaISD::CALL
, dl
, NodeTys
, &Ops
[0], Ops
.size());
324 InFlag
= Chain
.getValue(1);
326 // Create the CALLSEQ_END node.
327 Chain
= DAG
.getCALLSEQ_END(Chain
,
328 DAG
.getConstant(NumBytes
, getPointerTy(), true),
329 DAG
.getConstant(0, getPointerTy(), true),
331 InFlag
= Chain
.getValue(1);
333 // Handle result values, copying them out of physregs into vregs that we
335 return LowerCallResult(Chain
, InFlag
, CallConv
, isVarArg
,
336 Ins
, dl
, DAG
, InVals
);
339 /// LowerCallResult - Lower the result values of a call into the
340 /// appropriate copies out of appropriate physical registers.
343 AlphaTargetLowering::LowerCallResult(SDValue Chain
, SDValue InFlag
,
344 CallingConv::ID CallConv
, bool isVarArg
,
345 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
346 DebugLoc dl
, SelectionDAG
&DAG
,
347 SmallVectorImpl
<SDValue
> &InVals
) const {
349 // Assign locations to each value returned by this call.
350 SmallVector
<CCValAssign
, 16> RVLocs
;
351 CCState
CCInfo(CallConv
, isVarArg
, getTargetMachine(), RVLocs
,
354 CCInfo
.AnalyzeCallResult(Ins
, RetCC_Alpha
);
356 // Copy all of the result registers out of their specified physreg.
357 for (unsigned i
= 0; i
!= RVLocs
.size(); ++i
) {
358 CCValAssign
&VA
= RVLocs
[i
];
360 Chain
= DAG
.getCopyFromReg(Chain
, dl
, VA
.getLocReg(),
361 VA
.getLocVT(), InFlag
).getValue(1);
362 SDValue RetValue
= Chain
.getValue(0);
363 InFlag
= Chain
.getValue(2);
365 // If this is an 8/16/32-bit value, it is really passed promoted to 64
366 // bits. Insert an assert[sz]ext to capture this, then truncate to the
368 if (VA
.getLocInfo() == CCValAssign::SExt
)
369 RetValue
= DAG
.getNode(ISD::AssertSext
, dl
, VA
.getLocVT(), RetValue
,
370 DAG
.getValueType(VA
.getValVT()));
371 else if (VA
.getLocInfo() == CCValAssign::ZExt
)
372 RetValue
= DAG
.getNode(ISD::AssertZext
, dl
, VA
.getLocVT(), RetValue
,
373 DAG
.getValueType(VA
.getValVT()));
375 if (VA
.getLocInfo() != CCValAssign::Full
)
376 RetValue
= DAG
.getNode(ISD::TRUNCATE
, dl
, VA
.getValVT(), RetValue
);
378 InVals
.push_back(RetValue
);
385 AlphaTargetLowering::LowerFormalArguments(SDValue Chain
,
386 CallingConv::ID CallConv
, bool isVarArg
,
387 const SmallVectorImpl
<ISD::InputArg
>
389 DebugLoc dl
, SelectionDAG
&DAG
,
390 SmallVectorImpl
<SDValue
> &InVals
)
393 MachineFunction
&MF
= DAG
.getMachineFunction();
394 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
395 AlphaMachineFunctionInfo
*FuncInfo
= MF
.getInfo
<AlphaMachineFunctionInfo
>();
397 unsigned args_int
[] = {
398 Alpha::R16
, Alpha::R17
, Alpha::R18
, Alpha::R19
, Alpha::R20
, Alpha::R21
};
399 unsigned args_float
[] = {
400 Alpha::F16
, Alpha::F17
, Alpha::F18
, Alpha::F19
, Alpha::F20
, Alpha::F21
};
402 for (unsigned ArgNo
= 0, e
= Ins
.size(); ArgNo
!= e
; ++ArgNo
) {
404 EVT ObjectVT
= Ins
[ArgNo
].VT
;
408 switch (ObjectVT
.getSimpleVT().SimpleTy
) {
410 assert(false && "Invalid value type!");
412 args_float
[ArgNo
] = AddLiveIn(MF
, args_float
[ArgNo
],
413 &Alpha::F8RCRegClass
);
414 ArgVal
= DAG
.getCopyFromReg(Chain
, dl
, args_float
[ArgNo
], ObjectVT
);
417 args_float
[ArgNo
] = AddLiveIn(MF
, args_float
[ArgNo
],
418 &Alpha::F4RCRegClass
);
419 ArgVal
= DAG
.getCopyFromReg(Chain
, dl
, args_float
[ArgNo
], ObjectVT
);
422 args_int
[ArgNo
] = AddLiveIn(MF
, args_int
[ArgNo
],
423 &Alpha::GPRCRegClass
);
424 ArgVal
= DAG
.getCopyFromReg(Chain
, dl
, args_int
[ArgNo
], MVT::i64
);
428 // Create the frame index object for this incoming parameter...
429 int FI
= MFI
->CreateFixedObject(8, 8 * (ArgNo
- 6), true);
431 // Create the SelectionDAG nodes corresponding to a load
432 //from this parameter
433 SDValue FIN
= DAG
.getFrameIndex(FI
, MVT::i64
);
434 ArgVal
= DAG
.getLoad(ObjectVT
, dl
, Chain
, FIN
, MachinePointerInfo(),
437 InVals
.push_back(ArgVal
);
440 // If the functions takes variable number of arguments, copy all regs to stack
442 FuncInfo
->setVarArgsOffset(Ins
.size() * 8);
443 std::vector
<SDValue
> LS
;
444 for (int i
= 0; i
< 6; ++i
) {
445 if (TargetRegisterInfo::isPhysicalRegister(args_int
[i
]))
446 args_int
[i
] = AddLiveIn(MF
, args_int
[i
], &Alpha::GPRCRegClass
);
447 SDValue argt
= DAG
.getCopyFromReg(Chain
, dl
, args_int
[i
], MVT::i64
);
448 int FI
= MFI
->CreateFixedObject(8, -8 * (6 - i
), true);
449 if (i
== 0) FuncInfo
->setVarArgsBase(FI
);
450 SDValue SDFI
= DAG
.getFrameIndex(FI
, MVT::i64
);
451 LS
.push_back(DAG
.getStore(Chain
, dl
, argt
, SDFI
, MachinePointerInfo(),
454 if (TargetRegisterInfo::isPhysicalRegister(args_float
[i
]))
455 args_float
[i
] = AddLiveIn(MF
, args_float
[i
], &Alpha::F8RCRegClass
);
456 argt
= DAG
.getCopyFromReg(Chain
, dl
, args_float
[i
], MVT::f64
);
457 FI
= MFI
->CreateFixedObject(8, - 8 * (12 - i
), true);
458 SDFI
= DAG
.getFrameIndex(FI
, MVT::i64
);
459 LS
.push_back(DAG
.getStore(Chain
, dl
, argt
, SDFI
, MachinePointerInfo(),
463 //Set up a token factor with all the stack traffic
464 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, &LS
[0], LS
.size());
471 AlphaTargetLowering::LowerReturn(SDValue Chain
,
472 CallingConv::ID CallConv
, bool isVarArg
,
473 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
474 const SmallVectorImpl
<SDValue
> &OutVals
,
475 DebugLoc dl
, SelectionDAG
&DAG
) const {
477 SDValue Copy
= DAG
.getCopyToReg(Chain
, dl
, Alpha::R26
,
478 DAG
.getNode(AlphaISD::GlobalRetAddr
,
479 DebugLoc(), MVT::i64
),
481 switch (Outs
.size()) {
483 llvm_unreachable("Do not know how to return this many arguments!");
486 //return SDValue(); // ret void is legal
488 EVT ArgVT
= Outs
[0].VT
;
490 if (ArgVT
.isInteger())
493 assert(ArgVT
.isFloatingPoint());
496 Copy
= DAG
.getCopyToReg(Copy
, dl
, ArgReg
,
497 OutVals
[0], Copy
.getValue(1));
498 if (DAG
.getMachineFunction().getRegInfo().liveout_empty())
499 DAG
.getMachineFunction().getRegInfo().addLiveOut(ArgReg
);
503 EVT ArgVT
= Outs
[0].VT
;
504 unsigned ArgReg1
, ArgReg2
;
505 if (ArgVT
.isInteger()) {
509 assert(ArgVT
.isFloatingPoint());
513 Copy
= DAG
.getCopyToReg(Copy
, dl
, ArgReg1
,
514 OutVals
[0], Copy
.getValue(1));
515 if (std::find(DAG
.getMachineFunction().getRegInfo().liveout_begin(),
516 DAG
.getMachineFunction().getRegInfo().liveout_end(), ArgReg1
)
517 == DAG
.getMachineFunction().getRegInfo().liveout_end())
518 DAG
.getMachineFunction().getRegInfo().addLiveOut(ArgReg1
);
519 Copy
= DAG
.getCopyToReg(Copy
, dl
, ArgReg2
,
520 OutVals
[1], Copy
.getValue(1));
521 if (std::find(DAG
.getMachineFunction().getRegInfo().liveout_begin(),
522 DAG
.getMachineFunction().getRegInfo().liveout_end(), ArgReg2
)
523 == DAG
.getMachineFunction().getRegInfo().liveout_end())
524 DAG
.getMachineFunction().getRegInfo().addLiveOut(ArgReg2
);
528 return DAG
.getNode(AlphaISD::RET_FLAG
, dl
,
529 MVT::Other
, Copy
, Copy
.getValue(1));
532 void AlphaTargetLowering::LowerVAARG(SDNode
*N
, SDValue
&Chain
,
534 SelectionDAG
&DAG
) const {
535 Chain
= N
->getOperand(0);
536 SDValue VAListP
= N
->getOperand(1);
537 const Value
*VAListS
= cast
<SrcValueSDNode
>(N
->getOperand(2))->getValue();
538 DebugLoc dl
= N
->getDebugLoc();
540 SDValue Base
= DAG
.getLoad(MVT::i64
, dl
, Chain
, VAListP
,
541 MachinePointerInfo(VAListS
),
543 SDValue Tmp
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, VAListP
,
544 DAG
.getConstant(8, MVT::i64
));
545 SDValue Offset
= DAG
.getExtLoad(ISD::SEXTLOAD
, MVT::i64
, dl
, Base
.getValue(1),
546 Tmp
, MachinePointerInfo(),
547 MVT::i32
, false, false, 0);
548 DataPtr
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, Base
, Offset
);
549 if (N
->getValueType(0).isFloatingPoint())
551 //if fp && Offset < 6*8, then subtract 6*8 from DataPtr
552 SDValue FPDataPtr
= DAG
.getNode(ISD::SUB
, dl
, MVT::i64
, DataPtr
,
553 DAG
.getConstant(8*6, MVT::i64
));
554 SDValue CC
= DAG
.getSetCC(dl
, MVT::i64
, Offset
,
555 DAG
.getConstant(8*6, MVT::i64
), ISD::SETLT
);
556 DataPtr
= DAG
.getNode(ISD::SELECT
, dl
, MVT::i64
, CC
, FPDataPtr
, DataPtr
);
559 SDValue NewOffset
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, Offset
,
560 DAG
.getConstant(8, MVT::i64
));
561 Chain
= DAG
.getTruncStore(Offset
.getValue(1), dl
, NewOffset
, Tmp
,
562 MachinePointerInfo(),
563 MVT::i32
, false, false, 0);
566 /// LowerOperation - Provide custom lowering hooks for some operations.
568 SDValue
AlphaTargetLowering::LowerOperation(SDValue Op
,
569 SelectionDAG
&DAG
) const {
570 DebugLoc dl
= Op
.getDebugLoc();
571 switch (Op
.getOpcode()) {
572 default: llvm_unreachable("Wasn't expecting to be able to lower this!");
573 case ISD::JumpTable
: return LowerJumpTable(Op
, DAG
);
575 case ISD::INTRINSIC_WO_CHAIN
: {
576 unsigned IntNo
= cast
<ConstantSDNode
>(Op
.getOperand(0))->getZExtValue();
578 default: break; // Don't custom lower most intrinsics.
579 case Intrinsic::alpha_umulh
:
580 return DAG
.getNode(ISD::MULHU
, dl
, MVT::i64
,
581 Op
.getOperand(1), Op
.getOperand(2));
585 case ISD::SRL_PARTS
: {
586 SDValue ShOpLo
= Op
.getOperand(0);
587 SDValue ShOpHi
= Op
.getOperand(1);
588 SDValue ShAmt
= Op
.getOperand(2);
589 SDValue bm
= DAG
.getNode(ISD::SUB
, dl
, MVT::i64
,
590 DAG
.getConstant(64, MVT::i64
), ShAmt
);
591 SDValue BMCC
= DAG
.getSetCC(dl
, MVT::i64
, bm
,
592 DAG
.getConstant(0, MVT::i64
), ISD::SETLE
);
593 // if 64 - shAmt <= 0
594 SDValue Hi_Neg
= DAG
.getConstant(0, MVT::i64
);
595 SDValue ShAmt_Neg
= DAG
.getNode(ISD::SUB
, dl
, MVT::i64
,
596 DAG
.getConstant(0, MVT::i64
), bm
);
597 SDValue Lo_Neg
= DAG
.getNode(ISD::SRL
, dl
, MVT::i64
, ShOpHi
, ShAmt_Neg
);
599 SDValue carries
= DAG
.getNode(ISD::SHL
, dl
, MVT::i64
, ShOpHi
, bm
);
600 SDValue Hi_Pos
= DAG
.getNode(ISD::SRL
, dl
, MVT::i64
, ShOpHi
, ShAmt
);
601 SDValue Lo_Pos
= DAG
.getNode(ISD::SRL
, dl
, MVT::i64
, ShOpLo
, ShAmt
);
602 Lo_Pos
= DAG
.getNode(ISD::OR
, dl
, MVT::i64
, Lo_Pos
, carries
);
604 SDValue Hi
= DAG
.getNode(ISD::SELECT
, dl
, MVT::i64
, BMCC
, Hi_Neg
, Hi_Pos
);
605 SDValue Lo
= DAG
.getNode(ISD::SELECT
, dl
, MVT::i64
, BMCC
, Lo_Neg
, Lo_Pos
);
606 SDValue Ops
[2] = { Lo
, Hi
};
607 return DAG
.getMergeValues(Ops
, 2, dl
);
609 // case ISD::SRA_PARTS:
611 // case ISD::SHL_PARTS:
614 case ISD::SINT_TO_FP
: {
615 assert(Op
.getOperand(0).getValueType() == MVT::i64
&&
616 "Unhandled SINT_TO_FP type in custom expander!");
618 bool isDouble
= Op
.getValueType() == MVT::f64
;
619 LD
= DAG
.getNode(ISD::BIT_CONVERT
, dl
, MVT::f64
, Op
.getOperand(0));
620 SDValue FP
= DAG
.getNode(isDouble
?AlphaISD::CVTQT_
:AlphaISD::CVTQS_
, dl
,
621 isDouble
?MVT::f64
:MVT::f32
, LD
);
624 case ISD::FP_TO_SINT
: {
625 bool isDouble
= Op
.getOperand(0).getValueType() == MVT::f64
;
626 SDValue src
= Op
.getOperand(0);
628 if (!isDouble
) //Promote
629 src
= DAG
.getNode(ISD::FP_EXTEND
, dl
, MVT::f64
, src
);
631 src
= DAG
.getNode(AlphaISD::CVTTQ_
, dl
, MVT::f64
, src
);
633 return DAG
.getNode(ISD::BIT_CONVERT
, dl
, MVT::i64
, src
);
635 case ISD::ConstantPool
: {
636 ConstantPoolSDNode
*CP
= cast
<ConstantPoolSDNode
>(Op
);
637 const Constant
*C
= CP
->getConstVal();
638 SDValue CPI
= DAG
.getTargetConstantPool(C
, MVT::i64
, CP
->getAlignment());
639 // FIXME there isn't really any debug info here
641 SDValue Hi
= DAG
.getNode(AlphaISD::GPRelHi
, dl
, MVT::i64
, CPI
,
642 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
643 SDValue Lo
= DAG
.getNode(AlphaISD::GPRelLo
, dl
, MVT::i64
, CPI
, Hi
);
646 case ISD::GlobalTLSAddress
:
647 llvm_unreachable("TLS not implemented for Alpha.");
648 case ISD::GlobalAddress
: {
649 GlobalAddressSDNode
*GSDN
= cast
<GlobalAddressSDNode
>(Op
);
650 const GlobalValue
*GV
= GSDN
->getGlobal();
651 SDValue GA
= DAG
.getTargetGlobalAddress(GV
, dl
, MVT::i64
,
653 // FIXME there isn't really any debug info here
655 // if (!GV->hasWeakLinkage() && !GV->isDeclaration()
656 // && !GV->hasLinkOnceLinkage()) {
657 if (GV
->hasLocalLinkage()) {
658 SDValue Hi
= DAG
.getNode(AlphaISD::GPRelHi
, dl
, MVT::i64
, GA
,
659 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
660 SDValue Lo
= DAG
.getNode(AlphaISD::GPRelLo
, dl
, MVT::i64
, GA
, Hi
);
663 return DAG
.getNode(AlphaISD::RelLit
, dl
, MVT::i64
, GA
,
664 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
666 case ISD::ExternalSymbol
: {
667 return DAG
.getNode(AlphaISD::RelLit
, dl
, MVT::i64
,
668 DAG
.getTargetExternalSymbol(cast
<ExternalSymbolSDNode
>(Op
)
669 ->getSymbol(), MVT::i64
),
670 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
675 //Expand only on constant case
676 if (Op
.getOperand(1).getOpcode() == ISD::Constant
) {
677 EVT VT
= Op
.getNode()->getValueType(0);
678 SDValue Tmp1
= Op
.getNode()->getOpcode() == ISD::UREM
?
679 BuildUDIV(Op
.getNode(), DAG
, NULL
) :
680 BuildSDIV(Op
.getNode(), DAG
, NULL
);
681 Tmp1
= DAG
.getNode(ISD::MUL
, dl
, VT
, Tmp1
, Op
.getOperand(1));
682 Tmp1
= DAG
.getNode(ISD::SUB
, dl
, VT
, Op
.getOperand(0), Tmp1
);
688 if (Op
.getValueType().isInteger()) {
689 if (Op
.getOperand(1).getOpcode() == ISD::Constant
)
690 return Op
.getOpcode() == ISD::SDIV
? BuildSDIV(Op
.getNode(), DAG
, NULL
)
691 : BuildUDIV(Op
.getNode(), DAG
, NULL
);
692 const char* opstr
= 0;
693 switch (Op
.getOpcode()) {
694 case ISD::UREM
: opstr
= "__remqu"; break;
695 case ISD::SREM
: opstr
= "__remq"; break;
696 case ISD::UDIV
: opstr
= "__divqu"; break;
697 case ISD::SDIV
: opstr
= "__divq"; break;
699 SDValue Tmp1
= Op
.getOperand(0),
700 Tmp2
= Op
.getOperand(1),
701 Addr
= DAG
.getExternalSymbol(opstr
, MVT::i64
);
702 return DAG
.getNode(AlphaISD::DivCall
, dl
, MVT::i64
, Addr
, Tmp1
, Tmp2
);
707 SDValue Chain
, DataPtr
;
708 LowerVAARG(Op
.getNode(), Chain
, DataPtr
, DAG
);
711 if (Op
.getValueType() == MVT::i32
)
712 Result
= DAG
.getExtLoad(ISD::SEXTLOAD
, MVT::i64
, dl
, Chain
, DataPtr
,
713 MachinePointerInfo(), MVT::i32
, false, false, 0);
715 Result
= DAG
.getLoad(Op
.getValueType(), dl
, Chain
, DataPtr
,
716 MachinePointerInfo(),
721 SDValue Chain
= Op
.getOperand(0);
722 SDValue DestP
= Op
.getOperand(1);
723 SDValue SrcP
= Op
.getOperand(2);
724 const Value
*DestS
= cast
<SrcValueSDNode
>(Op
.getOperand(3))->getValue();
725 const Value
*SrcS
= cast
<SrcValueSDNode
>(Op
.getOperand(4))->getValue();
727 SDValue Val
= DAG
.getLoad(getPointerTy(), dl
, Chain
, SrcP
,
728 MachinePointerInfo(SrcS
),
730 SDValue Result
= DAG
.getStore(Val
.getValue(1), dl
, Val
, DestP
,
731 MachinePointerInfo(DestS
),
733 SDValue NP
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, SrcP
,
734 DAG
.getConstant(8, MVT::i64
));
735 Val
= DAG
.getExtLoad(ISD::SEXTLOAD
, MVT::i64
, dl
, Result
,
736 NP
, MachinePointerInfo(), MVT::i32
, false, false, 0);
737 SDValue NPD
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, DestP
,
738 DAG
.getConstant(8, MVT::i64
));
739 return DAG
.getTruncStore(Val
.getValue(1), dl
, Val
, NPD
,
740 MachinePointerInfo(), MVT::i32
,
744 MachineFunction
&MF
= DAG
.getMachineFunction();
745 AlphaMachineFunctionInfo
*FuncInfo
= MF
.getInfo
<AlphaMachineFunctionInfo
>();
747 SDValue Chain
= Op
.getOperand(0);
748 SDValue VAListP
= Op
.getOperand(1);
749 const Value
*VAListS
= cast
<SrcValueSDNode
>(Op
.getOperand(2))->getValue();
751 // vastart stores the address of the VarArgsBase and VarArgsOffset
752 SDValue FR
= DAG
.getFrameIndex(FuncInfo
->getVarArgsBase(), MVT::i64
);
753 SDValue S1
= DAG
.getStore(Chain
, dl
, FR
, VAListP
,
754 MachinePointerInfo(VAListS
), false, false, 0);
755 SDValue SA2
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, VAListP
,
756 DAG
.getConstant(8, MVT::i64
));
757 return DAG
.getTruncStore(S1
, dl
,
758 DAG
.getConstant(FuncInfo
->getVarArgsOffset(),
760 SA2
, MachinePointerInfo(),
761 MVT::i32
, false, false, 0);
763 case ISD::RETURNADDR
:
764 return DAG
.getNode(AlphaISD::GlobalRetAddr
, DebugLoc(), MVT::i64
);
766 case ISD::FRAMEADDR
: break;
772 void AlphaTargetLowering::ReplaceNodeResults(SDNode
*N
,
773 SmallVectorImpl
<SDValue
>&Results
,
774 SelectionDAG
&DAG
) const {
775 DebugLoc dl
= N
->getDebugLoc();
776 assert(N
->getValueType(0) == MVT::i32
&&
777 N
->getOpcode() == ISD::VAARG
&&
778 "Unknown node to custom promote!");
780 SDValue Chain
, DataPtr
;
781 LowerVAARG(N
, Chain
, DataPtr
, DAG
);
782 SDValue Res
= DAG
.getLoad(N
->getValueType(0), dl
, Chain
, DataPtr
,
783 MachinePointerInfo(),
785 Results
.push_back(Res
);
786 Results
.push_back(SDValue(Res
.getNode(), 1));
792 /// getConstraintType - Given a constraint letter, return the type of
793 /// constraint it is for this target.
794 AlphaTargetLowering::ConstraintType
795 AlphaTargetLowering::getConstraintType(const std::string
&Constraint
) const {
796 if (Constraint
.size() == 1) {
797 switch (Constraint
[0]) {
801 return C_RegisterClass
;
804 return TargetLowering::getConstraintType(Constraint
);
807 /// Examine constraint type and operand type and determine a weight value.
808 /// This object must already have been set up with the operand type
809 /// and the current alternative constraint selected.
810 TargetLowering::ConstraintWeight
811 AlphaTargetLowering::getSingleConstraintMatchWeight(
812 AsmOperandInfo
&info
, const char *constraint
) const {
813 ConstraintWeight weight
= CW_Invalid
;
814 Value
*CallOperandVal
= info
.CallOperandVal
;
815 // If we don't have a value, we can't do a match,
816 // but allow it at the lowest weight.
817 if (CallOperandVal
== NULL
)
819 // Look at the constraint type.
820 switch (*constraint
) {
822 weight
= TargetLowering::getSingleConstraintMatchWeight(info
, constraint
);
825 weight
= CW_Register
;
831 std::vector
<unsigned> AlphaTargetLowering::
832 getRegClassForInlineAsmConstraint(const std::string
&Constraint
,
834 if (Constraint
.size() == 1) {
835 switch (Constraint
[0]) {
836 default: break; // Unknown constriant letter
838 return make_vector
<unsigned>(Alpha::F0
, Alpha::F1
, Alpha::F2
,
839 Alpha::F3
, Alpha::F4
, Alpha::F5
,
840 Alpha::F6
, Alpha::F7
, Alpha::F8
,
841 Alpha::F9
, Alpha::F10
, Alpha::F11
,
842 Alpha::F12
, Alpha::F13
, Alpha::F14
,
843 Alpha::F15
, Alpha::F16
, Alpha::F17
,
844 Alpha::F18
, Alpha::F19
, Alpha::F20
,
845 Alpha::F21
, Alpha::F22
, Alpha::F23
,
846 Alpha::F24
, Alpha::F25
, Alpha::F26
,
847 Alpha::F27
, Alpha::F28
, Alpha::F29
,
848 Alpha::F30
, Alpha::F31
, 0);
850 return make_vector
<unsigned>(Alpha::R0
, Alpha::R1
, Alpha::R2
,
851 Alpha::R3
, Alpha::R4
, Alpha::R5
,
852 Alpha::R6
, Alpha::R7
, Alpha::R8
,
853 Alpha::R9
, Alpha::R10
, Alpha::R11
,
854 Alpha::R12
, Alpha::R13
, Alpha::R14
,
855 Alpha::R15
, Alpha::R16
, Alpha::R17
,
856 Alpha::R18
, Alpha::R19
, Alpha::R20
,
857 Alpha::R21
, Alpha::R22
, Alpha::R23
,
858 Alpha::R24
, Alpha::R25
, Alpha::R26
,
859 Alpha::R27
, Alpha::R28
, Alpha::R29
,
860 Alpha::R30
, Alpha::R31
, 0);
864 return std::vector
<unsigned>();
866 //===----------------------------------------------------------------------===//
867 // Other Lowering Code
868 //===----------------------------------------------------------------------===//
871 AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr
*MI
,
872 MachineBasicBlock
*BB
) const {
873 const TargetInstrInfo
*TII
= getTargetMachine().getInstrInfo();
874 assert((MI
->getOpcode() == Alpha::CAS32
||
875 MI
->getOpcode() == Alpha::CAS64
||
876 MI
->getOpcode() == Alpha::LAS32
||
877 MI
->getOpcode() == Alpha::LAS64
||
878 MI
->getOpcode() == Alpha::SWAP32
||
879 MI
->getOpcode() == Alpha::SWAP64
) &&
880 "Unexpected instr type to insert");
882 bool is32
= MI
->getOpcode() == Alpha::CAS32
||
883 MI
->getOpcode() == Alpha::LAS32
||
884 MI
->getOpcode() == Alpha::SWAP32
;
886 //Load locked store conditional for atomic ops take on the same form
889 //do stuff (maybe branch to exit)
891 //test sc and maybe branck to start
893 const BasicBlock
*LLVM_BB
= BB
->getBasicBlock();
894 DebugLoc dl
= MI
->getDebugLoc();
895 MachineFunction::iterator It
= BB
;
898 MachineBasicBlock
*thisMBB
= BB
;
899 MachineFunction
*F
= BB
->getParent();
900 MachineBasicBlock
*llscMBB
= F
->CreateMachineBasicBlock(LLVM_BB
);
901 MachineBasicBlock
*sinkMBB
= F
->CreateMachineBasicBlock(LLVM_BB
);
903 sinkMBB
->splice(sinkMBB
->begin(), thisMBB
,
904 llvm::next(MachineBasicBlock::iterator(MI
)),
906 sinkMBB
->transferSuccessorsAndUpdatePHIs(thisMBB
);
908 F
->insert(It
, llscMBB
);
909 F
->insert(It
, sinkMBB
);
911 BuildMI(thisMBB
, dl
, TII
->get(Alpha::BR
)).addMBB(llscMBB
);
913 unsigned reg_res
= MI
->getOperand(0).getReg(),
914 reg_ptr
= MI
->getOperand(1).getReg(),
915 reg_v2
= MI
->getOperand(2).getReg(),
916 reg_store
= F
->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass
);
918 BuildMI(llscMBB
, dl
, TII
->get(is32
? Alpha::LDL_L
: Alpha::LDQ_L
),
919 reg_res
).addImm(0).addReg(reg_ptr
);
920 switch (MI
->getOpcode()) {
924 = F
->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass
);
925 BuildMI(llscMBB
, dl
, TII
->get(Alpha::CMPEQ
), reg_cmp
)
926 .addReg(reg_v2
).addReg(reg_res
);
927 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BEQ
))
928 .addImm(0).addReg(reg_cmp
).addMBB(sinkMBB
);
929 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BISr
), reg_store
)
930 .addReg(Alpha::R31
).addReg(MI
->getOperand(3).getReg());
935 BuildMI(llscMBB
, dl
,TII
->get(is32
? Alpha::ADDLr
: Alpha::ADDQr
), reg_store
)
936 .addReg(reg_res
).addReg(reg_v2
);
940 case Alpha::SWAP64
: {
941 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BISr
), reg_store
)
942 .addReg(reg_v2
).addReg(reg_v2
);
946 BuildMI(llscMBB
, dl
, TII
->get(is32
? Alpha::STL_C
: Alpha::STQ_C
), reg_store
)
947 .addReg(reg_store
).addImm(0).addReg(reg_ptr
);
948 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BEQ
))
949 .addImm(0).addReg(reg_store
).addMBB(llscMBB
);
950 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BR
)).addMBB(sinkMBB
);
952 thisMBB
->addSuccessor(llscMBB
);
953 llscMBB
->addSuccessor(llscMBB
);
954 llscMBB
->addSuccessor(sinkMBB
);
955 MI
->eraseFromParent(); // The pseudo instruction is gone now.
961 AlphaTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode
*GA
) const {
962 // The Alpha target isn't yet aware of offsets.
966 bool AlphaTargetLowering::isFPImmLegal(const APFloat
&Imm
, EVT VT
) const {
967 if (VT
!= MVT::f32
&& VT
!= MVT::f64
)
973 return Imm
.isZero() || Imm
.isNegZero();