OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632Traits.h - x86-32 traits -*- C++ -*-=// | 1 //===- subzero/src/IceTargetLoweringX8632Traits.h - x86-32 traits -*- C++ -*-=// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; | 61 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; |
62 | 62 |
63 using GPRRegister = ::Ice::RegX8632::GPRRegister; | 63 using GPRRegister = ::Ice::RegX8632::GPRRegister; |
64 using ByteRegister = ::Ice::RegX8632::ByteRegister; | 64 using ByteRegister = ::Ice::RegX8632::ByteRegister; |
65 using XmmRegister = ::Ice::RegX8632::XmmRegister; | 65 using XmmRegister = ::Ice::RegX8632::XmmRegister; |
66 using X87STRegister = ::Ice::RegX8632::X87STRegister; | 66 using X87STRegister = ::Ice::RegX8632::X87STRegister; |
67 | 67 |
68 using Cond = ::Ice::CondX86; | 68 using Cond = ::Ice::CondX86; |
69 | 69 |
70 using RegisterSet = ::Ice::RegX8632; | 70 using RegisterSet = ::Ice::RegX8632; |
71 static constexpr SizeT StackPtr = RegX8632::Reg_esp; | 71 static constexpr auto StackPtr = RegX8632::Reg_esp; |
72 static constexpr SizeT FramePtr = RegX8632::Reg_ebp; | 72 static constexpr auto FramePtr = RegX8632::Reg_ebp; |
73 static constexpr GPRRegister Encoded_Reg_Accumulator = | 73 static constexpr GPRRegister Encoded_Reg_Accumulator = |
74 RegX8632::Encoded_Reg_eax; | 74 RegX8632::Encoded_Reg_eax; |
75 static constexpr GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx; | 75 static constexpr GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx; |
76 static constexpr FixupKind FK_PcRel = llvm::ELF::R_386_PC32; | 76 static constexpr FixupKind FK_PcRel = llvm::ELF::R_386_PC32; |
77 static constexpr FixupKind FK_Abs = llvm::ELF::R_386_32; | 77 static constexpr FixupKind FK_Abs = llvm::ELF::R_386_32; |
78 static constexpr FixupKind FK_Gotoff = llvm::ELF::R_386_GOTOFF; | 78 static constexpr FixupKind FK_Gotoff = llvm::ELF::R_386_GOTOFF; |
79 static constexpr FixupKind FK_GotPC = llvm::ELF::R_386_GOTPC; | 79 static constexpr FixupKind FK_GotPC = llvm::ELF::R_386_GOTPC; |
80 | 80 |
81 class Operand { | 81 class Operand { |
82 public: | 82 public: |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 Begin, | 269 Begin, |
270 // SSE2 is the PNaCl baseline instruction set. | 270 // SSE2 is the PNaCl baseline instruction set. |
271 SSE2 = Begin, | 271 SSE2 = Begin, |
272 SSE4_1, | 272 SSE4_1, |
273 End | 273 End |
274 }; | 274 }; |
275 | 275 |
276 static const char *TargetName; | 276 static const char *TargetName; |
277 static constexpr Type WordType = IceType_i32; | 277 static constexpr Type WordType = IceType_i32; |
278 | 278 |
279 static IceString getRegName(int32_t RegNum) { | 279 static IceString getRegName(RegNumT RegNum) { |
280 static const char *const RegNames[RegisterSet::Reg_NUM] = { | 280 static const char *const RegNames[RegisterSet::Reg_NUM] = { |
281 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 281 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
282 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 282 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
283 isTrunc8Rcvr, isAhRcvr, aliases) \ | 283 isTrunc8Rcvr, isAhRcvr, aliases) \ |
284 name, | 284 name, |
285 REGX8632_TABLE | 285 REGX8632_TABLE |
286 #undef X | 286 #undef X |
287 }; | 287 }; |
288 assert(RegNum >= 0); | 288 RegNum.assertIsValid(); |
289 assert(RegNum < RegisterSet::Reg_NUM); | |
290 return RegNames[RegNum]; | 289 return RegNames[RegNum]; |
291 } | 290 } |
292 | 291 |
293 static GPRRegister getEncodedGPR(int32_t RegNum) { | 292 static GPRRegister getEncodedGPR(RegNumT RegNum) { |
294 static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = { | 293 static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = { |
295 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 294 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
296 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 295 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
297 isTrunc8Rcvr, isAhRcvr, aliases) \ | 296 isTrunc8Rcvr, isAhRcvr, aliases) \ |
298 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), | 297 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), |
299 REGX8632_TABLE | 298 REGX8632_TABLE |
300 #undef X | 299 #undef X |
301 }; | 300 }; |
302 assert(RegNum >= 0); | 301 RegNum.assertIsValid(); |
303 assert(RegNum < RegisterSet::Reg_NUM); | |
304 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); | 302 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); |
305 return GPRRegs[RegNum]; | 303 return GPRRegs[RegNum]; |
306 } | 304 } |
307 | 305 |
308 static ByteRegister getEncodedByteReg(int32_t RegNum) { | 306 static ByteRegister getEncodedByteReg(RegNumT RegNum) { |
309 static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = { | 307 static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = { |
310 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 308 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
311 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 309 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
312 isTrunc8Rcvr, isAhRcvr, aliases) \ | 310 isTrunc8Rcvr, isAhRcvr, aliases) \ |
313 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), | 311 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), |
314 REGX8632_TABLE | 312 REGX8632_TABLE |
315 #undef X | 313 #undef X |
316 }; | 314 }; |
317 assert(RegNum >= 0); | 315 RegNum.assertIsValid(); |
318 assert(RegNum < RegisterSet::Reg_NUM); | |
319 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); | 316 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); |
320 return ByteRegs[RegNum]; | 317 return ByteRegs[RegNum]; |
321 } | 318 } |
322 | 319 |
323 static XmmRegister getEncodedXmm(int32_t RegNum) { | 320 static XmmRegister getEncodedXmm(RegNumT RegNum) { |
324 static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = { | 321 static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = { |
325 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 322 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
326 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 323 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
327 isTrunc8Rcvr, isAhRcvr, aliases) \ | 324 isTrunc8Rcvr, isAhRcvr, aliases) \ |
328 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), | 325 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), |
329 REGX8632_TABLE | 326 REGX8632_TABLE |
330 #undef X | 327 #undef X |
331 }; | 328 }; |
332 assert(RegNum >= 0); | 329 RegNum.assertIsValid(); |
333 assert(RegNum < RegisterSet::Reg_NUM); | |
334 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); | 330 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); |
335 return XmmRegs[RegNum]; | 331 return XmmRegs[RegNum]; |
336 } | 332 } |
337 | 333 |
338 static uint32_t getEncoding(int32_t RegNum) { | 334 static uint32_t getEncoding(RegNumT RegNum) { |
339 static const uint32_t Encoding[RegisterSet::Reg_NUM] = { | 335 static const uint32_t Encoding[RegisterSet::Reg_NUM] = { |
340 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 336 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
341 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 337 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
342 isTrunc8Rcvr, isAhRcvr, aliases) \ | 338 isTrunc8Rcvr, isAhRcvr, aliases) \ |
343 encode, | 339 encode, |
344 REGX8632_TABLE | 340 REGX8632_TABLE |
345 #undef X | 341 #undef X |
346 }; | 342 }; |
347 assert(RegNum >= 0); | 343 RegNum.assertIsValid(); |
348 assert(RegNum < RegisterSet::Reg_NUM); | |
349 return Encoding[RegNum]; | 344 return Encoding[RegNum]; |
350 } | 345 } |
351 | 346 |
352 static int32_t getBaseReg(int32_t RegNum) { | 347 static RegNumT getBaseReg(RegNumT RegNum) { |
353 static const int32_t BaseRegs[RegisterSet::Reg_NUM] = { | 348 static const RegNumT BaseRegs[RegisterSet::Reg_NUM] = { |
354 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 349 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
355 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 350 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
356 isTrunc8Rcvr, isAhRcvr, aliases) \ | 351 isTrunc8Rcvr, isAhRcvr, aliases) \ |
357 RegisterSet::base, | 352 RegisterSet::base, |
358 REGX8632_TABLE | 353 REGX8632_TABLE |
359 #undef X | 354 #undef X |
360 }; | 355 }; |
361 assert(RegNum >= 0); | 356 RegNum.assertIsValid(); |
362 assert(RegNum < RegisterSet::Reg_NUM); | |
363 return BaseRegs[RegNum]; | 357 return BaseRegs[RegNum]; |
364 } | 358 } |
365 | 359 |
366 private: | 360 private: |
367 static int32_t getFirstGprForType(Type Ty) { | 361 static RegisterSet::AllRegisters getFirstGprForType(Type Ty) { |
368 switch (Ty) { | 362 switch (Ty) { |
369 default: | 363 default: |
370 llvm_unreachable("Invalid type for GPR."); | 364 llvm_unreachable("Invalid type for GPR."); |
371 case IceType_i1: | 365 case IceType_i1: |
372 case IceType_i8: | 366 case IceType_i8: |
373 return RegisterSet::Reg_al; | 367 return RegisterSet::Reg_al; |
374 case IceType_i16: | 368 case IceType_i16: |
375 return RegisterSet::Reg_ax; | 369 return RegisterSet::Reg_ax; |
376 case IceType_i32: | 370 case IceType_i32: |
377 return RegisterSet::Reg_eax; | 371 return RegisterSet::Reg_eax; |
378 } | 372 } |
379 } | 373 } |
380 | 374 |
381 public: | 375 public: |
382 // Return a register in RegNum's alias set that is suitable for Ty. | 376 // Return a register in RegNum's alias set that is suitable for Ty. |
383 static int32_t getGprForType(Type Ty, int32_t RegNum) { | 377 static RegNumT getGprForType(Type Ty, RegNumT RegNum) { |
384 assert(RegNum != Variable::NoRegister); | 378 assert(RegNum != RegNumT::NoRegister); |
385 | 379 |
386 if (!isScalarIntegerType(Ty)) { | 380 if (!isScalarIntegerType(Ty)) { |
387 return RegNum; | 381 return RegNum; |
388 } | 382 } |
389 | 383 |
390 // [abcd]h registers are not convertible to their ?l, ?x, and e?x versions. | 384 // [abcd]h registers are not convertible to their ?l, ?x, and e?x versions. |
391 switch (RegNum) { | 385 switch (RegNum) { |
392 default: | 386 default: |
393 break; | 387 break; |
394 case RegisterSet::Reg_ah: | 388 case RegisterSet::Reg_ah: |
395 case RegisterSet::Reg_bh: | 389 case RegisterSet::Reg_bh: |
396 case RegisterSet::Reg_ch: | 390 case RegisterSet::Reg_ch: |
397 case RegisterSet::Reg_dh: | 391 case RegisterSet::Reg_dh: |
398 assert(isByteSizedType(Ty)); | 392 assert(isByteSizedType(Ty)); |
399 return RegNum; | 393 return RegNum; |
400 } | 394 } |
401 | 395 |
402 const int32_t FirstGprForType = getFirstGprForType(Ty); | 396 const RegisterSet::AllRegisters FirstGprForType = getFirstGprForType(Ty); |
403 | 397 |
404 switch (RegNum) { | 398 switch (RegNum) { |
405 default: | 399 default: |
406 llvm::report_fatal_error("Unknown register."); | 400 llvm::report_fatal_error("Unknown register."); |
407 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 401 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
408 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 402 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
409 isTrunc8Rcvr, isAhRcvr, aliases) \ | 403 isTrunc8Rcvr, isAhRcvr, aliases) \ |
410 case RegisterSet::val: { \ | 404 case RegisterSet::val: { \ |
411 if (!isGPR) \ | 405 if (!isGPR) \ |
412 return RegisterSet::val; \ | 406 return RegisterSet::val; \ |
413 assert((is32) || (is16) || (is8) || \ | 407 assert((is32) || (is16) || (is8) || \ |
414 getBaseReg(RegisterSet::val) == RegisterSet::Reg_esp); \ | 408 getBaseReg(RegisterSet::val) == RegisterSet::Reg_esp); \ |
415 constexpr int32_t FirstGprWithRegNumSize = \ | 409 constexpr RegisterSet::AllRegisters FirstGprWithRegNumSize = \ |
416 (((is32) || RegisterSet::val == RegisterSet::Reg_esp) \ | 410 (((is32) || RegisterSet::val == RegisterSet::Reg_esp) \ |
417 ? RegisterSet::Reg_eax \ | 411 ? RegisterSet::Reg_eax \ |
418 : (((is16) || RegisterSet::val == RegisterSet::Reg_sp) \ | 412 : (((is16) || RegisterSet::val == RegisterSet::Reg_sp) \ |
419 ? RegisterSet::Reg_ax \ | 413 ? RegisterSet::Reg_ax \ |
420 : RegisterSet::Reg_al)); \ | 414 : RegisterSet::Reg_al)); \ |
421 const int32_t NewRegNum = \ | 415 const RegNumT NewRegNum = \ |
422 RegNum - FirstGprWithRegNumSize + FirstGprForType; \ | 416 RegNumT::fixme(RegNum - FirstGprWithRegNumSize + FirstGprForType); \ |
423 assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ | 417 assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ |
424 "Error involving " #val); \ | 418 "Error involving " #val); \ |
425 return NewRegNum; \ | 419 return NewRegNum; \ |
426 } | 420 } |
427 REGX8632_TABLE | 421 REGX8632_TABLE |
428 #undef X | 422 #undef X |
429 } | 423 } |
430 } | 424 } |
431 | 425 |
432 private: | 426 private: |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 | 567 |
574 REGX8632_TABLE | 568 REGX8632_TABLE |
575 | 569 |
576 #undef X | 570 #undef X |
577 | 571 |
578 return Registers; | 572 return Registers; |
579 } | 573 } |
580 | 574 |
581 static void | 575 static void |
582 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, | 576 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, |
583 llvm::SmallVectorImpl<int32_t> &Permutation, | 577 llvm::SmallVectorImpl<RegNumT> &Permutation, |
584 const llvm::SmallBitVector &ExcludeRegisters, | 578 const llvm::SmallBitVector &ExcludeRegisters, |
585 uint64_t Salt) { | 579 uint64_t Salt) { |
586 // TODO(stichnot): Declaring Permutation this way loses type/size | 580 // TODO(stichnot): Declaring Permutation this way loses type/size |
587 // information. Fix this in conjunction with the caller-side TODO. | 581 // information. Fix this in conjunction with the caller-side TODO. |
588 assert(Permutation.size() >= RegisterSet::Reg_NUM); | 582 assert(Permutation.size() >= RegisterSet::Reg_NUM); |
589 // Expected upper bound on the number of registers in a single equivalence | 583 // Expected upper bound on the number of registers in a single equivalence |
590 // class. For x86-32, this would comprise the 8 XMM registers. This is for | 584 // class. For x86-32, this would comprise the 8 XMM registers. This is for |
591 // performance, not correctness. | 585 // performance, not correctness. |
592 static const unsigned MaxEquivalenceClassSize = 8; | 586 static const unsigned MaxEquivalenceClassSize = 8; |
593 using RegisterList = llvm::SmallVector<int32_t, MaxEquivalenceClassSize>; | 587 using RegisterList = llvm::SmallVector<RegNumT, MaxEquivalenceClassSize>; |
594 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; | 588 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; |
595 EquivalenceClassMap EquivalenceClasses; | 589 EquivalenceClassMap EquivalenceClasses; |
596 SizeT NumShuffled = 0, NumPreserved = 0; | 590 SizeT NumShuffled = 0, NumPreserved = 0; |
597 | 591 |
598 // Build up the equivalence classes of registers by looking at the register | 592 // Build up the equivalence classes of registers by looking at the register |
599 // properties as well as whether the registers should be explicitly excluded | 593 // properties as well as whether the registers should be explicitly excluded |
600 // from shuffling. | 594 // from shuffling. |
601 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 595 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
602 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 596 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
603 isTrunc8Rcvr, isAhRcvr, aliases) \ | 597 isTrunc8Rcvr, isAhRcvr, aliases) \ |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM); | 639 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM); |
646 | 640 |
647 if (Func->isVerbose(IceV_Random)) { | 641 if (Func->isVerbose(IceV_Random)) { |
648 OstreamLocker L(Func->getContext()); | 642 OstreamLocker L(Func->getContext()); |
649 Ostream &Str = Func->getContext()->getStrDump(); | 643 Ostream &Str = Func->getContext()->getStrDump(); |
650 Str << "Register equivalence classes:\n"; | 644 Str << "Register equivalence classes:\n"; |
651 for (auto I : EquivalenceClasses) { | 645 for (auto I : EquivalenceClasses) { |
652 Str << "{"; | 646 Str << "{"; |
653 const RegisterList &List = I.second; | 647 const RegisterList &List = I.second; |
654 bool First = true; | 648 bool First = true; |
655 for (int32_t Register : List) { | 649 for (RegNumT Register : List) { |
656 if (!First) | 650 if (!First) |
657 Str << " "; | 651 Str << " "; |
658 First = false; | 652 First = false; |
659 Str << getRegName(Register); | 653 Str << getRegName(Register); |
660 } | 654 } |
661 Str << "}\n"; | 655 Str << "}\n"; |
662 } | 656 } |
663 } | 657 } |
664 } | 658 } |
665 | 659 |
666 static int32_t getRaxOrDie() { | 660 static RegNumT getRaxOrDie() { |
667 llvm::report_fatal_error("no rax in non-64-bit mode."); | 661 llvm::report_fatal_error("no rax in non-64-bit mode."); |
668 } | 662 } |
669 | 663 |
670 static int32_t getRdxOrDie() { | 664 static RegNumT getRdxOrDie() { |
671 llvm::report_fatal_error("no rdx in non-64-bit mode."); | 665 llvm::report_fatal_error("no rdx in non-64-bit mode."); |
672 } | 666 } |
673 | 667 |
674 // x86-32 calling convention: | 668 // x86-32 calling convention: |
675 // | 669 // |
676 // * The first four arguments of vector type, regardless of their position | 670 // * The first four arguments of vector type, regardless of their position |
677 // relative to the other arguments in the argument list, are placed in | 671 // relative to the other arguments in the argument list, are placed in |
678 // registers xmm0 - xmm3. | 672 // registers xmm0 - xmm3. |
679 // | 673 // |
680 // This intends to match the section "IA-32 Function Calling Convention" of | 674 // This intends to match the section "IA-32 Function Calling Convention" of |
681 // the document "OS X ABI Function Call Guide" by Apple. | 675 // the document "OS X ABI Function Call Guide" by Apple. |
682 | 676 |
683 /// The maximum number of arguments to pass in XMM registers | 677 /// The maximum number of arguments to pass in XMM registers |
684 static constexpr uint32_t X86_MAX_XMM_ARGS = 4; | 678 static constexpr uint32_t X86_MAX_XMM_ARGS = 4; |
685 /// The maximum number of arguments to pass in GPR registers | 679 /// The maximum number of arguments to pass in GPR registers |
686 static constexpr uint32_t X86_MAX_GPR_ARGS = 0; | 680 static constexpr uint32_t X86_MAX_GPR_ARGS = 0; |
687 /// Whether scalar floating point arguments are passed in XMM registers | 681 /// Whether scalar floating point arguments are passed in XMM registers |
688 static constexpr bool X86_PASS_SCALAR_FP_IN_XMM = false; | 682 static constexpr bool X86_PASS_SCALAR_FP_IN_XMM = false; |
689 /// Get the register for a given argument slot in the XMM registers. | 683 /// Get the register for a given argument slot in the XMM registers. |
690 static int32_t getRegisterForXmmArgNum(uint32_t ArgNum) { | 684 static RegNumT getRegisterForXmmArgNum(uint32_t ArgNum) { |
691 // TODO(sehr): Change to use the CCArg technique used in ARM32. | 685 // TODO(sehr): Change to use the CCArg technique used in ARM32. |
692 static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1, | 686 static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1, |
693 "Inconsistency between XMM register numbers and ordinals"); | 687 "Inconsistency between XMM register numbers and ordinals"); |
694 if (ArgNum >= X86_MAX_XMM_ARGS) { | 688 if (ArgNum >= X86_MAX_XMM_ARGS) { |
695 return Variable::NoRegister; | 689 return RegNumT::NoRegister; |
696 } | 690 } |
697 return static_cast<int32_t>(RegisterSet::Reg_xmm0 + ArgNum); | 691 return RegNumT::fixme(RegisterSet::Reg_xmm0 + ArgNum); |
698 } | 692 } |
699 /// Get the register for a given argument slot in the GPRs. | 693 /// Get the register for a given argument slot in the GPRs. |
700 static int32_t getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) { | 694 static RegNumT getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) { |
701 assert(Ty == IceType_i64 || Ty == IceType_i32); | 695 assert(Ty == IceType_i64 || Ty == IceType_i32); |
702 (void)Ty; | 696 (void)Ty; |
703 (void)ArgNum; | 697 (void)ArgNum; |
704 return Variable::NoRegister; | 698 return RegNumT::NoRegister; |
705 } | 699 } |
706 | 700 |
707 /// The number of bits in a byte | 701 /// The number of bits in a byte |
708 static constexpr uint32_t X86_CHAR_BIT = 8; | 702 static constexpr uint32_t X86_CHAR_BIT = 8; |
709 /// Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it | 703 /// Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it |
710 /// is used as an argument to std::max(), and the default std::less<T> has an | 704 /// is used as an argument to std::max(), and the default std::less<T> has an |
711 /// operator(T const&, T const&) which requires this member to have an | 705 /// operator(T const&, T const&) which requires this member to have an |
712 /// address. | 706 /// address. |
713 static const uint32_t X86_STACK_ALIGNMENT_BYTES; | 707 static const uint32_t X86_STACK_ALIGNMENT_BYTES; |
714 /// Size of the return address on the stack | 708 /// Size of the return address on the stack |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 | 991 |
998 static uint8_t InstSegmentPrefixes[]; | 992 static uint8_t InstSegmentPrefixes[]; |
999 }; | 993 }; |
1000 | 994 |
1001 using Traits = ::Ice::X8632::TargetX8632Traits; | 995 using Traits = ::Ice::X8632::TargetX8632Traits; |
1002 } // end of namespace X8632 | 996 } // end of namespace X8632 |
1003 | 997 |
1004 } // end of namespace Ice | 998 } // end of namespace Ice |
1005 | 999 |
1006 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 1000 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H |
OLD | NEW |