LLVM: lib/Target/CSKY/CSKYISelLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

25

26using namespace llvm;

27

28#define DEBUG_TYPE "csky-isel-lowering"

29

30STATISTIC(NumTailCalls, "Number of tail calls");

31

32#include "CSKYGenCallingConv.inc"

33

35

39

41

47

52 }

53

57

80

84

89 if (!Subtarget.hasE2()) {

91 }

94

95 if (!Subtarget.hasE2()) {

100 }

101

102 if (!Subtarget.has2E3()) {

108 }

109

111

112

113

117 };

118

120 ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOW,

122

124

125 MVT AllVTy[] = {MVT::f32, MVT::f64};

126

127 for (auto VT : AllVTy) {

131

132 for (auto CC : FPCCToExtend)

134 for (auto Op : FPOpToExpand)

136 }

137

142 }

148 }

149 }

150

151

153

156

157

159

163}

164

167 switch (Op.getOpcode()) {

168 default:

171 return LowerGlobalAddress(Op, DAG);

173 return LowerExternalSymbol(Op, DAG);

175 return LowerGlobalTLSAddress(Op, DAG);

177 return LowerJumpTable(Op, DAG);

179 return LowerBlockAddress(Op, DAG);

181 return LowerConstantPool(Op, DAG);

182 case ISD::VASTART:

183 return LowerVASTART(Op, DAG);

185 return LowerFRAMEADDR(Op, DAG);

187 return LowerRETURNADDR(Op, DAG);

188 }

189}

190

194 return MVT::i32;

195

197}

198

202

204 default:

207 break;

209 Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val);

210 break;

211 }

212 return Val;

213}

214

218 default:

221 break;

224 break;

225 }

226 return Val;

227}

228

237

239 default:

241 case MVT::i32:

242 RC = &CSKY::GPRRegClass;

243 break;

244 case MVT::f32:

246 : &CSKY::FPR32RegClass;

247 break;

248 case MVT::f64:

250 : &CSKY::FPR64RegClass;

251 break;

252 }

253

257

259}

260

272

275 default:

280 break;

281 }

283 ExtType, DL, LocVT, Chain, FIN,

285 return Val;

286}

287

292 "Unexpected VA");

296

298

303 }

304

305 assert(VA.isRegLoc() && "Expected register VA assignment");

306

307 Register LoVReg = RegInfo.createVirtualRegister(&CSKY::GPRRegClass);

311 if (VA.getLocReg() == CSKY::R3) {

312

315 Hi = DAG.getLoad(MVT::i32, DL, Chain, FIN,

317 } else {

318

319 Register HiVReg = RegInfo.createVirtualRegister(&CSKY::GPRRegClass);

322 }

324}

325

326

327SDValue CSKYTargetLowering::LowerFormalArguments(

331

332 switch (CallConv) {

333 default:

337 break;

338 }

339

341

342

343 std::vector OutChains;

344

345

347 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());

348

349 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));

350

351 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {

352 CCValAssign &VA = ArgLocs[i];

354

355 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;

356

357 if (IsF64OnCSKY)

358 ArgValue = unpack64(DAG, Chain, VA, DL);

361 else

363

365 }

366

367 if (IsVarArg) {

368 const unsigned XLenInBytes = 4;

369 const MVT XLenVT = MVT::i32;

370

372 unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);

373 const TargetRegisterClass *RC = &CSKY::GPRRegClass;

375 MachineRegisterInfo &RegInfo = MF.getRegInfo();

376 CSKYMachineFunctionInfo *CSKYFI = MF.getInfo();

377

378

379

380

381 int VaArgOffset, VarArgsSaveSize;

382

383

384

385 if (ArgRegs.size() == Idx) {

386 VaArgOffset = CCInfo.getStackSize();

387 VarArgsSaveSize = 0;

388 } else {

389 VarArgsSaveSize = XLenInBytes * (ArgRegs.size() - Idx);

390 VaArgOffset = -VarArgsSaveSize;

391 }

392

393

394

397

398

399

400 for (unsigned I = Idx; I < ArgRegs.size();

401 ++I, VaArgOffset += XLenInBytes) {

410 ->getMemOperand()

411 ->setValue((Value *)nullptr);

412 OutChains.push_back(Store);

413 }

415 }

416

417

418

419 if (!OutChains.empty()) {

420 OutChains.push_back(Chain);

422 }

423

424 return Chain;

425}

426

427bool CSKYTargetLowering::CanLowerReturn(

430 const Type *RetTy) const {

432 CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context);

433 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));

434}

435

438 bool IsVarArg,

442

444

445

446 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), CSKYLocs,

448 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));

449

452

453

454 for (unsigned i = 0, e = CSKYLocs.size(); i < e; ++i) {

455 SDValue Val = OutVals[i];

456 CCValAssign &VA = CSKYLocs[i];

457 assert(VA.isRegLoc() && "Can only return in registers!");

458

459 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;

460

461 if (IsF64OnCSKY) {

462

463 assert(VA.isRegLoc() && "Expected return via registers");

465 DAG.getVTList(MVT::i32, MVT::i32), Val);

468

470 assert(RegLo < CSKY::R31 && "Invalid register pair");

472

475 RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));

478 RetOps.push_back(DAG.getRegister(RegHi, MVT::i32));

479 } else {

480

483

484

487 }

488 }

489

490 RetOps[0] = Chain;

491

492

494 RetOps.push_back(Glue);

495 }

496

497

499 return DAG.getNode(CSKYISD::NIR, DL, MVT::Other, RetOps);

500

501 return DAG.getNode(CSKYISD::RET, DL, MVT::Other, RetOps);

502}

503

504

505

506SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,

508 SelectionDAG &DAG = CLI.DAG;

509 SDLoc &DL = CLI.DL;

510 SmallVectorImplISD::OutputArg &Outs = CLI.Outs;

511 SmallVectorImpl &OutVals = CLI.OutVals;

512 SmallVectorImplISD::InputArg &Ins = CLI.Ins;

513 SDValue Chain = CLI.Chain;

515 bool &IsTailCall = CLI.IsTailCall;

517 bool IsVarArg = CLI.IsVarArg;

519 MVT XLenVT = MVT::i32;

520

522

523

525 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());

526

527 ArgCCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, IsVarArg));

528

529

530 if (IsTailCall)

531 IsTailCall = false;

532

533 if (IsTailCall)

534 ++NumTailCalls;

535 else if (CLI.CB && CLI.CB->isMustTailCall())

536 report_fatal_error("failed to perform tail call elimination on a call "

537 "site marked musttail");

538

539

540 unsigned NumBytes = ArgCCInfo.getStackSize();

541

542

544 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {

545 ISD::ArgFlagsTy Flags = Outs[i].Flags;

546 if (Flags.isByVal())

547 continue;

548

549 SDValue Arg = OutVals[i];

550 unsigned Size = Flags.getByValSize();

551 Align Alignment = Flags.getNonZeroByValAlign();

552

553 int FI =

557

558 Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment,

559 false,

560 false, nullptr, IsTailCall,

561 MachinePointerInfo(), MachinePointerInfo());

563 }

564

565 if (!IsTailCall)

567

568

572 for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; ++i) {

573 CCValAssign &VA = ArgLocs[i];

574 SDValue ArgValue = OutVals[i];

575 ISD::ArgFlagsTy Flags = Outs[i].Flags;

576

577 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;

578

579 if (IsF64OnCSKY && VA.isRegLoc()) {

581 DAG.getNode(CSKYISD::BITCAST_TO_LOHI, DL,

582 DAG.getVTList(MVT::i32, MVT::i32), ArgValue);

585

587 RegsToPass.push_back(std::make_pair(RegLo, Lo));

588

589 if (RegLo == CSKY::R3) {

590

591

594

596 DAG.getStore(Chain, DL, Hi, StackPtr, MachinePointerInfo()));

597 } else {

598

599 assert(RegLo < CSKY::R31 && "Invalid register pair");

600 Register RegHigh = RegLo + 1;

601 RegsToPass.push_back(std::make_pair(RegHigh, Hi));

602 }

603 continue;

604 }

605

607

608

609 if (Flags.isByVal())

610 ArgValue = ByValArgs[j++];

611

613

615 } else {

616 assert(VA.isMemLoc() && "Argument not register or memory");

617 assert(!IsTailCall && "Tail call not allowed if stack is used "

618 "for passing parameters");

619

620

626

627

629 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));

630 }

631 }

632

633

634 if (!MemOpChains.empty())

636

638

639

640 for (auto &Reg : RegsToPass) {

643 }

644

647 bool IsRegCall = false;

648

649 Ops.push_back(Chain);

650

652 const GlobalValue *GV = S->getGlobal();

654

656 IsRegCall = true;

657 Ops.push_back(getAddr<GlobalAddressSDNode, true>(S, DAG, IsLocal));

658 } else {

661 Ops.push_back(getTargetConstantPoolValue(

663 }

666

668 IsRegCall = true;

669 Ops.push_back(getAddr<ExternalSymbolSDNode, true>(S, DAG, IsLocal));

670 } else {

673 Ops.push_back(getTargetConstantPoolValue(

675 }

676 } else {

677 IsRegCall = true;

678 Ops.push_back(Callee);

679 }

680

681

682

683 for (auto &Reg : RegsToPass)

685

686 if (!IsTailCall) {

687

688 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();

689 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);

690 assert(Mask && "Missing call preserved mask for calling convention");

692 }

693

694

696 Ops.push_back(Glue);

697

698

699 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);

700

701 if (IsTailCall) {

703 return DAG.getNode(IsRegCall ? CSKYISD::TAILReg : CSKYISD::TAIL, DL,

704 NodeTys, Ops);

705 }

706

707 Chain = DAG.getNode(IsRegCall ? CSKYISD::CALLReg : CSKYISD::CALL, DL, NodeTys,

711

712

715

716

718 CCState RetCCInfo(CallConv, IsVarArg, MF, CSKYLocs, *DAG.getContext());

719 RetCCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, IsVarArg));

720

721

722 for (auto &VA : CSKYLocs) {

723

726

727 Chain = RetValue.getValue(1);

729

730 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;

731

732 if (IsF64OnCSKY) {

736 Chain = RetValue2.getValue(1);

737 Glue = RetValue2.getValue(2);

738 RetValue = DAG.getNode(CSKYISD::BITCAST_FROM_LOHI, DL, VA.getValVT(),

739 RetValue, RetValue2);

740 }

741

743

745 }

746

747 return Chain;

748}

749

751 bool IsVarArg) const {

752 if (IsVarArg || !Subtarget.useHardFloatABI())

753 return RetCC_CSKY_ABIV2_SOFT;

754 else

755 return RetCC_CSKY_ABIV2_FP;

756}

757

759 bool IsVarArg) const {

760 if (IsVarArg || !Subtarget.useHardFloatABI())

761 return CC_CSKY_ABIV2_SOFT;

762 else

763 return CC_CSKY_ABIV2_FP;

764}

765

767

778 else

779 assert(0 && "unknown CSKYII Modifier");

781}

782

786 unsigned Flags) const {

789

791}

792

794CSKYTargetLowering::getConstraintType(StringRef Constraint) const {

795 if (Constraint.size() == 1) {

796 switch (Constraint[0]) {

797 default:

798 break;

799 case 'a':

800 case 'b':

801 case 'v':

802 case 'w':

803 case 'y':

805 case 'c':

806 case 'l':

807 case 'h':

808 case 'z':

810 }

811 }

813}

814

815std::pair<unsigned, const TargetRegisterClass *>

818 MVT VT) const {

819 if (Constraint.size() == 1) {

820 switch (Constraint[0]) {

821 case 'r':

822 return std::make_pair(0U, &CSKY::GPRRegClass);

823 case 'a':

824 return std::make_pair(0U, &CSKY::mGPRRegClass);

825 case 'b':

826 return std::make_pair(0U, &CSKY::sGPRRegClass);

827 case 'z':

828 return std::make_pair(CSKY::R14, &CSKY::GPRRegClass);

829 case 'c':

830 return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);

831 case 'w':

832 if ((Subtarget.hasFPUv2SingleFloat() ||

833 Subtarget.hasFPUv3SingleFloat()) &&

834 VT == MVT::f32)

835 return std::make_pair(0U, &CSKY::sFPR32RegClass);

836 if ((Subtarget.hasFPUv2DoubleFloat() ||

837 Subtarget.hasFPUv3DoubleFloat()) &&

838 VT == MVT::f64)

839 return std::make_pair(0U, &CSKY::sFPR64RegClass);

840 break;

841 case 'v':

842 if (Subtarget.hasFPUv2SingleFloat() && VT == MVT::f32)

843 return std::make_pair(0U, &CSKY::sFPR32RegClass);

844 if (Subtarget.hasFPUv3SingleFloat() && VT == MVT::f32)

845 return std::make_pair(0U, &CSKY::FPR32RegClass);

846 if (Subtarget.hasFPUv2DoubleFloat() && VT == MVT::f64)

847 return std::make_pair(0U, &CSKY::sFPR64RegClass);

848 if (Subtarget.hasFPUv3DoubleFloat() && VT == MVT::f64)

849 return std::make_pair(0U, &CSKY::FPR64RegClass);

850 break;

851 default:

852 break;

853 }

854 }

855

856 if (Constraint == "{c}")

857 return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);

858

859

860

861

862

863 unsigned XRegFromAlias = StringSwitch(Constraint.lower())

864 .Case("{a0}", CSKY::R0)

865 .Case("{a1}", CSKY::R1)

866 .Case("{a2}", CSKY::R2)

867 .Case("{a3}", CSKY::R3)

868 .Case("{l0}", CSKY::R4)

869 .Case("{l1}", CSKY::R5)

870 .Case("{l2}", CSKY::R6)

871 .Case("{l3}", CSKY::R7)

872 .Case("{l4}", CSKY::R8)

873 .Case("{l5}", CSKY::R9)

874 .Case("{l6}", CSKY::R10)

875 .Case("{l7}", CSKY::R11)

876 .Case("{t0}", CSKY::R12)

877 .Case("{t1}", CSKY::R13)

878 .Case("{sp}", CSKY::R14)

879 .Case("{lr}", CSKY::R15)

880 .Case("{l8}", CSKY::R16)

881 .Case("{l9}", CSKY::R17)

882 .Case("{t2}", CSKY::R18)

883 .Case("{t3}", CSKY::R19)

884 .Case("{t4}", CSKY::R20)

885 .Case("{t5}", CSKY::R21)

886 .Case("{t6}", CSKY::R22)

887 .Cases({"{t7}", "{fp}"}, CSKY::R23)

888 .Cases({"{t8}", "{top}"}, CSKY::R24)

889 .Cases({"{t9}", "{bsp}"}, CSKY::R25)

890 .Case("{r26}", CSKY::R26)

891 .Case("{r27}", CSKY::R27)

892 .Cases({"{gb}", "{rgb}", "{rdb}"}, CSKY::R28)

893 .Cases({"{tb}", "{rtb}"}, CSKY::R29)

894 .Case("{svbr}", CSKY::R30)

895 .Case("{tls}", CSKY::R31)

896 .Default(CSKY::NoRegister);

897

898 if (XRegFromAlias != CSKY::NoRegister)

899 return std::make_pair(XRegFromAlias, &CSKY::GPRRegClass);

900

901

902

903

904

905

906

907

908 if (Subtarget.useHardFloat()) {

909 unsigned FReg = StringSwitch(Constraint.lower())

910 .Cases({"{fr0}", "{vr0}"}, CSKY::F0_32)

911 .Cases({"{fr1}", "{vr1}"}, CSKY::F1_32)

912 .Cases({"{fr2}", "{vr2}"}, CSKY::F2_32)

913 .Cases({"{fr3}", "{vr3}"}, CSKY::F3_32)

914 .Cases({"{fr4}", "{vr4}"}, CSKY::F4_32)

915 .Cases({"{fr5}", "{vr5}"}, CSKY::F5_32)

916 .Cases({"{fr6}", "{vr6}"}, CSKY::F6_32)

917 .Cases({"{fr7}", "{vr7}"}, CSKY::F7_32)

918 .Cases({"{fr8}", "{vr8}"}, CSKY::F8_32)

919 .Cases({"{fr9}", "{vr9}"}, CSKY::F9_32)

920 .Cases({"{fr10}", "{vr10}"}, CSKY::F10_32)

921 .Cases({"{fr11}", "{vr11}"}, CSKY::F11_32)

922 .Cases({"{fr12}", "{vr12}"}, CSKY::F12_32)

923 .Cases({"{fr13}", "{vr13}"}, CSKY::F13_32)

924 .Cases({"{fr14}", "{vr14}"}, CSKY::F14_32)

925 .Cases({"{fr15}", "{vr15}"}, CSKY::F15_32)

926 .Cases({"{fr16}", "{vr16}"}, CSKY::F16_32)

927 .Cases({"{fr17}", "{vr17}"}, CSKY::F17_32)

928 .Cases({"{fr18}", "{vr18}"}, CSKY::F18_32)

929 .Cases({"{fr19}", "{vr19}"}, CSKY::F19_32)

930 .Cases({"{fr20}", "{vr20}"}, CSKY::F20_32)

931 .Cases({"{fr21}", "{vr21}"}, CSKY::F21_32)

932 .Cases({"{fr22}", "{vr22}"}, CSKY::F22_32)

933 .Cases({"{fr23}", "{vr23}"}, CSKY::F23_32)

934 .Cases({"{fr24}", "{vr24}"}, CSKY::F24_32)

935 .Cases({"{fr25}", "{vr25}"}, CSKY::F25_32)

936 .Cases({"{fr26}", "{vr26}"}, CSKY::F26_32)

937 .Cases({"{fr27}", "{vr27}"}, CSKY::F27_32)

938 .Cases({"{fr28}", "{vr28}"}, CSKY::F28_32)

939 .Cases({"{fr29}", "{vr29}"}, CSKY::F29_32)

940 .Cases({"{fr30}", "{vr30}"}, CSKY::F30_32)

941 .Cases({"{fr31}", "{vr31}"}, CSKY::F31_32)

942 .Default(CSKY::NoRegister);

943 if (FReg != CSKY::NoRegister) {

944 assert(CSKY::F0_32 <= FReg && FReg <= CSKY::F31_32 && "Unknown fp-reg");

945 unsigned RegNo = FReg - CSKY::F0_32;

946 unsigned DReg = CSKY::F0_64 + RegNo;

947

948 if (Subtarget.hasFPUv2DoubleFloat())

949 return std::make_pair(DReg, &CSKY::sFPR64RegClass);

950 else if (Subtarget.hasFPUv3DoubleFloat())

951 return std::make_pair(DReg, &CSKY::FPR64RegClass);

952 else if (Subtarget.hasFPUv2SingleFloat())

953 return std::make_pair(FReg, &CSKY::sFPR32RegClass);

954 else if (Subtarget.hasFPUv3SingleFloat())

955 return std::make_pair(FReg, &CSKY::FPR32RegClass);

956 }

957 }

958

960}

961

964

967

968

969

970

971

974

975

976

977

978

979

984 F->insert(It, copyMBB);

985 F->insert(It, sinkMBB);

986

987

991

992

995

996

998 .addReg(MI.getOperand(1).getReg())

1000

1001

1002

1003

1004 BB = copyMBB;

1005

1006

1008

1009

1010

1011

1012 BB = sinkMBB;

1013

1014 BuildMI(*BB, BB->begin(), DL, TII.get(CSKY::PHI), MI.getOperand(0).getReg())

1015 .addReg(MI.getOperand(2).getReg())

1017 .addReg(MI.getOperand(3).getReg())

1019

1020 MI.eraseFromParent();

1021

1022 return BB;

1023}

1024

1026CSKYTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,

1028 switch (MI.getOpcode()) {

1029 default:

1031 case CSKY::FSELS:

1032 case CSKY::FSELD:

1033 if (Subtarget.hasE2())

1035 else

1037 case CSKY::ISEL32:

1039 case CSKY::ISEL16:

1041 }

1042}

1043

1047 unsigned Flags) const {

1048 CSKYConstantPoolValue *CPV =

1051

1053}

1054

1058 unsigned Flags) const {

1059 CSKYConstantPoolValue *CPV =

1063}

1064

1068 unsigned Flags) const {

1069 assert(N->getOffset() == 0);

1072 false);

1074}

1075

1079 unsigned Flags) const {

1080 assert(N->getOffset() == 0);

1085}

1086

1089 unsigned Flags) const {

1091}

1092

1095 unsigned Flags) const {

1097}

1098

1101 unsigned Flags) const {

1103}

1104

1107 unsigned Flags) const {

1109 Flags);

1110}

1111

1114 unsigned Flags) const {

1115

1117 N->getOffset(), Flags);

1118}

1119

1122 SDLoc DL(Op);

1123 EVT Ty = Op.getValueType();

1125 int64_t Offset = N->getOffset();

1126

1127 const GlobalValue *GV = N->getGlobal();

1129 SDValue Addr = getAddr<GlobalAddressSDNode, false>(N, DAG, IsLocal);

1130

1131

1132

1133

1134

1138 return Addr;

1139}

1140

1144

1145 return getAddr(N, DAG, false);

1146}

1147

1151

1152 return getAddr<JumpTableSDNode, false>(N, DAG);

1153}

1154

1158

1159 return getAddr(N, DAG);

1160}

1161

1164 assert(!Subtarget.hasE2());

1166

1167 return getAddr(N, DAG);

1168}

1169

1172 CSKYMachineFunctionInfo *FuncInfo = MF.getInfo();

1173

1174 SDLoc DL(Op);

1177

1178

1179

1181 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),

1182 MachinePointerInfo(SV));

1183}

1184

1187 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();

1191

1192 EVT VT = Op.getValueType();

1193 SDLoc dl(Op);

1194 unsigned Depth = Op.getConstantOperandVal(0);

1199 MachinePointerInfo());

1200 return FrameAddr;

1201}

1202

1205 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();

1209

1210 EVT VT = Op.getValueType();

1211 SDLoc dl(Op);

1212 unsigned Depth = Op.getConstantOperandVal(0);

1214 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);

1218 MachinePointerInfo());

1219 }

1220

1221

1224}

1225

1226Register CSKYTargetLowering::getExceptionPointerRegister(

1227 const Constant *PersonalityFn) const {

1228 return CSKY::R0;

1229}

1230

1231Register CSKYTargetLowering::getExceptionSelectorRegister(

1232 const Constant *PersonalityFn) const {

1233 return CSKY::R1;

1234}

1235

1236SDValue CSKYTargetLowering::LowerGlobalTLSAddress(SDValue Op,

1238 SDLoc DL(Op);

1239 EVT Ty = Op.getValueType();

1241 int64_t Offset = N->getOffset();

1242 MVT XLenVT = MVT::i32;

1243

1246 switch (Model) {

1248 Addr = getStaticTLSAddr(N, DAG, false);

1249 break;

1251 Addr = getStaticTLSAddr(N, DAG, true);

1252 break;

1255 Addr = getDynamicTLSAddr(N, DAG);

1256 break;

1257 }

1258

1259

1260

1261

1262

1266 return Addr;

1267}

1268

1271 bool UseGOT) const {

1273 CSKYMachineFunctionInfo *CFI = MF.getInfo();

1274

1276

1277 SDLoc DL(N);

1279

1281 bool AddCurrentAddr = UseGOT ? true : false;

1282 unsigned char PCAjust = UseGOT ? 4 : 0;

1283

1284 CSKYConstantPoolValue *CPV =

1286 Flag, AddCurrentAddr, CSKYPCLabelIndex);

1288

1290 if (UseGOT) {

1292 auto *LRWGRS = DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty},

1293 {CAddr, PICLabel});

1294 auto LRWADDGRS =

1297 MachinePointerInfo(N->getGlobal()));

1298 } else {

1300 }

1301

1302

1305}

1306

1310 CSKYMachineFunctionInfo *CFI = MF.getInfo();

1311

1313

1314 SDLoc DL(N);

1317

1318 CSKYConstantPoolValue *CPV =

1323

1324 auto *LRWGRS =

1325 DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty}, {Addr, PICLabel});

1326

1329

1330

1332 Args.emplace_back(Load, CallTy);

1333

1334

1335 TargetLowering::CallLoweringInfo CLI(DAG);

1336 CLI.setDebugLoc(DL)

1340 std::move(Args));

1342

1343 return V;

1344}

1345

1349 return false;

1350

1351

1353 return false;

1354

1356 const APInt &Imm = ConstNode->getAPIntValue();

1357

1358 if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() ||

1359 (1 - Imm).isPowerOf2())

1360 return true;

1361

1362

1363

1364 if (!Subtarget.hasE2() && (-1 - Imm).isPowerOf2())

1365 return true;

1366

1367

1368 if (Imm.ugt(0xffff) && ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2()) &&

1369 Subtarget.hasE2())

1370 return true;

1371 if (Imm.ugt(0xffff) && (Imm - 8).isPowerOf2() && Subtarget.has2E3())

1372 return true;

1373 }

1374

1375 return false;

1376}

1377

1378bool CSKYTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {

1379 return Subtarget.has2E3();

1380}

1381

1382bool CSKYTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {

1383 return Subtarget.hasE2();

1384}

static const MCPhysReg GPRArgRegs[]

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static SDValue unpack64(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)

Definition CSKYISelLowering.cpp:288

static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)

Definition CSKYISelLowering.cpp:199

static CSKYCP::CSKYCPModifier getModifier(unsigned Flags)

Definition CSKYISelLowering.cpp:766

static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)

Definition CSKYISelLowering.cpp:261

static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)

Definition CSKYISelLowering.cpp:215

static MachineBasicBlock * emitSelectPseudo(MachineInstr &MI, MachineBasicBlock *BB, unsigned Opcode)

Definition CSKYISelLowering.cpp:963

static SDValue unpackFromRegLoc(const CSKYSubtarget &Subtarget, SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)

Definition CSKYISelLowering.cpp:229

const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]

Register const TargetRegisterInfo * TRI

Promote Memory to Register

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

size_t size() const

size - Get the array size.

LLVM Basic Block Representation.

CCValAssign - Represent assignment of one arg/retval to a location.

Register getLocReg() const

LocInfo getLocInfo() const

int64_t getLocMemOffset() const

static CSKYConstantPoolConstant * Create(const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, unsigned ID=0)

static CSKYConstantPoolJT * Create(Type *Ty, int JTI, unsigned PCAdj, CSKYCP::CSKYCPModifier Modifier)

static CSKYConstantPoolSymbol * Create(Type *Ty, const char *S, unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier)

unsigned createPICLabelUId()

int getVarArgsFrameIndex()

void setVarArgsFrameIndex(int v)

void setVarArgsSaveSize(int Size)

Register getFrameRegister(const MachineFunction &MF) const override

bool hasFPUv2SingleFloat() const

bool hasFPUv3SingleFloat() const

const CSKYRegisterInfo * getRegisterInfo() const override

bool hasFPUv2DoubleFloat() const

bool useHardFloat() const

bool hasFPUv3DoubleFloat() const

CSKYTargetLowering(const TargetMachine &TM, const CSKYSubtarget &STI)

Definition CSKYISelLowering.cpp:36

EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override

Return the ValueType of the result of SETCC operations.

Definition CSKYISelLowering.cpp:191

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...

Definition CSKYISelLowering.cpp:165

This is an important base class in LLVM.

A parsed version of the target data layout string in and methods for querying it.

unsigned getPointerSizeInBits(unsigned AS=0) const

The size in bits of the pointer representation in a given address space.

bool hasFnAttribute(Attribute::AttrKind Kind) const

Return true if the function has the attribute.

This is an important class for using LLVM in a threaded context.

static MVT getIntegerVT(unsigned BitWidth)

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)

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

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, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const

Representation of each machine instruction.

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.

Wrapper class representing virtual and physical registers.

Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...

Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.

SDNode * getNode() const

get the SDNode which holds the desired result

SDValue getValue(unsigned R) 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)

SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)

LLVM_ABI SDVTList getVTList(EVT VT)

Return an SDVTList that represents the list of values specified.

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 getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)

void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)

Set NoMergeSiteInfo to be associated with Node if NoMerge is true.

SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)

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 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 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.

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 getExternalSymbol(const char *Sym, EVT VT)

LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)

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 SDValue getRegisterMask(const uint32_t *RegMask)

LLVMContext * getContext() const

LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)

SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)

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)

StringRef - Represent a constant reference to a string, i.e.

constexpr size_t size() const

size - Get the string size.

LLVM_ABI std::string lower() const

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...

virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const

Return the register class that should be used for the specified value type.

const TargetMachine & getTargetMachine() const

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.

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 ...

@ UndefinedBooleanContent

@ ZeroOrNegativeOneBooleanContent

void setStackPointerRegisterToSaveRestore(Register R)

If set to a physical register, this specifies the register that llvm.savestack/llvm....

void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)

Indicate that the specified condition code is or isn't supported on the target and indicate what to d...

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 setSchedulingPreference(Sched::Preference Pref)

Specify the target scheduling preference.

virtual ConstraintType getConstraintType(StringRef Constraint) const

Given a constraint, return the type of constraint it is for this target.

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 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

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 shouldAssumeDSOLocal(const GlobalValue *GV) const

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

virtual const TargetInstrInfo * getInstrInfo() const

The instances of the Type class are immutable: once they are created, they are never changed.

static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)

self_iterator getIterator()

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

constexpr std::underlying_type_t< E > Mask()

Get a bitmask with 1s in all places up to the high-order bit of E's largest value.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ Fast

Attempts to make calls as fast as possible (e.g.

@ C

The default llvm calling convention, compatible with C.

NodeType

ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.

@ SMUL_LOHI

SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...

@ BSWAP

Byte Swap and Counting operators.

@ ADD

Simple integer binary arithmetic operators.

@ ABS

ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.

@ SDIVREM

SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.

@ MULHU

MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...

@ SELECT_CC

Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...

@ UADDO_CARRY

Carry-using nodes for multiple precision addition and subtraction.

@ FRAMEADDR

FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.

@ TokenFactor

TokenFactor - This node takes multiple tokens as input and produces a single token result.

@ SHL_PARTS

SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.

@ FCOPYSIGN

FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.

CondCode

ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...

LoadExtType

LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).

Flag

These should be considered private to the implementation of the MCInstrDesc class.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)

CCAssignFn - This function assigns a location for Val, updating State to reflect the change.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

DWARFExpression::Operation Op

ArrayRef(const T &OneElt) -> ArrayRef< T >

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

@ Default

The result values are uniform if and only if all operands are uniform.

This struct is a compact representation of a valid (non-zero power of two) alignment.

EVT changeVectorElementTypeToInteger() const

Return a vector with the same number of elements as this vector, but with the element type converted ...

TypeSize getSizeInBits() const

Return the size of the specified value type in bits.

MVT getSimpleVT() const

Return the SimpleValueType held in the specified simple EVT.

bool isVector() const

Return true if this is a vector value type.

bool isScalarInteger() const

Return true if this is an integer, but not a vector.

static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)

Return a MachinePointerInfo record that refers to the specified FrameIndex.