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 setBooleanContents(ZeroOrOneBooleanContent
);
53 addRegisterClass(MVT::i64
, Alpha::GPRCRegisterClass
);
54 addRegisterClass(MVT::f64
, Alpha::F8RCRegisterClass
);
55 addRegisterClass(MVT::f32
, Alpha::F4RCRegisterClass
);
57 // We want to custom lower some of our intrinsics.
58 setOperationAction(ISD::INTRINSIC_WO_CHAIN
, MVT::Other
, Custom
);
60 setLoadExtAction(ISD::EXTLOAD
, MVT::i1
, Promote
);
61 setLoadExtAction(ISD::EXTLOAD
, MVT::f32
, Expand
);
63 setLoadExtAction(ISD::ZEXTLOAD
, MVT::i1
, Promote
);
64 setLoadExtAction(ISD::ZEXTLOAD
, MVT::i32
, Expand
);
66 setLoadExtAction(ISD::SEXTLOAD
, MVT::i1
, Promote
);
67 setLoadExtAction(ISD::SEXTLOAD
, MVT::i8
, Expand
);
68 setLoadExtAction(ISD::SEXTLOAD
, MVT::i16
, Expand
);
70 setTruncStoreAction(MVT::f64
, MVT::f32
, Expand
);
72 // setOperationAction(ISD::BRIND, MVT::Other, Expand);
73 setOperationAction(ISD::BR_JT
, MVT::Other
, Expand
);
74 setOperationAction(ISD::BR_CC
, MVT::Other
, Expand
);
75 setOperationAction(ISD::SELECT_CC
, MVT::Other
, Expand
);
77 setOperationAction(ISD::SIGN_EXTEND_INREG
, MVT::i1
, Expand
);
79 setOperationAction(ISD::FREM
, MVT::f32
, Expand
);
80 setOperationAction(ISD::FREM
, MVT::f64
, Expand
);
82 setOperationAction(ISD::UINT_TO_FP
, MVT::i64
, Expand
);
83 setOperationAction(ISD::SINT_TO_FP
, MVT::i64
, Custom
);
84 setOperationAction(ISD::FP_TO_UINT
, MVT::i64
, Expand
);
85 setOperationAction(ISD::FP_TO_SINT
, MVT::i64
, Custom
);
87 if (!TM
.getSubtarget
<AlphaSubtarget
>().hasCT()) {
88 setOperationAction(ISD::CTPOP
, MVT::i64
, Expand
);
89 setOperationAction(ISD::CTTZ
, MVT::i64
, Expand
);
90 setOperationAction(ISD::CTLZ
, MVT::i64
, Expand
);
92 setOperationAction(ISD::BSWAP
, MVT::i64
, Expand
);
93 setOperationAction(ISD::ROTL
, MVT::i64
, Expand
);
94 setOperationAction(ISD::ROTR
, MVT::i64
, Expand
);
96 setOperationAction(ISD::SREM
, MVT::i64
, Custom
);
97 setOperationAction(ISD::UREM
, MVT::i64
, Custom
);
98 setOperationAction(ISD::SDIV
, MVT::i64
, Custom
);
99 setOperationAction(ISD::UDIV
, MVT::i64
, Custom
);
101 setOperationAction(ISD::ADDC
, MVT::i64
, Expand
);
102 setOperationAction(ISD::ADDE
, MVT::i64
, Expand
);
103 setOperationAction(ISD::SUBC
, MVT::i64
, Expand
);
104 setOperationAction(ISD::SUBE
, MVT::i64
, Expand
);
106 setOperationAction(ISD::UMUL_LOHI
, MVT::i64
, Expand
);
107 setOperationAction(ISD::SMUL_LOHI
, MVT::i64
, Expand
);
109 setOperationAction(ISD::SRL_PARTS
, MVT::i64
, Custom
);
110 setOperationAction(ISD::SRA_PARTS
, MVT::i64
, Expand
);
111 setOperationAction(ISD::SHL_PARTS
, MVT::i64
, Expand
);
113 // We don't support sin/cos/sqrt/pow
114 setOperationAction(ISD::FSIN
, MVT::f64
, Expand
);
115 setOperationAction(ISD::FCOS
, MVT::f64
, Expand
);
116 setOperationAction(ISD::FSIN
, MVT::f32
, Expand
);
117 setOperationAction(ISD::FCOS
, MVT::f32
, Expand
);
119 setOperationAction(ISD::FSQRT
, MVT::f64
, Expand
);
120 setOperationAction(ISD::FSQRT
, MVT::f32
, Expand
);
122 setOperationAction(ISD::FPOW
, MVT::f32
, Expand
);
123 setOperationAction(ISD::FPOW
, MVT::f64
, Expand
);
125 setOperationAction(ISD::FMA
, MVT::f64
, Expand
);
126 setOperationAction(ISD::FMA
, MVT::f32
, Expand
);
128 setOperationAction(ISD::SETCC
, MVT::f32
, Promote
);
130 setOperationAction(ISD::BITCAST
, MVT::f32
, Promote
);
132 setOperationAction(ISD::EH_LABEL
, MVT::Other
, Expand
);
134 // Not implemented yet.
135 setOperationAction(ISD::STACKSAVE
, MVT::Other
, Expand
);
136 setOperationAction(ISD::STACKRESTORE
, MVT::Other
, Expand
);
137 setOperationAction(ISD::DYNAMIC_STACKALLOC
, MVT::i64
, Expand
);
139 // We want to legalize GlobalAddress and ConstantPool and
140 // ExternalSymbols nodes into the appropriate instructions to
141 // materialize the address.
142 setOperationAction(ISD::GlobalAddress
, MVT::i64
, Custom
);
143 setOperationAction(ISD::ConstantPool
, MVT::i64
, Custom
);
144 setOperationAction(ISD::ExternalSymbol
, MVT::i64
, Custom
);
145 setOperationAction(ISD::GlobalTLSAddress
, MVT::i64
, Custom
);
147 setOperationAction(ISD::VASTART
, MVT::Other
, Custom
);
148 setOperationAction(ISD::VAEND
, MVT::Other
, Expand
);
149 setOperationAction(ISD::VACOPY
, MVT::Other
, Custom
);
150 setOperationAction(ISD::VAARG
, MVT::Other
, Custom
);
151 setOperationAction(ISD::VAARG
, MVT::i32
, Custom
);
153 setOperationAction(ISD::JumpTable
, MVT::i64
, Custom
);
154 setOperationAction(ISD::JumpTable
, MVT::i32
, Custom
);
156 setStackPointerRegisterToSaveRestore(Alpha::R30
);
159 setJumpBufAlignment(16);
161 setMinFunctionAlignment(4);
163 computeRegisterProperties();
166 MVT::SimpleValueType
AlphaTargetLowering::getSetCCResultType(EVT VT
) const {
170 const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode
) const {
173 case AlphaISD::CVTQT_
: return "Alpha::CVTQT_";
174 case AlphaISD::CVTQS_
: return "Alpha::CVTQS_";
175 case AlphaISD::CVTTQ_
: return "Alpha::CVTTQ_";
176 case AlphaISD::GPRelHi
: return "Alpha::GPRelHi";
177 case AlphaISD::GPRelLo
: return "Alpha::GPRelLo";
178 case AlphaISD::RelLit
: return "Alpha::RelLit";
179 case AlphaISD::GlobalRetAddr
: return "Alpha::GlobalRetAddr";
180 case AlphaISD::CALL
: return "Alpha::CALL";
181 case AlphaISD::DivCall
: return "Alpha::DivCall";
182 case AlphaISD::RET_FLAG
: return "Alpha::RET_FLAG";
183 case AlphaISD::COND_BRANCH_I
: return "Alpha::COND_BRANCH_I";
184 case AlphaISD::COND_BRANCH_F
: return "Alpha::COND_BRANCH_F";
188 static SDValue
LowerJumpTable(SDValue Op
, SelectionDAG
&DAG
) {
189 EVT PtrVT
= Op
.getValueType();
190 JumpTableSDNode
*JT
= cast
<JumpTableSDNode
>(Op
);
191 SDValue JTI
= DAG
.getTargetJumpTable(JT
->getIndex(), PtrVT
);
192 // FIXME there isn't really any debug info here
193 DebugLoc dl
= Op
.getDebugLoc();
195 SDValue Hi
= DAG
.getNode(AlphaISD::GPRelHi
, dl
, MVT::i64
, JTI
,
196 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
197 SDValue Lo
= DAG
.getNode(AlphaISD::GPRelLo
, dl
, MVT::i64
, JTI
, Hi
);
201 //http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/
202 //AA-PY8AC-TET1_html/callCH3.html#BLOCK21
204 //For now, just use variable size stack frame format
206 //In a standard call, the first six items are passed in registers $16
207 //- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
208 //of argument-to-register correspondence.) The remaining items are
209 //collected in a memory argument list that is a naturally aligned
210 //array of quadwords. In a standard call, this list, if present, must
211 //be passed at 0(SP).
212 //7 ... n 0(SP) ... (n-7)*8(SP)
220 #include "AlphaGenCallingConv.inc"
223 AlphaTargetLowering::LowerCall(SDValue Chain
, SDValue Callee
,
224 CallingConv::ID CallConv
, bool isVarArg
,
226 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
227 const SmallVectorImpl
<SDValue
> &OutVals
,
228 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
229 DebugLoc dl
, SelectionDAG
&DAG
,
230 SmallVectorImpl
<SDValue
> &InVals
) const {
231 // Alpha target does not yet support tail call optimization.
234 // Analyze operands of the call, assigning locations to each operand.
235 SmallVector
<CCValAssign
, 16> ArgLocs
;
236 CCState
CCInfo(CallConv
, isVarArg
, DAG
.getMachineFunction(),
237 getTargetMachine(), ArgLocs
, *DAG
.getContext());
239 CCInfo
.AnalyzeCallOperands(Outs
, CC_Alpha
);
241 // Get a count of how many bytes are to be pushed on the stack.
242 unsigned NumBytes
= CCInfo
.getNextStackOffset();
244 Chain
= DAG
.getCALLSEQ_START(Chain
, DAG
.getConstant(NumBytes
,
245 getPointerTy(), true));
247 SmallVector
<std::pair
<unsigned, SDValue
>, 4> RegsToPass
;
248 SmallVector
<SDValue
, 12> MemOpChains
;
251 // Walk the register/memloc assignments, inserting copies/loads.
252 for (unsigned i
= 0, e
= ArgLocs
.size(); i
!= e
; ++i
) {
253 CCValAssign
&VA
= ArgLocs
[i
];
255 SDValue Arg
= OutVals
[i
];
257 // Promote the value if needed.
258 switch (VA
.getLocInfo()) {
259 default: assert(0 && "Unknown loc info!");
260 case CCValAssign::Full
: break;
261 case CCValAssign::SExt
:
262 Arg
= DAG
.getNode(ISD::SIGN_EXTEND
, dl
, VA
.getLocVT(), Arg
);
264 case CCValAssign::ZExt
:
265 Arg
= DAG
.getNode(ISD::ZERO_EXTEND
, dl
, VA
.getLocVT(), Arg
);
267 case CCValAssign::AExt
:
268 Arg
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, VA
.getLocVT(), Arg
);
272 // Arguments that can be passed on register must be kept at RegsToPass
275 RegsToPass
.push_back(std::make_pair(VA
.getLocReg(), Arg
));
277 assert(VA
.isMemLoc());
279 if (StackPtr
.getNode() == 0)
280 StackPtr
= DAG
.getCopyFromReg(Chain
, dl
, Alpha::R30
, MVT::i64
);
282 SDValue PtrOff
= DAG
.getNode(ISD::ADD
, dl
, getPointerTy(),
284 DAG
.getIntPtrConstant(VA
.getLocMemOffset()));
286 MemOpChains
.push_back(DAG
.getStore(Chain
, dl
, Arg
, PtrOff
,
287 MachinePointerInfo(),false, false, 0));
291 // Transform all store nodes into one single node because all store nodes are
292 // independent of each other.
293 if (!MemOpChains
.empty())
294 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
295 &MemOpChains
[0], MemOpChains
.size());
297 // Build a sequence of copy-to-reg nodes chained together with token chain and
298 // flag operands which copy the outgoing args into registers. The InFlag in
299 // necessary since all emitted instructions must be stuck together.
301 for (unsigned i
= 0, e
= RegsToPass
.size(); i
!= e
; ++i
) {
302 Chain
= DAG
.getCopyToReg(Chain
, dl
, RegsToPass
[i
].first
,
303 RegsToPass
[i
].second
, InFlag
);
304 InFlag
= Chain
.getValue(1);
307 // Returns a chain & a flag for retval copy to use.
308 SDVTList NodeTys
= DAG
.getVTList(MVT::Other
, MVT::Glue
);
309 SmallVector
<SDValue
, 8> Ops
;
310 Ops
.push_back(Chain
);
311 Ops
.push_back(Callee
);
313 // Add argument registers to the end of the list so that they are
314 // known live into the call.
315 for (unsigned i
= 0, e
= RegsToPass
.size(); i
!= e
; ++i
)
316 Ops
.push_back(DAG
.getRegister(RegsToPass
[i
].first
,
317 RegsToPass
[i
].second
.getValueType()));
319 if (InFlag
.getNode())
320 Ops
.push_back(InFlag
);
322 Chain
= DAG
.getNode(AlphaISD::CALL
, dl
, NodeTys
, &Ops
[0], Ops
.size());
323 InFlag
= Chain
.getValue(1);
325 // Create the CALLSEQ_END node.
326 Chain
= DAG
.getCALLSEQ_END(Chain
,
327 DAG
.getConstant(NumBytes
, getPointerTy(), true),
328 DAG
.getConstant(0, getPointerTy(), true),
330 InFlag
= Chain
.getValue(1);
332 // Handle result values, copying them out of physregs into vregs that we
334 return LowerCallResult(Chain
, InFlag
, CallConv
, isVarArg
,
335 Ins
, dl
, DAG
, InVals
);
338 /// LowerCallResult - Lower the result values of a call into the
339 /// appropriate copies out of appropriate physical registers.
342 AlphaTargetLowering::LowerCallResult(SDValue Chain
, SDValue InFlag
,
343 CallingConv::ID CallConv
, bool isVarArg
,
344 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
345 DebugLoc dl
, SelectionDAG
&DAG
,
346 SmallVectorImpl
<SDValue
> &InVals
) const {
348 // Assign locations to each value returned by this call.
349 SmallVector
<CCValAssign
, 16> RVLocs
;
350 CCState
CCInfo(CallConv
, isVarArg
, DAG
.getMachineFunction(),
351 getTargetMachine(), RVLocs
, *DAG
.getContext());
353 CCInfo
.AnalyzeCallResult(Ins
, RetCC_Alpha
);
355 // Copy all of the result registers out of their specified physreg.
356 for (unsigned i
= 0; i
!= RVLocs
.size(); ++i
) {
357 CCValAssign
&VA
= RVLocs
[i
];
359 Chain
= DAG
.getCopyFromReg(Chain
, dl
, VA
.getLocReg(),
360 VA
.getLocVT(), InFlag
).getValue(1);
361 SDValue RetValue
= Chain
.getValue(0);
362 InFlag
= Chain
.getValue(2);
364 // If this is an 8/16/32-bit value, it is really passed promoted to 64
365 // bits. Insert an assert[sz]ext to capture this, then truncate to the
367 if (VA
.getLocInfo() == CCValAssign::SExt
)
368 RetValue
= DAG
.getNode(ISD::AssertSext
, dl
, VA
.getLocVT(), RetValue
,
369 DAG
.getValueType(VA
.getValVT()));
370 else if (VA
.getLocInfo() == CCValAssign::ZExt
)
371 RetValue
= DAG
.getNode(ISD::AssertZext
, dl
, VA
.getLocVT(), RetValue
,
372 DAG
.getValueType(VA
.getValVT()));
374 if (VA
.getLocInfo() != CCValAssign::Full
)
375 RetValue
= DAG
.getNode(ISD::TRUNCATE
, dl
, VA
.getValVT(), RetValue
);
377 InVals
.push_back(RetValue
);
384 AlphaTargetLowering::LowerFormalArguments(SDValue Chain
,
385 CallingConv::ID CallConv
, bool isVarArg
,
386 const SmallVectorImpl
<ISD::InputArg
>
388 DebugLoc dl
, SelectionDAG
&DAG
,
389 SmallVectorImpl
<SDValue
> &InVals
)
392 MachineFunction
&MF
= DAG
.getMachineFunction();
393 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
394 AlphaMachineFunctionInfo
*FuncInfo
= MF
.getInfo
<AlphaMachineFunctionInfo
>();
396 unsigned args_int
[] = {
397 Alpha::R16
, Alpha::R17
, Alpha::R18
, Alpha::R19
, Alpha::R20
, Alpha::R21
};
398 unsigned args_float
[] = {
399 Alpha::F16
, Alpha::F17
, Alpha::F18
, Alpha::F19
, Alpha::F20
, Alpha::F21
};
401 for (unsigned ArgNo
= 0, e
= Ins
.size(); ArgNo
!= e
; ++ArgNo
) {
403 EVT ObjectVT
= Ins
[ArgNo
].VT
;
407 switch (ObjectVT
.getSimpleVT().SimpleTy
) {
409 assert(false && "Invalid value type!");
411 args_float
[ArgNo
] = AddLiveIn(MF
, args_float
[ArgNo
],
412 &Alpha::F8RCRegClass
);
413 ArgVal
= DAG
.getCopyFromReg(Chain
, dl
, args_float
[ArgNo
], ObjectVT
);
416 args_float
[ArgNo
] = AddLiveIn(MF
, args_float
[ArgNo
],
417 &Alpha::F4RCRegClass
);
418 ArgVal
= DAG
.getCopyFromReg(Chain
, dl
, args_float
[ArgNo
], ObjectVT
);
421 args_int
[ArgNo
] = AddLiveIn(MF
, args_int
[ArgNo
],
422 &Alpha::GPRCRegClass
);
423 ArgVal
= DAG
.getCopyFromReg(Chain
, dl
, args_int
[ArgNo
], MVT::i64
);
427 // Create the frame index object for this incoming parameter...
428 int FI
= MFI
->CreateFixedObject(8, 8 * (ArgNo
- 6), true);
430 // Create the SelectionDAG nodes corresponding to a load
431 //from this parameter
432 SDValue FIN
= DAG
.getFrameIndex(FI
, MVT::i64
);
433 ArgVal
= DAG
.getLoad(ObjectVT
, dl
, Chain
, FIN
, MachinePointerInfo(),
436 InVals
.push_back(ArgVal
);
439 // If the functions takes variable number of arguments, copy all regs to stack
441 FuncInfo
->setVarArgsOffset(Ins
.size() * 8);
442 std::vector
<SDValue
> LS
;
443 for (int i
= 0; i
< 6; ++i
) {
444 if (TargetRegisterInfo::isPhysicalRegister(args_int
[i
]))
445 args_int
[i
] = AddLiveIn(MF
, args_int
[i
], &Alpha::GPRCRegClass
);
446 SDValue argt
= DAG
.getCopyFromReg(Chain
, dl
, args_int
[i
], MVT::i64
);
447 int FI
= MFI
->CreateFixedObject(8, -8 * (6 - i
), true);
448 if (i
== 0) FuncInfo
->setVarArgsBase(FI
);
449 SDValue SDFI
= DAG
.getFrameIndex(FI
, MVT::i64
);
450 LS
.push_back(DAG
.getStore(Chain
, dl
, argt
, SDFI
, MachinePointerInfo(),
453 if (TargetRegisterInfo::isPhysicalRegister(args_float
[i
]))
454 args_float
[i
] = AddLiveIn(MF
, args_float
[i
], &Alpha::F8RCRegClass
);
455 argt
= DAG
.getCopyFromReg(Chain
, dl
, args_float
[i
], MVT::f64
);
456 FI
= MFI
->CreateFixedObject(8, - 8 * (12 - i
), true);
457 SDFI
= DAG
.getFrameIndex(FI
, MVT::i64
);
458 LS
.push_back(DAG
.getStore(Chain
, dl
, argt
, SDFI
, MachinePointerInfo(),
462 //Set up a token factor with all the stack traffic
463 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, &LS
[0], LS
.size());
470 AlphaTargetLowering::LowerReturn(SDValue Chain
,
471 CallingConv::ID CallConv
, bool isVarArg
,
472 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
473 const SmallVectorImpl
<SDValue
> &OutVals
,
474 DebugLoc dl
, SelectionDAG
&DAG
) const {
476 SDValue Copy
= DAG
.getCopyToReg(Chain
, dl
, Alpha::R26
,
477 DAG
.getNode(AlphaISD::GlobalRetAddr
,
478 DebugLoc(), MVT::i64
),
480 switch (Outs
.size()) {
482 llvm_unreachable("Do not know how to return this many arguments!");
485 //return SDValue(); // ret void is legal
487 EVT ArgVT
= Outs
[0].VT
;
489 if (ArgVT
.isInteger())
492 assert(ArgVT
.isFloatingPoint());
495 Copy
= DAG
.getCopyToReg(Copy
, dl
, ArgReg
,
496 OutVals
[0], Copy
.getValue(1));
497 if (DAG
.getMachineFunction().getRegInfo().liveout_empty())
498 DAG
.getMachineFunction().getRegInfo().addLiveOut(ArgReg
);
502 EVT ArgVT
= Outs
[0].VT
;
503 unsigned ArgReg1
, ArgReg2
;
504 if (ArgVT
.isInteger()) {
508 assert(ArgVT
.isFloatingPoint());
512 Copy
= DAG
.getCopyToReg(Copy
, dl
, ArgReg1
,
513 OutVals
[0], Copy
.getValue(1));
514 if (std::find(DAG
.getMachineFunction().getRegInfo().liveout_begin(),
515 DAG
.getMachineFunction().getRegInfo().liveout_end(), ArgReg1
)
516 == DAG
.getMachineFunction().getRegInfo().liveout_end())
517 DAG
.getMachineFunction().getRegInfo().addLiveOut(ArgReg1
);
518 Copy
= DAG
.getCopyToReg(Copy
, dl
, ArgReg2
,
519 OutVals
[1], Copy
.getValue(1));
520 if (std::find(DAG
.getMachineFunction().getRegInfo().liveout_begin(),
521 DAG
.getMachineFunction().getRegInfo().liveout_end(), ArgReg2
)
522 == DAG
.getMachineFunction().getRegInfo().liveout_end())
523 DAG
.getMachineFunction().getRegInfo().addLiveOut(ArgReg2
);
527 return DAG
.getNode(AlphaISD::RET_FLAG
, dl
,
528 MVT::Other
, Copy
, Copy
.getValue(1));
531 void AlphaTargetLowering::LowerVAARG(SDNode
*N
, SDValue
&Chain
,
533 SelectionDAG
&DAG
) const {
534 Chain
= N
->getOperand(0);
535 SDValue VAListP
= N
->getOperand(1);
536 const Value
*VAListS
= cast
<SrcValueSDNode
>(N
->getOperand(2))->getValue();
537 DebugLoc dl
= N
->getDebugLoc();
539 SDValue Base
= DAG
.getLoad(MVT::i64
, dl
, Chain
, VAListP
,
540 MachinePointerInfo(VAListS
),
542 SDValue Tmp
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, VAListP
,
543 DAG
.getConstant(8, MVT::i64
));
544 SDValue Offset
= DAG
.getExtLoad(ISD::SEXTLOAD
, dl
, MVT::i64
, Base
.getValue(1),
545 Tmp
, MachinePointerInfo(),
546 MVT::i32
, false, false, 0);
547 DataPtr
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, Base
, Offset
);
548 if (N
->getValueType(0).isFloatingPoint())
550 //if fp && Offset < 6*8, then subtract 6*8 from DataPtr
551 SDValue FPDataPtr
= DAG
.getNode(ISD::SUB
, dl
, MVT::i64
, DataPtr
,
552 DAG
.getConstant(8*6, MVT::i64
));
553 SDValue CC
= DAG
.getSetCC(dl
, MVT::i64
, Offset
,
554 DAG
.getConstant(8*6, MVT::i64
), ISD::SETLT
);
555 DataPtr
= DAG
.getNode(ISD::SELECT
, dl
, MVT::i64
, CC
, FPDataPtr
, DataPtr
);
558 SDValue NewOffset
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, Offset
,
559 DAG
.getConstant(8, MVT::i64
));
560 Chain
= DAG
.getTruncStore(Offset
.getValue(1), dl
, NewOffset
, Tmp
,
561 MachinePointerInfo(),
562 MVT::i32
, false, false, 0);
565 /// LowerOperation - Provide custom lowering hooks for some operations.
567 SDValue
AlphaTargetLowering::LowerOperation(SDValue Op
,
568 SelectionDAG
&DAG
) const {
569 DebugLoc dl
= Op
.getDebugLoc();
570 switch (Op
.getOpcode()) {
571 default: llvm_unreachable("Wasn't expecting to be able to lower this!");
572 case ISD::JumpTable
: return LowerJumpTable(Op
, DAG
);
574 case ISD::INTRINSIC_WO_CHAIN
: {
575 unsigned IntNo
= cast
<ConstantSDNode
>(Op
.getOperand(0))->getZExtValue();
577 default: break; // Don't custom lower most intrinsics.
578 case Intrinsic::alpha_umulh
:
579 return DAG
.getNode(ISD::MULHU
, dl
, MVT::i64
,
580 Op
.getOperand(1), Op
.getOperand(2));
584 case ISD::SRL_PARTS
: {
585 SDValue ShOpLo
= Op
.getOperand(0);
586 SDValue ShOpHi
= Op
.getOperand(1);
587 SDValue ShAmt
= Op
.getOperand(2);
588 SDValue bm
= DAG
.getNode(ISD::SUB
, dl
, MVT::i64
,
589 DAG
.getConstant(64, MVT::i64
), ShAmt
);
590 SDValue BMCC
= DAG
.getSetCC(dl
, MVT::i64
, bm
,
591 DAG
.getConstant(0, MVT::i64
), ISD::SETLE
);
592 // if 64 - shAmt <= 0
593 SDValue Hi_Neg
= DAG
.getConstant(0, MVT::i64
);
594 SDValue ShAmt_Neg
= DAG
.getNode(ISD::SUB
, dl
, MVT::i64
,
595 DAG
.getConstant(0, MVT::i64
), bm
);
596 SDValue Lo_Neg
= DAG
.getNode(ISD::SRL
, dl
, MVT::i64
, ShOpHi
, ShAmt_Neg
);
598 SDValue carries
= DAG
.getNode(ISD::SHL
, dl
, MVT::i64
, ShOpHi
, bm
);
599 SDValue Hi_Pos
= DAG
.getNode(ISD::SRL
, dl
, MVT::i64
, ShOpHi
, ShAmt
);
600 SDValue Lo_Pos
= DAG
.getNode(ISD::SRL
, dl
, MVT::i64
, ShOpLo
, ShAmt
);
601 Lo_Pos
= DAG
.getNode(ISD::OR
, dl
, MVT::i64
, Lo_Pos
, carries
);
603 SDValue Hi
= DAG
.getNode(ISD::SELECT
, dl
, MVT::i64
, BMCC
, Hi_Neg
, Hi_Pos
);
604 SDValue Lo
= DAG
.getNode(ISD::SELECT
, dl
, MVT::i64
, BMCC
, Lo_Neg
, Lo_Pos
);
605 SDValue Ops
[2] = { Lo
, Hi
};
606 return DAG
.getMergeValues(Ops
, 2, dl
);
608 // case ISD::SRA_PARTS:
610 // case ISD::SHL_PARTS:
613 case ISD::SINT_TO_FP
: {
614 assert(Op
.getOperand(0).getValueType() == MVT::i64
&&
615 "Unhandled SINT_TO_FP type in custom expander!");
617 bool isDouble
= Op
.getValueType() == MVT::f64
;
618 LD
= DAG
.getNode(ISD::BITCAST
, dl
, MVT::f64
, Op
.getOperand(0));
619 SDValue FP
= DAG
.getNode(isDouble
?AlphaISD::CVTQT_
:AlphaISD::CVTQS_
, dl
,
620 isDouble
?MVT::f64
:MVT::f32
, LD
);
623 case ISD::FP_TO_SINT
: {
624 bool isDouble
= Op
.getOperand(0).getValueType() == MVT::f64
;
625 SDValue src
= Op
.getOperand(0);
627 if (!isDouble
) //Promote
628 src
= DAG
.getNode(ISD::FP_EXTEND
, dl
, MVT::f64
, src
);
630 src
= DAG
.getNode(AlphaISD::CVTTQ_
, dl
, MVT::f64
, src
);
632 return DAG
.getNode(ISD::BITCAST
, dl
, MVT::i64
, src
);
634 case ISD::ConstantPool
: {
635 ConstantPoolSDNode
*CP
= cast
<ConstantPoolSDNode
>(Op
);
636 const Constant
*C
= CP
->getConstVal();
637 SDValue CPI
= DAG
.getTargetConstantPool(C
, MVT::i64
, CP
->getAlignment());
638 // FIXME there isn't really any debug info here
640 SDValue Hi
= DAG
.getNode(AlphaISD::GPRelHi
, dl
, MVT::i64
, CPI
,
641 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
642 SDValue Lo
= DAG
.getNode(AlphaISD::GPRelLo
, dl
, MVT::i64
, CPI
, Hi
);
645 case ISD::GlobalTLSAddress
:
646 llvm_unreachable("TLS not implemented for Alpha.");
647 case ISD::GlobalAddress
: {
648 GlobalAddressSDNode
*GSDN
= cast
<GlobalAddressSDNode
>(Op
);
649 const GlobalValue
*GV
= GSDN
->getGlobal();
650 SDValue GA
= DAG
.getTargetGlobalAddress(GV
, dl
, MVT::i64
,
652 // FIXME there isn't really any debug info here
654 // if (!GV->hasWeakLinkage() && !GV->isDeclaration()
655 // && !GV->hasLinkOnceLinkage()) {
656 if (GV
->hasLocalLinkage()) {
657 SDValue Hi
= DAG
.getNode(AlphaISD::GPRelHi
, dl
, MVT::i64
, GA
,
658 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
659 SDValue Lo
= DAG
.getNode(AlphaISD::GPRelLo
, dl
, MVT::i64
, GA
, Hi
);
662 return DAG
.getNode(AlphaISD::RelLit
, dl
, MVT::i64
, GA
,
663 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
665 case ISD::ExternalSymbol
: {
666 return DAG
.getNode(AlphaISD::RelLit
, dl
, MVT::i64
,
667 DAG
.getTargetExternalSymbol(cast
<ExternalSymbolSDNode
>(Op
)
668 ->getSymbol(), MVT::i64
),
669 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
674 //Expand only on constant case
675 if (Op
.getOperand(1).getOpcode() == ISD::Constant
) {
676 EVT VT
= Op
.getNode()->getValueType(0);
677 SDValue Tmp1
= Op
.getNode()->getOpcode() == ISD::UREM
?
678 BuildUDIV(Op
.getNode(), DAG
, NULL
) :
679 BuildSDIV(Op
.getNode(), DAG
, NULL
);
680 Tmp1
= DAG
.getNode(ISD::MUL
, dl
, VT
, Tmp1
, Op
.getOperand(1));
681 Tmp1
= DAG
.getNode(ISD::SUB
, dl
, VT
, Op
.getOperand(0), Tmp1
);
687 if (Op
.getValueType().isInteger()) {
688 if (Op
.getOperand(1).getOpcode() == ISD::Constant
)
689 return Op
.getOpcode() == ISD::SDIV
? BuildSDIV(Op
.getNode(), DAG
, NULL
)
690 : BuildUDIV(Op
.getNode(), DAG
, NULL
);
691 const char* opstr
= 0;
692 switch (Op
.getOpcode()) {
693 case ISD::UREM
: opstr
= "__remqu"; break;
694 case ISD::SREM
: opstr
= "__remq"; break;
695 case ISD::UDIV
: opstr
= "__divqu"; break;
696 case ISD::SDIV
: opstr
= "__divq"; break;
698 SDValue Tmp1
= Op
.getOperand(0),
699 Tmp2
= Op
.getOperand(1),
700 Addr
= DAG
.getExternalSymbol(opstr
, MVT::i64
);
701 return DAG
.getNode(AlphaISD::DivCall
, dl
, MVT::i64
, Addr
, Tmp1
, Tmp2
);
706 SDValue Chain
, DataPtr
;
707 LowerVAARG(Op
.getNode(), Chain
, DataPtr
, DAG
);
710 if (Op
.getValueType() == MVT::i32
)
711 Result
= DAG
.getExtLoad(ISD::SEXTLOAD
, dl
, MVT::i64
, Chain
, DataPtr
,
712 MachinePointerInfo(), MVT::i32
, false, false, 0);
714 Result
= DAG
.getLoad(Op
.getValueType(), dl
, Chain
, DataPtr
,
715 MachinePointerInfo(),
720 SDValue Chain
= Op
.getOperand(0);
721 SDValue DestP
= Op
.getOperand(1);
722 SDValue SrcP
= Op
.getOperand(2);
723 const Value
*DestS
= cast
<SrcValueSDNode
>(Op
.getOperand(3))->getValue();
724 const Value
*SrcS
= cast
<SrcValueSDNode
>(Op
.getOperand(4))->getValue();
726 SDValue Val
= DAG
.getLoad(getPointerTy(), dl
, Chain
, SrcP
,
727 MachinePointerInfo(SrcS
),
729 SDValue Result
= DAG
.getStore(Val
.getValue(1), dl
, Val
, DestP
,
730 MachinePointerInfo(DestS
),
732 SDValue NP
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, SrcP
,
733 DAG
.getConstant(8, MVT::i64
));
734 Val
= DAG
.getExtLoad(ISD::SEXTLOAD
, dl
, MVT::i64
, Result
,
735 NP
, MachinePointerInfo(), MVT::i32
, false, false, 0);
736 SDValue NPD
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, DestP
,
737 DAG
.getConstant(8, MVT::i64
));
738 return DAG
.getTruncStore(Val
.getValue(1), dl
, Val
, NPD
,
739 MachinePointerInfo(), MVT::i32
,
743 MachineFunction
&MF
= DAG
.getMachineFunction();
744 AlphaMachineFunctionInfo
*FuncInfo
= MF
.getInfo
<AlphaMachineFunctionInfo
>();
746 SDValue Chain
= Op
.getOperand(0);
747 SDValue VAListP
= Op
.getOperand(1);
748 const Value
*VAListS
= cast
<SrcValueSDNode
>(Op
.getOperand(2))->getValue();
750 // vastart stores the address of the VarArgsBase and VarArgsOffset
751 SDValue FR
= DAG
.getFrameIndex(FuncInfo
->getVarArgsBase(), MVT::i64
);
752 SDValue S1
= DAG
.getStore(Chain
, dl
, FR
, VAListP
,
753 MachinePointerInfo(VAListS
), false, false, 0);
754 SDValue SA2
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, VAListP
,
755 DAG
.getConstant(8, MVT::i64
));
756 return DAG
.getTruncStore(S1
, dl
,
757 DAG
.getConstant(FuncInfo
->getVarArgsOffset(),
759 SA2
, MachinePointerInfo(),
760 MVT::i32
, false, false, 0);
762 case ISD::RETURNADDR
:
763 return DAG
.getNode(AlphaISD::GlobalRetAddr
, DebugLoc(), MVT::i64
);
765 case ISD::FRAMEADDR
: break;
771 void AlphaTargetLowering::ReplaceNodeResults(SDNode
*N
,
772 SmallVectorImpl
<SDValue
>&Results
,
773 SelectionDAG
&DAG
) const {
774 DebugLoc dl
= N
->getDebugLoc();
775 assert(N
->getValueType(0) == MVT::i32
&&
776 N
->getOpcode() == ISD::VAARG
&&
777 "Unknown node to custom promote!");
779 SDValue Chain
, DataPtr
;
780 LowerVAARG(N
, Chain
, DataPtr
, DAG
);
781 SDValue Res
= DAG
.getLoad(N
->getValueType(0), dl
, Chain
, DataPtr
,
782 MachinePointerInfo(),
784 Results
.push_back(Res
);
785 Results
.push_back(SDValue(Res
.getNode(), 1));
791 /// getConstraintType - Given a constraint letter, return the type of
792 /// constraint it is for this target.
793 AlphaTargetLowering::ConstraintType
794 AlphaTargetLowering::getConstraintType(const std::string
&Constraint
) const {
795 if (Constraint
.size() == 1) {
796 switch (Constraint
[0]) {
800 return C_RegisterClass
;
803 return TargetLowering::getConstraintType(Constraint
);
806 /// Examine constraint type and operand type and determine a weight value.
807 /// This object must already have been set up with the operand type
808 /// and the current alternative constraint selected.
809 TargetLowering::ConstraintWeight
810 AlphaTargetLowering::getSingleConstraintMatchWeight(
811 AsmOperandInfo
&info
, const char *constraint
) const {
812 ConstraintWeight weight
= CW_Invalid
;
813 Value
*CallOperandVal
= info
.CallOperandVal
;
814 // If we don't have a value, we can't do a match,
815 // but allow it at the lowest weight.
816 if (CallOperandVal
== NULL
)
818 // Look at the constraint type.
819 switch (*constraint
) {
821 weight
= TargetLowering::getSingleConstraintMatchWeight(info
, constraint
);
824 weight
= CW_Register
;
830 /// Given a register class constraint, like 'r', if this corresponds directly
831 /// to an LLVM register class, return a register of 0 and the register class
833 std::pair
<unsigned, const TargetRegisterClass
*> AlphaTargetLowering::
834 getRegForInlineAsmConstraint(const std::string
&Constraint
, EVT VT
) const
836 if (Constraint
.size() == 1) {
837 switch (Constraint
[0]) {
839 return std::make_pair(0U, Alpha::GPRCRegisterClass
);
841 return VT
== MVT::f64
? std::make_pair(0U, Alpha::F8RCRegisterClass
) :
842 std::make_pair(0U, Alpha::F4RCRegisterClass
);
845 return TargetLowering::getRegForInlineAsmConstraint(Constraint
, VT
);
848 //===----------------------------------------------------------------------===//
849 // Other Lowering Code
850 //===----------------------------------------------------------------------===//
853 AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr
*MI
,
854 MachineBasicBlock
*BB
) const {
855 const TargetInstrInfo
*TII
= getTargetMachine().getInstrInfo();
856 assert((MI
->getOpcode() == Alpha::CAS32
||
857 MI
->getOpcode() == Alpha::CAS64
||
858 MI
->getOpcode() == Alpha::LAS32
||
859 MI
->getOpcode() == Alpha::LAS64
||
860 MI
->getOpcode() == Alpha::SWAP32
||
861 MI
->getOpcode() == Alpha::SWAP64
) &&
862 "Unexpected instr type to insert");
864 bool is32
= MI
->getOpcode() == Alpha::CAS32
||
865 MI
->getOpcode() == Alpha::LAS32
||
866 MI
->getOpcode() == Alpha::SWAP32
;
868 //Load locked store conditional for atomic ops take on the same form
871 //do stuff (maybe branch to exit)
873 //test sc and maybe branck to start
875 const BasicBlock
*LLVM_BB
= BB
->getBasicBlock();
876 DebugLoc dl
= MI
->getDebugLoc();
877 MachineFunction::iterator It
= BB
;
880 MachineBasicBlock
*thisMBB
= BB
;
881 MachineFunction
*F
= BB
->getParent();
882 MachineBasicBlock
*llscMBB
= F
->CreateMachineBasicBlock(LLVM_BB
);
883 MachineBasicBlock
*sinkMBB
= F
->CreateMachineBasicBlock(LLVM_BB
);
885 sinkMBB
->splice(sinkMBB
->begin(), thisMBB
,
886 llvm::next(MachineBasicBlock::iterator(MI
)),
888 sinkMBB
->transferSuccessorsAndUpdatePHIs(thisMBB
);
890 F
->insert(It
, llscMBB
);
891 F
->insert(It
, sinkMBB
);
893 BuildMI(thisMBB
, dl
, TII
->get(Alpha::BR
)).addMBB(llscMBB
);
895 unsigned reg_res
= MI
->getOperand(0).getReg(),
896 reg_ptr
= MI
->getOperand(1).getReg(),
897 reg_v2
= MI
->getOperand(2).getReg(),
898 reg_store
= F
->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass
);
900 BuildMI(llscMBB
, dl
, TII
->get(is32
? Alpha::LDL_L
: Alpha::LDQ_L
),
901 reg_res
).addImm(0).addReg(reg_ptr
);
902 switch (MI
->getOpcode()) {
906 = F
->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass
);
907 BuildMI(llscMBB
, dl
, TII
->get(Alpha::CMPEQ
), reg_cmp
)
908 .addReg(reg_v2
).addReg(reg_res
);
909 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BEQ
))
910 .addImm(0).addReg(reg_cmp
).addMBB(sinkMBB
);
911 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BISr
), reg_store
)
912 .addReg(Alpha::R31
).addReg(MI
->getOperand(3).getReg());
917 BuildMI(llscMBB
, dl
,TII
->get(is32
? Alpha::ADDLr
: Alpha::ADDQr
), reg_store
)
918 .addReg(reg_res
).addReg(reg_v2
);
922 case Alpha::SWAP64
: {
923 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BISr
), reg_store
)
924 .addReg(reg_v2
).addReg(reg_v2
);
928 BuildMI(llscMBB
, dl
, TII
->get(is32
? Alpha::STL_C
: Alpha::STQ_C
), reg_store
)
929 .addReg(reg_store
).addImm(0).addReg(reg_ptr
);
930 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BEQ
))
931 .addImm(0).addReg(reg_store
).addMBB(llscMBB
);
932 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BR
)).addMBB(sinkMBB
);
934 thisMBB
->addSuccessor(llscMBB
);
935 llscMBB
->addSuccessor(llscMBB
);
936 llscMBB
->addSuccessor(sinkMBB
);
937 MI
->eraseFromParent(); // The pseudo instruction is gone now.
943 AlphaTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode
*GA
) const {
944 // The Alpha target isn't yet aware of offsets.
948 bool AlphaTargetLowering::isFPImmLegal(const APFloat
&Imm
, EVT VT
) const {
949 if (VT
!= MVT::f32
&& VT
!= MVT::f64
)
955 return Imm
.isZero() || Imm
.isNegZero();