LLVM学习笔记(46)

3.7.2.2. 参数传递惯例

接下来定义参数的传递惯例。首先是64位的C传递惯例。

251     def CC_X86_64_C : CallingConv<[

252       // Handles byval parameters.

253       CCIfByVal<CCPassByVal<8, 8>>,

254    

255       // Promote i1/i8/i16 arguments to i32.

256       CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,

257    

258       // The 'nest' parameter, if any, is passed in R10.

259       CCIfNest<CCIfSubtarget<"isTarget64BitILP32()", CCAssignToReg<[R10D]>>>,

260       CCIfNest<CCAssignToReg<[R10]>>,

 

  // Pass SwiftSelf in a callee saved register.                                                                          <- v7.0增加

  CCIfSwiftSelf<CCIfType<[i64], CCAssignToReg<[R13]>>>,

 

  // A SwiftError is passed in R12.

  CCIfSwiftError<CCIfType<[i64], CCAssignToReg<[R12]>>>,

 

  // For Swift Calling Convention, pass sret in %rax.

  CCIfCC<"CallingConv::Swift",

    CCIfSRet<CCIfType<[i64], CCAssignToReg<[RAX]>>>>,

261    

262       // The first 6 integer arguments are passed in integer registers.

263       CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D]>>,

264       CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8 , R9 ]>>,

265    

266       // The first 8 MMX vector arguments are passed in XMM registers on Darwin.

267       CCIfType<[x86mmx],

268                 CCIfSubtarget<"isTargetDarwin()",

269                 CCIfSubtarget<"hasSSE2()",

270                 CCPromoteToType<v2i64>>>>,

271    

272       // Boolean vectors of AVX-512 are passed in SIMD registers.

273       // The call from AVX to AVX-512 function should work,

274       // since the boolean types in AVX/AVX2 are promoted by default.

275       CCIfType<[v2i1],  CCPromoteToType<v2i64>>,

276       CCIfType<[v4i1],  CCPromoteToType<v4i32>>,

277       CCIfType<[v8i1],  CCPromoteToType<v8i16>>,

278       CCIfType<[v16i1], CCPromoteToType<v16i8>>,

279       CCIfType<[v32i1], CCPromoteToType<v32i8>>,

280       CCIfType<[v64i1], CCPromoteToType<v64i8>>,

281    

282       // The first 8 FP/Vector arguments are passed in XMM registers.

283       CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],

284                 CCIfSubtarget<"hasSSE1()",

285                 CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>>,

286    

287       // The first 8 256-bit vector arguments are passed in YMM registers, unless

288       // this is a vararg function.

289       // FIXME: This isn't precisely correct; the x86-64 ABI document says that

290       // fixed arguments to vararg functions are supposed to be passed in

291     // registers.  Actually modeling that would be a lot of work, though.

292       CCIfNotVarArg<CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

293                               CCIfSubtarget<"hasFp256()",                                                                 <- v7.0删除

                          CCIfSubtarget<"hasAVX()",                                                                               <- v7.0增加

294                               CCAssignToReg<[YMM0, YMM1, YMM2, YMM3,

295                                              YMM4, YMM5, YMM6, YMM7]>>>>,

296    

297       // The first 8 512-bit vector arguments are passed in ZMM registers.

298       CCIfNotVarArg<CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

299                 CCIfSubtarget<"hasAVX512()",

300               CCAssignToReg<[ZMM0, ZMM1, ZMM2, ZMM3, ZMM4, ZMM5, ZMM6, ZMM7]>>>>,

301    

302       // Integer/FP values get stored in stack slots that are 8 bytes in size and

303     // 8-byte aligned if there are no more registers to hold them.

304       CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>,

305    

306       // Long doubles get stack slots whose size and alignment depends on the

307       // subtarget.

308       CCIfType<[f80], CCAssignToStack<0, 0>>,                                                                <- v7.0删除

  CCIfType<[f80, f128], CCAssignToStack<0, 0>>,                                                                  <- v7.0增加

309    

310       // Vectors get 16-byte stack slots that are 16-byte aligned.

311       CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToStack<16, 16>>,

312    

313       // 256-bit vectors get 32-byte stack slots that are 32-byte aligned.

314       CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

315                CCAssignToStack<32, 32>>,

316    

317       // 512-bit vectors get 64-byte stack slots that are 64-byte aligned.

318       CCIfType<[v16i32, v8i64, v16f32, v8f64],

319                CCAssignToStack<64, 64>>

320     ]>;

V7.0提供了对HHVMHipHop Virtual Machine)的支持。

575     def CC_X86_64_HHVM : CallingConv<[

576       // Use all/any GP registers for args, except RSP.

577       CCIfType<[i64], CCAssignToReg<[RBX, R12, RBP, R15,

578                                      RDI, RSI, RDX, RCX, R8, R9,

579                                      RAX, R10, R11, R13, R14]>>

580     ]>;

581    

582     // Calling convention for helper functions in HHVM.

583     def CC_X86_64_HHVM_C : CallingConv<[

584       // Pass the first argument in RBP.

585       CCIfType<[i64], CCAssignToReg<[RBP]>>,

586    

587       // Otherwise it's the same as the regular C calling convention.

588       CCDelegateTo<CC_X86_64_C>

589     ]>;

接着是Windows使用的64位参数传递惯例。

323     def CC_X86_Win64_C : CallingConv<[

324       // FIXME: Handle byval stuff.

325       // FIXME: Handle varargs.

326    

327       // Promote i1/i8/i16 arguments to i32.

328       CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,

329    

330       // The 'nest' parameter, if any, is passed in R10.

331       CCIfNest<CCAssignToReg<[R10]>>,

332    

333       // 128 bit vectors are passed by pointer

334       CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCPassIndirect<i64>>,

335    

336    

337       // 256 bit vectors are passed by pointer

338       CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64], CCPassIndirect<i64>>,

339    

340       // 512 bit vectors are passed by pointer

341       CCIfType<[v16i32, v16f32, v8f64, v8i64], CCPassIndirect<i64>>,

342    

  // Long doubles are passed by pointer

  CCIfType<[f80], CCPassIndirect<i64>>,                                                                               <- v7.0增加

 

343       // The first 4 MMX vector arguments are passed in GPRs.

344       CCIfType<[x86mmx], CCBitConvertToType<i64>>,

345    

346       // The first 4 integer arguments are passed in integer registers.

347       CCIfType<[i32], CCAssignToRegWithShadow<[ECX , EDX , R8D , R9D ],

348                                               [XMM0, XMM1, XMM2, XMM3]>>,

349    

350       // Do not pass the sret argument in RCX, the Win64 thiscall calling

351       // convention requires "this" to be passed in RCX.

352       CCIfCC<"CallingConv::X86_ThisCall",

353         CCIfSRet<CCIfType<[i64], CCAssignToRegWithShadow<[RDX , R8  , R9  ],

354                                                          [XMM1, XMM2, XMM3]>>>>,

355    

356       CCIfType<[i64], CCAssignToRegWithShadow<[RCX , RDX , R8  , R9  ],

357                                               [XMM0, XMM1, XMM2, XMM3]>>,

358    

359       // The first 4 FP/Vector arguments are passed in XMM registers.

360       CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],

361                CCAssignToRegWithShadow<[XMM0, XMM1, XMM2, XMM3],

362                                        [RCX , RDX , R8  , R9  ]>>,

363    

364       // Integer/FP values get stored in stack slots that are 8 bytes in size and

365     // 8-byte aligned if there are no more registers to hold them.

366       CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>,

367    

368       // Long doubles get stack slots whose size and alignment depends on the                     <- v7.0删除

369       // subtarget.

370       CCIfType<[f80], CCAssignToStack<0, 0>>

371     ]>;

Windows的64位向量参数传递惯例。

373     def CC_X86_Win64_VectorCall : CallingConv<[

374       // The first 6 floating point and vector types of 128 bits or less use

375       // XMM0-XMM5.

376       CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],                                           <- v7.0删除

377                CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5]>>,

378    

379       // 256-bit vectors use YMM registers.

380       CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

381                CCAssignToReg<[YMM0, YMM1, YMM2, YMM3, YMM4, YMM5]>>,

382    

383       // 512-bit vectors use ZMM registers.

384       CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

385                CCAssignToReg<[ZMM0, ZMM1, ZMM2, ZMM3, ZMM4, ZMM5]>>,

386    

  CCCustom<"CC_X86_64_VectorCall">,                                                                                  <- v7.0增加

387       // Delegate to fastcall to handle integer types.

388       CCDelegateTo<CC_X86_Win64_C>

389     ]>;

Glasgow Haskell编译器(GHC)使用的参数传递惯例。

392     def CC_X86_64_GHC : CallingConv<[

393       // Promote i8/i16/i32 arguments to i64.

394       CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,

395    

396       // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, R6, SpLim

397       CCIfType<[i64],

398                 CCAssignToReg<[R13, RBP, R12, RBX, R14, RSI, RDI, R8, R9, R15]>>,

399    

400       // Pass in STG registers: F1, F2, F3, F4, D1, D2

401       CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],

402                 CCIfSubtarget<"hasSSE1()",

403                 CCAssignToReg<[XMM1, XMM2, XMM3, XMM4, XMM5, XMM6]>>>

  // AVX

  CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],                                                    <- v7.0增加

            CCIfSubtarget<"hasAVX()",

            CCAssignToReg<[YMM1, YMM2, YMM3, YMM4, YMM5, YMM6]>>>,

  // AVX-512

  CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

            CCIfSubtarget<"hasAVX512()",

            CCAssignToReg<[ZMM1, ZMM2, ZMM3, ZMM4, ZMM5, ZMM6]>>>

404     ]>;

64位的HiPE参数传递惯例。

405     def CC_X86_64_HiPE : CallingConv<[

406       // Promote i8/i16/i32 arguments to i64.

407       CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,

408    

409       // Pass in VM's registers: HP, P, ARG0, ARG1, ARG2, ARG3

410       CCIfType<[i64], CCAssignToReg<[R15, RBP, RSI, RDX, RCX, R8]>>,

411    

412       // Integer/FP values get stored in stack slots that are 8 bytes in size and

413     // 8-byte aligned if there are no more registers to hold them.

414       CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>

415     ]>;

64位的JScript参数传递惯例。

418     def CC_X86_64_WebKit_JS : CallingConv<[

419       // Promote i8/i16 arguments to i32.

420       CCIfType<[i8, i16], CCPromoteToType<i32>>,

421    

422       // Only the first integer argument is passed in register.

423       CCIfType<[i32], CCAssignToReg<[EAX]>>,

424       CCIfType<[i64], CCAssignToReg<[RAX]>>,

425    

426     // The remaining integer arguments are passed on the stack. 32bit integer and

427       // floating-point arguments are aligned to 4 byte and stored in 4 byte slots.

428       // 64bit integer and floating-point arguments are aligned to 8 byte and stored

429       // in 8 byte stack slots.

430       CCIfType<[i32, f32], CCAssignToStack<4, 4>>,

431       CCIfType<[i64, f64], CCAssignToStack<8, 8>>

432     ]>;

以及64位AnyReg参数传递惯例。

440     def CC_X86_64_AnyReg : CallingConv<[

441       CCCustom<"CC_X86_AnyReg_Error">

442     ]>;

接下来就是32位的参数传递惯例。与64位不同,它们是有一定尺寸结构的。

450     def CC_X86_32_Vector_Common : CallingConv<[

451       // Other SSE vectors get 16-byte stack slots that are 16-byte aligned.

452       CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToStack<16, 16>>,

453    

454       // 256-bit AVX vectors get 32-byte stack slots that are 32-byte aligned.

455       CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

456                CCAssignToStack<32, 32>>,

457    

458       // 512-bit AVX 512-bit vectors get 64-byte stack slots that are 64-byte aligned.

459       CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

460                CCAssignToStack<64, 64>>

461     ]>;

 

465     def CC_X86_32_Vector_Standard : CallingConv<[

466       // SSE vector arguments are passed in XMM registers.

467       CCIfNotVarArg<CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],

468                     CCAssignToReg<[XMM0, XMM1, XMM2]>>>,

469    

470       // AVX 256-bit vector arguments are passed in YMM registers.

471       CCIfNotVarArg<CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

472                     CCIfSubtarget<"hasFp256()",                                                                        <- v7.0删除

                CCIfSubtarget<"hasAVX()",                                                                                      <- v7.0增加

473                     CCAssignToReg<[YMM0, YMM1, YMM2]>>>>,

474    

475       // AVX 512-bit vector arguments are passed in ZMM registers.

476       CCIfNotVarArg<CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

477                     CCAssignToReg<[ZMM0, ZMM1, ZMM2]>>>,

478    

479       CCDelegateTo<CC_X86_32_Vector_Common>

480     ]>;

 

484     def CC_X86_32_Vector_Darwin : CallingConv<[

485       // SSE vector arguments are passed in XMM registers.

486       CCIfNotVarArg<CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],

487                     CCAssignToReg<[XMM0, XMM1, XMM2, XMM3]>>>,

488    

489       // AVX 256-bit vector arguments are passed in YMM registers.

490       CCIfNotVarArg<CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

491                     CCIfSubtarget<"hasFp256()",

492                     CCAssignToReg<[YMM0, YMM1, YMM2, YMM3]>>>>,

493    

494       // AVX 512-bit vector arguments are passed in ZMM registers.

495       CCIfNotVarArg<CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

496                     CCAssignToReg<[ZMM0, ZMM1, ZMM2, ZMM3]>>>,

497    

498       CCDelegateTo<CC_X86_32_Vector_Common>

499     ]>;

 

503     def CC_X86_32_Common : CallingConv<[

504       // Handles byval parameters.

505       CCIfByVal<CCPassByVal<4, 4>>,

506    

507       // The first 3 float or double arguments, if marked 'inreg' and if the call

508       // is not a vararg call and if SSE2 is available, are passed in SSE registers.

509       CCIfNotVarArg<CCIfInReg<CCIfType<[f32,f64],

510                     CCIfSubtarget<"hasSSE2()",

511                     CCAssignToReg<[XMM0,XMM1,XMM2]>>>>>,

512    

513       // The first 3 __m64 vector arguments are passed in mmx registers if the

514       // call is not a vararg call.

515       CCIfNotVarArg<CCIfType<[x86mmx],

516                     CCAssignToReg<[MM0, MM1, MM2]>>>,

517    

518       // Integer/Float values get stored in stack slots that are 4 bytes in

519       // size and 4-byte aligned.

520       CCIfType<[i32, f32], CCAssignToStack<4, 4>>,

521    

522       // Doubles get 8-byte slots that are 4-byte aligned.

523       CCIfType<[f64], CCAssignToStack<8, 4>>,

524    

525       // Long doubles get slots whose size depends on the subtarget.

526       CCIfType<[f80], CCAssignToStack<0, 4>>,

527    

528       // Boolean vectors of AVX-512 are passed in SIMD registers.

529       // The call from AVX to AVX-512 function should work,

530       // since the boolean types in AVX/AVX2 are promoted by default.

531       CCIfType<[v2i1],  CCPromoteToType<v2i64>>,

532       CCIfType<[v4i1],  CCPromoteToType<v4i32>>,

533       CCIfType<[v8i1],  CCPromoteToType<v8i16>>,

534       CCIfType<[v16i1], CCPromoteToType<v16i8>>,

535       CCIfType<[v32i1], CCPromoteToType<v32i8>>,

536       CCIfType<[v64i1], CCPromoteToType<v64i8>>,

537    

538       // __m64 vectors get 8-byte stack slots that are 4-byte aligned. They are

539       // passed in the parameter area.

540       CCIfType<[x86mmx], CCAssignToStack<8, 4>>,

541    

542       // Darwin passes vectors in a form that differs from the i386 psABI

543       CCIfSubtarget<"isTargetDarwin()", CCDelegateTo<CC_X86_32_Vector_Darwin>>,

544    

545       // Otherwise, drop to 'normal' X86-32 CC

546       CCDelegateTo<CC_X86_32_Vector_Standard>

547     ]>;

 

549     def CC_X86_32_C : CallingConv<[

550       // Promote i1/i8/i16 arguments to i32.

551       CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,

552    

553       // The 'nest' parameter, if any, is passed in ECX.

554       CCIfNest<CCAssignToReg<[ECX]>>,

555    

556       // The first 3 integer arguments, if marked 'inreg' and if the call is not

557       // a vararg call, are passed in integer registers.

558       CCIfNotVarArg<CCIfInReg<CCIfType<[i32], CCAssignToReg<[EAX, EDX, ECX]>>>>,

559    

560       // Otherwise, same as everything else.

561       CCDelegateTo<CC_X86_32_Common>

562     ]>;

V7.0支持MCU(微控制器单元,microcontroller unit)。微控制器是一个设计来控制嵌入式系统中一个特定操作的集成电路。一个典型的微控制器在单片上包括一个处理器、内存以及输入/输出(I/O)外围设备。微控制器出现在汽车、机器人、办公设备、医疗设备、移动通信接收器、贩卖机以及家电中。

836     def CC_X86_32_MCU : CallingConv<[

837       // Handles byval parameters.  Note that, like FastCC, we can't rely on

838       // the delegation to CC_X86_32_Common because that happens after code that

839       // puts arguments in registers.

840       CCIfByVal<CCPassByVal<4, 4>>,

841    

842       // Promote i1/i8/i16/v1i1 arguments to i32.

843       CCIfType<[i1, i8, i16, v1i1], CCPromoteToType<i32>>,

844    

845       // If the call is not a vararg call, some arguments may be passed

846       // in integer registers.

847       CCIfNotVarArg<CCIfType<[i32], CCCustom<"CC_X86_32_MCUInReg">>>,

848    

849       // Otherwise, same as everything else.

850       CCDelegateTo<CC_X86_32_Common>

851     ]>;

 

564     def CC_X86_32_FastCall : CallingConv<[

565       // Promote i1/i8/i16 arguments to i32.

566       CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,

567    

568       // The 'nest' parameter, if any, is passed in EAX.

569       CCIfNest<CCAssignToReg<[EAX]>>,

570    

571       // The first 2 integer arguments are passed in ECX/EDX

572       CCIfInReg<CCIfType<[i32], CCAssignToReg<[ECX, EDX]>>>,

573    

574       // Otherwise, same as everything else.

575       CCDelegateTo<CC_X86_32_Common>

576     ]>;

 

578     def CC_X86_32_VectorCall : CallingConv<[                                                                         <- v7.0删除

def CC_X86_Win32_VectorCall : CallingConv<[                                                                              <- v7.0增加

579       // The first 6 floating point and vector types of 128 bits or less use

580       // XMM0-XMM5.

581       CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],                                             <- v7.0删除

582                CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5]>>,

583    

584       // 256-bit vectors use YMM registers.

585       CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

586                CCAssignToReg<[YMM0, YMM1, YMM2, YMM3, YMM4, YMM5]>>,

587    

588       // 512-bit vectors use ZMM registers.

589       CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

590                CCAssignToReg<[ZMM0, ZMM1, ZMM2, ZMM3, ZMM4, ZMM5]>>,

591    

592       // Otherwise, pass it indirectly.

593       CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64,

594                 v32i8, v16i16, v8i32, v4i64, v8f32, v4f64,

595                 v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

596                CCCustom<"CC_X86_32_VectorCallIndirect">>,

597    

  // Pass floating point in XMMs

  CCCustom<"CC_X86_32_VectorCall">,                                                                                 ß v7.0增加

598       // Delegate to fastcall to handle integer types.

599       CCDelegateTo<CC_X86_32_FastCall>

600     ]>;

 

602     def CC_X86_32_ThisCall_Common : CallingConv<[

603       // The first integer argument is passed in ECX

604       CCIfType<[i32], CCAssignToReg<[ECX]>>,

605    

606       // Otherwise, same as everything else.

607       CCDelegateTo<CC_X86_32_Common>

608     ]>;

 

610     def CC_X86_32_ThisCall_Mingw : CallingConv<[

611       // Promote i1/i8/i16 arguments to i32.

612       CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,

613    

614       CCDelegateTo<CC_X86_32_ThisCall_Common>

615     ]>;

 

617     def CC_X86_32_ThisCall_Win : CallingConv<[

618       // Promote i1/i8/i16 arguments to i32.

619       CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,

620    

621       // Pass sret arguments indirectly through stack.

622       CCIfSRet<CCAssignToStack<4, 4>>,

623    

624       CCDelegateTo<CC_X86_32_ThisCall_Common>

625     ]>;

 

627     def CC_X86_32_ThisCall : CallingConv<[

628       CCIfSubtarget<"isTargetCygMing()", CCDelegateTo<CC_X86_32_ThisCall_Mingw>>,

629       CCDelegateTo<CC_X86_32_ThisCall_Win>

630     ]>;

 

632     def CC_X86_32_FastCC : CallingConv<[

633       // Handles byval parameters.  Note that we can't rely on the delegation

634       // to CC_X86_32_Common for this because that happens after code that

635       // puts arguments in registers.

636       CCIfByVal<CCPassByVal<4, 4>>,

637    

638       // Promote i1/i8/i16 arguments to i32.

639       CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,

640    

641       // The 'nest' parameter, if any, is passed in EAX.

642       CCIfNest<CCAssignToReg<[EAX]>>,

643    

644       // The first 2 integer arguments are passed in ECX/EDX

645       CCIfType<[i32], CCAssignToReg<[ECX, EDX]>>,

646    

647       // The first 3 float or double arguments, if the call is not a vararg

648       // call and if SSE2 is available, are passed in SSE registers.

649       CCIfNotVarArg<CCIfType<[f32,f64],

650                     CCIfSubtarget<"hasSSE2()",

651                     CCAssignToReg<[XMM0,XMM1,XMM2]>>>>,

652    

653       // Doubles get 8-byte slots that are 8-byte aligned.

654       CCIfType<[f64], CCAssignToStack<8, 8>>,

655    

656       // Otherwise, same as everything else.

657       CCDelegateTo<CC_X86_32_Common>

658     ]>;

 

660     def CC_X86_32_GHC : CallingConv<[

661       // Promote i8/i16 arguments to i32.

662       CCIfType<[i8, i16], CCPromoteToType<i32>>,

663    

664       // Pass in STG registers: Base, Sp, Hp, R1

665       CCIfType<[i32], CCAssignToReg<[EBX, EBP, EDI, ESI]>>

666     ]>;

 

668     def CC_X86_32_HiPE : CallingConv<[

669       // Promote i8/i16 arguments to i32.

670       CCIfType<[i8, i16], CCPromoteToType<i32>>,

671    

672       // Pass in VM's registers: HP, P, ARG0, ARG1, ARG2

673     CCIfType<[i32], CCAssignToReg<[ESI, EBP, EAX, EDX, ECX]>>,

674    

675       // Integer/Float values get stored in stack slots that are 4 bytes in

676       // size and 4-byte aligned.

677       CCIfType<[i32, f32], CCAssignToStack<4, 4>>

678     ]>;

最后是32-64位Intel OpenCL参数传递惯例。

681     def CC_Intel_OCL_BI : CallingConv<[

682    

683       CCIfType<[i32], CCIfSubtarget<"isTargetWin64()", CCAssignToReg<[ECX, EDX, R8D, R9D]>>>,

684       CCIfType<[i64], CCIfSubtarget<"isTargetWin64()", CCAssignToReg<[RCX, RDX, R8,  R9 ]>>>,

685    

686       CCIfType<[i32], CCIfSubtarget<"is64Bit()", CCAssignToReg<[EDI, ESI, EDX, ECX]>>>,

687       CCIfType<[i64], CCIfSubtarget<"is64Bit()", CCAssignToReg<[RDI, RSI, RDX, RCX]>>>,

688    

689       CCIfType<[i32], CCAssignToStack<4, 4>>,

690    

691       // The SSE vector arguments are passed in XMM registers.

692       CCIfType<[f32, f64, v4i32, v2i64, v4f32, v2f64],

693                CCAssignToReg<[XMM0, XMM1, XMM2, XMM3]>>,

694    

695       // The 256-bit vector arguments are passed in YMM registers.

696       CCIfType<[v8f32, v4f64, v8i32, v4i64],

697                CCAssignToReg<[YMM0, YMM1, YMM2, YMM3]>>,

698    

699       // The 512-bit vector arguments are passed in ZMM registers.

700       CCIfType<[v16f32, v8f64, v16i32, v8i64],

701                CCAssignToReg<[ZMM0, ZMM1, ZMM2, ZMM3]>>,

702    

703       // Pass masks in mask registers

704       CCIfType<[v16i1, v8i1], CCAssignToReg<[K1]>>,

705    

706       CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_C>>,

707       CCIfSubtarget<"is64Bit()",       CCDelegateTo<CC_X86_64_C>>,

708       CCDelegateTo<CC_X86_32_C>

709     ]>;​​​​​​​

3.7.2.3. 调用惯例的分发

最后就是将这些定义整合起来的分发定义。

716     def CC_X86_32 : CallingConv<[

717       CCIfCC<"CallingConv::X86_FastCall", CCDelegateTo<CC_X86_32_FastCall>>,

718       CCIfCC<"CallingConv::X86_VectorCall", CCDelegateTo<CC_X86_32_VectorCall>>,

719       CCIfCC<"CallingConv::X86_ThisCall", CCDelegateTo<CC_X86_32_ThisCall>>,

720       CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_X86_32_FastCC>>,

721       CCIfCC<"CallingConv::GHC", CCDelegateTo<CC_X86_32_GHC>>,

722       CCIfCC<"CallingConv::HiPE", CCDelegateTo<CC_X86_32_HiPE>>,

723    

724       // Otherwise, drop to normal X86-32 CC

725       CCDelegateTo<CC_X86_32_C>

726     ]>;

 

729     def CC_X86_64 : CallingConv<[

730       CCIfCC<"CallingConv::GHC", CCDelegateTo<CC_X86_64_GHC>>,

731       CCIfCC<"CallingConv::HiPE", CCDelegateTo<CC_X86_64_HiPE>>,

732       CCIfCC<"CallingConv::WebKit_JS", CCDelegateTo<CC_X86_64_WebKit_JS>>,

733       CCIfCC<"CallingConv::AnyReg", CCDelegateTo<CC_X86_64_AnyReg>>,

734       CCIfCC<"CallingConv::X86_64_Win64", CCDelegateTo<CC_X86_Win64_C>>,

735       CCIfCC<"CallingConv::X86_64_SysV", CCDelegateTo<CC_X86_64_C>>,

736       CCIfCC<"CallingConv::X86_VectorCall", CCDelegateTo<CC_X86_Win64_VectorCall>>,

737    

738       // Mingw64 and native Win64 use Win64 CC

739       CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_C>>,

740    

741       // Otherwise, drop to normal X86-64 CC

742       CCDelegateTo<CC_X86_64_C>>

743     ]>;

 

746     def CC_X86 : CallingConv<[

747       CCIfCC<"CallingConv::Intel_OCL_BI", CCDelegateTo<CC_Intel_OCL_BI>>,

748       CCIfSubtarget<"is64Bit()", CCDelegateTo<CC_X86_64>>,

749       CCDelegateTo<CC_X86_32>

750     ]>;

V7.0所给出的定义如下:

999     def CC_X86_32 : CallingConv<[

1000    // X86_INTR calling convention is valid in MCU target and should override the

1001    // MCU calling convention. Thus, this should be checked before isTargetMCU().

1002    CCIfCC<"CallingConv::X86_INTR", CCDelegateTo<CC_X86_32_Intr>>,

1003    CCIfSubtarget<"isTargetMCU()", CCDelegateTo<CC_X86_32_MCU>>,

1004    CCIfCC<"CallingConv::X86_FastCall", CCDelegateTo<CC_X86_32_FastCall>>,

1005    CCIfCC<"CallingConv::X86_VectorCall", CCDelegateTo<CC_X86_Win32_VectorCall>>,

1006    CCIfCC<"CallingConv::X86_ThisCall", CCDelegateTo<CC_X86_32_ThisCall>>,

1007    CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_X86_32_FastCC>>,

1008    CCIfCC<"CallingConv::GHC", CCDelegateTo<CC_X86_32_GHC>>,

1009    CCIfCC<"CallingConv::HiPE", CCDelegateTo<CC_X86_32_HiPE>>,

1010    CCIfCC<"CallingConv::X86_RegCall", CCDelegateTo<CC_X86_32_RegCall>>,

1011 

1012   // Otherwise, drop to normal X86-32 CC

1013    CCDelegateTo<CC_X86_32_C>

1014  ]>;

1015 

1016  // This is the root argument convention for the X86-64 backend.

1017  def CC_X86_64 : CallingConv<[

1018    CCIfCC<"CallingConv::GHC", CCDelegateTo<CC_X86_64_GHC>>,

1019    CCIfCC<"CallingConv::HiPE", CCDelegateTo<CC_X86_64_HiPE>>,

1020    CCIfCC<"CallingConv::WebKit_JS", CCDelegateTo<CC_X86_64_WebKit_JS>>,

1021    CCIfCC<"CallingConv::AnyReg", CCDelegateTo<CC_X86_64_AnyReg>>,

1022    CCIfCC<"CallingConv::Win64", CCDelegateTo<CC_X86_Win64_C>>,

1023    CCIfCC<"CallingConv::X86_64_SysV", CCDelegateTo<CC_X86_64_C>>,

1024    CCIfCC<"CallingConv::X86_VectorCall", CCDelegateTo<CC_X86_Win64_VectorCall>>,

1025    CCIfCC<"CallingConv::HHVM", CCDelegateTo<CC_X86_64_HHVM>>,

1026    CCIfCC<"CallingConv::HHVM_C", CCDelegateTo<CC_X86_64_HHVM_C>>,

1027    CCIfCC<"CallingConv::X86_RegCall",

1028      CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_RegCall>>>,

1029    CCIfCC<"CallingConv::X86_RegCall", CCDelegateTo<CC_X86_SysV64_RegCall>>,

1030    CCIfCC<"CallingConv::X86_INTR", CCDelegateTo<CC_X86_64_Intr>>,

1031 

1032    // Mingw64 and native Win64 use Win64 CC

1033    CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_C>>,

1034 

1035    // Otherwise, drop to normal X86-64 CC

1036    CCDelegateTo<CC_X86_64_C>

1037  ]>;

1038 

1039  // This is the argument convention used for the entire X86 backend.

1040  def CC_X86 : CallingConv<[

1041    CCIfCC<"CallingConv::Intel_OCL_BI", CCDelegateTo<CC_Intel_OCL_BI>>,

1042    CCIfSubtarget<"is64Bit()", CCDelegateTo<CC_X86_64>>,

1043    CCDelegateTo<CC_X86_32>

1044  ]>;

其中1002CC_X86_32_Intr1030行的CC_X86_64_Intrx86的硬件中断上下文。被调用者可以接受一或两个参数,其中第一个参数是代表硬件上下文栈框的指针,第二个参数是硬件错误码,后者的出现依赖于获取的中断向量。因此,它们的定义是:

986     def CC_X86_32_Intr : CallingConv<[

987       CCAssignToStack<4, 4>

988     ]>;

989    

990     def CC_X86_64_Intr : CallingConv<[

991       CCAssignToStack<8, 8>

992     ]>;

101010281029行的CC_X86_32_RegCallCC_X86_Win64_RegCallCC_X86_SysV64_RegCall是用于参数传递优化的寄存器调用惯例,它们有一套比较复杂的定义体系。首先是基类:

76       multiclass X86_RegCall_base<RC_X86_RegCall RC> {

77       def CC_#NAME : CallingConv<[

78         // Handles byval parameters.

79           CCIfSubtarget<"is64Bit()", CCIfByVal<CCPassByVal<8, 8>>>,

80           CCIfByVal<CCPassByVal<4, 4>>,

81      

82           // Promote i1/i8/i16/v1i1 arguments to i32.

83           CCIfType<[i1, i8, i16, v1i1], CCPromoteToType<i32>>,

84      

85           // Promote v8i1/v16i1/v32i1 arguments to i32.

86           CCIfType<[v8i1, v16i1, v32i1], CCPromoteToType<i32>>,

87      

88           // bool, char, int, enum, long, pointer --> GPR

89           CCIfType<[i32], CCAssignToReg<RC.GPR_32>>,

90      

91           // long long, __int64 --> GPR

92           CCIfType<[i64], CCAssignToReg<RC.GPR_64>>,

93      

94           // __mmask64 (v64i1) --> GPR64 (for x64) or 2 x GPR32 (for IA32)

95           CCIfType<[v64i1], CCPromoteToType<i64>>,

96           CCIfSubtarget<"is64Bit()", CCIfType<[i64],

97             CCAssignToReg<RC.GPR_64>>>,

98           CCIfSubtarget<"is32Bit()", CCIfType<[i64],

99             CCCustom<"CC_X86_32_RegCall_Assign2Regs">>>,

100    

101         // float, double, float128 --> XMM

102         // In the case of SSE disabled --> save to stack

103         CCIfType<[f32, f64, f128],

104           CCIfSubtarget<"hasSSE1()", CCAssignToReg<RC.XMM>>>,

105    

106         // long double --> FP

107         CCIfType<[f80], CCAssignToReg<RC.FP_CALL>>,

108    

109         // __m128, __m128i, __m128d --> XMM

110         // In the case of SSE disabled --> save to stack

111         CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],

112           CCIfSubtarget<"hasSSE1()", CCAssignToReg<RC.XMM>>>,

113    

114         // __m256, __m256i, __m256d --> YMM

115         // In the case of SSE disabled --> save to stack

116         CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

117           CCIfSubtarget<"hasAVX()", CCAssignToReg<RC.YMM>>>,

118    

119         // __m512, __m512i, __m512d --> ZMM

120         // In the case of SSE disabled --> save to stack

121         CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

122           CCIfSubtarget<"hasAVX512()",CCAssignToReg<RC.ZMM>>>,

123    

124         // If no register was found -> assign to stack

125    

126         // In 64 bit, assign 64/32 bit values to 8 byte stack

127         CCIfSubtarget<"is64Bit()", CCIfType<[i32, i64, f32, f64],

128           CCAssignToStack<8, 8>>>,

129    

130         // In 32 bit, assign 64/32 bit values to 8/4 byte stack

131         CCIfType<[i32, f32], CCAssignToStack<4, 4>>,

132         CCIfType<[i64, f64], CCAssignToStack<8, 4>>,

133    

134         // MMX type gets 8 byte slot in stack , while alignment depends on target

135         CCIfSubtarget<"is64Bit()", CCIfType<[x86mmx], CCAssignToStack<8, 8>>>,

136         CCIfType<[x86mmx], CCAssignToStack<8, 4>>,

137    

138         // float 128 get stack slots whose size and alignment depends

139         // on the subtarget.

140         CCIfType<[f80, f128], CCAssignToStack<0, 0>>,

141    

142         // Vectors get 16-byte stack slots that are 16-byte aligned.

143         CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],

144           CCAssignToStack<16, 16>>,

145    

146         // 256-bit vectors get 32-byte stack slots that are 32-byte aligned.

147         CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

148           CCAssignToStack<32, 32>>,

149    

150         // 512-bit vectors get 64-byte stack slots that are 64-byte aligned.

151         CCIfType<[v16i32, v8i64, v16f32, v8f64], CCAssignToStack<64, 64>>

152     ]>;

153    

154     def RetCC_#NAME : CallingConv<[

155         // Promote i1, v1i1, v8i1 arguments to i8.

156         CCIfType<[i1, v1i1, v8i1], CCPromoteToType<i8>>,

157    

158         // Promote v16i1 arguments to i16.

159         CCIfType<[v16i1], CCPromoteToType<i16>>,

160    

161         // Promote v32i1 arguments to i32.

162         CCIfType<[v32i1], CCPromoteToType<i32>>,

163    

164         // bool, char, int, enum, long, pointer --> GPR

165         CCIfType<[i8], CCAssignToReg<RC.GPR_8>>,

166         CCIfType<[i16], CCAssignToReg<RC.GPR_16>>,

167         CCIfType<[i32], CCAssignToReg<RC.GPR_32>>,

168    

169         // long long, __int64 --> GPR

170         CCIfType<[i64], CCAssignToReg<RC.GPR_64>>,

171    

172         // __mmask64 (v64i1) --> GPR64 (for x64) or 2 x GPR32 (for IA32)

173         CCIfType<[v64i1], CCPromoteToType<i64>>,

174         CCIfSubtarget<"is64Bit()", CCIfType<[i64],

175           CCAssignToReg<RC.GPR_64>>>,

176         CCIfSubtarget<"is32Bit()", CCIfType<[i64],

177           CCCustom<"CC_X86_32_RegCall_Assign2Regs">>>,

178    

179         // long double --> FP

180         CCIfType<[f80], CCAssignToReg<RC.FP_RET>>,

181    

182         // float, double, float128 --> XMM

183         CCIfType<[f32, f64, f128],

184           CCIfSubtarget<"hasSSE1()", CCAssignToReg<RC.XMM>>>,

185    

186         // __m128, __m128i, __m128d --> XMM

187         CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],

188           CCIfSubtarget<"hasSSE1()", CCAssignToReg<RC.XMM>>>,

189    

190         // __m256, __m256i, __m256d --> YMM

191         CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],

192           CCIfSubtarget<"hasAVX()", CCAssignToReg<RC.YMM>>>,

193    

194         // __m512, __m512i, __m512d --> ZMM

195         CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],

196           CCIfSubtarget<"hasAVX512()", CCAssignToReg<RC.ZMM>>>

197     ]>;

198     }

X86_RegCall_base包含了两个定义,其中CC_#NAMENAME是派生定义的名字)描述参数传递惯例,RetCC_#NAME描述返回值传递惯例。

另外,参数RC(类型RC_X86_RegCall)是描述各种寄存器类别的基类:

28       class RC_X86_RegCall {

29         list<Register> GPR_8 = [];

30         list<Register> GPR_16 = [];

31         list<Register> GPR_32 = [];

32         list<Register> GPR_64 = [];

33         list<Register> FP_CALL = [FP0];

34         list<Register> FP_RET = [FP0, FP1];

35         list<Register> XMM = [];

36         list<Register> YMM = [];

37         list<Register> ZMM = [];

38       }

上面提到的定义则分别是:

425     defm X86_32_RegCall :

426          X86_RegCall_base<RC_X86_32_RegCall>;

427     defm X86_Win64_RegCall :

428          X86_RegCall_base<RC_X86_64_RegCall_Win>;

429     defm X86_SysV64_RegCall :

430          X86_RegCall_base<RC_X86_64_RegCall_SysV>;

其中涉及到的寄存器类别定义是:

def RC_X86_32_RegCall : RC_X86_RegCall {

  let GPR_8 = [AL, CL, DL, DIL, SIL];

  let GPR_16 = [AX, CX, DX, DI, SI];

  let GPR_32 = [EAX, ECX, EDX, EDI, ESI];

  let GPR_64 = [RAX]; ///< Not actually used, but AssignToReg can't handle []

                      ///< \todo Fix AssignToReg to enable empty lists

  let XMM = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7];

  let YMM = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7];

  let ZMM = [ZMM0, ZMM1, ZMM2, ZMM3, ZMM4, ZMM5, ZMM6, ZMM7];

}

 

class RC_X86_64_RegCall : RC_X86_RegCall {

  let XMM = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,

             XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15];

  let YMM = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,

             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15];

  let ZMM = [ZMM0, ZMM1, ZMM2, ZMM3, ZMM4, ZMM5, ZMM6, ZMM7,

             ZMM8, ZMM9, ZMM10, ZMM11, ZMM12, ZMM13, ZMM14, ZMM15];

}

 

def RC_X86_64_RegCall_Win : RC_X86_64_RegCall {

  let GPR_8 = [AL, CL, DL, DIL, SIL, R8B, R9B, R10B, R11B, R12B, R14B, R15B];

  let GPR_16 = [AX, CX, DX, DI, SI, R8W, R9W, R10W, R11W, R12W, R14W, R15W];

  let GPR_32 = [EAX, ECX, EDX, EDI, ESI, R8D, R9D, R10D, R11D, R12D, R14D, R15D];

  let GPR_64 = [RAX, RCX, RDX, RDI, RSI, R8, R9, R10, R11, R12, R14, R15];

}

 

def RC_X86_64_RegCall_SysV : RC_X86_64_RegCall {

  let GPR_8 = [AL, CL, DL, DIL, SIL, R8B, R9B, R12B, R13B, R14B, R15B];

  let GPR_16 = [AX, CX, DX, DI, SI, R8W, R9W, R12W, R13W, R14W, R15W];

  let GPR_32 = [EAX, ECX, EDX, EDI, ESI, R8D, R9D, R12D, R13D, R14D, R15D];

  let GPR_64 = [RAX, RCX, RDX, RDI, RSI, R8, R9, R12, R13, R14, R15];

}

 

​​​​​​​3.7.2.4. 被调用者保存的寄存器

被调用者保存的寄存器由选项“-gen-register-info”处理、生成XXX_ RegMask与XXX_ SaveList列表(参考前面被调用者保存寄存器一节)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值