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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 // SSE2 is the PNaCl baseline instruction set. | 264 // SSE2 is the PNaCl baseline instruction set. |
265 SSE2 = Begin, | 265 SSE2 = Begin, |
266 SSE4_1, | 266 SSE4_1, |
267 End | 267 End |
268 }; | 268 }; |
269 | 269 |
270 static const char *TargetName; | 270 static const char *TargetName; |
271 static constexpr Type WordType = IceType_i32; | 271 static constexpr Type WordType = IceType_i32; |
272 | 272 |
273 static IceString getRegName(int32_t RegNum) { | 273 static IceString getRegName(int32_t RegNum) { |
274 static const char *const RegNames[] = { | 274 static const char *const RegNames[] = {{/* Empty for Reg_Invalid */}, |
275 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 275 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
276 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 276 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
277 isTrunc8Rcvr, isAhRcvr, aliases) \ | 277 isTrunc8Rcvr, isAhRcvr, aliases) \ |
278 name, | 278 name, |
279 REGX8632_TABLE | 279 REGX8632_TABLE |
280 #undef X | 280 #undef X |
281 }; | 281 }; |
282 assert(RegNum >= 0); | 282 assert(RegNum >= 0); |
283 assert(RegNum < RegisterSet::Reg_NUM); | 283 assert(RegNum < RegisterSet::Reg_NUM); |
284 return RegNames[RegNum]; | 284 return RegNames[RegNum]; |
285 } | 285 } |
286 | 286 |
287 static GPRRegister getEncodedGPR(int32_t RegNum) { | 287 static GPRRegister getEncodedGPR(int32_t RegNum) { |
288 static const GPRRegister GPRRegs[] = { | 288 static const GPRRegister GPRRegs[] = {{/* Empty for Reg_Invalid */}, |
289 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 289 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
290 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 290 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
291 isTrunc8Rcvr, isAhRcvr, aliases) \ | 291 isTrunc8Rcvr, isAhRcvr, aliases) \ |
292 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), | 292 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), |
293 REGX8632_TABLE | 293 REGX8632_TABLE |
294 #undef X | 294 #undef X |
295 }; | 295 }; |
296 assert(RegNum >= 0); | 296 assert(RegNum >= 0); |
297 assert(RegNum < RegisterSet::Reg_NUM); | 297 assert(RegNum < RegisterSet::Reg_NUM); |
298 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); | 298 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); |
299 return GPRRegs[RegNum]; | 299 return GPRRegs[RegNum]; |
300 } | 300 } |
301 | 301 |
302 static ByteRegister getEncodedByteReg(int32_t RegNum) { | 302 static ByteRegister getEncodedByteReg(int32_t RegNum) { |
303 static const ByteRegister ByteRegs[] = { | 303 static const ByteRegister ByteRegs[] = {{/* Empty for Reg_Invalid */}, |
304 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 304 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
305 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 305 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
306 isTrunc8Rcvr, isAhRcvr, aliases) \ | 306 isTrunc8Rcvr, isAhRcvr, aliases) \ |
307 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), | 307 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), |
308 REGX8632_TABLE | 308 REGX8632_TABLE |
309 #undef X | 309 #undef X |
310 }; | 310 }; |
311 assert(RegNum >= 0); | 311 assert(RegNum >= 0); |
312 assert(RegNum < RegisterSet::Reg_NUM); | 312 assert(RegNum < RegisterSet::Reg_NUM); |
313 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); | 313 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); |
314 return ByteRegs[RegNum]; | 314 return ByteRegs[RegNum]; |
315 } | 315 } |
316 | 316 |
317 static XmmRegister getEncodedXmm(int32_t RegNum) { | 317 static XmmRegister getEncodedXmm(int32_t RegNum) { |
318 static const XmmRegister XmmRegs[] = { | 318 static const XmmRegister XmmRegs[] = {{/* Empty for Reg_Invalid */}, |
319 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 319 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
320 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 320 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
321 isTrunc8Rcvr, isAhRcvr, aliases) \ | 321 isTrunc8Rcvr, isAhRcvr, aliases) \ |
322 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), | 322 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), |
323 REGX8632_TABLE | 323 REGX8632_TABLE |
324 #undef X | 324 #undef X |
325 }; | 325 }; |
326 assert(RegNum >= 0); | 326 assert(RegNum >= 0); |
327 assert(RegNum < RegisterSet::Reg_NUM); | 327 assert(RegNum < RegisterSet::Reg_NUM); |
328 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); | 328 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); |
329 return XmmRegs[RegNum]; | 329 return XmmRegs[RegNum]; |
330 } | 330 } |
331 | 331 |
332 static uint32_t getEncoding(int32_t RegNum) { | 332 static uint32_t getEncoding(int32_t RegNum) { |
333 static const uint32_t Encoding[] = { | 333 static const uint32_t Encoding[] = {{/* Empty for Reg_Invalid */}, |
334 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 334 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
335 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 335 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
336 isTrunc8Rcvr, isAhRcvr, aliases) \ | 336 isTrunc8Rcvr, isAhRcvr, aliases) \ |
337 encode, | 337 encode, |
338 REGX8632_TABLE | 338 REGX8632_TABLE |
339 #undef X | 339 #undef X |
340 }; | 340 }; |
341 assert(RegNum >= 0); | 341 assert(RegNum >= 0); |
342 assert(RegNum < RegisterSet::Reg_NUM); | 342 assert(RegNum < RegisterSet::Reg_NUM); |
343 return Encoding[RegNum]; | 343 return Encoding[RegNum]; |
344 } | 344 } |
345 | 345 |
346 static int32_t getBaseReg(int32_t RegNum) { | 346 static int32_t getBaseReg(int32_t RegNum) { |
347 static const int32_t BaseRegs[] = { | 347 static const int32_t BaseRegs[] = {{/* Empty for Reg_Invalid */}, |
348 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 348 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
349 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 349 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
350 isTrunc8Rcvr, isAhRcvr, aliases) \ | 350 isTrunc8Rcvr, isAhRcvr, aliases) \ |
351 RegisterSet::base, | 351 RegisterSet::base, |
352 REGX8632_TABLE | 352 REGX8632_TABLE |
353 #undef X | 353 #undef X |
354 }; | 354 }; |
355 assert(RegNum >= 0); | 355 assert(RegNum >= 0); |
356 assert(RegNum < RegisterSet::Reg_NUM); | 356 assert(RegNum < RegisterSet::Reg_NUM); |
357 return BaseRegs[RegNum]; | 357 return BaseRegs[RegNum]; |
358 } | 358 } |
359 | 359 |
360 // Return a register in RegNum's alias set that is suitable for Ty. | 360 // Return a register in RegNum's alias set that is suitable for Ty. |
361 static int32_t getGprForType(Type Ty, int32_t RegNum) { | 361 static int32_t getGprForType(Type Ty, int32_t RegNum) { |
362 assert(RegNum != Variable::NoRegister); | 362 assert(RegNum != Variable::NoRegister); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
409 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); | 409 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); |
410 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); | 410 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); |
411 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); | 411 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); |
412 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); | 412 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); |
413 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); | 413 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); |
414 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); | 414 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); |
415 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); | 415 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); |
416 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); | 416 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); |
417 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); | 417 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); |
418 ScratchRegs->resize(RegisterSet::Reg_NUM); | 418 ScratchRegs->resize(RegisterSet::Reg_NUM); |
419 | |
420 static struct { | |
421 uint16_t Val; | |
422 int Is64 : 1; | |
423 int Is32 : 1; | |
424 int Is16 : 1; | |
425 int Is8 : 1; | |
426 int IsXmm : 1; | |
427 int Is64To8 : 1; | |
428 int Is32To8 : 1; | |
429 int Is16To8 : 1; | |
430 int IsTrunc8Rcvr : 1; | |
431 int IsAhRcvr : 1; | |
432 int Scratch : 1; | |
433 uint16_t Aliases[4]; | |
434 } X8632RegTable[RegisterSet::Reg_NUM] = { | |
435 {/* Empty entry for RegInvalid. */}, | |
419 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 436 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
420 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 437 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
421 isTrunc8Rcvr, isAhRcvr, aliases) \ | 438 isTrunc8Rcvr, isAhRcvr, aliases) \ |
422 (IntegerRegistersI32)[RegisterSet::val] = is32; \ | 439 { \ |
423 (IntegerRegistersI16)[RegisterSet::val] = is16; \ | 440 RegisterSet::val, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
424 (IntegerRegistersI8)[RegisterSet::val] = is8; \ | 441 isTrunc8Rcvr, isAhRcvr, scratch, aliases \ |
425 (FloatRegisters)[RegisterSet::val] = isXmm; \ | |
426 (VectorRegisters)[RegisterSet::val] = isXmm; \ | |
427 (Trunc64To8Registers)[RegisterSet::val] = is64To8; \ | |
428 (Trunc32To8Registers)[RegisterSet::val] = is32To8; \ | |
429 (Trunc16To8Registers)[RegisterSet::val] = is16To8; \ | |
430 (Trunc8RcvrRegisters)[RegisterSet::val] = isTrunc8Rcvr; \ | |
431 (AhRcvrRegisters)[RegisterSet::val] = isAhRcvr; \ | |
432 (*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \ | |
433 for (SizeT RegAlias : aliases) { \ | |
434 assert(!(*RegisterAliases)[RegisterSet::val][RegAlias] && \ | |
435 "Duplicate alias for " #val); \ | |
436 (*RegisterAliases)[RegisterSet::val].set(RegAlias); \ | |
437 } \ | 442 } \ |
438 (*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \ | 443 , |
439 (*ScratchRegs)[RegisterSet::val] = scratch; | 444 REGX8632_TABLE |
440 REGX8632_TABLE; | |
441 #undef X | 445 #undef X |
446 }; | |
447 | |
448 for (SizeT ii = 1; ii < llvm::array_lengthof(X8632RegTable); ++ii) { | |
449 const auto &Entry = X8632RegTable[ii]; | |
450 (IntegerRegistersI32)[Entry.Val] = Entry.Is32; | |
451 (IntegerRegistersI16)[Entry.Val] = Entry.Is16; | |
452 (IntegerRegistersI8)[Entry.Val] = Entry.Is8; | |
453 (FloatRegisters)[Entry.Val] = Entry.IsXmm; | |
454 (VectorRegisters)[Entry.Val] = Entry.IsXmm; | |
455 (Trunc64To8Registers)[Entry.Val] = Entry.Is64To8; | |
456 (Trunc32To8Registers)[Entry.Val] = Entry.Is32To8; | |
457 (Trunc16To8Registers)[Entry.Val] = Entry.Is16To8; | |
458 (Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr; | |
459 (AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr; | |
460 (*RegisterAliases)[Entry.Val].resize(RegisterSet::Reg_NUM); | |
461 for (SizeT Alias : Entry.Aliases) { | |
462 if (Alias == 0) { | |
463 break; | |
464 } | |
465 assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias"); | |
466 (*RegisterAliases)[Entry.Val].set(Alias); | |
467 } | |
468 (*RegisterAliases)[Entry.Val].set(Entry.Val); | |
469 (*ScratchRegs)[Entry.Val] = Entry.Scratch; | |
470 } | |
442 | 471 |
443 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; | 472 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; |
444 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; | 473 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; |
445 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; | 474 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; |
446 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; | 475 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; |
447 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; | 476 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; |
448 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI32; | 477 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI32; |
449 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; | 478 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; |
450 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; | 479 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; |
451 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; | 480 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
551 for (auto I : EquivalenceClasses) { | 580 for (auto I : EquivalenceClasses) { |
552 const RegisterList &List = I.second; | 581 const RegisterList &List = I.second; |
553 RegisterList Shuffled(List); | 582 RegisterList Shuffled(List); |
554 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNGW); | 583 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNGW); |
555 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { | 584 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { |
556 Permutation[List[SI]] = Shuffled[SI]; | 585 Permutation[List[SI]] = Shuffled[SI]; |
557 ++NumShuffled; | 586 ++NumShuffled; |
558 } | 587 } |
559 } | 588 } |
560 | 589 |
561 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM); | 590 // We need to subtract one to account for Reg_Invalid. |
Jim Stichnoth
2015/12/30 02:50:24
Any chance this would be unnecessary, and everythi
John
2015/12/30 17:55:36
Yes, and no. I don't know anyway of telling the li
| |
591 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM - 1); | |
562 | 592 |
563 if (Func->isVerbose(IceV_Random)) { | 593 if (Func->isVerbose(IceV_Random)) { |
564 OstreamLocker L(Func->getContext()); | 594 OstreamLocker L(Func->getContext()); |
565 Ostream &Str = Func->getContext()->getStrDump(); | 595 Ostream &Str = Func->getContext()->getStrDump(); |
566 Str << "Register equivalence classes:\n"; | 596 Str << "Register equivalence classes:\n"; |
567 for (auto I : EquivalenceClasses) { | 597 for (auto I : EquivalenceClasses) { |
568 Str << "{"; | 598 Str << "{"; |
569 const RegisterList &List = I.second; | 599 const RegisterList &List = I.second; |
570 bool First = true; | 600 bool First = true; |
571 for (int32_t Register : List) { | 601 for (int32_t Register : List) { |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
877 | 907 |
878 } // end of namespace X86Internal | 908 } // end of namespace X86Internal |
879 | 909 |
880 namespace X8632 { | 910 namespace X8632 { |
881 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8632>; | 911 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8632>; |
882 } // end of namespace X8632 | 912 } // end of namespace X8632 |
883 | 913 |
884 } // end of namespace Ice | 914 } // end of namespace Ice |
885 | 915 |
886 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 916 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H |
OLD | NEW |