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 "llvm/CodeGen/CallingConvLower.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/CodeGen/SelectionDAG.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/CodeGen/PseudoSourceValue.h"
24 #include "llvm/Target/TargetLoweringObjectFile.h"
25 #include "llvm/Constants.h"
26 #include "llvm/Function.h"
27 #include "llvm/Module.h"
28 #include "llvm/Intrinsics.h"
29 #include "llvm/Support/CommandLine.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/raw_ostream.h"
35 class TargetLoweringObjectFileAlpha
: public TargetLoweringObjectFile
{
37 void Initialize(MCContext
&Ctx
, const TargetMachine
&TM
) {
38 TargetLoweringObjectFile::Initialize(Ctx
, TM
);
39 TextSection
= getOrCreateSection("_text", true,
40 SectionKind::getText());
41 DataSection
= getOrCreateSection("_data", true,
42 SectionKind::getDataRel());
43 ReadOnlySection
= getOrCreateSection("_rodata", true,
44 SectionKind::getReadOnly());
51 /// AddLiveIn - This helper function adds the specified physical register to the
52 /// MachineFunction as a live in value. It also creates a corresponding virtual
54 static unsigned AddLiveIn(MachineFunction
&MF
, unsigned PReg
,
55 TargetRegisterClass
*RC
) {
56 assert(RC
->contains(PReg
) && "Not the correct regclass!");
57 unsigned VReg
= MF
.getRegInfo().createVirtualRegister(RC
);
58 MF
.getRegInfo().addLiveIn(PReg
, VReg
);
62 AlphaTargetLowering::AlphaTargetLowering(TargetMachine
&TM
)
63 : TargetLowering(TM
, new TargetLoweringObjectFileAlpha()) {
64 // Set up the TargetLowering object.
65 //I am having problems with shr n i8 1
66 setShiftAmountType(MVT::i64
);
67 setBooleanContents(ZeroOrOneBooleanContent
);
69 setUsesGlobalOffsetTable(true);
71 addRegisterClass(MVT::i64
, Alpha::GPRCRegisterClass
);
72 addRegisterClass(MVT::f64
, Alpha::F8RCRegisterClass
);
73 addRegisterClass(MVT::f32
, Alpha::F4RCRegisterClass
);
75 // We want to custom lower some of our intrinsics.
76 setOperationAction(ISD::INTRINSIC_WO_CHAIN
, MVT::Other
, Custom
);
78 setLoadExtAction(ISD::EXTLOAD
, MVT::i1
, Promote
);
79 setLoadExtAction(ISD::EXTLOAD
, MVT::f32
, Expand
);
81 setLoadExtAction(ISD::ZEXTLOAD
, MVT::i1
, Promote
);
82 setLoadExtAction(ISD::ZEXTLOAD
, MVT::i32
, Expand
);
84 setLoadExtAction(ISD::SEXTLOAD
, MVT::i1
, Promote
);
85 setLoadExtAction(ISD::SEXTLOAD
, MVT::i8
, Expand
);
86 setLoadExtAction(ISD::SEXTLOAD
, MVT::i16
, Expand
);
88 setTruncStoreAction(MVT::f64
, MVT::f32
, Expand
);
90 // setOperationAction(ISD::BRIND, MVT::Other, Expand);
91 setOperationAction(ISD::BR_JT
, MVT::Other
, Expand
);
92 setOperationAction(ISD::BR_CC
, MVT::Other
, Expand
);
93 setOperationAction(ISD::SELECT_CC
, MVT::Other
, Expand
);
95 setOperationAction(ISD::SIGN_EXTEND_INREG
, MVT::i1
, Expand
);
97 setOperationAction(ISD::FREM
, MVT::f32
, Expand
);
98 setOperationAction(ISD::FREM
, MVT::f64
, Expand
);
100 setOperationAction(ISD::UINT_TO_FP
, MVT::i64
, Expand
);
101 setOperationAction(ISD::SINT_TO_FP
, MVT::i64
, Custom
);
102 setOperationAction(ISD::FP_TO_UINT
, MVT::i64
, Expand
);
103 setOperationAction(ISD::FP_TO_SINT
, MVT::i64
, Custom
);
105 if (!TM
.getSubtarget
<AlphaSubtarget
>().hasCT()) {
106 setOperationAction(ISD::CTPOP
, MVT::i64
, Expand
);
107 setOperationAction(ISD::CTTZ
, MVT::i64
, Expand
);
108 setOperationAction(ISD::CTLZ
, MVT::i64
, Expand
);
110 setOperationAction(ISD::BSWAP
, MVT::i64
, Expand
);
111 setOperationAction(ISD::ROTL
, MVT::i64
, Expand
);
112 setOperationAction(ISD::ROTR
, MVT::i64
, Expand
);
114 setOperationAction(ISD::SREM
, MVT::i64
, Custom
);
115 setOperationAction(ISD::UREM
, MVT::i64
, Custom
);
116 setOperationAction(ISD::SDIV
, MVT::i64
, Custom
);
117 setOperationAction(ISD::UDIV
, MVT::i64
, Custom
);
119 setOperationAction(ISD::ADDC
, MVT::i64
, Expand
);
120 setOperationAction(ISD::ADDE
, MVT::i64
, Expand
);
121 setOperationAction(ISD::SUBC
, MVT::i64
, Expand
);
122 setOperationAction(ISD::SUBE
, MVT::i64
, Expand
);
124 setOperationAction(ISD::UMUL_LOHI
, MVT::i64
, Expand
);
125 setOperationAction(ISD::SMUL_LOHI
, MVT::i64
, Expand
);
128 // We don't support sin/cos/sqrt/pow
129 setOperationAction(ISD::FSIN
, MVT::f64
, Expand
);
130 setOperationAction(ISD::FCOS
, MVT::f64
, Expand
);
131 setOperationAction(ISD::FSIN
, MVT::f32
, Expand
);
132 setOperationAction(ISD::FCOS
, MVT::f32
, Expand
);
134 setOperationAction(ISD::FSQRT
, MVT::f64
, Expand
);
135 setOperationAction(ISD::FSQRT
, MVT::f32
, Expand
);
137 setOperationAction(ISD::FPOW
, MVT::f32
, Expand
);
138 setOperationAction(ISD::FPOW
, MVT::f64
, Expand
);
140 setOperationAction(ISD::SETCC
, MVT::f32
, Promote
);
142 setOperationAction(ISD::BIT_CONVERT
, MVT::f32
, Promote
);
144 // We don't have line number support yet.
145 setOperationAction(ISD::DBG_STOPPOINT
, MVT::Other
, Expand
);
146 setOperationAction(ISD::DEBUG_LOC
, MVT::Other
, Expand
);
147 setOperationAction(ISD::DBG_LABEL
, MVT::Other
, Expand
);
148 setOperationAction(ISD::EH_LABEL
, MVT::Other
, Expand
);
150 // Not implemented yet.
151 setOperationAction(ISD::STACKSAVE
, MVT::Other
, Expand
);
152 setOperationAction(ISD::STACKRESTORE
, MVT::Other
, Expand
);
153 setOperationAction(ISD::DYNAMIC_STACKALLOC
, MVT::i64
, Expand
);
155 // We want to legalize GlobalAddress and ConstantPool and
156 // ExternalSymbols nodes into the appropriate instructions to
157 // materialize the address.
158 setOperationAction(ISD::GlobalAddress
, MVT::i64
, Custom
);
159 setOperationAction(ISD::ConstantPool
, MVT::i64
, Custom
);
160 setOperationAction(ISD::ExternalSymbol
, MVT::i64
, Custom
);
161 setOperationAction(ISD::GlobalTLSAddress
, MVT::i64
, Custom
);
163 setOperationAction(ISD::VASTART
, MVT::Other
, Custom
);
164 setOperationAction(ISD::VAEND
, MVT::Other
, Expand
);
165 setOperationAction(ISD::VACOPY
, MVT::Other
, Custom
);
166 setOperationAction(ISD::VAARG
, MVT::Other
, Custom
);
167 setOperationAction(ISD::VAARG
, MVT::i32
, Custom
);
169 setOperationAction(ISD::RET
, MVT::Other
, Custom
);
171 setOperationAction(ISD::JumpTable
, MVT::i64
, Custom
);
172 setOperationAction(ISD::JumpTable
, MVT::i32
, Custom
);
174 setStackPointerRegisterToSaveRestore(Alpha::R30
);
176 addLegalFPImmediate(APFloat(+0.0)); //F31
177 addLegalFPImmediate(APFloat(+0.0f
)); //F31
178 addLegalFPImmediate(APFloat(-0.0)); //-F31
179 addLegalFPImmediate(APFloat(-0.0f
)); //-F31
182 setJumpBufAlignment(16);
184 computeRegisterProperties();
187 MVT
AlphaTargetLowering::getSetCCResultType(MVT VT
) const {
191 const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode
) const {
194 case AlphaISD::CVTQT_
: return "Alpha::CVTQT_";
195 case AlphaISD::CVTQS_
: return "Alpha::CVTQS_";
196 case AlphaISD::CVTTQ_
: return "Alpha::CVTTQ_";
197 case AlphaISD::GPRelHi
: return "Alpha::GPRelHi";
198 case AlphaISD::GPRelLo
: return "Alpha::GPRelLo";
199 case AlphaISD::RelLit
: return "Alpha::RelLit";
200 case AlphaISD::GlobalRetAddr
: return "Alpha::GlobalRetAddr";
201 case AlphaISD::CALL
: return "Alpha::CALL";
202 case AlphaISD::DivCall
: return "Alpha::DivCall";
203 case AlphaISD::RET_FLAG
: return "Alpha::RET_FLAG";
204 case AlphaISD::COND_BRANCH_I
: return "Alpha::COND_BRANCH_I";
205 case AlphaISD::COND_BRANCH_F
: return "Alpha::COND_BRANCH_F";
209 /// getFunctionAlignment - Return the Log2 alignment of this function.
210 unsigned AlphaTargetLowering::getFunctionAlignment(const Function
*F
) const {
214 static SDValue
LowerJumpTable(SDValue Op
, SelectionDAG
&DAG
) {
215 MVT PtrVT
= Op
.getValueType();
216 JumpTableSDNode
*JT
= cast
<JumpTableSDNode
>(Op
);
217 SDValue JTI
= DAG
.getTargetJumpTable(JT
->getIndex(), PtrVT
);
218 SDValue Zero
= DAG
.getConstant(0, PtrVT
);
219 // FIXME there isn't really any debug info here
220 DebugLoc dl
= Op
.getDebugLoc();
222 SDValue Hi
= DAG
.getNode(AlphaISD::GPRelHi
, dl
, MVT::i64
, JTI
,
223 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
224 SDValue Lo
= DAG
.getNode(AlphaISD::GPRelLo
, dl
, MVT::i64
, JTI
, Hi
);
228 //http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/
229 //AA-PY8AC-TET1_html/callCH3.html#BLOCK21
231 //For now, just use variable size stack frame format
233 //In a standard call, the first six items are passed in registers $16
234 //- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
235 //of argument-to-register correspondence.) The remaining items are
236 //collected in a memory argument list that is a naturally aligned
237 //array of quadwords. In a standard call, this list, if present, must
238 //be passed at 0(SP).
239 //7 ... n 0(SP) ... (n-7)*8(SP)
247 #include "AlphaGenCallingConv.inc"
249 SDValue
AlphaTargetLowering::LowerCALL(SDValue Op
, SelectionDAG
&DAG
) {
250 CallSDNode
*TheCall
= cast
<CallSDNode
>(Op
.getNode());
251 SDValue Chain
= TheCall
->getChain();
252 SDValue Callee
= TheCall
->getCallee();
253 bool isVarArg
= TheCall
->isVarArg();
254 DebugLoc dl
= Op
.getDebugLoc();
255 MachineFunction
&MF
= DAG
.getMachineFunction();
256 unsigned CC
= MF
.getFunction()->getCallingConv();
258 // Analyze operands of the call, assigning locations to each operand.
259 SmallVector
<CCValAssign
, 16> ArgLocs
;
260 CCState
CCInfo(CC
, isVarArg
, getTargetMachine(), ArgLocs
, *DAG
.getContext());
262 CCInfo
.AnalyzeCallOperands(TheCall
, CC_Alpha
);
264 // Get a count of how many bytes are to be pushed on the stack.
265 unsigned NumBytes
= CCInfo
.getNextStackOffset();
267 Chain
= DAG
.getCALLSEQ_START(Chain
, DAG
.getConstant(NumBytes
,
268 getPointerTy(), true));
270 SmallVector
<std::pair
<unsigned, SDValue
>, 4> RegsToPass
;
271 SmallVector
<SDValue
, 12> MemOpChains
;
274 // Walk the register/memloc assignments, inserting copies/loads.
275 for (unsigned i
= 0, e
= ArgLocs
.size(); i
!= e
; ++i
) {
276 CCValAssign
&VA
= ArgLocs
[i
];
278 // Arguments start after the 5 first operands of ISD::CALL
279 SDValue Arg
= TheCall
->getArg(i
);
281 // Promote the value if needed.
282 switch (VA
.getLocInfo()) {
283 default: assert(0 && "Unknown loc info!");
284 case CCValAssign::Full
: break;
285 case CCValAssign::SExt
:
286 Arg
= DAG
.getNode(ISD::SIGN_EXTEND
, dl
, VA
.getLocVT(), Arg
);
288 case CCValAssign::ZExt
:
289 Arg
= DAG
.getNode(ISD::ZERO_EXTEND
, dl
, VA
.getLocVT(), Arg
);
291 case CCValAssign::AExt
:
292 Arg
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, VA
.getLocVT(), Arg
);
296 // Arguments that can be passed on register must be kept at RegsToPass
299 RegsToPass
.push_back(std::make_pair(VA
.getLocReg(), Arg
));
301 assert(VA
.isMemLoc());
303 if (StackPtr
.getNode() == 0)
304 StackPtr
= DAG
.getCopyFromReg(Chain
, dl
, Alpha::R30
, MVT::i64
);
306 SDValue PtrOff
= DAG
.getNode(ISD::ADD
, dl
, getPointerTy(),
308 DAG
.getIntPtrConstant(VA
.getLocMemOffset()));
310 MemOpChains
.push_back(DAG
.getStore(Chain
, dl
, Arg
, PtrOff
,
311 PseudoSourceValue::getStack(), 0));
315 // Transform all store nodes into one single node because all store nodes are
316 // independent of each other.
317 if (!MemOpChains
.empty())
318 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
319 &MemOpChains
[0], MemOpChains
.size());
321 // Build a sequence of copy-to-reg nodes chained together with token chain and
322 // flag operands which copy the outgoing args into registers. The InFlag in
323 // necessary since all emited instructions must be stuck together.
325 for (unsigned i
= 0, e
= RegsToPass
.size(); i
!= e
; ++i
) {
326 Chain
= DAG
.getCopyToReg(Chain
, dl
, RegsToPass
[i
].first
,
327 RegsToPass
[i
].second
, InFlag
);
328 InFlag
= Chain
.getValue(1);
331 // Returns a chain & a flag for retval copy to use.
332 SDVTList NodeTys
= DAG
.getVTList(MVT::Other
, MVT::Flag
);
333 SmallVector
<SDValue
, 8> Ops
;
334 Ops
.push_back(Chain
);
335 Ops
.push_back(Callee
);
337 // Add argument registers to the end of the list so that they are
338 // known live into the call.
339 for (unsigned i
= 0, e
= RegsToPass
.size(); i
!= e
; ++i
)
340 Ops
.push_back(DAG
.getRegister(RegsToPass
[i
].first
,
341 RegsToPass
[i
].second
.getValueType()));
343 if (InFlag
.getNode())
344 Ops
.push_back(InFlag
);
346 Chain
= DAG
.getNode(AlphaISD::CALL
, dl
, NodeTys
, &Ops
[0], Ops
.size());
347 InFlag
= Chain
.getValue(1);
349 // Create the CALLSEQ_END node.
350 Chain
= DAG
.getCALLSEQ_END(Chain
,
351 DAG
.getConstant(NumBytes
, getPointerTy(), true),
352 DAG
.getConstant(0, getPointerTy(), true),
354 InFlag
= Chain
.getValue(1);
356 // Handle result values, copying them out of physregs into vregs that we
358 return SDValue(LowerCallResult(Chain
, InFlag
, TheCall
, CC
, DAG
),
362 /// LowerCallResult - Lower the result values of an ISD::CALL into the
363 /// appropriate copies out of appropriate physical registers. This assumes that
364 /// Chain/InFlag are the input chain/flag to use, and that TheCall is the call
365 /// being lowered. Returns a SDNode with the same number of values as the
368 AlphaTargetLowering::LowerCallResult(SDValue Chain
, SDValue InFlag
,
370 unsigned CallingConv
,
372 bool isVarArg
= TheCall
->isVarArg();
373 DebugLoc dl
= TheCall
->getDebugLoc();
375 // Assign locations to each value returned by this call.
376 SmallVector
<CCValAssign
, 16> RVLocs
;
377 CCState
CCInfo(CallingConv
, isVarArg
, getTargetMachine(), RVLocs
,
380 CCInfo
.AnalyzeCallResult(TheCall
, RetCC_Alpha
);
381 SmallVector
<SDValue
, 8> ResultVals
;
383 // Copy all of the result registers out of their specified physreg.
384 for (unsigned i
= 0; i
!= RVLocs
.size(); ++i
) {
385 CCValAssign
&VA
= RVLocs
[i
];
387 Chain
= DAG
.getCopyFromReg(Chain
, dl
, VA
.getLocReg(),
388 VA
.getLocVT(), InFlag
).getValue(1);
389 SDValue RetValue
= Chain
.getValue(0);
390 InFlag
= Chain
.getValue(2);
392 // If this is an 8/16/32-bit value, it is really passed promoted to 64
393 // bits. Insert an assert[sz]ext to capture this, then truncate to the
395 if (VA
.getLocInfo() == CCValAssign::SExt
)
396 RetValue
= DAG
.getNode(ISD::AssertSext
, dl
, VA
.getLocVT(), RetValue
,
397 DAG
.getValueType(VA
.getValVT()));
398 else if (VA
.getLocInfo() == CCValAssign::ZExt
)
399 RetValue
= DAG
.getNode(ISD::AssertZext
, dl
, VA
.getLocVT(), RetValue
,
400 DAG
.getValueType(VA
.getValVT()));
402 if (VA
.getLocInfo() != CCValAssign::Full
)
403 RetValue
= DAG
.getNode(ISD::TRUNCATE
, dl
, VA
.getValVT(), RetValue
);
405 ResultVals
.push_back(RetValue
);
408 ResultVals
.push_back(Chain
);
410 // Merge everything together with a MERGE_VALUES node.
411 return DAG
.getNode(ISD::MERGE_VALUES
, dl
, TheCall
->getVTList(),
412 &ResultVals
[0], ResultVals
.size()).getNode();
415 static SDValue
LowerFORMAL_ARGUMENTS(SDValue Op
, SelectionDAG
&DAG
,
417 int &VarArgsOffset
) {
418 MachineFunction
&MF
= DAG
.getMachineFunction();
419 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
420 std::vector
<SDValue
> ArgValues
;
421 SDValue Root
= Op
.getOperand(0);
422 DebugLoc dl
= Op
.getDebugLoc();
424 unsigned args_int
[] = {
425 Alpha::R16
, Alpha::R17
, Alpha::R18
, Alpha::R19
, Alpha::R20
, Alpha::R21
};
426 unsigned args_float
[] = {
427 Alpha::F16
, Alpha::F17
, Alpha::F18
, Alpha::F19
, Alpha::F20
, Alpha::F21
};
429 for (unsigned ArgNo
= 0, e
= Op
.getNode()->getNumValues()-1; ArgNo
!= e
; ++ArgNo
) {
431 MVT ObjectVT
= Op
.getValue(ArgNo
).getValueType();
435 switch (ObjectVT
.getSimpleVT()) {
437 assert(false && "Invalid value type!");
439 args_float
[ArgNo
] = AddLiveIn(MF
, args_float
[ArgNo
],
440 &Alpha::F8RCRegClass
);
441 ArgVal
= DAG
.getCopyFromReg(Root
, dl
, args_float
[ArgNo
], ObjectVT
);
444 args_float
[ArgNo
] = AddLiveIn(MF
, args_float
[ArgNo
],
445 &Alpha::F4RCRegClass
);
446 ArgVal
= DAG
.getCopyFromReg(Root
, dl
, args_float
[ArgNo
], ObjectVT
);
449 args_int
[ArgNo
] = AddLiveIn(MF
, args_int
[ArgNo
],
450 &Alpha::GPRCRegClass
);
451 ArgVal
= DAG
.getCopyFromReg(Root
, dl
, args_int
[ArgNo
], MVT::i64
);
455 // Create the frame index object for this incoming parameter...
456 int FI
= MFI
->CreateFixedObject(8, 8 * (ArgNo
- 6));
458 // Create the SelectionDAG nodes corresponding to a load
459 //from this parameter
460 SDValue FIN
= DAG
.getFrameIndex(FI
, MVT::i64
);
461 ArgVal
= DAG
.getLoad(ObjectVT
, dl
, Root
, FIN
, NULL
, 0);
463 ArgValues
.push_back(ArgVal
);
466 // If the functions takes variable number of arguments, copy all regs to stack
467 bool isVarArg
= cast
<ConstantSDNode
>(Op
.getOperand(2))->getZExtValue() != 0;
469 VarArgsOffset
= (Op
.getNode()->getNumValues()-1) * 8;
470 std::vector
<SDValue
> LS
;
471 for (int i
= 0; i
< 6; ++i
) {
472 if (TargetRegisterInfo::isPhysicalRegister(args_int
[i
]))
473 args_int
[i
] = AddLiveIn(MF
, args_int
[i
], &Alpha::GPRCRegClass
);
474 SDValue argt
= DAG
.getCopyFromReg(Root
, dl
, args_int
[i
], MVT::i64
);
475 int FI
= MFI
->CreateFixedObject(8, -8 * (6 - i
));
476 if (i
== 0) VarArgsBase
= FI
;
477 SDValue SDFI
= DAG
.getFrameIndex(FI
, MVT::i64
);
478 LS
.push_back(DAG
.getStore(Root
, dl
, argt
, SDFI
, NULL
, 0));
480 if (TargetRegisterInfo::isPhysicalRegister(args_float
[i
]))
481 args_float
[i
] = AddLiveIn(MF
, args_float
[i
], &Alpha::F8RCRegClass
);
482 argt
= DAG
.getCopyFromReg(Root
, dl
, args_float
[i
], MVT::f64
);
483 FI
= MFI
->CreateFixedObject(8, - 8 * (12 - i
));
484 SDFI
= DAG
.getFrameIndex(FI
, MVT::i64
);
485 LS
.push_back(DAG
.getStore(Root
, dl
, argt
, SDFI
, NULL
, 0));
488 //Set up a token factor with all the stack traffic
489 Root
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, &LS
[0], LS
.size());
492 ArgValues
.push_back(Root
);
494 // Return the new list of results.
495 return DAG
.getNode(ISD::MERGE_VALUES
, dl
, Op
.getNode()->getVTList(),
496 &ArgValues
[0], ArgValues
.size());
499 static SDValue
LowerRET(SDValue Op
, SelectionDAG
&DAG
) {
500 DebugLoc dl
= Op
.getDebugLoc();
501 SDValue Copy
= DAG
.getCopyToReg(Op
.getOperand(0), dl
, Alpha::R26
,
502 DAG
.getNode(AlphaISD::GlobalRetAddr
,
503 DebugLoc::getUnknownLoc(),
506 switch (Op
.getNumOperands()) {
508 llvm_unreachable("Do not know how to return this many arguments!");
511 //return SDValue(); // ret void is legal
513 MVT ArgVT
= Op
.getOperand(1).getValueType();
515 if (ArgVT
.isInteger())
518 assert(ArgVT
.isFloatingPoint());
521 Copy
= DAG
.getCopyToReg(Copy
, dl
, ArgReg
,
522 Op
.getOperand(1), Copy
.getValue(1));
523 if (DAG
.getMachineFunction().getRegInfo().liveout_empty())
524 DAG
.getMachineFunction().getRegInfo().addLiveOut(ArgReg
);
528 MVT ArgVT
= Op
.getOperand(1).getValueType();
529 unsigned ArgReg1
, ArgReg2
;
530 if (ArgVT
.isInteger()) {
534 assert(ArgVT
.isFloatingPoint());
538 Copy
= DAG
.getCopyToReg(Copy
, dl
, ArgReg1
,
539 Op
.getOperand(1), Copy
.getValue(1));
540 if (std::find(DAG
.getMachineFunction().getRegInfo().liveout_begin(),
541 DAG
.getMachineFunction().getRegInfo().liveout_end(), ArgReg1
)
542 == DAG
.getMachineFunction().getRegInfo().liveout_end())
543 DAG
.getMachineFunction().getRegInfo().addLiveOut(ArgReg1
);
544 Copy
= DAG
.getCopyToReg(Copy
, dl
, ArgReg2
,
545 Op
.getOperand(3), Copy
.getValue(1));
546 if (std::find(DAG
.getMachineFunction().getRegInfo().liveout_begin(),
547 DAG
.getMachineFunction().getRegInfo().liveout_end(), ArgReg2
)
548 == DAG
.getMachineFunction().getRegInfo().liveout_end())
549 DAG
.getMachineFunction().getRegInfo().addLiveOut(ArgReg2
);
553 return DAG
.getNode(AlphaISD::RET_FLAG
, dl
,
554 MVT::Other
, Copy
, Copy
.getValue(1));
557 void AlphaTargetLowering::LowerVAARG(SDNode
*N
, SDValue
&Chain
,
558 SDValue
&DataPtr
, SelectionDAG
&DAG
) {
559 Chain
= N
->getOperand(0);
560 SDValue VAListP
= N
->getOperand(1);
561 const Value
*VAListS
= cast
<SrcValueSDNode
>(N
->getOperand(2))->getValue();
562 DebugLoc dl
= N
->getDebugLoc();
564 SDValue Base
= DAG
.getLoad(MVT::i64
, dl
, Chain
, VAListP
, VAListS
, 0);
565 SDValue Tmp
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, VAListP
,
566 DAG
.getConstant(8, MVT::i64
));
567 SDValue Offset
= DAG
.getExtLoad(ISD::SEXTLOAD
, dl
, MVT::i64
, Base
.getValue(1),
568 Tmp
, NULL
, 0, MVT::i32
);
569 DataPtr
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, Base
, Offset
);
570 if (N
->getValueType(0).isFloatingPoint())
572 //if fp && Offset < 6*8, then subtract 6*8 from DataPtr
573 SDValue FPDataPtr
= DAG
.getNode(ISD::SUB
, dl
, MVT::i64
, DataPtr
,
574 DAG
.getConstant(8*6, MVT::i64
));
575 SDValue CC
= DAG
.getSetCC(dl
, MVT::i64
, Offset
,
576 DAG
.getConstant(8*6, MVT::i64
), ISD::SETLT
);
577 DataPtr
= DAG
.getNode(ISD::SELECT
, dl
, MVT::i64
, CC
, FPDataPtr
, DataPtr
);
580 SDValue NewOffset
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, Offset
,
581 DAG
.getConstant(8, MVT::i64
));
582 Chain
= DAG
.getTruncStore(Offset
.getValue(1), dl
, NewOffset
, Tmp
, NULL
, 0,
586 /// LowerOperation - Provide custom lowering hooks for some operations.
588 SDValue
AlphaTargetLowering::LowerOperation(SDValue Op
, SelectionDAG
&DAG
) {
589 DebugLoc dl
= Op
.getDebugLoc();
590 switch (Op
.getOpcode()) {
591 default: llvm_unreachable("Wasn't expecting to be able to lower this!");
592 case ISD::FORMAL_ARGUMENTS
: return LowerFORMAL_ARGUMENTS(Op
, DAG
,
595 case ISD::CALL
: return LowerCALL(Op
, DAG
);
596 case ISD::RET
: return LowerRET(Op
,DAG
);
597 case ISD::JumpTable
: return LowerJumpTable(Op
, DAG
);
599 case ISD::INTRINSIC_WO_CHAIN
: {
600 unsigned IntNo
= cast
<ConstantSDNode
>(Op
.getOperand(0))->getZExtValue();
602 default: break; // Don't custom lower most intrinsics.
603 case Intrinsic::alpha_umulh
:
604 return DAG
.getNode(ISD::MULHU
, dl
, MVT::i64
,
605 Op
.getOperand(1), Op
.getOperand(2));
609 case ISD::SINT_TO_FP
: {
610 assert(Op
.getOperand(0).getValueType() == MVT::i64
&&
611 "Unhandled SINT_TO_FP type in custom expander!");
613 bool isDouble
= Op
.getValueType() == MVT::f64
;
614 LD
= DAG
.getNode(ISD::BIT_CONVERT
, dl
, MVT::f64
, Op
.getOperand(0));
615 SDValue FP
= DAG
.getNode(isDouble
?AlphaISD::CVTQT_
:AlphaISD::CVTQS_
, dl
,
616 isDouble
?MVT::f64
:MVT::f32
, LD
);
619 case ISD::FP_TO_SINT
: {
620 bool isDouble
= Op
.getOperand(0).getValueType() == MVT::f64
;
621 SDValue src
= Op
.getOperand(0);
623 if (!isDouble
) //Promote
624 src
= DAG
.getNode(ISD::FP_EXTEND
, dl
, MVT::f64
, src
);
626 src
= DAG
.getNode(AlphaISD::CVTTQ_
, dl
, MVT::f64
, src
);
628 return DAG
.getNode(ISD::BIT_CONVERT
, dl
, MVT::i64
, src
);
630 case ISD::ConstantPool
: {
631 ConstantPoolSDNode
*CP
= cast
<ConstantPoolSDNode
>(Op
);
632 Constant
*C
= CP
->getConstVal();
633 SDValue CPI
= DAG
.getTargetConstantPool(C
, MVT::i64
, CP
->getAlignment());
634 // FIXME there isn't really any debug info here
636 SDValue Hi
= DAG
.getNode(AlphaISD::GPRelHi
, dl
, MVT::i64
, CPI
,
637 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
638 SDValue Lo
= DAG
.getNode(AlphaISD::GPRelLo
, dl
, MVT::i64
, CPI
, Hi
);
641 case ISD::GlobalTLSAddress
:
642 llvm_unreachable("TLS not implemented for Alpha.");
643 case ISD::GlobalAddress
: {
644 GlobalAddressSDNode
*GSDN
= cast
<GlobalAddressSDNode
>(Op
);
645 GlobalValue
*GV
= GSDN
->getGlobal();
646 SDValue GA
= DAG
.getTargetGlobalAddress(GV
, MVT::i64
, GSDN
->getOffset());
647 // FIXME there isn't really any debug info here
649 // if (!GV->hasWeakLinkage() && !GV->isDeclaration() && !GV->hasLinkOnceLinkage()) {
650 if (GV
->hasLocalLinkage()) {
651 SDValue Hi
= DAG
.getNode(AlphaISD::GPRelHi
, dl
, MVT::i64
, GA
,
652 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
653 SDValue Lo
= DAG
.getNode(AlphaISD::GPRelLo
, dl
, MVT::i64
, GA
, Hi
);
656 return DAG
.getNode(AlphaISD::RelLit
, dl
, MVT::i64
, GA
,
657 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
659 case ISD::ExternalSymbol
: {
660 return DAG
.getNode(AlphaISD::RelLit
, dl
, MVT::i64
,
661 DAG
.getTargetExternalSymbol(cast
<ExternalSymbolSDNode
>(Op
)
662 ->getSymbol(), MVT::i64
),
663 DAG
.getGLOBAL_OFFSET_TABLE(MVT::i64
));
668 //Expand only on constant case
669 if (Op
.getOperand(1).getOpcode() == ISD::Constant
) {
670 MVT VT
= Op
.getNode()->getValueType(0);
671 SDValue Tmp1
= Op
.getNode()->getOpcode() == ISD::UREM
?
672 BuildUDIV(Op
.getNode(), DAG
, NULL
) :
673 BuildSDIV(Op
.getNode(), DAG
, NULL
);
674 Tmp1
= DAG
.getNode(ISD::MUL
, dl
, VT
, Tmp1
, Op
.getOperand(1));
675 Tmp1
= DAG
.getNode(ISD::SUB
, dl
, VT
, Op
.getOperand(0), Tmp1
);
681 if (Op
.getValueType().isInteger()) {
682 if (Op
.getOperand(1).getOpcode() == ISD::Constant
)
683 return Op
.getOpcode() == ISD::SDIV
? BuildSDIV(Op
.getNode(), DAG
, NULL
)
684 : BuildUDIV(Op
.getNode(), DAG
, NULL
);
685 const char* opstr
= 0;
686 switch (Op
.getOpcode()) {
687 case ISD::UREM
: opstr
= "__remqu"; break;
688 case ISD::SREM
: opstr
= "__remq"; break;
689 case ISD::UDIV
: opstr
= "__divqu"; break;
690 case ISD::SDIV
: opstr
= "__divq"; break;
692 SDValue Tmp1
= Op
.getOperand(0),
693 Tmp2
= Op
.getOperand(1),
694 Addr
= DAG
.getExternalSymbol(opstr
, MVT::i64
);
695 return DAG
.getNode(AlphaISD::DivCall
, dl
, MVT::i64
, Addr
, Tmp1
, Tmp2
);
700 SDValue Chain
, DataPtr
;
701 LowerVAARG(Op
.getNode(), Chain
, DataPtr
, DAG
);
704 if (Op
.getValueType() == MVT::i32
)
705 Result
= DAG
.getExtLoad(ISD::SEXTLOAD
, dl
, MVT::i64
, Chain
, DataPtr
,
708 Result
= DAG
.getLoad(Op
.getValueType(), dl
, Chain
, DataPtr
, NULL
, 0);
712 SDValue Chain
= Op
.getOperand(0);
713 SDValue DestP
= Op
.getOperand(1);
714 SDValue SrcP
= Op
.getOperand(2);
715 const Value
*DestS
= cast
<SrcValueSDNode
>(Op
.getOperand(3))->getValue();
716 const Value
*SrcS
= cast
<SrcValueSDNode
>(Op
.getOperand(4))->getValue();
718 SDValue Val
= DAG
.getLoad(getPointerTy(), dl
, Chain
, SrcP
, SrcS
, 0);
719 SDValue Result
= DAG
.getStore(Val
.getValue(1), dl
, Val
, DestP
, DestS
, 0);
720 SDValue NP
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, SrcP
,
721 DAG
.getConstant(8, MVT::i64
));
722 Val
= DAG
.getExtLoad(ISD::SEXTLOAD
, dl
, MVT::i64
, Result
,
723 NP
, NULL
,0, MVT::i32
);
724 SDValue NPD
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, DestP
,
725 DAG
.getConstant(8, MVT::i64
));
726 return DAG
.getTruncStore(Val
.getValue(1), dl
, Val
, NPD
, NULL
, 0, MVT::i32
);
729 SDValue Chain
= Op
.getOperand(0);
730 SDValue VAListP
= Op
.getOperand(1);
731 const Value
*VAListS
= cast
<SrcValueSDNode
>(Op
.getOperand(2))->getValue();
733 // vastart stores the address of the VarArgsBase and VarArgsOffset
734 SDValue FR
= DAG
.getFrameIndex(VarArgsBase
, MVT::i64
);
735 SDValue S1
= DAG
.getStore(Chain
, dl
, FR
, VAListP
, VAListS
, 0);
736 SDValue SA2
= DAG
.getNode(ISD::ADD
, dl
, MVT::i64
, VAListP
,
737 DAG
.getConstant(8, MVT::i64
));
738 return DAG
.getTruncStore(S1
, dl
, DAG
.getConstant(VarArgsOffset
, MVT::i64
),
739 SA2
, NULL
, 0, MVT::i32
);
741 case ISD::RETURNADDR
:
742 return DAG
.getNode(AlphaISD::GlobalRetAddr
, DebugLoc::getUnknownLoc(),
745 case ISD::FRAMEADDR
: break;
751 void AlphaTargetLowering::ReplaceNodeResults(SDNode
*N
,
752 SmallVectorImpl
<SDValue
>&Results
,
754 DebugLoc dl
= N
->getDebugLoc();
755 assert(N
->getValueType(0) == MVT::i32
&&
756 N
->getOpcode() == ISD::VAARG
&&
757 "Unknown node to custom promote!");
759 SDValue Chain
, DataPtr
;
760 LowerVAARG(N
, Chain
, DataPtr
, DAG
);
761 SDValue Res
= DAG
.getLoad(N
->getValueType(0), dl
, Chain
, DataPtr
, NULL
, 0);
762 Results
.push_back(Res
);
763 Results
.push_back(SDValue(Res
.getNode(), 1));
769 /// getConstraintType - Given a constraint letter, return the type of
770 /// constraint it is for this target.
771 AlphaTargetLowering::ConstraintType
772 AlphaTargetLowering::getConstraintType(const std::string
&Constraint
) const {
773 if (Constraint
.size() == 1) {
774 switch (Constraint
[0]) {
778 return C_RegisterClass
;
781 return TargetLowering::getConstraintType(Constraint
);
784 std::vector
<unsigned> AlphaTargetLowering::
785 getRegClassForInlineAsmConstraint(const std::string
&Constraint
,
787 if (Constraint
.size() == 1) {
788 switch (Constraint
[0]) {
789 default: break; // Unknown constriant letter
791 return make_vector
<unsigned>(Alpha::F0
, Alpha::F1
, Alpha::F2
,
792 Alpha::F3
, Alpha::F4
, Alpha::F5
,
793 Alpha::F6
, Alpha::F7
, Alpha::F8
,
794 Alpha::F9
, Alpha::F10
, Alpha::F11
,
795 Alpha::F12
, Alpha::F13
, Alpha::F14
,
796 Alpha::F15
, Alpha::F16
, Alpha::F17
,
797 Alpha::F18
, Alpha::F19
, Alpha::F20
,
798 Alpha::F21
, Alpha::F22
, Alpha::F23
,
799 Alpha::F24
, Alpha::F25
, Alpha::F26
,
800 Alpha::F27
, Alpha::F28
, Alpha::F29
,
801 Alpha::F30
, Alpha::F31
, 0);
803 return make_vector
<unsigned>(Alpha::R0
, Alpha::R1
, Alpha::R2
,
804 Alpha::R3
, Alpha::R4
, Alpha::R5
,
805 Alpha::R6
, Alpha::R7
, Alpha::R8
,
806 Alpha::R9
, Alpha::R10
, Alpha::R11
,
807 Alpha::R12
, Alpha::R13
, Alpha::R14
,
808 Alpha::R15
, Alpha::R16
, Alpha::R17
,
809 Alpha::R18
, Alpha::R19
, Alpha::R20
,
810 Alpha::R21
, Alpha::R22
, Alpha::R23
,
811 Alpha::R24
, Alpha::R25
, Alpha::R26
,
812 Alpha::R27
, Alpha::R28
, Alpha::R29
,
813 Alpha::R30
, Alpha::R31
, 0);
817 return std::vector
<unsigned>();
819 //===----------------------------------------------------------------------===//
820 // Other Lowering Code
821 //===----------------------------------------------------------------------===//
824 AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr
*MI
,
825 MachineBasicBlock
*BB
) const {
826 const TargetInstrInfo
*TII
= getTargetMachine().getInstrInfo();
827 assert((MI
->getOpcode() == Alpha::CAS32
||
828 MI
->getOpcode() == Alpha::CAS64
||
829 MI
->getOpcode() == Alpha::LAS32
||
830 MI
->getOpcode() == Alpha::LAS64
||
831 MI
->getOpcode() == Alpha::SWAP32
||
832 MI
->getOpcode() == Alpha::SWAP64
) &&
833 "Unexpected instr type to insert");
835 bool is32
= MI
->getOpcode() == Alpha::CAS32
||
836 MI
->getOpcode() == Alpha::LAS32
||
837 MI
->getOpcode() == Alpha::SWAP32
;
839 //Load locked store conditional for atomic ops take on the same form
842 //do stuff (maybe branch to exit)
844 //test sc and maybe branck to start
846 const BasicBlock
*LLVM_BB
= BB
->getBasicBlock();
847 DebugLoc dl
= MI
->getDebugLoc();
848 MachineFunction::iterator It
= BB
;
851 MachineBasicBlock
*thisMBB
= BB
;
852 MachineFunction
*F
= BB
->getParent();
853 MachineBasicBlock
*llscMBB
= F
->CreateMachineBasicBlock(LLVM_BB
);
854 MachineBasicBlock
*sinkMBB
= F
->CreateMachineBasicBlock(LLVM_BB
);
856 sinkMBB
->transferSuccessors(thisMBB
);
858 F
->insert(It
, llscMBB
);
859 F
->insert(It
, sinkMBB
);
861 BuildMI(thisMBB
, dl
, TII
->get(Alpha::BR
)).addMBB(llscMBB
);
863 unsigned reg_res
= MI
->getOperand(0).getReg(),
864 reg_ptr
= MI
->getOperand(1).getReg(),
865 reg_v2
= MI
->getOperand(2).getReg(),
866 reg_store
= F
->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass
);
868 BuildMI(llscMBB
, dl
, TII
->get(is32
? Alpha::LDL_L
: Alpha::LDQ_L
),
869 reg_res
).addImm(0).addReg(reg_ptr
);
870 switch (MI
->getOpcode()) {
874 = F
->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass
);
875 BuildMI(llscMBB
, dl
, TII
->get(Alpha::CMPEQ
), reg_cmp
)
876 .addReg(reg_v2
).addReg(reg_res
);
877 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BEQ
))
878 .addImm(0).addReg(reg_cmp
).addMBB(sinkMBB
);
879 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BISr
), reg_store
)
880 .addReg(Alpha::R31
).addReg(MI
->getOperand(3).getReg());
885 BuildMI(llscMBB
, dl
,TII
->get(is32
? Alpha::ADDLr
: Alpha::ADDQr
), reg_store
)
886 .addReg(reg_res
).addReg(reg_v2
);
890 case Alpha::SWAP64
: {
891 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BISr
), reg_store
)
892 .addReg(reg_v2
).addReg(reg_v2
);
896 BuildMI(llscMBB
, dl
, TII
->get(is32
? Alpha::STL_C
: Alpha::STQ_C
), reg_store
)
897 .addReg(reg_store
).addImm(0).addReg(reg_ptr
);
898 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BEQ
))
899 .addImm(0).addReg(reg_store
).addMBB(llscMBB
);
900 BuildMI(llscMBB
, dl
, TII
->get(Alpha::BR
)).addMBB(sinkMBB
);
902 thisMBB
->addSuccessor(llscMBB
);
903 llscMBB
->addSuccessor(llscMBB
);
904 llscMBB
->addSuccessor(sinkMBB
);
905 F
->DeleteMachineInstr(MI
); // The pseudo instruction is gone now.
911 AlphaTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode
*GA
) const {
912 // The Alpha target isn't yet aware of offsets.