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[RegisterSet::Reg_NUM] = { |
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[RegisterSet::Reg_NUM] = { |
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[RegisterSet::Reg_NUM] = { |
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[RegisterSet::Reg_NUM] = { |
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[RegisterSet::Reg_NUM] = { |
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[RegisterSet::Reg_NUM] = { |
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]; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 return RegisterSet::Reg_bp; | 393 return RegisterSet::Reg_bp; |
394 case RegisterSet::Reg_esi: | 394 case RegisterSet::Reg_esi: |
395 return RegisterSet::Reg_si; | 395 return RegisterSet::Reg_si; |
396 case RegisterSet::Reg_edi: | 396 case RegisterSet::Reg_edi: |
397 return RegisterSet::Reg_di; | 397 return RegisterSet::Reg_di; |
398 } | 398 } |
399 } | 399 } |
400 return RegNum; | 400 return RegNum; |
401 } | 401 } |
402 | 402 |
| 403 private: |
| 404 /// SizeOf is used to obtain the size of an initializer list as a constexpr |
| 405 /// expression. This is only needed until our C++ library is updated to |
| 406 /// C++ 14 -- which defines constexpr members to std::initializer_list. |
| 407 class SizeOf { |
| 408 SizeOf(const SizeOf &) = delete; |
| 409 SizeOf &operator=(const SizeOf &) = delete; |
| 410 |
| 411 public: |
| 412 constexpr SizeOf() : Size(0) {} |
| 413 template <typename... T> |
| 414 explicit constexpr SizeOf(T...) |
| 415 : Size(__length<T...>::value) {} |
| 416 constexpr SizeT size() const { return Size; } |
| 417 |
| 418 private: |
| 419 template <typename T, typename... U> struct __length { |
| 420 static constexpr std::size_t value = 1 + __length<U...>::value; |
| 421 }; |
| 422 |
| 423 template <typename T> struct __length<T> { |
| 424 static constexpr std::size_t value = 1; |
| 425 }; |
| 426 |
| 427 const std::size_t Size; |
| 428 }; |
| 429 |
| 430 public: |
403 static void initRegisterSet( | 431 static void initRegisterSet( |
404 std::array<llvm::SmallBitVector, RCX86_NUM> *TypeToRegisterSet, | 432 std::array<llvm::SmallBitVector, RCX86_NUM> *TypeToRegisterSet, |
405 std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases, | 433 std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases, |
406 llvm::SmallBitVector *ScratchRegs) { | 434 llvm::SmallBitVector *ScratchRegs) { |
407 llvm::SmallBitVector IntegerRegistersI32(RegisterSet::Reg_NUM); | 435 llvm::SmallBitVector IntegerRegistersI32(RegisterSet::Reg_NUM); |
408 llvm::SmallBitVector IntegerRegistersI16(RegisterSet::Reg_NUM); | 436 llvm::SmallBitVector IntegerRegistersI16(RegisterSet::Reg_NUM); |
409 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); | 437 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); |
410 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); | 438 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); |
411 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); | 439 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); |
412 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); | 440 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); |
413 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); | 441 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); |
414 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); | 442 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); |
415 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); | 443 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); |
416 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); | 444 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); |
417 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); | 445 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); |
418 ScratchRegs->resize(RegisterSet::Reg_NUM); | 446 ScratchRegs->resize(RegisterSet::Reg_NUM); |
| 447 |
| 448 static constexpr struct { |
| 449 uint16_t Val; |
| 450 int Is64 : 1; |
| 451 int Is32 : 1; |
| 452 int Is16 : 1; |
| 453 int Is8 : 1; |
| 454 int IsXmm : 1; |
| 455 int Is64To8 : 1; |
| 456 int Is32To8 : 1; |
| 457 int Is16To8 : 1; |
| 458 int IsTrunc8Rcvr : 1; |
| 459 int IsAhRcvr : 1; |
| 460 int Scratch : 1; |
| 461 #define NUM_ALIASES_BITS 2 |
| 462 SizeT NumAliases : (NUM_ALIASES_BITS + 1); |
| 463 uint16_t Aliases[1 << NUM_ALIASES_BITS]; |
| 464 #undef NUM_ALIASES_BITS |
| 465 } X8632RegTable[RegisterSet::Reg_NUM] = { |
419 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 466 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
420 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 467 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
421 isTrunc8Rcvr, isAhRcvr, aliases) \ | 468 isTrunc8Rcvr, isAhRcvr, aliases) \ |
422 (IntegerRegistersI32)[RegisterSet::val] = is32; \ | 469 { \ |
423 (IntegerRegistersI16)[RegisterSet::val] = is16; \ | 470 RegisterSet::val, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
424 (IntegerRegistersI8)[RegisterSet::val] = is8; \ | 471 isTrunc8Rcvr, isAhRcvr, scratch, (SizeOf aliases).size(), 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 } \ | 472 } \ |
438 (*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \ | 473 , |
439 (*ScratchRegs)[RegisterSet::val] = scratch; | 474 REGX8632_TABLE |
440 REGX8632_TABLE; | |
441 #undef X | 475 #undef X |
| 476 }; |
| 477 |
| 478 for (SizeT ii = 0; ii < llvm::array_lengthof(X8632RegTable); ++ii) { |
| 479 const auto &Entry = X8632RegTable[ii]; |
| 480 (IntegerRegistersI32)[Entry.Val] = Entry.Is32; |
| 481 (IntegerRegistersI16)[Entry.Val] = Entry.Is16; |
| 482 (IntegerRegistersI8)[Entry.Val] = Entry.Is8; |
| 483 (FloatRegisters)[Entry.Val] = Entry.IsXmm; |
| 484 (VectorRegisters)[Entry.Val] = Entry.IsXmm; |
| 485 (Trunc64To8Registers)[Entry.Val] = Entry.Is64To8; |
| 486 (Trunc32To8Registers)[Entry.Val] = Entry.Is32To8; |
| 487 (Trunc16To8Registers)[Entry.Val] = Entry.Is16To8; |
| 488 (Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr; |
| 489 (AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr; |
| 490 (*RegisterAliases)[Entry.Val].resize(RegisterSet::Reg_NUM); |
| 491 for (int J = 0; J < Entry.NumAliases; J++) { |
| 492 SizeT Alias = Entry.Aliases[J]; |
| 493 assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias"); |
| 494 (*RegisterAliases)[Entry.Val].set(Alias); |
| 495 } |
| 496 (*RegisterAliases)[Entry.Val].set(Entry.Val); |
| 497 (*ScratchRegs)[Entry.Val] = Entry.Scratch; |
| 498 } |
442 | 499 |
443 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; | 500 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; |
444 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; | 501 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; |
445 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; | 502 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; |
446 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; | 503 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; |
447 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; | 504 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; |
448 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI32; | 505 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI32; |
449 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; | 506 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; |
450 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; | 507 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; |
451 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; | 508 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 | 934 |
878 } // end of namespace X86Internal | 935 } // end of namespace X86Internal |
879 | 936 |
880 namespace X8632 { | 937 namespace X8632 { |
881 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8632>; | 938 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8632>; |
882 } // end of namespace X8632 | 939 } // end of namespace X8632 |
883 | 940 |
884 } // end of namespace Ice | 941 } // end of namespace Ice |
885 | 942 |
886 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 943 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H |
OLD | NEW |