LLVM: lib/Target/X86/X86CallingConv.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

19

20using namespace llvm;

21

22

23

24

25

27 MVT &LocVT,

31

32

33 static const MCPhysReg RegList[] = {X86::EAX, X86::ECX, X86::EDX, X86::EDI,

34 X86::ESI};

35

36

38

39

40 for (auto Reg : RegList) {

41 if (!State.isAllocated(Reg))

43 }

44

45 const size_t RequiredGprsUponSplit = 2;

46 if (AvailableRegs.size() < RequiredGprsUponSplit)

47 return false;

48

49

50 for (unsigned I = 0; I < RequiredGprsUponSplit; I++) {

51

52

54

55

56

57 assert(Reg && "Expecting a register will be available");

58

59

61 }

62

63

64 return true;

65}

66

69 static const MCPhysReg RegListZMM[] = {X86::ZMM0, X86::ZMM1, X86::ZMM2,

70 X86::ZMM3, X86::ZMM4, X86::ZMM5};

71 return RegListZMM;

72 }

73

75 static const MCPhysReg RegListYMM[] = {X86::YMM0, X86::YMM1, X86::YMM2,

76 X86::YMM3, X86::YMM4, X86::YMM5};

77 return RegListYMM;

78 }

79

80 static const MCPhysReg RegListXMM[] = {X86::XMM0, X86::XMM1, X86::XMM2,

81 X86::XMM3, X86::XMM4, X86::XMM5};

82 return RegListXMM;

83}

84

86 static const MCPhysReg RegListGPR[] = {X86::RCX, X86::RDX, X86::R8, X86::R9};

87 return RegListGPR;

88}

89

91 MVT &LocVT,

95

97 bool Is64bit = static_cast<const X86Subtarget &>(

98 State.getMachineFunction().getSubtarget())

99 .is64Bit();

100

101 for (auto Reg : RegList) {

102

103 if (!State.isAllocated(Reg)) {

105 assert(AssigedReg == Reg && "Expecting a valid register allocation");

106 State.addLoc(

108 return true;

109 }

110

111 if (Is64bit && State.IsShadowAllocatedReg(Reg)) {

113 return true;

114 }

115 }

116

117 llvm_unreachable("Clang should ensure that hva marked vectors will have "

118 "an available register.");

119 return false;

120}

121

122

123

124

125

126

127

131

133 if (ArgFlags.isHva())

135 ArgFlags, State);

136 return true;

137 }

138

139

140

141

144

145

146

147 if (State.isAllocated(X86::R9)) {

148

150 }

151

152 return false;

153 }

154

156

158

159

161

162

163

164

166 State.getMachineFunction().getSubtarget().getRegisterInfo();

167 if (TRI->regsOverlap(Reg, X86::XMM4) ||

168 TRI->regsOverlap(Reg, X86::XMM5))

169 State.AllocateStack(8, Align(8));

170

171 if (!ArgFlags.isHva()) {

173 return true;

174 }

175 }

176 }

177

178

179

180 return ArgFlags.isHva();

181}

182

183

184

185

186

187

191

193 if (ArgFlags.isHva())

195 ArgFlags, State);

196 return true;

197 }

198

199

200

201

204 return false;

205 }

206

207 if (ArgFlags.isHva())

208 return true;

209

210

213 return true;

214 }

215

216

217

218

220 LocVT = MVT::i32;

223 }

224

225 return false;

226}

227

231 llvm_unreachable("The AnyReg calling convention is only supported by the "

232 "stackmap and patchpoint intrinsics.");

233

234 return false;

235}

236

240

241

242 static const MCPhysReg RegList[] = {X86::EAX, X86::EDX, X86::ECX};

243 static const unsigned NumRegs = std::size(RegList);

244

246

247

248

249

250

251 if (ArgFlags.isSplit() || !PendingMembers.empty()) {

255 return true;

256 }

257

258

259

260 if (PendingMembers.empty()) {

261 if (MCRegister Reg = State.AllocateReg(RegList)) {

263 return true;

264 }

265 return false;

266 }

267

269

270

271

272

273

274

275

276

277 unsigned FirstFree = State.getFirstUnallocated(RegList);

278 bool UseRegs = PendingMembers.size() <= std::min(2U, NumRegs - FirstFree);

279

280 for (auto &It : PendingMembers) {

281 if (UseRegs)

282 It.convertToReg(State.AllocateReg(RegList[FirstFree++]));

283 else

284 It.convertToMem(State.AllocateStack(4, Align(4)));

285 State.addLoc(It);

286 }

287

288 PendingMembers.clear();

289

290 return true;

291}

292

293

294

295

296

303 unsigned SlotSize = Is64Bit ? 8 : 4;

305 if (ArgCount == 1 && ValNo == 0) {

306

307

308 Offset = State.AllocateStack(5 * SlotSize, Align(4));

309 } else if (ArgCount == 2 && ValNo == 0) {

310

311

312

314 } else if (ArgCount == 2 && ValNo == 1) {

315

316

317

319 (void)State.AllocateStack(6 * SlotSize, Align(4));

320 } else {

322 }

323

324

325

326 if (Is64Bit && ArgCount == 2)

328

330 return true;

331}

332

336 if (LocVT != MVT::i64) {

337 LocVT = MVT::i64;

339 }

340 return false;

341}

342

343

344

345

349 assert(ValVT == MVT::i64 && "Should have i64 parts");

353

355 return true;

356

357 unsigned NumRegs = PendingMembers.size();

358 assert(NumRegs == 2 && "Should have two parts");

359

360 static const MCPhysReg Regs[] = {X86::RDI, X86::RSI, X86::RDX,

361 X86::RCX, X86::R8, X86::R9};

363 if (!Allocated.empty()) {

364 PendingMembers[0].convertToReg(Allocated[0]);

365 PendingMembers[1].convertToReg(Allocated[1]);

366 } else {

367 int64_t Offset = State.AllocateStack(16, Align(16));

368 PendingMembers[0].convertToMem(Offset);

369 PendingMembers[1].convertToMem(Offset + 8);

370 }

371 State.addLoc(PendingMembers[0]);

372 State.addLoc(PendingMembers[1]);

373 PendingMembers.clear();

374 return true;

375}

376

377

378

379

380

384 assert(ValVT == MVT::i32 && "Should have i32 parts");

388

390 return true;

391

392 assert(PendingMembers.size() == 4 && "Should have four parts");

393

394 int64_t Offset = State.AllocateStack(16, Align(16));

395 PendingMembers[0].convertToMem(Offset);

396 PendingMembers[1].convertToMem(Offset + 4);

397 PendingMembers[2].convertToMem(Offset + 8);

398 PendingMembers[3].convertToMem(Offset + 12);

399

400 State.addLoc(PendingMembers[0]);

401 State.addLoc(PendingMembers[1]);

402 State.addLoc(PendingMembers[2]);

403 State.addLoc(PendingMembers[3]);

404 PendingMembers.clear();

405 return true;

406}

407

408

409#include "X86GenCallingConv.inc"

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

Module.h This file contains the declarations for the Module class.

Register const TargetRegisterInfo * TRI

This file defines the SmallVector class.

static bool CC_X86_AnyReg_Error(unsigned &, MVT &, MVT &, CCValAssign::LocInfo &, ISD::ArgFlagsTy &, CCState &)

Definition X86CallingConv.cpp:228

static bool CC_X86_VectorCallAssignRegister(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

Definition X86CallingConv.cpp:90

static bool CC_X86_32_MCUInReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

Definition X86CallingConv.cpp:237

static bool CC_X86_32_RegCall_Assign2Regs(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

When regcall calling convention compiled to 32 bit arch, special treatment is required for 64 bit mas...

Definition X86CallingConv.cpp:26

static bool CC_X86_64_I128(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

Special handling for i128: Either allocate the value to two consecutive i64 registers,...

Definition X86CallingConv.cpp:346

static ArrayRef< MCPhysReg > CC_X86_VectorCallGetSSEs(const MVT &ValVT)

Definition X86CallingConv.cpp:67

static bool CC_X86_Intr(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

X86 interrupt handlers can only take one or two stack arguments, but if there are two arguments,...

Definition X86CallingConv.cpp:297

static ArrayRef< MCPhysReg > CC_X86_64_VectorCallGetGPRs()

Definition X86CallingConv.cpp:85

static bool CC_X86_64_VectorCall(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

Vectorcall calling convention has special handling for vector types or HVA for 64 bit arch.

Definition X86CallingConv.cpp:128

static bool CC_X86_32_I128_FP128(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

Special handling for i128 and fp128: on x86-32, i128 and fp128 get legalized as four i32s,...

Definition X86CallingConv.cpp:381

static bool CC_X86_32_VectorCall(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

Vectorcall calling convention has special handling for vector types or HVA for 32 bit arch.

Definition X86CallingConv.cpp:188

static bool CC_X86_64_Pointer(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

Definition X86CallingConv.cpp:333

static bool is64Bit(const char *name)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

bool empty() const

empty - Check if the array is empty.

CCState - This class holds information needed while lowering arguments and return values.

static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)

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)

Wrapper class representing physical registers. Should be passed by value.

bool isVector() const

Return true if this is a vector value type.

bool is512BitVector() const

Return true if this is a 512-bit vector type.

TypeSize getSizeInBits() const

Returns the size of the specified MVT in bits.

bool is256BitVector() const

Return true if this is a 256-bit vector type.

bool isFloatingPoint() const

Return true if this is a FP or a vector FP type.

const TargetSubtargetInfo & getSubtarget() const

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

Function & getFunction()

Return the LLVM function that this machine code represents.

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.

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

#define llvm_unreachable(msg)

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

This is an optimization pass for GlobalISel generic memory operations.

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

uint16_t MCPhysReg

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

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

bool isSecArgPass() const

bool isInConsecutiveRegsLast() const