LLVM 23.0.0git
SparcISelLowering.cpp
Go to the documentation of this file.
1//===-- SparcISelLowering.cpp - Sparc DAG Lowering Implementation ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the interfaces that Sparc uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SparcISelLowering.h"
17#include "SparcRegisterInfo.h"
19#include "SparcTargetMachine.h"
35#include "llvm/IR/Function.h"
36#include "llvm/IR/IRBuilder.h"
37#include "llvm/IR/Module.h"
40using namespace llvm;
41
42
43//===----------------------------------------------------------------------===//
44// Calling Convention Implementation
45//===----------------------------------------------------------------------===//
46
47static bool CC_Sparc_Assign_SRet(unsigned &ValNo, MVT &ValVT,
48 MVT &LocVT, CCValAssign::LocInfo &LocInfo,
49 ISD::ArgFlagsTy &ArgFlags, CCState &State)
50{
51 assert (ArgFlags.isSRet());
52
53 // Assign SRet argument.
54 State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
55 0,
56 LocVT, LocInfo));
57 return true;
58}
59
60static bool CC_Sparc_Assign_Split_64(unsigned &ValNo, MVT &ValVT,
61 MVT &LocVT, CCValAssign::LocInfo &LocInfo,
62 ISD::ArgFlagsTy &ArgFlags, CCState &State)
63{
64 static const MCPhysReg RegList[] = {
65 SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
66 };
67 // Try to get first reg.
68 if (Register Reg = State.AllocateReg(RegList)) {
69 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
70 } else {
71 // Assign whole thing in stack.
72 State.addLoc(CCValAssign::getCustomMem(
73 ValNo, ValVT, State.AllocateStack(8, Align(4)), LocVT, LocInfo));
74 return true;
75 }
76
77 // Try to get second reg.
78 if (Register Reg = State.AllocateReg(RegList))
79 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
80 else
81 State.addLoc(CCValAssign::getCustomMem(
82 ValNo, ValVT, State.AllocateStack(4, Align(4)), LocVT, LocInfo));
83 return true;
84}
85
86static bool CC_Sparc_Assign_Ret_Split_64(unsigned &ValNo, MVT &ValVT,
87 MVT &LocVT, CCValAssign::LocInfo &LocInfo,
88 ISD::ArgFlagsTy &ArgFlags, CCState &State)
89{
90 static const MCPhysReg RegList[] = {
91 SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
92 };
93
94 // Try to get first reg.
95 if (Register Reg = State.AllocateReg(RegList))
96 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
97 else
98 return false;
99
100 // Try to get second reg.
101 if (Register Reg = State.AllocateReg(RegList))
102 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
103 else
104 return false;
105
106 return true;
107}
108
109// Allocate a full-sized argument for the 64-bit ABI.
110static bool Analyze_CC_Sparc64_Full(bool IsReturn, unsigned &ValNo, MVT &ValVT,
111 MVT &LocVT, CCValAssign::LocInfo &LocInfo,
112 ISD::ArgFlagsTy &ArgFlags, CCState &State) {
113 assert((LocVT == MVT::f32 || LocVT == MVT::f128
114 || LocVT.getSizeInBits() == 64) &&
115 "Can't handle non-64 bits locations");
116
117 // Stack space is allocated for all arguments starting from [%fp+BIAS+128].
118 unsigned size = (LocVT == MVT::f128) ? 16 : 8;
119 Align alignment =
120 (LocVT == MVT::f128 || ArgFlags.isSplit()) ? Align(16) : Align(8);
121 unsigned Offset = State.AllocateStack(size, alignment);
122 unsigned Reg = 0;
123
124 if (LocVT == MVT::i64 && Offset < 6*8)
125 // Promote integers to %i0-%i5.
126 Reg = SP::I0 + Offset/8;
127 else if (LocVT == MVT::f64 && Offset < 16*8)
128 // Promote doubles to %d0-%d30. (Which LLVM calls D0-D15).
129 Reg = SP::D0 + Offset/8;
130 else if (LocVT == MVT::f32 && Offset < 16*8)
131 // Promote floats to %f1, %f3, ...
132 Reg = SP::F1 + Offset/4;
133 else if (LocVT == MVT::f128 && Offset < 16*8)
134 // Promote long doubles to %q0-%q28. (Which LLVM calls Q0-Q7).
135 Reg = SP::Q0 + Offset/16;
136
137 // Promote to register when possible, otherwise use the stack slot.
138 if (Reg) {
139 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
140 return true;
141 }
142
143 // Bail out if this is a return CC and we run out of registers to place
144 // values into.
145 if (IsReturn)
146 return false;
147
148 // This argument goes on the stack in an 8-byte slot.
149 // When passing floats, LocVT is smaller than 8 bytes. Adjust the offset to
150 // the right-aligned float. The first 4 bytes of the stack slot are undefined.
151 if (LocVT == MVT::f32)
152 Offset += 4;
153
154 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
155 return true;
156}
157
158// Allocate a half-sized argument for the 64-bit ABI.
159//
160// This is used when passing { float, int } structs by value in registers.
161static bool Analyze_CC_Sparc64_Half(bool IsReturn, unsigned &ValNo, MVT &ValVT,
162 MVT &LocVT, CCValAssign::LocInfo &LocInfo,
163 ISD::ArgFlagsTy &ArgFlags, CCState &State) {
164 assert(LocVT.getSizeInBits() == 32 && "Can't handle non-32 bits locations");
165 unsigned Offset = State.AllocateStack(4, Align(4));
166
167 if (LocVT == MVT::f32 && Offset < 16*8) {
168 // Promote floats to %f0-%f31.
169 State.addLoc(CCValAssign::getReg(ValNo, ValVT, SP::F0 + Offset/4,
170 LocVT, LocInfo));
171 return true;
172 }
173
174 if (LocVT == MVT::i32 && Offset < 6*8) {
175 // Promote integers to %i0-%i5, using half the register.
176 unsigned Reg = SP::I0 + Offset/8;
177 LocVT = MVT::i64;
178 LocInfo = CCValAssign::AExt;
179
180 // Set the Custom bit if this i32 goes in the high bits of a register.
181 if (Offset % 8 == 0)
182 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg,
183 LocVT, LocInfo));
184 else
185 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
186 return true;
187 }
188
189 // Bail out if this is a return CC and we run out of registers to place
190 // values into.
191 if (IsReturn)
192 return false;
193
194 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
195 return true;
196}
197
198static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
199 CCValAssign::LocInfo &LocInfo,
200 ISD::ArgFlagsTy &ArgFlags, CCState &State) {
201 return Analyze_CC_Sparc64_Full(false, ValNo, ValVT, LocVT, LocInfo, ArgFlags,
202 State);
203}
204
205static bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
206 CCValAssign::LocInfo &LocInfo,
207 ISD::ArgFlagsTy &ArgFlags, CCState &State) {
208 return Analyze_CC_Sparc64_Half(false, ValNo, ValVT, LocVT, LocInfo, ArgFlags,
209 State);
210}
211
212static bool RetCC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
213 CCValAssign::LocInfo &LocInfo,
214 ISD::ArgFlagsTy &ArgFlags, CCState &State) {
215 return Analyze_CC_Sparc64_Full(true, ValNo, ValVT, LocVT, LocInfo, ArgFlags,
216 State);
217}
218
219static bool RetCC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
220 CCValAssign::LocInfo &LocInfo,
221 ISD::ArgFlagsTy &ArgFlags, CCState &State) {
222 return Analyze_CC_Sparc64_Half(true, ValNo, ValVT, LocVT, LocInfo, ArgFlags,
223 State);
224}
225
226#define GET_CALLING_CONV_IMPL
227#include "SparcGenCallingConv.inc"
228
229// The calling conventions in SparcCallingConv.td are described in terms of the
230// callee's register window. This function translates registers to the
231// corresponding caller window %o register.
232static unsigned toCallerWindow(unsigned Reg) {
233 static_assert(SP::I0 + 7 == SP::I7 && SP::O0 + 7 == SP::O7,
234 "Unexpected enum");
235 if (Reg >= SP::I0 && Reg <= SP::I7)
236 return Reg - SP::I0 + SP::O0;
237 return Reg;
238}
239
241 CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
242 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
243 const Type *RetTy) const {
245 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
246 return CCInfo.CheckReturn(Outs, Subtarget->is64Bit() ? RetCC_Sparc64
247 : RetCC_Sparc32);
248}
249
252 bool IsVarArg,
254 const SmallVectorImpl<SDValue> &OutVals,
255 const SDLoc &DL, SelectionDAG &DAG) const {
256 if (Subtarget->is64Bit())
257 return LowerReturn_64(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG);
258 return LowerReturn_32(Chain, CallConv, IsVarArg, Outs, OutVals, DL, DAG);
259}
260
263 bool IsVarArg,
265 const SmallVectorImpl<SDValue> &OutVals,
266 const SDLoc &DL, SelectionDAG &DAG) const {
268
269 // CCValAssign - represent the assignment of the return value to locations.
271
272 // CCState - Info about the registers and stack slot.
273 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
274 *DAG.getContext());
275
276 // Analyze return values.
277 CCInfo.AnalyzeReturn(Outs, RetCC_Sparc32);
278
279 SDValue Glue;
280 SmallVector<SDValue, 4> RetOps(1, Chain);
281 // Make room for the return address offset.
282 RetOps.push_back(SDValue());
283
284 // Copy the result values into the output registers.
285 for (unsigned i = 0, realRVLocIdx = 0;
286 i != RVLocs.size();
287 ++i, ++realRVLocIdx) {
288 CCValAssign &VA = RVLocs[i];
289 assert(VA.isRegLoc() && "Can only return in registers!");
290
291 SDValue Arg = OutVals[realRVLocIdx];
292
293 if (VA.needsCustom()) {
294 assert(VA.getLocVT() == MVT::v2i32);
295 // Legalize ret v2i32 -> ret 2 x i32 (Basically: do what would
296 // happen by default if this wasn't a legal type)
297
298 SDValue Part0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32,
299 Arg,
301 SDValue Part1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32,
302 Arg,
304
305 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Part0, Glue);
306 Glue = Chain.getValue(1);
307 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
308 VA = RVLocs[++i]; // skip ahead to next loc
309 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Part1,
310 Glue);
311 } else
312 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Arg, Glue);
313
314 // Guarantee that all emitted copies are stuck together with flags.
315 Glue = Chain.getValue(1);
316 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
317 }
318
319 unsigned RetAddrOffset = 8; // Call Inst + Delay Slot
320 // If the function returns a struct, copy the SRetReturnReg to I0
321 if (MF.getFunction().hasStructRetAttr()) {
323 Register Reg = SFI->getSRetReturnReg();
324 if (!Reg)
325 llvm_unreachable("sret virtual register not created in the entry block");
326 auto PtrVT = getPointerTy(DAG.getDataLayout());
327 SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, PtrVT);
328 Chain = DAG.getCopyToReg(Chain, DL, SP::I0, Val, Glue);
329 Glue = Chain.getValue(1);
330 RetOps.push_back(DAG.getRegister(SP::I0, PtrVT));
331 RetAddrOffset = 12; // CallInst + Delay Slot + Unimp
332 }
333
334 RetOps[0] = Chain; // Update chain.
335 RetOps[1] = DAG.getConstant(RetAddrOffset, DL, MVT::i32);
336
337 // Add the glue if we have it.
338 if (Glue.getNode())
339 RetOps.push_back(Glue);
340
341 return DAG.getNode(SPISD::RET_GLUE, DL, MVT::Other, RetOps);
342}
343
344// Lower return values for the 64-bit ABI.
345// Return values are passed the exactly the same way as function arguments.
348 bool IsVarArg,
350 const SmallVectorImpl<SDValue> &OutVals,
351 const SDLoc &DL, SelectionDAG &DAG) const {
352 // CCValAssign - represent the assignment of the return value to locations.
354
355 // CCState - Info about the registers and stack slot.
356 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
357 *DAG.getContext());
358
359 // Analyze return values.
360 CCInfo.AnalyzeReturn(Outs, RetCC_Sparc64);
361
362 SDValue Glue;
363 SmallVector<SDValue, 4> RetOps(1, Chain);
364
365 // The second operand on the return instruction is the return address offset.
366 // The return address is always %i7+8 with the 64-bit ABI.
367 RetOps.push_back(DAG.getConstant(8, DL, MVT::i32));
368
369 // Copy the result values into the output registers.
370 for (unsigned i = 0; i != RVLocs.size(); ++i) {
371 CCValAssign &VA = RVLocs[i];
372 assert(VA.isRegLoc() && "Can only return in registers!");
373 SDValue OutVal = OutVals[i];
374
375 // Integer return values must be sign or zero extended by the callee.
376 switch (VA.getLocInfo()) {
377 case CCValAssign::Full: break;
379 OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal);
380 break;
382 OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal);
383 break;
385 OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal);
386 break;
387 default:
388 llvm_unreachable("Unknown loc info!");
389 }
390
391 // The custom bit on an i32 return value indicates that it should be passed
392 // in the high bits of the register.
393 if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
394 OutVal = DAG.getNode(ISD::SHL, DL, MVT::i64, OutVal,
395 DAG.getConstant(32, DL, MVT::i32));
396
397 // The next value may go in the low bits of the same register.
398 // Handle both at once.
399 if (i+1 < RVLocs.size() && RVLocs[i+1].getLocReg() == VA.getLocReg()) {
400 SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, OutVals[i+1]);
401 OutVal = DAG.getNode(ISD::OR, DL, MVT::i64, OutVal, NV);
402 // Skip the next value, it's already done.
403 ++i;
404 }
405 }
406
407 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Glue);
408
409 // Guarantee that all emitted copies are stuck together with flags.
410 Glue = Chain.getValue(1);
411 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
412 }
413
414 RetOps[0] = Chain; // Update chain.
415
416 // Add the flag if we have it.
417 if (Glue.getNode())
418 RetOps.push_back(Glue);
419
420 return DAG.getNode(SPISD::RET_GLUE, DL, MVT::Other, RetOps);
421}
422
424 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
425 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
426 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
427 if (Subtarget->is64Bit())
428 return LowerFormalArguments_64(Chain, CallConv, IsVarArg, Ins,
429 DL, DAG, InVals);
430 return LowerFormalArguments_32(Chain, CallConv, IsVarArg, Ins,
431 DL, DAG, InVals);
432}
433
434/// LowerFormalArguments32 - V8 uses a very simple ABI, where all values are
435/// passed in either one or two GPRs, including FP values. TODO: we should
436/// pass FP values in FP registers for fastcc functions.
438 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
439 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
440 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
442 MachineRegisterInfo &RegInfo = MF.getRegInfo();
444 EVT PtrVT = getPointerTy(DAG.getDataLayout());
445
446 // Assign locations to all of the incoming arguments.
448 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
449 *DAG.getContext());
450 CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc32);
451
452 const unsigned StackOffset = 92;
453 bool IsLittleEndian = DAG.getDataLayout().isLittleEndian();
454
455 unsigned InIdx = 0;
456 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i, ++InIdx) {
457 CCValAssign &VA = ArgLocs[i];
458 EVT LocVT = VA.getLocVT();
459
460 if (Ins[InIdx].Flags.isSRet()) {
461 if (InIdx != 0)
462 report_fatal_error("sparc only supports sret on the first parameter");
463 // Get SRet from [%fp+64].
464 int FrameIdx = MF.getFrameInfo().CreateFixedObject(4, 64, true);
465 SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
466 SDValue Arg =
467 DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo());
468 InVals.push_back(Arg);
469 continue;
470 }
471
472 SDValue Arg;
473 if (VA.isRegLoc()) {
474 if (VA.needsCustom()) {
475 assert(VA.getLocVT() == MVT::f64 || VA.getLocVT() == MVT::v2i32);
476
477 Register VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
478 MF.getRegInfo().addLiveIn(VA.getLocReg(), VRegHi);
479 SDValue HiVal = DAG.getCopyFromReg(Chain, dl, VRegHi, MVT::i32);
480
481 assert(i+1 < e);
482 CCValAssign &NextVA = ArgLocs[++i];
483
484 SDValue LoVal;
485 if (NextVA.isMemLoc()) {
486 int FrameIdx = MF.getFrameInfo().
487 CreateFixedObject(4, StackOffset+NextVA.getLocMemOffset(),true);
488 SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
489 LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo());
490 } else {
491 Register loReg = MF.addLiveIn(NextVA.getLocReg(),
492 &SP::IntRegsRegClass);
493 LoVal = DAG.getCopyFromReg(Chain, dl, loReg, MVT::i32);
494 }
495
496 if (IsLittleEndian)
497 std::swap(LoVal, HiVal);
498
499 SDValue WholeValue =
500 DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal);
501 WholeValue = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), WholeValue);
502 InVals.push_back(WholeValue);
503 continue;
504 }
505 Register VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
506 MF.getRegInfo().addLiveIn(VA.getLocReg(), VReg);
507 Arg = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
508 if (VA.getLocInfo() != CCValAssign::Indirect) {
509 if (VA.getLocVT() == MVT::f32)
510 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Arg);
511 else if (VA.getLocVT() != MVT::i32) {
512 Arg = DAG.getNode(ISD::AssertSext, dl, MVT::i32, Arg,
513 DAG.getValueType(VA.getLocVT()));
514 Arg = DAG.getNode(ISD::TRUNCATE, dl, VA.getLocVT(), Arg);
515 }
516 InVals.push_back(Arg);
517 continue;
518 }
519 } else {
520 assert(VA.isMemLoc());
521
522 unsigned Offset = VA.getLocMemOffset() + StackOffset;
523
524 if (VA.needsCustom()) {
525 assert(VA.getValVT() == MVT::f64 || VA.getValVT() == MVT::v2i32);
526 // If it is double-word aligned, just load.
527 if (Offset % 8 == 0) {
528 int FI = MF.getFrameInfo().CreateFixedObject(8, Offset, true);
529 SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
530 SDValue Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr,
532 InVals.push_back(Load);
533 continue;
534 }
535
536 int FI = MF.getFrameInfo().CreateFixedObject(4, Offset, true);
537 SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
538 SDValue HiVal =
539 DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo());
540 int FI2 = MF.getFrameInfo().CreateFixedObject(4, Offset + 4, true);
541 SDValue FIPtr2 = DAG.getFrameIndex(FI2, PtrVT);
542
543 SDValue LoVal =
544 DAG.getLoad(MVT::i32, dl, Chain, FIPtr2, MachinePointerInfo());
545
546 if (IsLittleEndian)
547 std::swap(LoVal, HiVal);
548
549 SDValue WholeValue =
550 DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal);
551 WholeValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), WholeValue);
552 InVals.push_back(WholeValue);
553 continue;
554 }
555
556 int FI = MF.getFrameInfo().CreateFixedObject(LocVT.getSizeInBits() / 8,
557 Offset, true);
558 SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
559 SDValue Load = DAG.getLoad(LocVT, dl, Chain, FIPtr,
561 if (VA.getLocInfo() != CCValAssign::Indirect) {
562 InVals.push_back(Load);
563 continue;
564 }
565 Arg = Load;
566 }
567
569
570 SDValue ArgValue =
571 DAG.getLoad(VA.getValVT(), dl, Chain, Arg, MachinePointerInfo());
572 InVals.push_back(ArgValue);
573
574 unsigned ArgIndex = Ins[InIdx].OrigArgIndex;
575 assert(Ins[InIdx].PartOffset == 0);
576 while (i + 1 != e && Ins[InIdx + 1].OrigArgIndex == ArgIndex) {
577 CCValAssign &PartVA = ArgLocs[i + 1];
578 unsigned PartOffset = Ins[InIdx + 1].PartOffset;
580 ArgValue, TypeSize::getFixed(PartOffset), dl);
581 InVals.push_back(DAG.getLoad(PartVA.getValVT(), dl, Chain, Address,
583 ++i;
584 ++InIdx;
585 }
586 }
587
588 if (MF.getFunction().hasStructRetAttr()) {
589 // Copy the SRet Argument to SRetReturnReg.
591 Register Reg = SFI->getSRetReturnReg();
592 if (!Reg) {
593 Reg = MF.getRegInfo().createVirtualRegister(&SP::IntRegsRegClass);
594 SFI->setSRetReturnReg(Reg);
595 }
596 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]);
597 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
598 }
599
600 // Store remaining ArgRegs to the stack if this is a varargs function.
601 if (isVarArg) {
602 static const MCPhysReg ArgRegs[] = {
603 SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
604 };
605 unsigned NumAllocated = CCInfo.getFirstUnallocated(ArgRegs);
606 const MCPhysReg *CurArgReg = ArgRegs+NumAllocated, *ArgRegEnd = ArgRegs+6;
607 unsigned ArgOffset = CCInfo.getStackSize();
608 if (NumAllocated == 6)
609 ArgOffset += StackOffset;
610 else {
611 assert(!ArgOffset);
612 ArgOffset = 68+4*NumAllocated;
613 }
614
615 // Remember the vararg offset for the va_start implementation.
616 FuncInfo->setVarArgsFrameOffset(ArgOffset);
617
618 std::vector<SDValue> OutChains;
619
620 for (; CurArgReg != ArgRegEnd; ++CurArgReg) {
621 Register VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
622 MF.getRegInfo().addLiveIn(*CurArgReg, VReg);
623 SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32);
624
625 int FrameIdx = MF.getFrameInfo().CreateFixedObject(4, ArgOffset,
626 true);
627 SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
628
629 OutChains.push_back(
630 DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, MachinePointerInfo()));
631 ArgOffset += 4;
632 }
633
634 if (!OutChains.empty()) {
635 OutChains.push_back(Chain);
636 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
637 }
638 }
639
640 return Chain;
641}
642
643// Lower formal arguments for the 64 bit ABI.
645 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
646 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
647 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
649
650 // Analyze arguments according to CC_Sparc64.
652 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
653 *DAG.getContext());
654 CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc64);
655
656 // The argument array begins at %fp+BIAS+128, after the register save area.
657 const unsigned ArgArea = 128;
658
659 for (const CCValAssign &VA : ArgLocs) {
660 if (VA.isRegLoc()) {
661 // This argument is passed in a register.
662 // All integer register arguments are promoted by the caller to i64.
663
664 // Create a virtual register for the promoted live-in value.
665 Register VReg = MF.addLiveIn(VA.getLocReg(),
666 getRegClassFor(VA.getLocVT()));
667 SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT());
668
669 // Get the high bits for i32 struct elements.
670 if (VA.getValVT() == MVT::i32 && VA.needsCustom())
671 Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg,
672 DAG.getConstant(32, DL, MVT::i32));
673
674 // The caller promoted the argument, so insert an Assert?ext SDNode so we
675 // won't promote the value again in this function.
676 switch (VA.getLocInfo()) {
678 Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg,
679 DAG.getValueType(VA.getValVT()));
680 break;
682 Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg,
683 DAG.getValueType(VA.getValVT()));
684 break;
685 default:
686 break;
687 }
688
689 // Truncate the register down to the argument type.
690 if (VA.isExtInLoc())
691 Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg);
692
693 InVals.push_back(Arg);
694 continue;
695 }
696
697 // The registers are exhausted. This argument was passed on the stack.
698 assert(VA.isMemLoc());
699 // The CC_Sparc64_Full/Half functions compute stack offsets relative to the
700 // beginning of the arguments area at %fp+BIAS+128.
701 unsigned Offset = VA.getLocMemOffset() + ArgArea;
702 unsigned ValSize = VA.getValVT().getSizeInBits() / 8;
703 // Adjust offset for extended arguments, SPARC is big-endian.
704 // The caller will have written the full slot with extended bytes, but we
705 // prefer our own extending loads.
706 if (VA.isExtInLoc())
707 Offset += 8 - ValSize;
708 int FI = MF.getFrameInfo().CreateFixedObject(ValSize, Offset, true);
709 InVals.push_back(
710 DAG.getLoad(VA.getValVT(), DL, Chain,
713 }
714
715 if (!IsVarArg)
716 return Chain;
717
718 // This function takes variable arguments, some of which may have been passed
719 // in registers %i0-%i5. Variable floating point arguments are never passed
720 // in floating point registers. They go on %i0-%i5 or on the stack like
721 // integer arguments.
722 //
723 // The va_start intrinsic needs to know the offset to the first variable
724 // argument.
725 unsigned ArgOffset = CCInfo.getStackSize();
727 // Skip the 128 bytes of register save area.
728 FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgArea +
729 Subtarget->getStackPointerBias());
730
731 // Save the variable arguments that were passed in registers.
732 // The caller is required to reserve stack space for 6 arguments regardless
733 // of how many arguments were actually passed.
734 SmallVector<SDValue, 8> OutChains;
735 for (; ArgOffset < 6*8; ArgOffset += 8) {
736 Register VReg = MF.addLiveIn(SP::I0 + ArgOffset/8, &SP::I64RegsRegClass);
737 SDValue VArg = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i64);
738 int FI = MF.getFrameInfo().CreateFixedObject(8, ArgOffset + ArgArea, true);
739 auto PtrVT = getPointerTy(MF.getDataLayout());
740 OutChains.push_back(
741 DAG.getStore(Chain, DL, VArg, DAG.getFrameIndex(FI, PtrVT),
743 }
744
745 if (!OutChains.empty())
746 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
747
748 return Chain;
749}
750
751// Check whether any of the argument registers are reserved
753 const MachineFunction &MF) {
754 // The register window design means that outgoing parameters at O*
755 // will appear in the callee as I*.
756 // Be conservative and check both sides of the register names.
757 bool Outgoing =
758 llvm::any_of(SP::GPROutgoingArgRegClass, [TRI, &MF](MCPhysReg r) {
759 return TRI->isReservedReg(MF, r);
760 });
761 bool Incoming =
762 llvm::any_of(SP::GPRIncomingArgRegClass, [TRI, &MF](MCPhysReg r) {
763 return TRI->isReservedReg(MF, r);
764 });
765 return Outgoing || Incoming;
766}
767
769 const Function &F = MF.getFunction();
770 F.getContext().diagnose(DiagnosticInfoUnsupported{
771 F, ("SPARC doesn't support"
772 " function calls if any of the argument registers is reserved.")});
773}
774
777 SmallVectorImpl<SDValue> &InVals) const {
778 if (Subtarget->is64Bit())
779 return LowerCall_64(CLI, InVals);
780 return LowerCall_32(CLI, InVals);
781}
782
783static bool hasReturnsTwiceAttr(SelectionDAG &DAG, SDValue Callee,
784 const CallBase *Call) {
785 if (Call)
786 return Call->hasFnAttr(Attribute::ReturnsTwice);
787
788 const Function *CalleeFn = nullptr;
790 CalleeFn = dyn_cast<Function>(G->getGlobal());
791 } else if (ExternalSymbolSDNode *E =
793 const Function &Fn = DAG.getMachineFunction().getFunction();
794 const Module *M = Fn.getParent();
795 const char *CalleeName = E->getSymbol();
796 CalleeFn = M->getFunction(CalleeName);
797 }
798
799 if (!CalleeFn)
800 return false;
801 return CalleeFn->hasFnAttribute(Attribute::ReturnsTwice);
802}
803
804/// IsEligibleForTailCallOptimization - Check whether the call is eligible
805/// for tail call optimization.
807 CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF) const {
808
809 auto &Outs = CLI.Outs;
810 auto &Caller = MF.getFunction();
811
812 // Do not tail call opt functions with "disable-tail-calls" attribute.
813 if (Caller.getFnAttribute("disable-tail-calls").getValueAsString() == "true")
814 return false;
815
816 // Do not tail call opt if the stack is used to pass parameters.
817 // 64-bit targets have a slightly higher limit since the ABI requires
818 // to allocate some space even when all the parameters fit inside registers.
819 unsigned StackSizeLimit = Subtarget->is64Bit() ? 48 : 0;
820 if (CCInfo.getStackSize() > StackSizeLimit)
821 return false;
822
823 // Do not tail call opt if either the callee or caller returns
824 // a struct and the other does not.
825 if (!Outs.empty() && Caller.hasStructRetAttr() != Outs[0].Flags.isSRet())
826 return false;
827
828 // Byval parameters hand the function a pointer directly into the stack area
829 // we want to reuse during a tail call.
830 for (auto &Arg : Outs)
831 if (Arg.Flags.isByVal())
832 return false;
833
834 return true;
835}
836
837// Lower a call for the 32-bit ABI.
840 SmallVectorImpl<SDValue> &InVals) const {
841 SelectionDAG &DAG = CLI.DAG;
842 SDLoc &dl = CLI.DL;
844 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
846 SDValue Chain = CLI.Chain;
847 SDValue Callee = CLI.Callee;
848 bool &isTailCall = CLI.IsTailCall;
849 CallingConv::ID CallConv = CLI.CallConv;
850 bool isVarArg = CLI.IsVarArg;
852 LLVMContext &Ctx = *DAG.getContext();
853 EVT PtrVT = getPointerTy(MF.getDataLayout());
854
855 // Analyze operands of the call, assigning locations to each operand.
857 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
858 *DAG.getContext());
859 CCInfo.AnalyzeCallOperands(Outs, CC_Sparc32);
860
861 isTailCall = isTailCall && IsEligibleForTailCallOptimization(
862 CCInfo, CLI, DAG.getMachineFunction());
863
864 // Get the size of the outgoing arguments stack space requirement.
865 unsigned ArgsSize = CCInfo.getStackSize();
866
867 // Keep stack frames 8-byte aligned.
868 ArgsSize = (ArgsSize+7) & ~7;
869
871
872 // Create local copies for byval args.
873 SmallVector<SDValue, 8> ByValArgs;
874 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
875 ISD::ArgFlagsTy Flags = Outs[i].Flags;
876 if (!Flags.isByVal())
877 continue;
878
879 SDValue Arg = OutVals[i];
880 unsigned Size = Flags.getByValSize();
881 Align Alignment = Flags.getNonZeroByValAlign();
882
883 if (Size > 0U) {
884 int FI = MFI.CreateStackObject(Size, Alignment, false);
885 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
886 SDValue SizeNode = DAG.getConstant(Size, dl, MVT::i32);
887
888 Chain =
889 DAG.getMemcpy(Chain, dl, FIPtr, Arg, SizeNode, Alignment, Alignment,
890 false, // isVolatile,
891 (Size <= 32), // AlwaysInline if size <= 32,
892 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(),
894 ByValArgs.push_back(FIPtr);
895 }
896 else {
897 SDValue nullVal;
898 ByValArgs.push_back(nullVal);
899 }
900 }
901
902 assert(!isTailCall || ArgsSize == 0);
903
904 if (!isTailCall)
905 Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, dl);
906
908 SmallVector<SDValue, 8> MemOpChains;
909
910 const unsigned StackOffset = 92;
911 bool hasStructRetAttr = false;
912 unsigned SRetArgSize = 0;
913 // Walk the register/memloc assignments, inserting copies/loads.
914 for (unsigned i = 0, realArgIdx = 0, byvalArgIdx = 0, e = ArgLocs.size();
915 i != e;
916 ++i, ++realArgIdx) {
917 CCValAssign &VA = ArgLocs[i];
918 SDValue Arg = OutVals[realArgIdx];
919
920 ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
921
922 // Use local copy if it is a byval arg.
923 if (Flags.isByVal()) {
924 Arg = ByValArgs[byvalArgIdx++];
925 if (!Arg) {
926 continue;
927 }
928 }
929
930 // Promote the value if needed.
931 switch (VA.getLocInfo()) {
932 default: llvm_unreachable("Unknown loc info!");
935 break;
937 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
938 break;
940 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
941 break;
943 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
944 break;
946 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
947 break;
948 }
949
950 if (Flags.isSRet()) {
951 assert(VA.needsCustom());
952
953 if (isTailCall)
954 continue;
955
956 // store SRet argument in %sp+64
957 SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
958 SDValue PtrOff = DAG.getIntPtrConstant(64, dl);
959 PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
960 MemOpChains.push_back(
961 DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
962 hasStructRetAttr = true;
963 // sret only allowed on first argument
964 assert(Outs[realArgIdx].OrigArgIndex == 0);
965 SRetArgSize =
966 DAG.getDataLayout().getTypeAllocSize(CLI.getArgs()[0].IndirectType);
967 continue;
968 }
969
970 if (VA.needsCustom()) {
971 assert(VA.getLocVT() == MVT::f64 || VA.getLocVT() == MVT::v2i32);
972
973 if (VA.isMemLoc()) {
974 unsigned Offset = VA.getLocMemOffset() + StackOffset;
975 // if it is double-word aligned, just store.
976 if (Offset % 8 == 0) {
977 SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
978 SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
979 PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
980 MemOpChains.push_back(
981 DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
982 continue;
983 }
984 }
985
986 if (VA.getLocVT() == MVT::f64) {
987 // Move from the float value from float registers into the
988 // integer registers.
990 Arg = bitcastConstantFPToInt(C, dl, DAG);
991 else
992 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::v2i32, Arg);
993 }
994
995 SDValue Part0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
996 Arg,
997 DAG.getConstant(0, dl, getVectorIdxTy(DAG.getDataLayout())));
998 SDValue Part1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
999 Arg,
1000 DAG.getConstant(1, dl, getVectorIdxTy(DAG.getDataLayout())));
1001
1002 if (VA.isRegLoc()) {
1003 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Part0));
1004 assert(i+1 != e);
1005 CCValAssign &NextVA = ArgLocs[++i];
1006 if (NextVA.isRegLoc()) {
1007 RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), Part1));
1008 } else {
1009 // Store the second part in stack.
1010 unsigned Offset = NextVA.getLocMemOffset() + StackOffset;
1011 SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
1012 SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
1013 PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
1014 MemOpChains.push_back(
1015 DAG.getStore(Chain, dl, Part1, PtrOff, MachinePointerInfo()));
1016 }
1017 } else {
1018 unsigned Offset = VA.getLocMemOffset() + StackOffset;
1019 // Store the first part.
1020 SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
1021 SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
1022 PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
1023 MemOpChains.push_back(
1024 DAG.getStore(Chain, dl, Part0, PtrOff, MachinePointerInfo()));
1025 // Store the second part.
1026 PtrOff = DAG.getIntPtrConstant(Offset + 4, dl);
1027 PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
1028 MemOpChains.push_back(
1029 DAG.getStore(Chain, dl, Part1, PtrOff, MachinePointerInfo()));
1030 }
1031 continue;
1032 }
1033
1034 if (VA.getLocInfo() == CCValAssign::Indirect) {
1035 // Store the argument in a stack slot and pass its address.
1036 unsigned ArgIndex = Outs[realArgIdx].OrigArgIndex;
1037 assert(Outs[realArgIdx].PartOffset == 0);
1038
1039 EVT SlotVT;
1040 if (i + 1 != e && Outs[realArgIdx + 1].OrigArgIndex == ArgIndex) {
1041 Type *OrigArgType = CLI.Args[ArgIndex].Ty;
1042 EVT OrigArgVT = getValueType(MF.getDataLayout(), OrigArgType);
1043 MVT PartVT =
1044 getRegisterTypeForCallingConv(Ctx, CLI.CallConv, OrigArgVT);
1045 unsigned N =
1046 getNumRegistersForCallingConv(Ctx, CLI.CallConv, OrigArgVT);
1047 SlotVT = EVT::getIntegerVT(Ctx, PartVT.getSizeInBits() * N);
1048 } else {
1049 SlotVT = Outs[realArgIdx].VT;
1050 }
1051
1052 SDValue SpillSlot = DAG.CreateStackTemporary(SlotVT);
1053 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
1054 MemOpChains.push_back(
1055 DAG.getStore(Chain, dl, Arg, SpillSlot,
1057 // If the original argument was split (e.g. f128), we need
1058 // to store all parts of it here (and pass just one address).
1059 while (i + 1 != e && Outs[realArgIdx + 1].OrigArgIndex == ArgIndex) {
1060 SDValue PartValue = OutVals[realArgIdx + 1];
1061 unsigned PartOffset = Outs[realArgIdx + 1].PartOffset;
1063 DAG.getFrameIndex(FI, PtrVT), TypeSize::getFixed(PartOffset), dl);
1064 MemOpChains.push_back(
1065 DAG.getStore(Chain, dl, PartValue, Address,
1067 assert((PartOffset + PartValue.getValueType().getStoreSize() <=
1068 SlotVT.getStoreSize()) &&
1069 "Not enough space for argument part!");
1070 ++i;
1071 ++realArgIdx;
1072 }
1073
1074 Arg = SpillSlot;
1075 }
1076
1077 // Arguments that can be passed on register must be kept at
1078 // RegsToPass vector
1079 if (VA.isRegLoc()) {
1080 if (VA.getLocVT() != MVT::f32) {
1081 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
1082 continue;
1083 }
1084 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg);
1085 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
1086 continue;
1087 }
1088
1089 assert(VA.isMemLoc());
1090
1091 // Create a store off the stack pointer for this argument.
1092 SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
1094 dl);
1095 PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
1096 MemOpChains.push_back(
1097 DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
1098 }
1099
1100
1101 // Emit all stores, make sure the occur before any copies into physregs.
1102 if (!MemOpChains.empty())
1103 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
1104
1105 // Build a sequence of copy-to-reg nodes chained together with token
1106 // chain and flag operands which copy the outgoing args into registers.
1107 // The InGlue in necessary since all emitted instructions must be
1108 // stuck together.
1109 SDValue InGlue;
1110 for (const auto &[OrigReg, N] : RegsToPass) {
1111 Register Reg = isTailCall ? OrigReg : toCallerWindow(OrigReg);
1112 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
1113 InGlue = Chain.getValue(1);
1114 }
1115
1116 bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CB);
1117
1118 // If the callee is a GlobalAddress node (quite common, every direct call is)
1119 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
1120 // Likewise ExternalSymbol -> TargetExternalSymbol.
1122 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32, 0);
1124 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
1125
1126 // Returns a chain & a flag for retval copy to use
1127 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1129 Ops.push_back(Chain);
1130 Ops.push_back(Callee);
1131 if (hasStructRetAttr)
1132 Ops.push_back(DAG.getTargetConstant(SRetArgSize, dl, MVT::i32));
1133 for (const auto &[OrigReg, N] : RegsToPass) {
1134 Register Reg = isTailCall ? OrigReg : toCallerWindow(OrigReg);
1135 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
1136 }
1137
1138 // Add a register mask operand representing the call-preserved registers.
1139 const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo();
1140 const uint32_t *Mask =
1141 ((hasReturnsTwice)
1142 ? TRI->getRTCallPreservedMask(CallConv)
1143 : TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv));
1144
1145 if (isAnyArgRegReserved(TRI, MF))
1147
1148 assert(Mask && "Missing call preserved mask for calling convention");
1149 Ops.push_back(DAG.getRegisterMask(Mask));
1150
1151 if (InGlue.getNode())
1152 Ops.push_back(InGlue);
1153
1154 if (isTailCall) {
1156 return DAG.getNode(SPISD::TAIL_CALL, dl, MVT::Other, Ops);
1157 }
1158
1159 Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, Ops);
1160 InGlue = Chain.getValue(1);
1161
1162 Chain = DAG.getCALLSEQ_END(Chain, ArgsSize, 0, InGlue, dl);
1163 InGlue = Chain.getValue(1);
1164
1165 // Assign locations to each value returned by this call.
1167 CCState RVInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1168 *DAG.getContext());
1169
1170 RVInfo.AnalyzeCallResult(Ins, RetCC_Sparc32);
1171
1172 // Copy all of the result registers out of their specified physreg.
1173 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1174 assert(RVLocs[i].isRegLoc() && "Can only return in registers!");
1175 if (RVLocs[i].getLocVT() == MVT::v2i32) {
1176 SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2i32);
1178 Chain, dl, toCallerWindow(RVLocs[i++].getLocReg()), MVT::i32, InGlue);
1179 Chain = Lo.getValue(1);
1180 InGlue = Lo.getValue(2);
1181 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2i32, Vec, Lo,
1182 DAG.getConstant(0, dl, MVT::i32));
1184 Chain, dl, toCallerWindow(RVLocs[i].getLocReg()), MVT::i32, InGlue);
1185 Chain = Hi.getValue(1);
1186 InGlue = Hi.getValue(2);
1187 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2i32, Vec, Hi,
1188 DAG.getConstant(1, dl, MVT::i32));
1189 InVals.push_back(Vec);
1190 } else {
1191 Chain =
1192 DAG.getCopyFromReg(Chain, dl, toCallerWindow(RVLocs[i].getLocReg()),
1193 RVLocs[i].getValVT(), InGlue)
1194 .getValue(1);
1195 InGlue = Chain.getValue(2);
1196 InVals.push_back(Chain.getValue(0));
1197 }
1198 }
1199
1200 return Chain;
1201}
1202
1203// FIXME? Maybe this could be a TableGen attribute on some registers and
1204// this table could be generated automatically from RegInfo.
1206 const MachineFunction &MF) const {
1208 .Case("i0", SP::I0).Case("i1", SP::I1).Case("i2", SP::I2).Case("i3", SP::I3)
1209 .Case("i4", SP::I4).Case("i5", SP::I5).Case("i6", SP::I6).Case("i7", SP::I7)
1210 .Case("o0", SP::O0).Case("o1", SP::O1).Case("o2", SP::O2).Case("o3", SP::O3)
1211 .Case("o4", SP::O4).Case("o5", SP::O5).Case("o6", SP::O6).Case("o7", SP::O7)
1212 .Case("l0", SP::L0).Case("l1", SP::L1).Case("l2", SP::L2).Case("l3", SP::L3)
1213 .Case("l4", SP::L4).Case("l5", SP::L5).Case("l6", SP::L6).Case("l7", SP::L7)
1214 .Case("g0", SP::G0).Case("g1", SP::G1).Case("g2", SP::G2).Case("g3", SP::G3)
1215 .Case("g4", SP::G4).Case("g5", SP::G5).Case("g6", SP::G6).Case("g7", SP::G7)
1216 .Default(0);
1217
1218 // If we're directly referencing register names
1219 // (e.g in GCC C extension `register int r asm("g1");`),
1220 // make sure that said register is in the reserve list.
1221 const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo();
1222 if (!TRI->isReservedReg(MF, Reg))
1223 Reg = Register();
1224
1225 return Reg;
1226}
1227
1228// Fixup floating point arguments in the ... part of a varargs call.
1229//
1230// The SPARC v9 ABI requires that floating point arguments are treated the same
1231// as integers when calling a varargs function. This does not apply to the
1232// fixed arguments that are part of the function's prototype.
1233//
1234// This function post-processes a CCValAssign array created by
1235// AnalyzeCallOperands().
1238 for (CCValAssign &VA : ArgLocs) {
1239 MVT ValTy = VA.getLocVT();
1240 // FIXME: What about f32 arguments? C promotes them to f64 when calling
1241 // varargs functions.
1242 if (!VA.isRegLoc() || (ValTy != MVT::f64 && ValTy != MVT::f128))
1243 continue;
1244 // The fixed arguments to a varargs function still go in FP registers.
1245 if (!Outs[VA.getValNo()].Flags.isVarArg())
1246 continue;
1247
1248 // This floating point argument should be reassigned.
1249 // Determine the offset into the argument array.
1250 Register firstReg = (ValTy == MVT::f64) ? SP::D0 : SP::Q0;
1251 unsigned argSize = (ValTy == MVT::f64) ? 8 : 16;
1252 unsigned Offset = argSize * (VA.getLocReg() - firstReg);
1253 assert(Offset < 16*8 && "Offset out of range, bad register enum?");
1254
1255 if (Offset < 6*8) {
1256 // This argument should go in %i0-%i5.
1257 unsigned IReg = SP::I0 + Offset/8;
1258 if (ValTy == MVT::f64)
1259 // Full register, just bitconvert into i64.
1260 VA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(), IReg, MVT::i64,
1262 else {
1263 assert(ValTy == MVT::f128 && "Unexpected type!");
1264 // Full register, just bitconvert into i128 -- We will lower this into
1265 // two i64s in LowerCall_64.
1266 VA = CCValAssign::getCustomReg(VA.getValNo(), VA.getValVT(), IReg,
1267 MVT::i128, CCValAssign::BCvt);
1268 }
1269 } else {
1270 // This needs to go to memory, we're out of integer registers.
1271 VA = CCValAssign::getMem(VA.getValNo(), VA.getValVT(), Offset,
1272 VA.getLocVT(), VA.getLocInfo());
1273 }
1274 }
1275}
1276
1277// Lower a call for the 64-bit ABI.
1278SDValue
1280 SmallVectorImpl<SDValue> &InVals) const {
1281 SelectionDAG &DAG = CLI.DAG;
1282 SDLoc DL = CLI.DL;
1283 SDValue Chain = CLI.Chain;
1284 auto PtrVT = getPointerTy(DAG.getDataLayout());
1286
1287 // Analyze operands of the call, assigning locations to each operand.
1289 CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), ArgLocs,
1290 *DAG.getContext());
1291 CCInfo.AnalyzeCallOperands(CLI.Outs, CC_Sparc64);
1292
1294 CCInfo, CLI, DAG.getMachineFunction());
1295
1296 // Get the size of the outgoing arguments stack space requirement.
1297 // The stack offset computed by CC_Sparc64 includes all arguments.
1298 // Called functions expect 6 argument words to exist in the stack frame, used
1299 // or not.
1300 unsigned StackReserved = 6 * 8u;
1301 unsigned ArgsSize = std::max<unsigned>(StackReserved, CCInfo.getStackSize());
1302
1303 // Keep stack frames 16-byte aligned.
1304 ArgsSize = alignTo(ArgsSize, 16);
1305
1306 // Varargs calls require special treatment.
1307 if (CLI.IsVarArg)
1308 fixupVariableFloatArgs(ArgLocs, CLI.Outs);
1309
1310 assert(!CLI.IsTailCall || ArgsSize == StackReserved);
1311
1312 // Adjust the stack pointer to make room for the arguments.
1313 // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls
1314 // with more than 6 arguments.
1315 if (!CLI.IsTailCall)
1316 Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, DL);
1317
1318 // Collect the set of registers to pass to the function and their values.
1319 // This will be emitted as a sequence of CopyToReg nodes glued to the call
1320 // instruction.
1322
1323 // Collect chains from all the memory opeations that copy arguments to the
1324 // stack. They must follow the stack pointer adjustment above and precede the
1325 // call instruction itself.
1326 SmallVector<SDValue, 8> MemOpChains;
1327
1328 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1329 const CCValAssign &VA = ArgLocs[i];
1330 SDValue Arg = CLI.OutVals[i];
1331
1332 // Promote the value if needed.
1333 switch (VA.getLocInfo()) {
1334 default:
1335 llvm_unreachable("Unknown location info!");
1336 case CCValAssign::Full:
1337 break;
1338 case CCValAssign::SExt:
1339 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
1340 break;
1341 case CCValAssign::ZExt:
1342 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
1343 break;
1344 case CCValAssign::AExt:
1345 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
1346 break;
1347 case CCValAssign::BCvt:
1348 // fixupVariableFloatArgs() may create bitcasts from f128 to i128. But
1349 // SPARC does not support i128 natively. Lower it into two i64, see below.
1350 if (!VA.needsCustom() || VA.getValVT() != MVT::f128
1351 || VA.getLocVT() != MVT::i128)
1352 Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
1353 break;
1354 }
1355
1356 if (VA.isRegLoc()) {
1357 if (VA.needsCustom() && VA.getValVT() == MVT::f128
1358 && VA.getLocVT() == MVT::i128) {
1359 // Store and reload into the integer register reg and reg+1.
1360 unsigned Offset = 8 * (VA.getLocReg() - SP::I0);
1361 unsigned StackOffset = Offset + Subtarget->getStackPointerBias() + 128;
1362 SDValue StackPtr = DAG.getRegister(SP::O6, PtrVT);
1363 SDValue HiPtrOff = DAG.getIntPtrConstant(StackOffset, DL);
1364 HiPtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, HiPtrOff);
1365 SDValue LoPtrOff = DAG.getIntPtrConstant(StackOffset + 8, DL);
1366 LoPtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, LoPtrOff);
1367
1368 // Store to %sp+BIAS+128+Offset
1369 SDValue Store =
1370 DAG.getStore(Chain, DL, Arg, HiPtrOff, MachinePointerInfo());
1371 // Load into Reg and Reg+1
1372 SDValue Hi64 =
1373 DAG.getLoad(MVT::i64, DL, Store, HiPtrOff, MachinePointerInfo());
1374 SDValue Lo64 =
1375 DAG.getLoad(MVT::i64, DL, Store, LoPtrOff, MachinePointerInfo());
1376
1377 Register HiReg = VA.getLocReg();
1378 Register LoReg = VA.getLocReg() + 1;
1379 if (!CLI.IsTailCall) {
1380 HiReg = toCallerWindow(HiReg);
1381 LoReg = toCallerWindow(LoReg);
1382 }
1383
1384 RegsToPass.push_back(std::make_pair(HiReg, Hi64));
1385 RegsToPass.push_back(std::make_pair(LoReg, Lo64));
1386 continue;
1387 }
1388
1389 // The custom bit on an i32 return value indicates that it should be
1390 // passed in the high bits of the register.
1391 if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
1392 Arg = DAG.getNode(ISD::SHL, DL, MVT::i64, Arg,
1393 DAG.getConstant(32, DL, MVT::i32));
1394
1395 // The next value may go in the low bits of the same register.
1396 // Handle both at once.
1397 if (i+1 < ArgLocs.size() && ArgLocs[i+1].isRegLoc() &&
1398 ArgLocs[i+1].getLocReg() == VA.getLocReg()) {
1399 SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64,
1400 CLI.OutVals[i+1]);
1401 Arg = DAG.getNode(ISD::OR, DL, MVT::i64, Arg, NV);
1402 // Skip the next value, it's already done.
1403 ++i;
1404 }
1405 }
1406
1407 Register Reg = VA.getLocReg();
1408 if (!CLI.IsTailCall)
1409 Reg = toCallerWindow(Reg);
1410 RegsToPass.push_back(std::make_pair(Reg, Arg));
1411 continue;
1412 }
1413
1414 assert(VA.isMemLoc());
1415
1416 // Create a store off the stack pointer for this argument.
1417 SDValue StackPtr = DAG.getRegister(SP::O6, PtrVT);
1418 // The argument area starts at %fp+BIAS+128 in the callee frame,
1419 // %sp+BIAS+128 in ours.
1420 SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset() +
1421 Subtarget->getStackPointerBias() +
1422 128, DL);
1423 PtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, PtrOff);
1424 MemOpChains.push_back(
1425 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo()));
1426 }
1427
1428 // Emit all stores, make sure they occur before the call.
1429 if (!MemOpChains.empty())
1430 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
1431
1432 // Build a sequence of CopyToReg nodes glued together with token chain and
1433 // glue operands which copy the outgoing args into registers. The InGlue is
1434 // necessary since all emitted instructions must be stuck together in order
1435 // to pass the live physical registers.
1436 SDValue InGlue;
1437 for (const auto &[Reg, N] : RegsToPass) {
1438 Chain = DAG.getCopyToReg(Chain, DL, Reg, N, InGlue);
1439 InGlue = Chain.getValue(1);
1440 }
1441
1442 // If the callee is a GlobalAddress node (quite common, every direct call is)
1443 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
1444 // Likewise ExternalSymbol -> TargetExternalSymbol.
1445 SDValue Callee = CLI.Callee;
1446 bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CB);
1448 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, PtrVT, 0);
1450 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT);
1451
1452 // Build the operands for the call instruction itself.
1454 Ops.push_back(Chain);
1455 Ops.push_back(Callee);
1456 for (const auto &[Reg, N] : RegsToPass)
1457 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
1458
1459 // Add a register mask operand representing the call-preserved registers.
1460 const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo();
1461 const uint32_t *Mask =
1462 ((hasReturnsTwice) ? TRI->getRTCallPreservedMask(CLI.CallConv)
1463 : TRI->getCallPreservedMask(DAG.getMachineFunction(),
1464 CLI.CallConv));
1465
1466 if (isAnyArgRegReserved(TRI, MF))
1468
1469 assert(Mask && "Missing call preserved mask for calling convention");
1470 Ops.push_back(DAG.getRegisterMask(Mask));
1471
1472 // Make sure the CopyToReg nodes are glued to the call instruction which
1473 // consumes the registers.
1474 if (InGlue.getNode())
1475 Ops.push_back(InGlue);
1476
1477 // Now the call itself.
1478 if (CLI.IsTailCall) {
1480 return DAG.getNode(SPISD::TAIL_CALL, DL, MVT::Other, Ops);
1481 }
1482 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1483 Chain = DAG.getNode(SPISD::CALL, DL, NodeTys, Ops);
1484 InGlue = Chain.getValue(1);
1485
1486 // Revert the stack pointer immediately after the call.
1487 Chain = DAG.getCALLSEQ_END(Chain, ArgsSize, 0, InGlue, DL);
1488 InGlue = Chain.getValue(1);
1489
1490 // Now extract the return values. This is more or less the same as
1491 // LowerFormalArguments_64.
1492
1493 // Assign locations to each value returned by this call.
1495 CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), RVLocs,
1496 *DAG.getContext());
1497
1498 // Set inreg flag manually for codegen generated library calls that
1499 // return float.
1500 if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && !CLI.CB)
1501 CLI.Ins[0].Flags.setInReg();
1502
1503 RVInfo.AnalyzeCallResult(CLI.Ins, RetCC_Sparc64);
1504
1505 // Copy all of the result registers out of their specified physreg.
1506 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1507 CCValAssign &VA = RVLocs[i];
1508 assert(VA.isRegLoc() && "Can only return in registers!");
1509 unsigned Reg = toCallerWindow(VA.getLocReg());
1510
1511 // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can
1512 // reside in the same register in the high and low bits. Reuse the
1513 // CopyFromReg previous node to avoid duplicate copies.
1514 SDValue RV;
1515 if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1)))
1516 if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg)
1517 RV = Chain.getValue(0);
1518
1519 // But usually we'll create a new CopyFromReg for a different register.
1520 if (!RV.getNode()) {
1521 RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue);
1522 Chain = RV.getValue(1);
1523 InGlue = Chain.getValue(2);
1524 }
1525
1526 // Get the high bits for i32 struct elements.
1527 if (VA.getValVT() == MVT::i32 && VA.needsCustom())
1528 RV = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), RV,
1529 DAG.getConstant(32, DL, MVT::i32));
1530
1531 // The callee promoted the return value, so insert an Assert?ext SDNode so
1532 // we won't promote the value again in this function.
1533 switch (VA.getLocInfo()) {
1534 case CCValAssign::SExt:
1535 RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV,
1536 DAG.getValueType(VA.getValVT()));
1537 break;
1538 case CCValAssign::ZExt:
1539 RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV,
1540 DAG.getValueType(VA.getValVT()));
1541 break;
1542 default:
1543 break;
1544 }
1545
1546 // Truncate the register down to the return value type.
1547 if (VA.isExtInLoc())
1548 RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV);
1549
1550 InVals.push_back(RV);
1551 }
1552
1553 return Chain;
1554}
1555
1556//===----------------------------------------------------------------------===//
1557// TargetLowering Implementation
1558//===----------------------------------------------------------------------===//
1559
1562 if (AI->getOperation() == AtomicRMWInst::Xchg &&
1563 AI->getType()->getPrimitiveSizeInBits() == 32)
1564 return AtomicExpansionKind::None; // Uses xchg instruction
1565
1567}
1568
1569/// intCondCCodeToRcond - Convert a DAG integer condition code to a SPARC
1570/// rcond condition.
1572 switch (CC) {
1573 default:
1574 llvm_unreachable("Unknown/unsigned integer condition code!");
1575 case ISD::SETEQ:
1576 return SPCC::REG_Z;
1577 case ISD::SETNE:
1578 return SPCC::REG_NZ;
1579 case ISD::SETLT:
1580 return SPCC::REG_LZ;
1581 case ISD::SETGT:
1582 return SPCC::REG_GZ;
1583 case ISD::SETLE:
1584 return SPCC::REG_LEZ;
1585 case ISD::SETGE:
1586 return SPCC::REG_GEZ;
1587 }
1588}
1589
1590/// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC
1591/// condition.
1593 switch (CC) {
1594 default: llvm_unreachable("Unknown integer condition code!");
1595 case ISD::SETEQ: return SPCC::ICC_E;
1596 case ISD::SETNE: return SPCC::ICC_NE;
1597 case ISD::SETLT: return SPCC::ICC_L;
1598 case ISD::SETGT: return SPCC::ICC_G;
1599 case ISD::SETLE: return SPCC::ICC_LE;
1600 case ISD::SETGE: return SPCC::ICC_GE;
1601 case ISD::SETULT: return SPCC::ICC_CS;
1602 case ISD::SETULE: return SPCC::ICC_LEU;
1603 case ISD::SETUGT: return SPCC::ICC_GU;
1604 case ISD::SETUGE: return SPCC::ICC_CC;
1605 }
1606}
1607
1608/// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC
1609/// FCC condition.
1611 switch (CC) {
1612 default: llvm_unreachable("Unknown fp condition code!");
1613 case ISD::SETEQ:
1614 case ISD::SETOEQ: return SPCC::FCC_E;
1615 case ISD::SETNE:
1616 case ISD::SETUNE: return SPCC::FCC_NE;
1617 case ISD::SETLT:
1618 case ISD::SETOLT: return SPCC::FCC_L;
1619 case ISD::SETGT:
1620 case ISD::SETOGT: return SPCC::FCC_G;
1621 case ISD::SETLE:
1622 case ISD::SETOLE: return SPCC::FCC_LE;
1623 case ISD::SETGE:
1624 case ISD::SETOGE: return SPCC::FCC_GE;
1625 case ISD::SETULT: return SPCC::FCC_UL;
1626 case ISD::SETULE: return SPCC::FCC_ULE;
1627 case ISD::SETUGT: return SPCC::FCC_UG;
1628 case ISD::SETUGE: return SPCC::FCC_UGE;
1629 case ISD::SETUO: return SPCC::FCC_U;
1630 case ISD::SETO: return SPCC::FCC_O;
1631 case ISD::SETONE: return SPCC::FCC_LG;
1632 case ISD::SETUEQ: return SPCC::FCC_UE;
1633 }
1634}
1635
1637 const SparcSubtarget &STI)
1638 : TargetLowering(TM, STI), Subtarget(&STI) {
1639 MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
1640
1641 // Instructions which use registers as conditionals examine all the
1642 // bits (as does the pseudo SELECT_CC expansion). I don't think it
1643 // matters much whether it's ZeroOrOneBooleanContent, or
1644 // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the
1645 // former.
1648
1649 // Set up the register classes.
1650 addRegisterClass(MVT::i32, &SP::IntRegsRegClass);
1651 if (!Subtarget->useSoftFloat()) {
1652 addRegisterClass(MVT::f32, &SP::FPRegsRegClass);
1653 addRegisterClass(MVT::f64, &SP::DFPRegsRegClass);
1654 addRegisterClass(MVT::f128, &SP::QFPRegsRegClass);
1655 }
1656 if (Subtarget->is64Bit()) {
1657 addRegisterClass(MVT::i64, &SP::I64RegsRegClass);
1658 } else {
1659 // On 32bit sparc, we define a double-register 32bit register
1660 // class, as well. This is modeled in LLVM as a 2-vector of i32.
1661 addRegisterClass(MVT::v2i32, &SP::IntPairRegClass);
1662
1663 // ...but almost all operations must be expanded, so set that as
1664 // the default.
1665 for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op) {
1666 setOperationAction(Op, MVT::v2i32, Expand);
1667 }
1668 // Truncating/extending stores/loads are also not supported.
1670 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::v2i32, Expand);
1671 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::v2i32, Expand);
1672 setLoadExtAction(ISD::EXTLOAD, VT, MVT::v2i32, Expand);
1673
1674 setLoadExtAction(ISD::SEXTLOAD, MVT::v2i32, VT, Expand);
1675 setLoadExtAction(ISD::ZEXTLOAD, MVT::v2i32, VT, Expand);
1676 setLoadExtAction(ISD::EXTLOAD, MVT::v2i32, VT, Expand);
1677
1678 setTruncStoreAction(VT, MVT::v2i32, Expand);
1679 setTruncStoreAction(MVT::v2i32, VT, Expand);
1680 }
1681 // However, load and store *are* legal.
1682 setOperationAction(ISD::LOAD, MVT::v2i32, Legal);
1683 setOperationAction(ISD::STORE, MVT::v2i32, Legal);
1686
1687 // And we need to promote i64 loads/stores into vector load/store
1690
1691 // Sadly, this doesn't work:
1692 // AddPromotedToType(ISD::LOAD, MVT::i64, MVT::v2i32);
1693 // AddPromotedToType(ISD::STORE, MVT::i64, MVT::v2i32);
1694 }
1695
1696 // Turn FP extload into load/fpextend
1697 for (MVT VT : MVT::fp_valuetypes()) {
1698 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
1699 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
1700 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f64, Expand);
1701 }
1702
1703 // Sparc doesn't have i1 sign extending load
1704 for (MVT VT : MVT::integer_valuetypes())
1705 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
1706
1707 // Turn FP truncstore into trunc + store.
1708 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
1709 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
1710 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
1711 setTruncStoreAction(MVT::f128, MVT::f16, Expand);
1712 setTruncStoreAction(MVT::f128, MVT::f32, Expand);
1713 setTruncStoreAction(MVT::f128, MVT::f64, Expand);
1714
1715 // Custom legalize GlobalAddress nodes into LO/HI parts.
1720
1721 // Sparc doesn't have sext_inreg, replace them with shl/sra
1725
1726 // Sparc has no REM or DIVREM operations.
1731
1732 // ... nor does SparcV9.
1733 if (Subtarget->is64Bit()) {
1738 }
1739
1740 // Custom expand fp<->sint
1745
1746 // Custom Expand fp<->uint
1751
1752 // Lower f16 conversion operations into library calls
1759
1761 Subtarget->isVIS3() ? Legal : Expand);
1763 Subtarget->isVIS3() ? Legal : Expand);
1764
1765 // Sparc has no select or setcc: expand to SELECT_CC.
1770
1775
1776 // Sparc doesn't have BRCOND either, it has BR_CC.
1778 setOperationAction(ISD::BRIND, MVT::Other, Expand);
1779 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
1784
1789
1794
1795 if (Subtarget->isVIS3()) {
1798 }
1799
1800 if (Subtarget->is64Bit()) {
1802 Subtarget->isVIS3() ? Legal : Expand);
1804 Subtarget->isVIS3() ? Legal : Expand);
1809
1811 Subtarget->usePopc() ? Legal : Expand);
1813 setOperationAction(ISD::ROTL , MVT::i64, Expand);
1814 setOperationAction(ISD::ROTR , MVT::i64, Expand);
1816 }
1817
1818 // ATOMICs.
1819 // Atomics are supported on SparcV9. 32-bit atomics are also
1820 // supported by some Leon SparcV8 variants. Otherwise, atomics
1821 // are unsupported.
1822 if (Subtarget->isV9()) {
1823 // TODO: we _ought_ to be able to support 64-bit atomics on 32-bit sparcv9,
1824 // but it hasn't been implemented in the backend yet.
1825 if (Subtarget->is64Bit())
1827 else
1829 } else if (Subtarget->hasLeonCasa())
1831 else
1833
1835
1837
1839
1840 // Custom Lower Atomic LOAD/STORE
1843
1844 if (Subtarget->is64Bit()) {
1849 }
1850
1851 if (!Subtarget->isV9()) {
1852 // SparcV8 does not have FNEGD and FABSD.
1855 }
1856
1857 setOperationAction(ISD::FSIN , MVT::f128, Expand);
1858 setOperationAction(ISD::FCOS , MVT::f128, Expand);
1861 setOperationAction(ISD::FMA , MVT::f128, Expand);
1862 setOperationAction(ISD::FSIN , MVT::f64, Expand);
1863 setOperationAction(ISD::FCOS , MVT::f64, Expand);
1866 setOperationAction(ISD::FMA, MVT::f64,
1867 Subtarget->isUA2007() ? Legal : Expand);
1868 setOperationAction(ISD::FSIN , MVT::f32, Expand);
1869 setOperationAction(ISD::FCOS , MVT::f32, Expand);
1872 setOperationAction(ISD::FMA, MVT::f32,
1873 Subtarget->isUA2007() ? Legal : Expand);
1874 setOperationAction(ISD::ROTL , MVT::i32, Expand);
1875 setOperationAction(ISD::ROTR , MVT::i32, Expand);
1876 setOperationAction(ISD::BSWAP, MVT::i32, Subtarget->isV9() ? Custom : Expand);
1880 setOperationAction(ISD::FPOW , MVT::f128, Expand);
1881 setOperationAction(ISD::FPOW , MVT::f64, Expand);
1882 setOperationAction(ISD::FPOW , MVT::f32, Expand);
1883
1887
1888 // Expands to [SU]MUL_LOHI.
1892
1893 if (Subtarget->useSoftMulDiv()) {
1894 // .umul works for both signed and unsigned
1899 }
1900
1901 if (Subtarget->is64Bit()) {
1905 Subtarget->isVIS3() ? Legal : Expand);
1907 Subtarget->isVIS3() ? Legal : Expand);
1908
1912 }
1913
1914 // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
1915 setOperationAction(ISD::VASTART , MVT::Other, Custom);
1916 // VAARG needs to be lowered to not do unaligned accesses for doubles.
1917 setOperationAction(ISD::VAARG , MVT::Other, Custom);
1918
1919 setOperationAction(ISD::TRAP , MVT::Other, Legal);
1921
1922 // Use the default implementation.
1923 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
1924 setOperationAction(ISD::VAEND , MVT::Other, Expand);
1929
1931
1933 Subtarget->usePopc() ? Legal : Expand);
1934
1935 if (Subtarget->isV9() && Subtarget->hasHardQuad()) {
1936 setOperationAction(ISD::LOAD, MVT::f128, Legal);
1937 setOperationAction(ISD::STORE, MVT::f128, Legal);
1938 } else {
1939 setOperationAction(ISD::LOAD, MVT::f128, Custom);
1941 }
1942
1943 if (Subtarget->hasHardQuad()) {
1944 setOperationAction(ISD::FADD, MVT::f128, Legal);
1945 setOperationAction(ISD::FSUB, MVT::f128, Legal);
1946 setOperationAction(ISD::FMUL, MVT::f128, Legal);
1947 setOperationAction(ISD::FDIV, MVT::f128, Legal);
1948 setOperationAction(ISD::FSQRT, MVT::f128, Legal);
1951 if (Subtarget->isV9()) {
1952 setOperationAction(ISD::FNEG, MVT::f128, Legal);
1953 setOperationAction(ISD::FABS, MVT::f128, Legal);
1954 } else {
1955 setOperationAction(ISD::FNEG, MVT::f128, Custom);
1956 setOperationAction(ISD::FABS, MVT::f128, Custom);
1957 }
1958 } else {
1959 // Custom legalize f128 operations.
1960
1961 setOperationAction(ISD::FADD, MVT::f128, Custom);
1962 setOperationAction(ISD::FSUB, MVT::f128, Custom);
1963 setOperationAction(ISD::FMUL, MVT::f128, Custom);
1964 setOperationAction(ISD::FDIV, MVT::f128, Custom);
1966 setOperationAction(ISD::FNEG, MVT::f128, Custom);
1967 setOperationAction(ISD::FABS, MVT::f128, Custom);
1968
1972 }
1973
1974 if (Subtarget->fixAllFDIVSQRT()) {
1975 // Promote FDIVS and FSQRTS to FDIVD and FSQRTD instructions instead as
1976 // the former instructions generate errata on LEON processors.
1979 }
1980
1981 if (Subtarget->hasNoFMULS()) {
1983 }
1984
1985 // Custom combine bitcast between f64 and v2i32
1986 if (!Subtarget->is64Bit())
1988
1989 if (Subtarget->isV9())
1991
1992 if (Subtarget->hasLeonCycleCounter())
1994
1995 if (Subtarget->isVIS3()) {
2000
2001 setOperationAction(ISD::CTTZ, MVT::i32,
2002 Subtarget->is64Bit() ? Promote : Expand);
2005 Subtarget->is64Bit() ? Promote : Expand);
2007 } else if (Subtarget->usePopc()) {
2012
2017 } else {
2021 Subtarget->is64Bit() ? Promote : LibCall);
2023
2024 // FIXME here we don't have any ISA extensions that could help us, so to
2025 // prevent large expansions those should be made into LibCalls.
2030 }
2031
2033
2034 // Some processors have no branch predictor and have pipelines longer than
2035 // what can be covered by the delay slot. This results in a stall, so mark
2036 // branches to be expensive on those processors.
2037 setJumpIsExpensive(Subtarget->hasNoPredictor());
2038 // The high cost of branching means that using conditional moves will
2039 // still be profitable even if the condition is predictable.
2041
2043
2044 computeRegisterProperties(Subtarget->getRegisterInfo());
2045}
2046
2048 return Subtarget->useSoftFloat();
2049}
2050
2052 EVT VT) const {
2053 if (!VT.isVector())
2054 return MVT::i32;
2056}
2057
2058/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
2059/// be zero. Op is expected to be a target specific node. Used by DAG
2060/// combiner.
2062 (const SDValue Op,
2064 const APInt &DemandedElts,
2065 const SelectionDAG &DAG,
2066 unsigned Depth) const {
2067 KnownBits Known2;
2068 Known.resetAll();
2069
2070 switch (Op.getOpcode()) {
2071 default: break;
2072 case SPISD::SELECT_ICC:
2073 case SPISD::SELECT_XCC:
2074 case SPISD::SELECT_FCC:
2075 Known = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
2076 Known2 = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
2077
2078 // Only known if known in both the LHS and RHS.
2079 Known = Known.intersectWith(Known2);
2080 break;
2081 }
2082}
2083
2084// Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so
2085// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
2087 ISD::CondCode CC, unsigned &SPCC) {
2088 if (isNullConstant(RHS) && CC == ISD::SETNE &&
2089 (((LHS.getOpcode() == SPISD::SELECT_ICC ||
2090 LHS.getOpcode() == SPISD::SELECT_XCC) &&
2091 LHS.getOperand(3).getOpcode() == SPISD::CMPICC) ||
2092 (LHS.getOpcode() == SPISD::SELECT_FCC &&
2093 (LHS.getOperand(3).getOpcode() == SPISD::CMPFCC ||
2094 LHS.getOperand(3).getOpcode() == SPISD::CMPFCC_V9))) &&
2095 isOneConstant(LHS.getOperand(0)) && isNullConstant(LHS.getOperand(1))) {
2096 SDValue CMPCC = LHS.getOperand(3);
2097 SPCC = LHS.getConstantOperandVal(2);
2098 LHS = CMPCC.getOperand(0);
2099 RHS = CMPCC.getOperand(1);
2100 }
2101}
2102
2103// Convert to a target node and set target flags.
2105 SelectionDAG &DAG) const {
2107 return DAG.getTargetGlobalAddress(GA->getGlobal(),
2108 SDLoc(GA),
2109 GA->getValueType(0),
2110 GA->getOffset(), TF);
2111
2113 return DAG.getTargetConstantPool(CP->getConstVal(), CP->getValueType(0),
2114 CP->getAlign(), CP->getOffset(), TF);
2115
2117 return DAG.getTargetBlockAddress(BA->getBlockAddress(),
2118 Op.getValueType(),
2119 0,
2120 TF);
2121
2123 return DAG.getTargetExternalSymbol(ES->getSymbol(),
2124 ES->getValueType(0), TF);
2125
2126 llvm_unreachable("Unhandled address SDNode");
2127}
2128
2129// Split Op into high and low parts according to HiTF and LoTF.
2130// Return an ADD node combining the parts.
2132 unsigned HiTF, unsigned LoTF,
2133 SelectionDAG &DAG) const {
2134 SDLoc DL(Op);
2135 EVT VT = Op.getValueType();
2136 SDValue Hi = DAG.getNode(SPISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG));
2137 SDValue Lo = DAG.getNode(SPISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG));
2138 return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
2139}
2140
2141// Build SDNodes for producing an address from a GlobalAddress, ConstantPool,
2142// or ExternalSymbol SDNode.
2144 SDLoc DL(Op);
2145 EVT VT = getPointerTy(DAG.getDataLayout());
2146
2147 // Handle PIC mode first. SPARC needs a got load for every variable!
2148 if (isPositionIndependent()) {
2149 const Module *M = DAG.getMachineFunction().getFunction().getParent();
2150 PICLevel::Level picLevel = M->getPICLevel();
2151 SDValue Idx;
2152
2153 if (picLevel == PICLevel::SmallPIC) {
2154 // This is the pic13 code model, the GOT is known to be smaller than 8KiB.
2155 Idx = DAG.getNode(SPISD::Lo, DL, Op.getValueType(),
2156 withTargetFlags(Op, ELF::R_SPARC_GOT13, DAG));
2157 } else {
2158 // This is the pic32 code model, the GOT is known to be smaller than 4GB.
2159 Idx = makeHiLoPair(Op, ELF::R_SPARC_GOT22, ELF::R_SPARC_GOT10, DAG);
2160 }
2161
2162 SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT);
2163 SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, Idx);
2164 // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
2165 // function has calls.
2167 MFI.setHasCalls(true);
2168 return DAG.getLoad(VT, DL, DAG.getEntryNode(), AbsAddr,
2170 }
2171
2172 // This is one of the absolute code models.
2173 switch(getTargetMachine().getCodeModel()) {
2174 default:
2175 llvm_unreachable("Unsupported absolute code model");
2176 case CodeModel::Small:
2177 // abs32.
2178 return makeHiLoPair(Op, ELF::R_SPARC_HI22, ELF::R_SPARC_LO10, DAG);
2179 case CodeModel::Medium: {
2180 // abs44.
2181 SDValue H44 = makeHiLoPair(Op, ELF::R_SPARC_H44, ELF::R_SPARC_M44, DAG);
2182 H44 = DAG.getNode(ISD::SHL, DL, VT, H44, DAG.getConstant(12, DL, MVT::i32));
2183 SDValue L44 = withTargetFlags(Op, ELF::R_SPARC_L44, DAG);
2184 L44 = DAG.getNode(SPISD::Lo, DL, VT, L44);
2185 return DAG.getNode(ISD::ADD, DL, VT, H44, L44);
2186 }
2187 case CodeModel::Large: {
2188 // abs64.
2189 SDValue Hi = makeHiLoPair(Op, ELF::R_SPARC_HH22, ELF::R_SPARC_HM10, DAG);
2190 Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, DAG.getConstant(32, DL, MVT::i32));
2191 SDValue Lo = makeHiLoPair(Op, ELF::R_SPARC_HI22, ELF::R_SPARC_LO10, DAG);
2192 return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
2193 }
2194 }
2195}
2196
2201
2206
2211
2213 SelectionDAG &DAG) const {
2214
2216 if (DAG.getTarget().useEmulatedTLS())
2217 return LowerToTLSEmulatedModel(GA, DAG);
2218
2219 SDLoc DL(GA);
2220 const GlobalValue *GV = GA->getGlobal();
2221 EVT PtrVT = getPointerTy(DAG.getDataLayout());
2222
2224
2225 if (model == TLSModel::GeneralDynamic || model == TLSModel::LocalDynamic) {
2226 unsigned HiTF =
2227 ((model == TLSModel::GeneralDynamic) ? ELF::R_SPARC_TLS_GD_HI22
2228 : ELF::R_SPARC_TLS_LDM_HI22);
2229 unsigned LoTF =
2230 ((model == TLSModel::GeneralDynamic) ? ELF::R_SPARC_TLS_GD_LO10
2231 : ELF::R_SPARC_TLS_LDM_LO10);
2232 unsigned addTF =
2233 ((model == TLSModel::GeneralDynamic) ? ELF::R_SPARC_TLS_GD_ADD
2234 : ELF::R_SPARC_TLS_LDM_ADD);
2235 unsigned callTF =
2236 ((model == TLSModel::GeneralDynamic) ? ELF::R_SPARC_TLS_GD_CALL
2237 : ELF::R_SPARC_TLS_LDM_CALL);
2238
2239 SDValue HiLo = makeHiLoPair(Op, HiTF, LoTF, DAG);
2240 SDValue Base = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, PtrVT);
2241 SDValue Argument = DAG.getNode(SPISD::TLS_ADD, DL, PtrVT, Base, HiLo,
2242 withTargetFlags(Op, addTF, DAG));
2243
2244 SDValue Chain = DAG.getEntryNode();
2245 SDValue InGlue;
2246
2247 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL);
2248 Chain = DAG.getCopyToReg(Chain, DL, SP::O0, Argument, InGlue);
2249 InGlue = Chain.getValue(1);
2250 SDValue Callee = DAG.getTargetExternalSymbol("__tls_get_addr", PtrVT);
2251 SDValue Symbol = withTargetFlags(Op, callTF, DAG);
2252
2253 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
2254 const uint32_t *Mask = Subtarget->getRegisterInfo()->getCallPreservedMask(
2256 assert(Mask && "Missing call preserved mask for calling convention");
2257 SDValue Ops[] = {Chain,
2258 Callee,
2259 Symbol,
2260 DAG.getRegister(SP::O0, PtrVT),
2261 DAG.getRegisterMask(Mask),
2262 InGlue};
2263 Chain = DAG.getNode(SPISD::TLS_CALL, DL, NodeTys, Ops);
2264 InGlue = Chain.getValue(1);
2265 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, InGlue, DL);
2266 InGlue = Chain.getValue(1);
2267 SDValue Ret = DAG.getCopyFromReg(Chain, DL, SP::O0, PtrVT, InGlue);
2268
2269 if (model != TLSModel::LocalDynamic)
2270 return Ret;
2271
2272 SDValue Hi =
2273 DAG.getNode(SPISD::Hi, DL, PtrVT,
2274 withTargetFlags(Op, ELF::R_SPARC_TLS_LDO_HIX22, DAG));
2275 SDValue Lo =
2276 DAG.getNode(SPISD::Lo, DL, PtrVT,
2277 withTargetFlags(Op, ELF::R_SPARC_TLS_LDO_LOX10, DAG));
2278 HiLo = DAG.getNode(ISD::XOR, DL, PtrVT, Hi, Lo);
2279 return DAG.getNode(SPISD::TLS_ADD, DL, PtrVT, Ret, HiLo,
2280 withTargetFlags(Op, ELF::R_SPARC_TLS_LDO_ADD, DAG));
2281 }
2282
2283 if (model == TLSModel::InitialExec) {
2284 unsigned ldTF = ((PtrVT == MVT::i64) ? ELF::R_SPARC_TLS_IE_LDX
2285 : ELF::R_SPARC_TLS_IE_LD);
2286
2287 SDValue Base = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, PtrVT);
2288
2289 // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
2290 // function has calls.
2292 MFI.setHasCalls(true);
2293
2294 SDValue TGA = makeHiLoPair(Op, ELF::R_SPARC_TLS_IE_HI22,
2295 ELF::R_SPARC_TLS_IE_LO10, DAG);
2296 SDValue Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Base, TGA);
2297 SDValue Offset = DAG.getNode(SPISD::TLS_LD,
2298 DL, PtrVT, Ptr,
2299 withTargetFlags(Op, ldTF, DAG));
2300 return DAG.getNode(SPISD::TLS_ADD, DL, PtrVT,
2301 DAG.getRegister(SP::G7, PtrVT), Offset,
2302 withTargetFlags(Op, ELF::R_SPARC_TLS_IE_ADD, DAG));
2303 }
2304
2305 assert(model == TLSModel::LocalExec);
2306 SDValue Hi = DAG.getNode(SPISD::Hi, DL, PtrVT,
2307 withTargetFlags(Op, ELF::R_SPARC_TLS_LE_HIX22, DAG));
2308 SDValue Lo = DAG.getNode(SPISD::Lo, DL, PtrVT,
2309 withTargetFlags(Op, ELF::R_SPARC_TLS_LE_LOX10, DAG));
2310 SDValue Offset = DAG.getNode(ISD::XOR, DL, PtrVT, Hi, Lo);
2311
2312 return DAG.getNode(ISD::ADD, DL, PtrVT,
2313 DAG.getRegister(SP::G7, PtrVT), Offset);
2314}
2315
2317 ArgListTy &Args, SDValue Arg,
2318 const SDLoc &DL,
2319 SelectionDAG &DAG) const {
2321 EVT ArgVT = Arg.getValueType();
2322 Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
2323
2324 if (ArgTy->isFP128Ty()) {
2325 // Create a stack object and pass the pointer to the library function.
2326 int FI = MFI.CreateStackObject(16, Align(8), false);
2327 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
2328 Chain = DAG.getStore(Chain, DL, Arg, FIPtr, MachinePointerInfo(), Align(8));
2329 Args.emplace_back(FIPtr, PointerType::getUnqual(ArgTy->getContext()));
2330 } else {
2331 Args.emplace_back(Arg, ArgTy);
2332 }
2333 return Chain;
2334}
2335
2337 RTLIB::Libcall LibFunc,
2338 unsigned numArgs) const {
2339 RTLIB::LibcallImpl LibFuncImpl = DAG.getLibcalls().getLibcallImpl(LibFunc);
2340 if (LibFuncImpl == RTLIB::Unsupported)
2341 return SDValue();
2342
2343 ArgListTy Args;
2344
2346 auto PtrVT = getPointerTy(DAG.getDataLayout());
2347
2348 SDValue Callee = DAG.getExternalSymbol(LibFuncImpl, PtrVT);
2349 Type *RetTy = Op.getValueType().getTypeForEVT(*DAG.getContext());
2350 Type *RetTyABI = RetTy;
2351 SDValue Chain = DAG.getEntryNode();
2352 SDValue RetPtr;
2353
2354 if (RetTy->isFP128Ty()) {
2355 // Create a Stack Object to receive the return value of type f128.
2356 int RetFI = MFI.CreateStackObject(16, Align(8), false);
2357 RetPtr = DAG.getFrameIndex(RetFI, PtrVT);
2358 ArgListEntry Entry(RetPtr, PointerType::getUnqual(RetTy->getContext()));
2359 if (!Subtarget->is64Bit()) {
2360 Entry.IsSRet = true;
2361 Entry.IndirectType = RetTy;
2362 }
2363 Entry.IsReturned = false;
2364 Args.push_back(Entry);
2365 RetTyABI = Type::getVoidTy(*DAG.getContext());
2366 }
2367
2368 assert(Op->getNumOperands() >= numArgs && "Not enough operands!");
2369 for (unsigned i = 0, e = numArgs; i != e; ++i) {
2370 Chain = LowerF128_LibCallArg(Chain, Args, Op.getOperand(i), SDLoc(Op), DAG);
2371 }
2372
2375 CLI.setDebugLoc(SDLoc(Op)).setChain(Chain).setCallee(CC, RetTyABI, Callee,
2376 std::move(Args));
2377
2378 std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
2379
2380 // chain is in second result.
2381 if (RetTyABI == RetTy)
2382 return CallInfo.first;
2383
2384 assert (RetTy->isFP128Ty() && "Unexpected return type!");
2385
2386 Chain = CallInfo.second;
2387
2388 // Load RetPtr to get the return value.
2389 return DAG.getLoad(Op.getValueType(), SDLoc(Op), Chain, RetPtr,
2391}
2392
2394 unsigned &SPCC, const SDLoc &DL,
2395 SelectionDAG &DAG) const {
2396
2397 const char *LibCall = nullptr;
2398 bool is64Bit = Subtarget->is64Bit();
2399 switch(SPCC) {
2400 default: llvm_unreachable("Unhandled conditional code!");
2401 case SPCC::FCC_E : LibCall = is64Bit? "_Qp_feq" : "_Q_feq"; break;
2402 case SPCC::FCC_NE : LibCall = is64Bit? "_Qp_fne" : "_Q_fne"; break;
2403 case SPCC::FCC_L : LibCall = is64Bit? "_Qp_flt" : "_Q_flt"; break;
2404 case SPCC::FCC_G : LibCall = is64Bit? "_Qp_fgt" : "_Q_fgt"; break;
2405 case SPCC::FCC_LE : LibCall = is64Bit? "_Qp_fle" : "_Q_fle"; break;
2406 case SPCC::FCC_GE : LibCall = is64Bit? "_Qp_fge" : "_Q_fge"; break;
2407 case SPCC::FCC_UL :
2408 case SPCC::FCC_ULE:
2409 case SPCC::FCC_UG :
2410 case SPCC::FCC_UGE:
2411 case SPCC::FCC_U :
2412 case SPCC::FCC_O :
2413 case SPCC::FCC_LG :
2414 case SPCC::FCC_UE : LibCall = is64Bit? "_Qp_cmp" : "_Q_cmp"; break;
2415 }
2416
2417 auto PtrVT = getPointerTy(DAG.getDataLayout());
2418 SDValue Callee = DAG.getExternalSymbol(LibCall, PtrVT);
2419 Type *RetTy = Type::getInt32Ty(*DAG.getContext());
2420 ArgListTy Args;
2421 SDValue Chain = DAG.getEntryNode();
2422 Chain = LowerF128_LibCallArg(Chain, Args, LHS, DL, DAG);
2423 Chain = LowerF128_LibCallArg(Chain, Args, RHS, DL, DAG);
2424
2426 CLI.setDebugLoc(DL).setChain(Chain)
2427 .setCallee(CallingConv::C, RetTy, Callee, std::move(Args));
2428
2429 std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
2430
2431 // result is in first, and chain is in second result.
2432 SDValue Result = CallInfo.first;
2433
2434 switch(SPCC) {
2435 default: {
2436 SDValue RHS = DAG.getConstant(0, DL, Result.getValueType());
2438 return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
2439 }
2440 case SPCC::FCC_UL : {
2441 SDValue Mask = DAG.getConstant(1, DL, Result.getValueType());
2442 Result = DAG.getNode(ISD::AND, DL, Result.getValueType(), Result, Mask);
2443 SDValue RHS = DAG.getConstant(0, DL, Result.getValueType());
2445 return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
2446 }
2447 case SPCC::FCC_ULE: {
2448 SDValue RHS = DAG.getConstant(2, DL, Result.getValueType());
2450 return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
2451 }
2452 case SPCC::FCC_UG : {
2453 SDValue RHS = DAG.getConstant(1, DL, Result.getValueType());
2454 SPCC = SPCC::ICC_G;
2455 return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
2456 }
2457 case SPCC::FCC_UGE: {
2458 SDValue RHS = DAG.getConstant(1, DL, Result.getValueType());
2460 return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
2461 }
2462
2463 case SPCC::FCC_U : {
2464 SDValue RHS = DAG.getConstant(3, DL, Result.getValueType());
2465 SPCC = SPCC::ICC_E;
2466 return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
2467 }
2468 case SPCC::FCC_O : {
2469 SDValue RHS = DAG.getConstant(3, DL, Result.getValueType());
2471 return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
2472 }
2473 case SPCC::FCC_LG : {
2474 SDValue Mask = DAG.getConstant(3, DL, Result.getValueType());
2475 Result = DAG.getNode(ISD::AND, DL, Result.getValueType(), Result, Mask);
2476 SDValue RHS = DAG.getConstant(0, DL, Result.getValueType());
2478 return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
2479 }
2480 case SPCC::FCC_UE : {
2481 SDValue Mask = DAG.getConstant(3, DL, Result.getValueType());
2482 Result = DAG.getNode(ISD::AND, DL, Result.getValueType(), Result, Mask);
2483 SDValue RHS = DAG.getConstant(0, DL, Result.getValueType());
2484 SPCC = SPCC::ICC_E;
2485 return DAG.getNode(SPISD::CMPICC, DL, MVT::Glue, Result, RHS);
2486 }
2487 }
2488}
2489
2490static SDValue
2492 const SparcTargetLowering &TLI) {
2493
2494 if (Op.getOperand(0).getValueType() == MVT::f64)
2495 return TLI.LowerF128Op(Op, DAG, RTLIB::FPEXT_F64_F128, 1);
2496
2497 if (Op.getOperand(0).getValueType() == MVT::f32)
2498 return TLI.LowerF128Op(Op, DAG, RTLIB::FPEXT_F32_F128, 1);
2499
2500 llvm_unreachable("fpextend with non-float operand!");
2501 return SDValue();
2502}
2503
2504static SDValue
2506 const SparcTargetLowering &TLI) {
2507 // FP_ROUND on f64 and f32 are legal.
2508 if (Op.getOperand(0).getValueType() != MVT::f128)
2509 return Op;
2510
2511 if (Op.getValueType() == MVT::f64)
2512 return TLI.LowerF128Op(Op, DAG, RTLIB::FPROUND_F128_F64, 1);
2513 if (Op.getValueType() == MVT::f32)
2514 return TLI.LowerF128Op(Op, DAG, RTLIB::FPROUND_F128_F32, 1);
2515
2516 llvm_unreachable("fpround to non-float!");
2517 return SDValue();
2518}
2519
2521 const SparcTargetLowering &TLI,
2522 bool hasHardQuad) {
2523 SDLoc dl(Op);
2524 EVT VT = Op.getValueType();
2525 assert(VT == MVT::i32 || VT == MVT::i64);
2526
2527 // Expand f128 operations to fp128 abi calls.
2528 if (Op.getOperand(0).getValueType() == MVT::f128
2529 && (!hasHardQuad || !TLI.isTypeLegal(VT))) {
2530 RTLIB::Libcall LibFunc =
2531 VT == MVT::i32 ? RTLIB::FPTOSINT_F128_I32 : RTLIB::FPTOSINT_F128_I64;
2532 return TLI.LowerF128Op(Op, DAG, LibFunc, 1);
2533 }
2534
2535 // Expand if the resulting type is illegal.
2536 if (!TLI.isTypeLegal(VT))
2537 return SDValue();
2538
2539 // Otherwise, Convert the fp value to integer in an FP register.
2540 if (VT == MVT::i32)
2541 Op = DAG.getNode(SPISD::FTOI, dl, MVT::f32, Op.getOperand(0));
2542 else
2543 Op = DAG.getNode(SPISD::FTOX, dl, MVT::f64, Op.getOperand(0));
2544
2545 return DAG.getNode(ISD::BITCAST, dl, VT, Op);
2546}
2547
2549 const SparcTargetLowering &TLI,
2550 bool hasHardQuad) {
2551 SDLoc dl(Op);
2552 EVT OpVT = Op.getOperand(0).getValueType();
2553 assert(OpVT == MVT::i32 || (OpVT == MVT::i64));
2554
2555 EVT floatVT = (OpVT == MVT::i32) ? MVT::f32 : MVT::f64;
2556
2557 // Expand f128 operations to fp128 ABI calls.
2558 if (Op.getValueType() == MVT::f128
2559 && (!hasHardQuad || !TLI.isTypeLegal(OpVT))) {
2560 RTLIB::Libcall LibFunc =
2561 OpVT == MVT::i32 ? RTLIB::SINTTOFP_I32_F128 : RTLIB::SINTTOFP_I64_F128;
2562 return TLI.LowerF128Op(Op, DAG, LibFunc, 1);
2563 }
2564
2565 // Expand if the operand type is illegal.
2566 if (!TLI.isTypeLegal(OpVT))
2567 return SDValue();
2568
2569 // Otherwise, Convert the int value to FP in an FP register.
2570 SDValue Tmp = DAG.getNode(ISD::BITCAST, dl, floatVT, Op.getOperand(0));
2571 unsigned opcode = (OpVT == MVT::i32)? SPISD::ITOF : SPISD::XTOF;
2572 return DAG.getNode(opcode, dl, Op.getValueType(), Tmp);
2573}
2574
2576 const SparcTargetLowering &TLI,
2577 bool hasHardQuad) {
2578 EVT VT = Op.getValueType();
2579
2580 // Expand if it does not involve f128 or the target has support for
2581 // quad floating point instructions and the resulting type is legal.
2582 if (Op.getOperand(0).getValueType() != MVT::f128 ||
2583 (hasHardQuad && TLI.isTypeLegal(VT)))
2584 return SDValue();
2585
2586 assert(VT == MVT::i32 || VT == MVT::i64);
2587
2588 return TLI.LowerF128Op(
2589 Op, DAG,
2590 VT == MVT::i32 ? RTLIB::FPTOUINT_F128_I32 : RTLIB::FPTOUINT_F128_I64, 1);
2591}
2592
2594 const SparcTargetLowering &TLI,
2595 bool hasHardQuad) {
2596 EVT OpVT = Op.getOperand(0).getValueType();
2597 assert(OpVT == MVT::i32 || OpVT == MVT::i64);
2598
2599 // Expand if it does not involve f128 or the target has support for
2600 // quad floating point instructions and the operand type is legal.
2601 if (Op.getValueType() != MVT::f128 || (hasHardQuad && TLI.isTypeLegal(OpVT)))
2602 return SDValue();
2603
2604 return TLI.LowerF128Op(Op, DAG,
2605 OpVT == MVT::i32 ? RTLIB::UINTTOFP_I32_F128
2606 : RTLIB::UINTTOFP_I64_F128,
2607 1);
2608}
2609
2611 const SparcTargetLowering &TLI, bool hasHardQuad,
2612 bool isV9, bool is64Bit) {
2613 SDValue Chain = Op.getOperand(0);
2614 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
2615 SDValue LHS = Op.getOperand(2);
2616 SDValue RHS = Op.getOperand(3);
2617 SDValue Dest = Op.getOperand(4);
2618 SDLoc dl(Op);
2619 unsigned Opc, SPCC = ~0U;
2620
2621 // If this is a br_cc of a "setcc", and if the setcc got lowered into
2622 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
2624 assert(LHS.getValueType() == RHS.getValueType());
2625
2626 // Get the condition flag.
2627 SDValue CompareFlag;
2628 if (LHS.getValueType().isInteger()) {
2629 // On V9 processors running in 64-bit mode, if CC compares two `i64`s
2630 // and the RHS is zero we might be able to use a specialized branch.
2631 if (is64Bit && isV9 && LHS.getValueType() == MVT::i64 &&
2633 return DAG.getNode(SPISD::BR_REG, dl, MVT::Other, Chain, Dest,
2634 DAG.getConstant(intCondCCodeToRcond(CC), dl, MVT::i32),
2635 LHS);
2636
2637 CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS);
2638 if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
2639 if (isV9)
2640 // 32-bit compares use the icc flags, 64-bit uses the xcc flags.
2641 Opc = LHS.getValueType() == MVT::i32 ? SPISD::BPICC : SPISD::BPXCC;
2642 else
2643 // Non-v9 targets don't have xcc.
2644 Opc = SPISD::BRICC;
2645 } else {
2646 if (!hasHardQuad && LHS.getValueType() == MVT::f128) {
2647 if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
2648 CompareFlag = TLI.LowerF128Compare(LHS, RHS, SPCC, dl, DAG);
2649 Opc = isV9 ? SPISD::BPICC : SPISD::BRICC;
2650 } else {
2651 unsigned CmpOpc = isV9 ? SPISD::CMPFCC_V9 : SPISD::CMPFCC;
2652 CompareFlag = DAG.getNode(CmpOpc, dl, MVT::Glue, LHS, RHS);
2653 if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
2654 Opc = isV9 ? SPISD::BRFCC_V9 : SPISD::BRFCC;
2655 }
2656 }
2657 return DAG.getNode(Opc, dl, MVT::Other, Chain, Dest,
2658 DAG.getConstant(SPCC, dl, MVT::i32), CompareFlag);
2659}
2660
2662 const SparcTargetLowering &TLI, bool hasHardQuad,
2663 bool isV9, bool is64Bit) {
2664 SDValue LHS = Op.getOperand(0);
2665 SDValue RHS = Op.getOperand(1);
2666 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
2667 SDValue TrueVal = Op.getOperand(2);
2668 SDValue FalseVal = Op.getOperand(3);
2669 SDLoc dl(Op);
2670 unsigned Opc, SPCC = ~0U;
2671
2672 // If this is a select_cc of a "setcc", and if the setcc got lowered into
2673 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
2675 assert(LHS.getValueType() == RHS.getValueType());
2676
2677 SDValue CompareFlag;
2678 if (LHS.getValueType().isInteger()) {
2679 // On V9 processors running in 64-bit mode, if CC compares two `i64`s
2680 // and the RHS is zero we might be able to use a specialized select.
2681 // All SELECT_CC between any two scalar integer types are eligible for
2682 // lowering to specialized instructions. Additionally, f32 and f64 types
2683 // are also eligible, but for f128 we can only use the specialized
2684 // instruction when we have hardquad.
2685 EVT ValType = TrueVal.getValueType();
2686 bool IsEligibleType = ValType.isScalarInteger() || ValType == MVT::f32 ||
2687 ValType == MVT::f64 ||
2688 (ValType == MVT::f128 && hasHardQuad);
2689 if (is64Bit && isV9 && LHS.getValueType() == MVT::i64 &&
2690 isNullConstant(RHS) && !ISD::isUnsignedIntSetCC(CC) && IsEligibleType)
2691 return DAG.getNode(
2692 SPISD::SELECT_REG, dl, TrueVal.getValueType(), TrueVal, FalseVal,
2693 DAG.getConstant(intCondCCodeToRcond(CC), dl, MVT::i32), LHS);
2694
2695 CompareFlag = DAG.getNode(SPISD::CMPICC, dl, MVT::Glue, LHS, RHS);
2696 Opc = LHS.getValueType() == MVT::i32 ?
2697 SPISD::SELECT_ICC : SPISD::SELECT_XCC;
2698 if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
2699 } else {
2700 if (!hasHardQuad && LHS.getValueType() == MVT::f128) {
2701 if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
2702 CompareFlag = TLI.LowerF128Compare(LHS, RHS, SPCC, dl, DAG);
2703 Opc = SPISD::SELECT_ICC;
2704 } else {
2705 unsigned CmpOpc = isV9 ? SPISD::CMPFCC_V9 : SPISD::CMPFCC;
2706 CompareFlag = DAG.getNode(CmpOpc, dl, MVT::Glue, LHS, RHS);
2707 Opc = SPISD::SELECT_FCC;
2708 if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
2709 }
2710 }
2711 return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal,
2712 DAG.getConstant(SPCC, dl, MVT::i32), CompareFlag);
2713}
2714
2716 const SparcTargetLowering &TLI) {
2719 auto PtrVT = TLI.getPointerTy(DAG.getDataLayout());
2720
2721 // Need frame address to find the address of VarArgsFrameIndex.
2723
2724 // vastart just stores the address of the VarArgsFrameIndex slot into the
2725 // memory location argument.
2726 SDLoc DL(Op);
2727 SDValue Offset =
2728 DAG.getNode(ISD::ADD, DL, PtrVT, DAG.getRegister(SP::I6, PtrVT),
2729 DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset(), DL));
2730 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
2731 return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1),
2732 MachinePointerInfo(SV));
2733}
2734
2736 SDNode *Node = Op.getNode();
2737 EVT VT = Node->getValueType(0);
2738 SDValue InChain = Node->getOperand(0);
2739 SDValue VAListPtr = Node->getOperand(1);
2740 EVT PtrVT = VAListPtr.getValueType();
2741 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
2742 SDLoc DL(Node);
2743 SDValue VAList =
2744 DAG.getLoad(PtrVT, DL, InChain, VAListPtr, MachinePointerInfo(SV));
2745 // Increment the pointer, VAList, to the next vaarg.
2746 SDValue NextPtr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
2748 DL));
2749 // Store the incremented VAList to the legalized pointer.
2750 InChain = DAG.getStore(VAList.getValue(1), DL, NextPtr, VAListPtr,
2751 MachinePointerInfo(SV));
2752 // Load the actual argument out of the pointer VAList.
2753 // We can't count on greater alignment than the word size.
2754 return DAG.getLoad(
2755 VT, DL, InChain, VAList, MachinePointerInfo(),
2756 Align(std::min(PtrVT.getFixedSizeInBits(), VT.getFixedSizeInBits()) / 8));
2757}
2758
2760 const SparcSubtarget &Subtarget) {
2761 SDValue Chain = Op.getOperand(0);
2762 EVT VT = Op->getValueType(0);
2763 SDLoc DL(Op);
2764
2765 MCRegister SPReg = SP::O6;
2766 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);
2767
2768 // Unbias the stack pointer register.
2769 unsigned OffsetToStackStart = Subtarget.getStackPointerBias();
2770 // Move past the register save area: 8 in registers + 8 local registers.
2771 OffsetToStackStart += 16 * (Subtarget.is64Bit() ? 8 : 4);
2772 // Move past the struct return address slot (4 bytes) on SPARC 32-bit.
2773 if (!Subtarget.is64Bit())
2774 OffsetToStackStart += 4;
2775
2776 SDValue StackAddr = DAG.getNode(ISD::ADD, DL, VT, SP,
2777 DAG.getConstant(OffsetToStackStart, DL, VT));
2778 return DAG.getMergeValues({StackAddr, Chain}, DL);
2779}
2780
2782 const SparcSubtarget *Subtarget) {
2783 SDValue Chain = Op.getOperand(0);
2784 SDValue Size = Op.getOperand(1);
2785 SDValue Alignment = Op.getOperand(2);
2786 MaybeAlign MaybeAlignment =
2787 cast<ConstantSDNode>(Alignment)->getMaybeAlignValue();
2788 EVT VT = Size->getValueType(0);
2789 SDLoc dl(Op);
2790
2791 unsigned SPReg = SP::O6;
2792 SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
2793
2794 // The resultant pointer needs to be above the register spill area
2795 // at the bottom of the stack.
2796 unsigned regSpillArea;
2797 if (Subtarget->is64Bit()) {
2798 regSpillArea = 128;
2799 } else {
2800 // On Sparc32, the size of the spill area is 92. Unfortunately,
2801 // that's only 4-byte aligned, not 8-byte aligned (the stack
2802 // pointer is 8-byte aligned). So, if the user asked for an 8-byte
2803 // aligned dynamic allocation, we actually need to add 96 to the
2804 // bottom of the stack, instead of 92, to ensure 8-byte alignment.
2805
2806 // That also means adding 4 to the size of the allocation --
2807 // before applying the 8-byte rounding. Unfortunately, we the
2808 // value we get here has already had rounding applied. So, we need
2809 // to add 8, instead, wasting a bit more memory.
2810
2811 // Further, this only actually needs to be done if the required
2812 // alignment is > 4, but, we've lost that info by this point, too,
2813 // so we always apply it.
2814
2815 // (An alternative approach would be to always reserve 96 bytes
2816 // instead of the required 92, but then we'd waste 4 extra bytes
2817 // in every frame, not just those with dynamic stack allocations)
2818
2819 // TODO: modify code in SelectionDAGBuilder to make this less sad.
2820
2821 Size = DAG.getNode(ISD::ADD, dl, VT, Size,
2822 DAG.getConstant(8, dl, VT));
2823 regSpillArea = 96;
2824 }
2825
2826 int64_t Bias = Subtarget->getStackPointerBias();
2827
2828 // Debias and increment SP past the reserved spill area.
2829 // We need the SP to point to the first usable region before calculating
2830 // anything to prevent any of the pointers from becoming out of alignment when
2831 // we rebias the SP later on.
2832 SDValue StartOfUsableStack = DAG.getNode(
2833 ISD::ADD, dl, VT, SP, DAG.getConstant(regSpillArea + Bias, dl, VT));
2834 SDValue AllocatedPtr =
2835 DAG.getNode(ISD::SUB, dl, VT, StartOfUsableStack, Size);
2836
2837 bool IsOveraligned = MaybeAlignment.has_value();
2838 SDValue AlignedPtr =
2839 IsOveraligned
2840 ? DAG.getNode(ISD::AND, dl, VT, AllocatedPtr,
2841 DAG.getSignedConstant(-MaybeAlignment->value(), dl, VT))
2842 : AllocatedPtr;
2843
2844 // Now that we are done, restore the bias and reserved spill area.
2845 SDValue NewSP = DAG.getNode(ISD::SUB, dl, VT, AlignedPtr,
2846 DAG.getConstant(regSpillArea + Bias, dl, VT));
2847 Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP);
2848 SDValue Ops[2] = {AlignedPtr, Chain};
2849 return DAG.getMergeValues(Ops, dl);
2850}
2851
2852
2854 SDLoc dl(Op);
2855 SDValue Chain = DAG.getNode(SPISD::FLUSHW,
2856 dl, MVT::Other, DAG.getEntryNode());
2857 return Chain;
2858}
2859
2861 const SparcSubtarget *Subtarget,
2862 bool AlwaysFlush = false) {
2864 MFI.setFrameAddressIsTaken(true);
2865
2866 EVT VT = Op.getValueType();
2867 SDLoc dl(Op);
2868 unsigned FrameReg = SP::I6;
2869 unsigned stackBias = Subtarget->getStackPointerBias();
2870
2871 SDValue FrameAddr;
2872 SDValue Chain;
2873
2874 // flush first to make sure the windowed registers' values are in stack
2875 Chain = (depth || AlwaysFlush) ? getFLUSHW(Op, DAG) : DAG.getEntryNode();
2876
2877 FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
2878
2879 unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56;
2880
2881 while (depth--) {
2882 SDValue Ptr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
2883 DAG.getIntPtrConstant(Offset, dl));
2884 FrameAddr = DAG.getLoad(VT, dl, Chain, Ptr, MachinePointerInfo());
2885 }
2886 if (Subtarget->is64Bit())
2887 FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
2888 DAG.getIntPtrConstant(stackBias, dl));
2889 return FrameAddr;
2890}
2891
2892
2894 const SparcSubtarget *Subtarget) {
2895
2896 uint64_t depth = Op.getConstantOperandVal(0);
2897
2898 return getFRAMEADDR(depth, Op, DAG, Subtarget);
2899
2900}
2901
2903 const SparcTargetLowering &TLI,
2904 const SparcSubtarget *Subtarget) {
2906 MachineFrameInfo &MFI = MF.getFrameInfo();
2907 MFI.setReturnAddressIsTaken(true);
2908
2909 EVT VT = Op.getValueType();
2910 SDLoc dl(Op);
2911 uint64_t depth = Op.getConstantOperandVal(0);
2912
2913 SDValue RetAddr;
2914 if (depth == 0) {
2915 auto PtrVT = TLI.getPointerTy(DAG.getDataLayout());
2916 Register RetReg = MF.addLiveIn(SP::I7, TLI.getRegClassFor(PtrVT));
2917 RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT);
2918 return RetAddr;
2919 }
2920
2921 // Need frame address to find return address of the caller.
2922 SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget, true);
2923
2924 unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60;
2925 SDValue Ptr = DAG.getNode(ISD::ADD,
2926 dl, VT,
2927 FrameAddr,
2928 DAG.getIntPtrConstant(Offset, dl));
2929 RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr, MachinePointerInfo());
2930
2931 return RetAddr;
2932}
2933
2934static SDValue LowerF64Op(SDValue SrcReg64, const SDLoc &dl, SelectionDAG &DAG,
2935 unsigned opcode) {
2936 assert(SrcReg64.getValueType() == MVT::f64 && "LowerF64Op called on non-double!");
2937 assert(opcode == ISD::FNEG || opcode == ISD::FABS);
2938
2939 // Lower fneg/fabs on f64 to fneg/fabs on f32.
2940 // fneg f64 => fneg f32:sub_even, fmov f32:sub_odd.
2941 // fabs f64 => fabs f32:sub_even, fmov f32:sub_odd.
2942
2943 // Note: in little-endian, the floating-point value is stored in the
2944 // registers are in the opposite order, so the subreg with the sign
2945 // bit is the highest-numbered (odd), rather than the
2946 // lowest-numbered (even).
2947
2948 SDValue Hi32 = DAG.getTargetExtractSubreg(SP::sub_even, dl, MVT::f32,
2949 SrcReg64);
2950 SDValue Lo32 = DAG.getTargetExtractSubreg(SP::sub_odd, dl, MVT::f32,
2951 SrcReg64);
2952
2953 if (DAG.getDataLayout().isLittleEndian())
2954 Lo32 = DAG.getNode(opcode, dl, MVT::f32, Lo32);
2955 else
2956 Hi32 = DAG.getNode(opcode, dl, MVT::f32, Hi32);
2957
2958 SDValue DstReg64 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
2959 dl, MVT::f64), 0);
2960 DstReg64 = DAG.getTargetInsertSubreg(SP::sub_even, dl, MVT::f64,
2961 DstReg64, Hi32);
2962 DstReg64 = DAG.getTargetInsertSubreg(SP::sub_odd, dl, MVT::f64,
2963 DstReg64, Lo32);
2964 return DstReg64;
2965}
2966
2967// Lower a f128 load into two f64 loads.
2969{
2970 SDLoc dl(Op);
2971 LoadSDNode *LdNode = cast<LoadSDNode>(Op.getNode());
2972 assert(LdNode->getOffset().isUndef() && "Unexpected node type");
2973
2974 Align Alignment = commonAlignment(LdNode->getBaseAlign(), 8);
2975
2976 SDValue Hi64 =
2977 DAG.getLoad(MVT::f64, dl, LdNode->getChain(), LdNode->getBasePtr(),
2978 LdNode->getPointerInfo(), Alignment);
2979 EVT addrVT = LdNode->getBasePtr().getValueType();
2980 SDValue LoPtr = DAG.getNode(ISD::ADD, dl, addrVT,
2981 LdNode->getBasePtr(),
2982 DAG.getConstant(8, dl, addrVT));
2983 SDValue Lo64 = DAG.getLoad(MVT::f64, dl, LdNode->getChain(), LoPtr,
2984 LdNode->getPointerInfo().getWithOffset(8),
2985 Alignment);
2986
2987 SDValue SubRegEven = DAG.getTargetConstant(SP::sub_even64, dl, MVT::i32);
2988 SDValue SubRegOdd = DAG.getTargetConstant(SP::sub_odd64, dl, MVT::i32);
2989
2990 SDNode *InFP128 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
2991 dl, MVT::f128);
2992 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
2993 MVT::f128,
2994 SDValue(InFP128, 0),
2995 Hi64,
2996 SubRegEven);
2997 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
2998 MVT::f128,
2999 SDValue(InFP128, 0),
3000 Lo64,
3001 SubRegOdd);
3002 SDValue OutChains[2] = { SDValue(Hi64.getNode(), 1),
3003 SDValue(Lo64.getNode(), 1) };
3004 SDValue OutChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
3005 SDValue Ops[2] = {SDValue(InFP128,0), OutChain};
3006 return DAG.getMergeValues(Ops, dl);
3007}
3008
3010 // We don't have an in-register bswap, so expand bswap(x) into
3011 // load(store-swapped(x)). The reason the swap is done during the store is
3012 // that on some implementations (mainly older ones) ASI-tagged memory
3013 // operations are not pipelined, and generally stores finish faster than
3014 // loads.
3015
3017 MachineFrameInfo &MFI = MF.getFrameInfo();
3018 MVT PtrVT = getPointerTy(DAG.getDataLayout());
3019 SDValue Chain = DAG.getEntryNode();
3020 bool IsLittleEndian = DAG.getDataLayout().isLittleEndian();
3021 SDLoc DL(Op);
3022
3023 SDValue BSwapOp = Op.getOperand(0);
3024 EVT VT = BSwapOp.getValueType();
3025 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
3026 Align Al = DAG.getDataLayout().getPrefTypeAlign(Ty);
3027
3028 // Create a stack object to serve as temporary storage.
3029 int TmpFI = MFI.CreateStackObject(VT.getStoreSize(), Al, false);
3030 SDValue TmpPtr = DAG.getFrameIndex(TmpFI, PtrVT);
3031
3032 // Store-swap the value, then load it back.
3033 SDValue Ops[] = {Chain, BSwapOp, TmpPtr, DAG.getValueType(VT)};
3035 IsLittleEndian ? SPISD::STORE_BIG : SPISD::STORE_LITTLE, DL,
3036 DAG.getVTList(MVT::Other), Ops, VT,
3037 MachinePointerInfo::getFixedStack(MF, TmpFI), std::nullopt,
3039 return DAG.getLoad(VT, DL, ST, TmpPtr,
3041}
3042
3044{
3045 LoadSDNode *LdNode = cast<LoadSDNode>(Op.getNode());
3046
3047 EVT MemVT = LdNode->getMemoryVT();
3048 if (MemVT == MVT::f128)
3049 return LowerF128Load(Op, DAG);
3050
3051 return Op;
3052}
3053
3054// Lower a f128 store into two f64 stores.
3056 SDLoc dl(Op);
3057 StoreSDNode *StNode = cast<StoreSDNode>(Op.getNode());
3058 assert(StNode->getOffset().isUndef() && "Unexpected node type");
3059
3060 SDValue SubRegEven = DAG.getTargetConstant(SP::sub_even64, dl, MVT::i32);
3061 SDValue SubRegOdd = DAG.getTargetConstant(SP::sub_odd64, dl, MVT::i32);
3062
3063 SDNode *Hi64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG,
3064 dl,
3065 MVT::f64,
3066 StNode->getValue(),
3067 SubRegEven);
3068 SDNode *Lo64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG,
3069 dl,
3070 MVT::f64,
3071 StNode->getValue(),
3072 SubRegOdd);
3073
3074 Align Alignment = commonAlignment(StNode->getBaseAlign(), 8);
3075
3076 SDValue OutChains[2];
3077 OutChains[0] =
3078 DAG.getStore(StNode->getChain(), dl, SDValue(Hi64, 0),
3079 StNode->getBasePtr(), StNode->getPointerInfo(),
3080 Alignment);
3081 EVT addrVT = StNode->getBasePtr().getValueType();
3082 SDValue LoPtr = DAG.getNode(ISD::ADD, dl, addrVT,
3083 StNode->getBasePtr(),
3084 DAG.getConstant(8, dl, addrVT));
3085 OutChains[1] = DAG.getStore(StNode->getChain(), dl, SDValue(Lo64, 0), LoPtr,
3086 StNode->getPointerInfo().getWithOffset(8),
3087 Alignment);
3088 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
3089}
3090
3092{
3093 SDLoc dl(Op);
3094 StoreSDNode *St = cast<StoreSDNode>(Op.getNode());
3095
3096 EVT MemVT = St->getMemoryVT();
3097 if (MemVT == MVT::f128)
3098 return LowerF128Store(Op, DAG);
3099
3100 if (MemVT == MVT::i64) {
3101 // Custom handling for i64 stores: turn it into a bitcast and a
3102 // v2i32 store.
3103 SDValue Val = DAG.getNode(ISD::BITCAST, dl, MVT::v2i32, St->getValue());
3104 SDValue Chain = DAG.getStore(
3105 St->getChain(), dl, Val, St->getBasePtr(), St->getPointerInfo(),
3106 St->getBaseAlign(), St->getMemOperand()->getFlags(), St->getAAInfo());
3107 return Chain;
3108 }
3109
3110 return SDValue();
3111}
3112
3114 assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS)
3115 && "invalid opcode");
3116
3117 SDLoc dl(Op);
3118
3119 if (Op.getValueType() == MVT::f64)
3120 return LowerF64Op(Op.getOperand(0), dl, DAG, Op.getOpcode());
3121 if (Op.getValueType() != MVT::f128)
3122 return Op;
3123
3124 // Lower fabs/fneg on f128 to fabs/fneg on f64
3125 // fabs/fneg f128 => fabs/fneg f64:sub_even64, fmov f64:sub_odd64
3126 // (As with LowerF64Op, on little-endian, we need to negate the odd
3127 // subreg)
3128
3129 SDValue SrcReg128 = Op.getOperand(0);
3130 SDValue Hi64 = DAG.getTargetExtractSubreg(SP::sub_even64, dl, MVT::f64,
3131 SrcReg128);
3132 SDValue Lo64 = DAG.getTargetExtractSubreg(SP::sub_odd64, dl, MVT::f64,
3133 SrcReg128);
3134
3135 if (DAG.getDataLayout().isLittleEndian()) {
3136 if (isV9)
3137 Lo64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Lo64);
3138 else
3139 Lo64 = LowerF64Op(Lo64, dl, DAG, Op.getOpcode());
3140 } else {
3141 if (isV9)
3142 Hi64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Hi64);
3143 else
3144 Hi64 = LowerF64Op(Hi64, dl, DAG, Op.getOpcode());
3145 }
3146
3147 SDValue DstReg128 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
3148 dl, MVT::f128), 0);
3149 DstReg128 = DAG.getTargetInsertSubreg(SP::sub_even64, dl, MVT::f128,
3150 DstReg128, Hi64);
3151 DstReg128 = DAG.getTargetInsertSubreg(SP::sub_odd64, dl, MVT::f128,
3152 DstReg128, Lo64);
3153 return DstReg128;
3154}
3155
3157 if (isStrongerThanMonotonic(cast<AtomicSDNode>(Op)->getSuccessOrdering())) {
3158 // Expand with a fence.
3159 return SDValue();
3160 }
3161
3162 // Monotonic load/stores are legal.
3163 return Op;
3164}
3165
3167 SelectionDAG &DAG) const {
3168 unsigned IntNo = Op.getConstantOperandVal(0);
3169 switch (IntNo) {
3170 default: return SDValue(); // Don't custom lower most intrinsics.
3171 case Intrinsic::thread_pointer: {
3172 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3173 return DAG.getRegister(SP::G7, PtrVT);
3174 }
3175 }
3176}
3177
3180
3181 bool hasHardQuad = Subtarget->hasHardQuad();
3182 bool isV9 = Subtarget->isV9();
3183 bool is64Bit = Subtarget->is64Bit();
3184
3185 switch (Op.getOpcode()) {
3186 default: llvm_unreachable("Should not custom lower this!");
3187
3188 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this,
3189 Subtarget);
3190 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG,
3191 Subtarget);
3193 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
3194 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
3195 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
3196 case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG, *this,
3197 hasHardQuad);
3198 case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG, *this,
3199 hasHardQuad);
3200 case ISD::FP_TO_UINT: return LowerFP_TO_UINT(Op, DAG, *this,
3201 hasHardQuad);
3202 case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG, *this,
3203 hasHardQuad);
3204 case ISD::BR_CC:
3205 return LowerBR_CC(Op, DAG, *this, hasHardQuad, isV9, is64Bit);
3206 case ISD::SELECT_CC:
3207 return LowerSELECT_CC(Op, DAG, *this, hasHardQuad, isV9, is64Bit);
3208 case ISD::VASTART: return LowerVASTART(Op, DAG, *this);
3209 case ISD::VAARG: return LowerVAARG(Op, DAG);
3211 Subtarget);
3212 case ISD::STACKADDRESS:
3213 return LowerSTACKADDRESS(Op, DAG, *Subtarget);
3214
3215 case ISD::BSWAP:
3216 return LowerBSWAP(Op, DAG);
3217
3218 case ISD::LOAD: return LowerLOAD(Op, DAG);
3219 case ISD::STORE: return LowerSTORE(Op, DAG);
3220 case ISD::FADD:
3221 return LowerF128Op(Op, DAG, RTLIB::ADD_F128, 2);
3222 case ISD::FSUB:
3223 return LowerF128Op(Op, DAG, RTLIB::SUB_F128, 2);
3224 case ISD::FMUL:
3225 return LowerF128Op(Op, DAG, RTLIB::MUL_F128, 2);
3226 case ISD::FDIV:
3227 return LowerF128Op(Op, DAG, RTLIB::DIV_F128, 2);
3228 case ISD::FSQRT:
3229 return LowerF128Op(Op, DAG, RTLIB::SQRT_F128, 1);
3230 case ISD::FABS:
3231 case ISD::FNEG: return LowerFNEGorFABS(Op, DAG, isV9);
3232 case ISD::FP_EXTEND: return LowerF128_FPEXTEND(Op, DAG, *this);
3233 case ISD::FP_ROUND: return LowerF128_FPROUND(Op, DAG, *this);
3234 case ISD::ATOMIC_LOAD:
3235 case ISD::ATOMIC_STORE: return LowerATOMIC_LOAD_STORE(Op, DAG);
3237 }
3238}
3239
3241 const SDLoc &DL,
3242 SelectionDAG &DAG) const {
3243 APInt V = C->getValueAPF().bitcastToAPInt();
3244 SDValue Lo = DAG.getConstant(V.zextOrTrunc(32), DL, MVT::i32);
3245 SDValue Hi = DAG.getConstant(V.lshr(32).zextOrTrunc(32), DL, MVT::i32);
3246 if (DAG.getDataLayout().isLittleEndian())
3247 std::swap(Lo, Hi);
3248 return DAG.getBuildVector(MVT::v2i32, DL, {Hi, Lo});
3249}
3250
3252 DAGCombinerInfo &DCI) const {
3253 SDLoc dl(N);
3254 SDValue Src = N->getOperand(0);
3255
3256 if (isa<ConstantFPSDNode>(Src) && N->getSimpleValueType(0) == MVT::v2i32 &&
3257 Src.getSimpleValueType() == MVT::f64)
3259
3260 return SDValue();
3261}
3262
3264 DAGCombinerInfo &DCI) const {
3265 SDLoc DL(N);
3266 SelectionDAG &DAG = DCI.DAG;
3267 SDValue Op = N->getOperand(0);
3268 EVT VT = N->getValueType(0);
3269 auto *LN = dyn_cast<LoadSDNode>(Op.getNode());
3270
3271 bool IsLittleEndian = DAG.getDataLayout().isLittleEndian();
3272 bool IsAlignedLoad = LN && ISD::isNormalLoad(Op.getNode()) &&
3273 LN->getAlign() >= VT.getScalarStoreSize();
3274
3275 // Turn BSWAP (aligned-LOAD) -> ld*a #ASI_P(_L) on V9.
3276 if (Subtarget->isV9() && IsAlignedLoad && Op.getNode()->hasOneUse() &&
3277 (VT == MVT::i16 || VT == MVT::i32 ||
3278 (Subtarget->is64Bit() && VT == MVT::i64))) {
3279 SDValue Load = Op;
3280 auto *LD = cast<LoadSDNode>(Load);
3281
3282 // Create the byte-swapping load.
3283 SDValue Ops[] = {LD->getChain(), LD->getBasePtr(), DAG.getValueType(VT)};
3284
3285 SDValue BSLoad = DAG.getMemIntrinsicNode(
3286 IsLittleEndian ? SPISD::LOAD_BIG : SPISD::LOAD_LITTLE, DL,
3287 DAG.getVTList(VT == MVT::i64 ? MVT::i64 : MVT::i32, MVT::Other), Ops,
3288 LD->getMemoryVT(), LD->getMemOperand());
3289
3290 // If this is an i16 load, insert the truncate.
3291 SDValue ResVal = BSLoad;
3292 if (VT == MVT::i16)
3293 ResVal = DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, BSLoad);
3294
3295 return DCI.CombineTo(N, ResVal);
3296 }
3297
3298 return SDValue();
3299}
3300
3302 DAGCombinerInfo &DCI) const {
3303 SDLoc DL(N);
3304 SelectionDAG &DAG = DCI.DAG;
3305 SDValue Op = N->getOperand(1);
3306 EVT VT = Op.getValueType();
3307 EVT MemVT = cast<StoreSDNode>(N)->getMemoryVT();
3308 unsigned Opcode = Op.getOpcode();
3309 auto *SN = dyn_cast<StoreSDNode>(N);
3310
3311 bool IsLittleEndian = DAG.getDataLayout().isLittleEndian();
3312 bool IsAlignedStore = SN && SN->getAlign() >= MemVT.getScalarStoreSize();
3313
3314 // Turn aligned-STORE (BSWAP) -> st*a #ASI_P(_L) on V9.
3315 if (Subtarget->isV9() && Opcode == ISD::BSWAP && Op.getNode()->hasOneUse() &&
3316 IsAlignedStore &&
3317 (VT == MVT::i16 || VT == MVT::i32 ||
3318 (Subtarget->is64Bit() && VT == MVT::i64))) {
3319
3320 // st*a can only handle simple types and it makes no sense to store less
3321 // than two bytes in byte-reversed order.
3322 if (MemVT.getSizeInBits() < 16)
3323 return SDValue();
3324
3325 SDValue BSwapOp = Op.getOperand(0);
3326 // Do an any-extend to 32-bits if this is a half-word input.
3327 if (BSwapOp.getValueType() == MVT::i16)
3328 BSwapOp = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, BSwapOp);
3329
3330 // If the type of BSWAP operand is wider than stored memory width
3331 // it needs to be shifted to the right side before st*a.
3332 if (VT.bitsGT(MemVT)) {
3333 unsigned Shift = VT.getSizeInBits() - MemVT.getSizeInBits();
3334 BSwapOp = DAG.getNode(ISD::SRL, DL, VT, BSwapOp,
3335 DAG.getShiftAmountConstant(Shift, VT, DL));
3336 }
3337
3338 SDValue Ops[] = {N->getOperand(0), BSwapOp, N->getOperand(2),
3339 DAG.getValueType(MemVT)};
3340 return DAG.getMemIntrinsicNode(
3341 IsLittleEndian ? SPISD::STORE_BIG : SPISD::STORE_LITTLE, DL,
3342 DAG.getVTList(MVT::Other), Ops, cast<StoreSDNode>(N)->getMemoryVT(),
3343 cast<StoreSDNode>(N)->getMemOperand());
3344 }
3345
3346 return SDValue();
3347}
3348
3350 DAGCombinerInfo &DCI) const {
3351 switch (N->getOpcode()) {
3352 default:
3353 break;
3354 case ISD::BITCAST:
3355 return PerformBITCASTCombine(N, DCI);
3356 case ISD::BSWAP:
3357 return PerformBSWAPCombine(N, DCI);
3358 case ISD::STORE:
3359 return PerformSTORECombine(N, DCI);
3360 }
3361 return SDValue();
3362}
3363
3366 MachineBasicBlock *BB) const {
3367 switch (MI.getOpcode()) {
3368 default: llvm_unreachable("Unknown SELECT_CC!");
3369 case SP::SELECT_CC_Int_ICC:
3370 case SP::SELECT_CC_FP_ICC:
3371 case SP::SELECT_CC_DFP_ICC:
3372 case SP::SELECT_CC_QFP_ICC:
3373 if (Subtarget->isV9())
3374 return expandSelectCC(MI, BB, SP::BPICC);
3375 return expandSelectCC(MI, BB, SP::BCOND);
3376 case SP::SELECT_CC_Int_XCC:
3377 case SP::SELECT_CC_FP_XCC:
3378 case SP::SELECT_CC_DFP_XCC:
3379 case SP::SELECT_CC_QFP_XCC:
3380 return expandSelectCC(MI, BB, SP::BPXCC);
3381 case SP::SELECT_CC_Int_FCC:
3382 case SP::SELECT_CC_FP_FCC:
3383 case SP::SELECT_CC_DFP_FCC:
3384 case SP::SELECT_CC_QFP_FCC:
3385 if (Subtarget->isV9())
3386 return expandSelectCC(MI, BB, SP::FBCOND_V9);
3387 return expandSelectCC(MI, BB, SP::FBCOND);
3388 }
3389}
3390
3393 unsigned BROpcode) const {
3394 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
3395 DebugLoc dl = MI.getDebugLoc();
3396 unsigned CC = (SPCC::CondCodes)MI.getOperand(3).getImm();
3397
3398 // To "insert" a SELECT_CC instruction, we actually have to insert the
3399 // triangle control-flow pattern. The incoming instruction knows the
3400 // destination vreg to set, the condition code register to branch on, the
3401 // true/false values to select between, and the condition code for the branch.
3402 //
3403 // We produce the following control flow:
3404 // ThisMBB
3405 // | \
3406 // | IfFalseMBB
3407 // | /
3408 // SinkMBB
3409 const BasicBlock *LLVM_BB = BB->getBasicBlock();
3411
3412 MachineBasicBlock *ThisMBB = BB;
3413 MachineFunction *F = BB->getParent();
3414 MachineBasicBlock *IfFalseMBB = F->CreateMachineBasicBlock(LLVM_BB);
3415 MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
3416 F->insert(It, IfFalseMBB);
3417 F->insert(It, SinkMBB);
3418
3419 // Transfer the remainder of ThisMBB and its successor edges to SinkMBB.
3420 SinkMBB->splice(SinkMBB->begin(), ThisMBB,
3421 std::next(MachineBasicBlock::iterator(MI)), ThisMBB->end());
3422 SinkMBB->transferSuccessorsAndUpdatePHIs(ThisMBB);
3423
3424 // Set the new successors for ThisMBB.
3425 ThisMBB->addSuccessor(IfFalseMBB);
3426 ThisMBB->addSuccessor(SinkMBB);
3427
3428 BuildMI(ThisMBB, dl, TII.get(BROpcode))
3429 .addMBB(SinkMBB)
3430 .addImm(CC);
3431
3432 // IfFalseMBB just falls through to SinkMBB.
3433 IfFalseMBB->addSuccessor(SinkMBB);
3434
3435 // %Result = phi [ %TrueValue, ThisMBB ], [ %FalseValue, IfFalseMBB ]
3436 BuildMI(*SinkMBB, SinkMBB->begin(), dl, TII.get(SP::PHI),
3437 MI.getOperand(0).getReg())
3438 .addReg(MI.getOperand(1).getReg())
3439 .addMBB(ThisMBB)
3440 .addReg(MI.getOperand(2).getReg())
3441 .addMBB(IfFalseMBB);
3442
3443 MI.eraseFromParent(); // The pseudo instruction is gone now.
3444 return SinkMBB;
3445}
3446
3447//===----------------------------------------------------------------------===//
3448// Sparc Inline Assembly Support
3449//===----------------------------------------------------------------------===//
3450
3451/// getConstraintType - Given a constraint letter, return the type of
3452/// constraint it is for this target.
3455 if (Constraint.size() == 1) {
3456 switch (Constraint[0]) {
3457 default: break;
3458 case 'r':
3459 case 'f':
3460 case 'e':
3461 return C_RegisterClass;
3462 case 'I': // SIMM13
3463 return C_Immediate;
3464 }
3465 }
3466
3467 return TargetLowering::getConstraintType(Constraint);
3468}
3469
3472 const char *constraint) const {
3474 Value *CallOperandVal = info.CallOperandVal;
3475 // If we don't have a value, we can't do a match,
3476 // but allow it at the lowest weight.
3477 if (!CallOperandVal)
3478 return CW_Default;
3479
3480 // Look at the constraint type.
3481 switch (*constraint) {
3482 default:
3484 break;
3485 case 'I': // SIMM13
3486 if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) {
3487 if (isInt<13>(C->getSExtValue()))
3488 weight = CW_Constant;
3489 }
3490 break;
3491 }
3492 return weight;
3493}
3494
3495/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
3496/// vector. If it is invalid, don't add anything to Ops.
3498 SDValue Op, StringRef Constraint, std::vector<SDValue> &Ops,
3499 SelectionDAG &DAG) const {
3500 SDValue Result;
3501
3502 // Only support length 1 constraints for now.
3503 if (Constraint.size() > 1)
3504 return;
3505
3506 char ConstraintLetter = Constraint[0];
3507 switch (ConstraintLetter) {
3508 default: break;
3509 case 'I':
3511 if (isInt<13>(C->getSExtValue())) {
3512 Result = DAG.getSignedTargetConstant(C->getSExtValue(), SDLoc(Op),
3513 Op.getValueType());
3514 break;
3515 }
3516 return;
3517 }
3518 }
3519
3520 if (Result.getNode()) {
3521 Ops.push_back(Result);
3522 return;
3523 }
3525}
3526
3527std::pair<unsigned, const TargetRegisterClass *>
3529 StringRef Constraint,
3530 MVT VT) const {
3531 if (Constraint.empty())
3532 return std::make_pair(0U, nullptr);
3533
3534 if (Constraint.size() == 1) {
3535 switch (Constraint[0]) {
3536 case 'r':
3537 if (VT == MVT::v2i32)
3538 return std::make_pair(0U, &SP::IntPairRegClass);
3539 else if (Subtarget->is64Bit())
3540 return std::make_pair(0U, &SP::I64RegsRegClass);
3541 else
3542 return std::make_pair(0U, &SP::IntRegsRegClass);
3543 case 'f':
3544 if (VT == MVT::f32 || VT == MVT::i32)
3545 return std::make_pair(0U, &SP::FPRegsRegClass);
3546 else if (VT == MVT::f64 || VT == MVT::i64)
3547 return std::make_pair(0U, &SP::LowDFPRegsRegClass);
3548 else if (VT == MVT::f128)
3549 return std::make_pair(0U, &SP::LowQFPRegsRegClass);
3550 // This will generate an error message
3551 return std::make_pair(0U, nullptr);
3552 case 'e':
3553 if (VT == MVT::f32 || VT == MVT::i32)
3554 return std::make_pair(0U, &SP::FPRegsRegClass);
3555 else if (VT == MVT::f64 || VT == MVT::i64 )
3556 return std::make_pair(0U, &SP::DFPRegsRegClass);
3557 else if (VT == MVT::f128)
3558 return std::make_pair(0U, &SP::QFPRegsRegClass);
3559 // This will generate an error message
3560 return std::make_pair(0U, nullptr);
3561 }
3562 }
3563
3564 if (Constraint.front() != '{')
3565 return std::make_pair(0U, nullptr);
3566
3567 assert(Constraint.back() == '}' && "Not a brace enclosed constraint?");
3568 StringRef RegName(Constraint.data() + 1, Constraint.size() - 2);
3569 if (RegName.empty())
3570 return std::make_pair(0U, nullptr);
3571
3572 unsigned long long RegNo;
3573 // Handle numbered register aliases.
3574 if (RegName[0] == 'r' &&
3575 getAsUnsignedInteger(RegName.begin() + 1, 10, RegNo)) {
3576 // r0-r7 -> g0-g7
3577 // r8-r15 -> o0-o7
3578 // r16-r23 -> l0-l7
3579 // r24-r31 -> i0-i7
3580 if (RegNo > 31)
3581 return std::make_pair(0U, nullptr);
3582 const char RegTypes[] = {'g', 'o', 'l', 'i'};
3583 char RegType = RegTypes[RegNo / 8];
3584 char RegIndex = '0' + (RegNo % 8);
3585 char Tmp[] = {'{', RegType, RegIndex, '}', 0};
3586 return getRegForInlineAsmConstraint(TRI, Tmp, VT);
3587 }
3588
3589 // Rewrite the fN constraint according to the value type if needed.
3590 if (VT != MVT::f32 && VT != MVT::Other && RegName[0] == 'f' &&
3591 getAsUnsignedInteger(RegName.begin() + 1, 10, RegNo)) {
3592 if (VT == MVT::f64 && (RegNo % 2 == 0)) {
3594 TRI, StringRef("{d" + utostr(RegNo / 2) + "}"), VT);
3595 } else if (VT == MVT::f128 && (RegNo % 4 == 0)) {
3597 TRI, StringRef("{q" + utostr(RegNo / 4) + "}"), VT);
3598 } else {
3599 return std::make_pair(0U, nullptr);
3600 }
3601 }
3602
3603 auto ResultPair =
3605 if (!ResultPair.second)
3606 return std::make_pair(0U, nullptr);
3607
3608 // Force the use of I64Regs over IntRegs for 64-bit values.
3609 if (Subtarget->is64Bit() && VT == MVT::i64) {
3610 assert(ResultPair.second == &SP::IntRegsRegClass &&
3611 "Unexpected register class");
3612 return std::make_pair(ResultPair.first, &SP::I64RegsRegClass);
3613 }
3614
3615 return ResultPair;
3616}
3617
3618bool
3620 // The Sparc target isn't yet aware of offsets.
3621 return false;
3622}
3623
3626 SelectionDAG &DAG) const {
3627
3628 SDLoc dl(N);
3629
3630 RTLIB::Libcall libCall = RTLIB::UNKNOWN_LIBCALL;
3631
3632 switch (N->getOpcode()) {
3633 default:
3634 llvm_unreachable("Do not know how to custom type legalize this operation!");
3635
3636 case ISD::FP_TO_SINT:
3637 case ISD::FP_TO_UINT:
3638 // Custom lower only if it involves f128 or i64.
3639 if (N->getOperand(0).getValueType() != MVT::f128
3640 || N->getValueType(0) != MVT::i64)
3641 return;
3642 libCall = ((N->getOpcode() == ISD::FP_TO_SINT)
3643 ? RTLIB::FPTOSINT_F128_I64
3644 : RTLIB::FPTOUINT_F128_I64);
3645
3646 Results.push_back(LowerF128Op(SDValue(N, 0), DAG, libCall, 1));
3647 return;
3648 case ISD::READCYCLECOUNTER: {
3649 assert(Subtarget->hasLeonCycleCounter());
3650 SDValue Lo = DAG.getCopyFromReg(N->getOperand(0), dl, SP::ASR23, MVT::i32);
3651 SDValue Hi = DAG.getCopyFromReg(Lo, dl, SP::G0, MVT::i32);
3652 SDValue Ops[] = { Lo, Hi };
3653 SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Ops);
3654 Results.push_back(Pair);
3655 Results.push_back(N->getOperand(0));
3656 return;
3657 }
3658 case ISD::SINT_TO_FP:
3659 case ISD::UINT_TO_FP:
3660 // Custom lower only if it involves f128 or i64.
3661 if (N->getValueType(0) != MVT::f128
3662 || N->getOperand(0).getValueType() != MVT::i64)
3663 return;
3664
3665 libCall = ((N->getOpcode() == ISD::SINT_TO_FP)
3666 ? RTLIB::SINTTOFP_I64_F128
3667 : RTLIB::UINTTOFP_I64_F128);
3668
3669 Results.push_back(LowerF128Op(SDValue(N, 0), DAG, libCall, 1));
3670 return;
3671 case ISD::LOAD: {
3673 // Custom handling only for i64: turn i64 load into a v2i32 load,
3674 // and a bitcast.
3675 if (Ld->getValueType(0) != MVT::i64 || Ld->getMemoryVT() != MVT::i64)
3676 return;
3677
3678 SDLoc dl(N);
3679 SDValue LoadRes = DAG.getExtLoad(
3680 Ld->getExtensionType(), dl, MVT::v2i32, Ld->getChain(),
3681 Ld->getBasePtr(), Ld->getPointerInfo(), MVT::v2i32, Ld->getBaseAlign(),
3682 Ld->getMemOperand()->getFlags(), Ld->getAAInfo());
3683
3684 SDValue Res = DAG.getNode(ISD::BITCAST, dl, MVT::i64, LoadRes);
3685 Results.push_back(Res);
3686 Results.push_back(LoadRes.getValue(1));
3687 return;
3688 }
3689 }
3690}
3691
3692// Override to enable LOAD_STACK_GUARD lowering on Linux.
3694 if (!Subtarget->getTargetTriple().isOSLinux())
3696 return true;
3697}
3698
3700 if (Subtarget->isVIS3())
3701 return VT == MVT::f32 || VT == MVT::f64;
3702 return false;
3703}
3704
3706 bool ForCodeSize) const {
3707 if (VT != MVT::f32 && VT != MVT::f64)
3708 return false;
3709 if (Subtarget->isVIS() && Imm.isZero())
3710 return true;
3711 if (Subtarget->isVIS3())
3712 return Imm.isExactlyValue(+0.5) || Imm.isExactlyValue(-0.5) ||
3713 Imm.getExactLog2Abs() == -1;
3714 return false;
3715}
3716
3717bool SparcTargetLowering::isCtlzFast() const { return Subtarget->isVIS3(); }
3718
3720 // We lack native cttz, however,
3721 // On 64-bit targets it is cheap to implement it in terms of popc.
3722 if (Subtarget->is64Bit() && Subtarget->usePopc())
3723 return true;
3724 // Otherwise, implementing cttz in terms of ctlz is still cheap.
3725 return isCheapToSpeculateCtlz(Ty);
3726}
3727
3729 EVT VT) const {
3730 return Subtarget->isUA2007() && !Subtarget->useSoftFloat();
3731}
3732
3734 SDNode *Node) const {
3735 assert(MI.getOpcode() == SP::SUBCCrr || MI.getOpcode() == SP::SUBCCri);
3736 // If the result is dead, replace it with %g0.
3737 if (!Node->hasAnyUseOfValue(0))
3738 MI.getOperand(0).setReg(SP::G0);
3739}
3740
3742 Instruction *Inst,
3743 AtomicOrdering Ord) const {
3744 bool HasStoreSemantics =
3746 if (HasStoreSemantics && isReleaseOrStronger(Ord))
3747 return Builder.CreateFence(AtomicOrdering::Release);
3748 return nullptr;
3749}
3750
3752 Instruction *Inst,
3753 AtomicOrdering Ord) const {
3754 // V8 loads already come with implicit acquire barrier so there's no need to
3755 // emit it again.
3756 bool HasLoadSemantics = isa<AtomicCmpXchgInst, AtomicRMWInst, LoadInst>(Inst);
3757 if (Subtarget->isV9() && HasLoadSemantics && isAcquireOrStronger(Ord))
3758 return Builder.CreateFence(AtomicOrdering::Acquire);
3759
3760 // SC plain stores would need a trailing full barrier.
3762 return Builder.CreateFence(Ord);
3763 return nullptr;
3764}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
static LPCC::CondCode IntCondCCodeToICC(SDValue CC, const SDLoc &DL, SDValue &RHS, SelectionDAG &DAG)
lazy value info
#define F(x, y, z)
Definition MD5.cpp:54
#define G(x, y, z)
Definition MD5.cpp:55
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static constexpr MCPhysReg SPReg
static SDValue LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI, bool hasHardQuad)
static bool CC_Sparc_Assign_Ret_Split_64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI, bool hasHardQuad)
static bool CC_Sparc_Assign_Split_64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget, bool AlwaysFlush=false)
static unsigned toCallerWindow(unsigned Reg)
static SDValue LowerSTACKADDRESS(SDValue Op, SelectionDAG &DAG, const SparcSubtarget &Subtarget)
static SDValue LowerF128Store(SDValue Op, SelectionDAG &DAG)
static SPCC::CondCodes intCondCCodeToRcond(ISD::CondCode CC)
intCondCCodeToRcond - Convert a DAG integer condition code to a SPARC rcond condition.
static SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG)
static void fixupVariableFloatArgs(SmallVectorImpl< CCValAssign > &ArgLocs, ArrayRef< ISD::OutputArg > Outs)
static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI, bool hasHardQuad)
static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC)
FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC FCC condition.
static bool isAnyArgRegReserved(const SparcRegisterInfo *TRI, const MachineFunction &MF)
static SDValue getFLUSHW(SDValue Op, SelectionDAG &DAG)
static bool hasReturnsTwiceAttr(SelectionDAG &DAG, SDValue Callee, const CallBase *Call)
static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
static SDValue LowerF128_FPROUND(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI)
static SDValue LowerF64Op(SDValue SrcReg64, const SDLoc &dl, SelectionDAG &DAG, unsigned opcode)
static bool RetCC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI, bool hasHardQuad, bool isV9, bool is64Bit)
static void emitReservedArgRegCallError(const MachineFunction &MF)
static SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG)
static bool RetCC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI, bool hasHardQuad, bool isV9, bool is64Bit)
static SDValue LowerF128_FPEXTEND(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI)
static SDValue LowerFNEGorFABS(SDValue Op, SelectionDAG &DAG, bool isV9)
static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG)
static bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static bool CC_Sparc_Assign_SRet(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static bool Analyze_CC_Sparc64_Half(bool IsReturn, unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static SDValue LowerF128Load(SDValue Op, SelectionDAG &DAG)
static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI, const SparcSubtarget *Subtarget)
static SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG)
static void LookThroughSetCC(SDValue &LHS, SDValue &RHS, ISD::CondCode CC, unsigned &SPCC)
static bool Analyze_CC_Sparc64_Full(bool IsReturn, unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI, bool hasHardQuad)
This file contains some functions that are useful when dealing with strings.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This file describes how to lower LLVM code to machine code.
static bool is64Bit(const char *name)
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
an instruction that atomically reads a memory location, combines it with another value,...
BinOp getOperation() const
LLVM Basic Block Representation.
Definition BasicBlock.h:62
CCState - This class holds information needed while lowering arguments and return values.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
bool needsCustom() const
bool isExtInLoc() const
int64_t getLocMemOffset() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
This is the shared class of boolean and integer constants.
Definition Constants.h:87
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
bool isLittleEndian() const
Layout endianness...
Definition DataLayout.h:217
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
LLVM_ABI Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
A debug info location.
Definition DebugLoc.h:126
Diagnostic information for unsupported feature in backend.
const Function & getFunction() const
Definition Function.h:166
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition Function.h:669
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:723
const GlobalValue * getGlobal() const
Module * getParent()
Get the module that this global value is contained inside of...
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const
Get the CallingConv that should be used for the specified libcall.
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Return the lowering's selection of implementation call for Call.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Machine Value Type.
static auto integer_fixedlen_vector_valuetypes()
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isUndef() const
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL, const SDNodeFlags Flags=SDNodeFlags())
Returns sum of the base pointer and offset.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
const LibcallLoweringInfo & getLibcalls() const
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
int64_t getStackPointerBias() const
The 64-bit ABI uses biased stack and frame pointers, so the stack frame of the current function is th...
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
bool useSoftFloat() const override
SDValue bitcastConstantFPToInt(ConstantFPSDNode *C, const SDLoc &DL, SelectionDAG &DAG) const
MachineBasicBlock * expandSelectCC(MachineInstr &MI, MachineBasicBlock *BB, unsigned BROpcode) const
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
bool isCtlzFast() const override
Return true if ctlz instruction is fast.
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint letter, return the type of constraint it is for this target.
SDValue PerformSTORECombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerFormalArguments_32(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const
LowerFormalArguments32 - V8 uses a very simple ABI, where all values are passed in either one or two ...
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
bool IsEligibleForTailCallOptimization(CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF) const
IsEligibleForTailCallOptimization - Check whether the call is eligible for tail call optimization.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
bool isFNegFree(EVT VT) const override
Return true if an fneg operation is free to the point where it is never worthwhile to replace it with...
SDValue LowerF128_LibCallArg(SDValue Chain, ArgListTy &Args, SDValue Arg, const SDLoc &DL, SelectionDAG &DAG) const
SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, SelectionDAG &DAG) const
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
void AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const override
This method should be implemented by targets that mark instructions with the 'hasPostISelHook' flag.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
computeKnownBitsForTargetNode - Determine which of the bits specified in Mask are known to be either ...
SDValue LowerCall_64(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &dl, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const
SDValue LowerReturn_32(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue PerformBITCASTCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerReturn_64(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const
SDValue LowerF128Op(SDValue Op, SelectionDAG &DAG, RTLIB::Libcall LibFunc, unsigned numArgs) const
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
SDValue LowerCall_32(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFormalArguments_64(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const
SparcTargetLowering(const TargetMachine &TM, const SparcSubtarget &STI)
SDValue LowerBSWAP(SDValue Op, SelectionDAG &DAG) const
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
SDValue PerformBSWAPCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerF128Compare(SDValue LHS, SDValue RHS, unsigned &SPCC, const SDLoc &DL, SelectionDAG &DAG) const
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
const SDValue & getValue() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
char back() const
Get the last character in the string.
Definition StringRef.h:153
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
char front() const
Get the first character in the string.
Definition StringRef.h:147
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
bool isJumpExpensive() const
Return true if Flow Control is an expensive operation that should be avoided.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
std::vector< ArgListEntry > ArgListTy
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:309
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:282
bool isFP128Ty() const
Return true if this is 'fp128'.
Definition Type.h:164
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:197
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
self_iterator getIterator()
Definition ilist_node.h:123
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:275
@ STACKADDRESS
STACKADDRESS - Represents the llvm.stackaddress intrinsic.
Definition ISDOpcodes.h:127
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:294
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:863
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:520
@ GlobalAddress
Definition ISDOpcodes.h:88
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:890
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition ISDOpcodes.h:254
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ GlobalTLSAddress
Definition ISDOpcodes.h:89
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:798
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ BRIND
BRIND - Indirect branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:806
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:233
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition ISDOpcodes.h:230
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:706
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:578
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:821
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:898
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:988
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:110
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:936
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:205
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:304
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:567
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:797
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:969
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:843
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:536
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:558
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
@ FCC_ULE
Definition Sparc.h:74
@ FCC_UG
Definition Sparc.h:64
@ ICC_G
Definition Sparc.h:46
@ REG_LEZ
Definition Sparc.h:97
@ ICC_L
Definition Sparc.h:49
@ FCC_NE
Definition Sparc.h:68
@ ICC_CS
Definition Sparc.h:53
@ FCC_LG
Definition Sparc.h:67
@ ICC_LEU
Definition Sparc.h:51
@ FCC_LE
Definition Sparc.h:73
@ ICC_LE
Definition Sparc.h:47
@ FCC_U
Definition Sparc.h:62
@ ICC_GE
Definition Sparc.h:48
@ FCC_E
Definition Sparc.h:69
@ REG_LZ
Definition Sparc.h:98
@ FCC_L
Definition Sparc.h:65
@ ICC_GU
Definition Sparc.h:50
@ FCC_O
Definition Sparc.h:75
@ ICC_NE
Definition Sparc.h:44
@ FCC_UE
Definition Sparc.h:70
@ REG_NZ
Definition Sparc.h:99
@ ICC_E
Definition Sparc.h:45
@ FCC_GE
Definition Sparc.h:71
@ FCC_UGE
Definition Sparc.h:72
@ REG_Z
Definition Sparc.h:96
@ ICC_CC
Definition Sparc.h:52
@ REG_GEZ
Definition Sparc.h:101
@ FCC_G
Definition Sparc.h:63
@ FCC_UL
Definition Sparc.h:66
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool isStrongerThanMonotonic(AtomicOrdering AO)
std::string utostr(uint64_t X, bool isNeg=false)
bool isReleaseOrStronger(AtomicOrdering AO)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
AtomicOrdering
Atomic ordering for LLVM's memory model.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
bool isAcquireOrStronger(AtomicOrdering AO)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
LLVM_ABI bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition ValueTypes.h:90
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition ValueTypes.h:418
uint64_t getScalarStoreSize() const
Definition ValueTypes.h:425
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
Definition ValueTypes.h:307
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Definition ValueTypes.h:61
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition ValueTypes.h:404
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
This class contains a discriminated union of information about pointers in memory operands,...
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
SmallVector< ISD::OutputArg, 32 > Outs
CallLoweringInfo & setChain(SDValue InChain)
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList, AttributeSet ResultAttrs={})
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)