OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// | 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- 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 2470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2481 // is passed. | 2481 // is passed. |
2482 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { | 2482 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { |
2483 Operand *Arg = Instr->getArg(i); | 2483 Operand *Arg = Instr->getArg(i); |
2484 const Type Ty = Arg->getType(); | 2484 const Type Ty = Arg->getType(); |
2485 // The PNaCl ABI requires the width of arguments to be at least 32 bits. | 2485 // The PNaCl ABI requires the width of arguments to be at least 32 bits. |
2486 assert(typeWidthInBytes(Ty) >= 4); | 2486 assert(typeWidthInBytes(Ty) >= 4); |
2487 if (isVectorType(Ty) && (Traits::getRegisterForXmmArgNum(XmmArgs.size()) != | 2487 if (isVectorType(Ty) && (Traits::getRegisterForXmmArgNum(XmmArgs.size()) != |
2488 Variable::NoRegister)) { | 2488 Variable::NoRegister)) { |
2489 XmmArgs.push_back(Arg); | 2489 XmmArgs.push_back(Arg); |
2490 } else if (isScalarFloatingType(Ty) && Traits::X86_PASS_SCALAR_FP_IN_XMM && | 2490 } else if (isScalarFloatingType(Ty) && Traits::X86_PASS_SCALAR_FP_IN_XMM && |
2491 (Traits::getRegisterForXmmArgNum(0) != Variable::NoRegister)) { | 2491 (Traits::getRegisterForXmmArgNum(XmmArgs.size()) != |
| 2492 Variable::NoRegister)) { |
2492 XmmArgs.push_back(Arg); | 2493 XmmArgs.push_back(Arg); |
2493 } else if (isScalarIntegerType(Ty) && | 2494 } else if (isScalarIntegerType(Ty) && |
2494 (Traits::getRegisterForGprArgNum(Ty, GprArgs.size()) != | 2495 (Traits::getRegisterForGprArgNum(Ty, GprArgs.size()) != |
2495 Variable::NoRegister)) { | 2496 Variable::NoRegister)) { |
2496 GprArgs.emplace_back(Ty, Arg); | 2497 GprArgs.emplace_back(Ty, Arg); |
2497 } else { | 2498 } else { |
2498 // Place on stack. | 2499 // Place on stack. |
2499 StackArgs.push_back(Arg); | 2500 StackArgs.push_back(Arg); |
2500 if (isVectorType(Arg->getType())) { | 2501 if (isVectorType(Arg->getType())) { |
2501 ParameterAreaSizeBytes = | 2502 ParameterAreaSizeBytes = |
(...skipping 2091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4593 void TargetX86Base<TraitsType>::lowerCountZeros(bool Cttz, Type Ty, | 4594 void TargetX86Base<TraitsType>::lowerCountZeros(bool Cttz, Type Ty, |
4594 Variable *Dest, | 4595 Variable *Dest, |
4595 Operand *FirstVal, | 4596 Operand *FirstVal, |
4596 Operand *SecondVal) { | 4597 Operand *SecondVal) { |
4597 // TODO(jvoung): Determine if the user CPU supports LZCNT (BMI). | 4598 // TODO(jvoung): Determine if the user CPU supports LZCNT (BMI). |
4598 // Then the instructions will handle the Val == 0 case much more simply | 4599 // Then the instructions will handle the Val == 0 case much more simply |
4599 // and won't require conversion from bit position to number of zeros. | 4600 // and won't require conversion from bit position to number of zeros. |
4600 // | 4601 // |
4601 // Otherwise: | 4602 // Otherwise: |
4602 // bsr IF_NOT_ZERO, Val | 4603 // bsr IF_NOT_ZERO, Val |
4603 // mov T_DEST, 63 | 4604 // mov T_DEST, ((Ty == i32) ? 63 : 127) |
4604 // cmovne T_DEST, IF_NOT_ZERO | 4605 // cmovne T_DEST, IF_NOT_ZERO |
4605 // xor T_DEST, 31 | 4606 // xor T_DEST, ((Ty == i32) ? 31 : 63) |
4606 // mov DEST, T_DEST | 4607 // mov DEST, T_DEST |
4607 // | 4608 // |
4608 // NOTE: T_DEST must be a register because cmov requires its dest to be a | 4609 // NOTE: T_DEST must be a register because cmov requires its dest to be a |
4609 // register. Also, bsf and bsr require their dest to be a register. | 4610 // register. Also, bsf and bsr require their dest to be a register. |
4610 // | 4611 // |
4611 // The xor DEST, 31 converts a bit position to # of leading zeroes. | 4612 // The xor DEST, C(31|63) converts a bit position to # of leading zeroes. |
4612 // E.g., for 000... 00001100, bsr will say that the most significant bit | 4613 // E.g., for 000... 00001100, bsr will say that the most significant bit |
4613 // set is at position 3, while the number of leading zeros is 28. Xor is | 4614 // set is at position 3, while the number of leading zeros is 28. Xor is |
4614 // like (31 - N) for N <= 31, and converts 63 to 32 (for the all-zeros case). | 4615 // like (M - N) for N <= M, and converts 63 to 32, and 127 to 64 (for the |
| 4616 // all-zeros case). |
4615 // | 4617 // |
4616 // Similar for 64-bit, but start w/ speculating that the upper 32 bits | 4618 // X8632 only: Similar for 64-bit, but start w/ speculating that the upper 32 |
4617 // are all zero, and compute the result for that case (checking the lower | 4619 // bits are all zero, and compute the result for that case (checking the |
4618 // 32 bits). Then actually compute the result for the upper bits and | 4620 // lower 32 bits). Then actually compute the result for the upper bits and |
4619 // cmov in the result from the lower computation if the earlier speculation | 4621 // cmov in the result from the lower computation if the earlier speculation |
4620 // was correct. | 4622 // was correct. |
4621 // | 4623 // |
4622 // Cttz, is similar, but uses bsf instead, and doesn't require the xor | 4624 // Cttz, is similar, but uses bsf instead, and doesn't require the xor |
4623 // bit position conversion, and the speculation is reversed. | 4625 // bit position conversion, and the speculation is reversed. |
| 4626 |
| 4627 // TODO(jpp): refactor this method. |
4624 assert(Ty == IceType_i32 || Ty == IceType_i64); | 4628 assert(Ty == IceType_i32 || Ty == IceType_i64); |
4625 const Type DestTy = Traits::Is64Bit ? Dest->getType() : IceType_i32; | 4629 const Type DestTy = Traits::Is64Bit ? Dest->getType() : IceType_i32; |
4626 Variable *T = makeReg(DestTy); | 4630 Variable *T = makeReg(DestTy); |
4627 Operand *FirstValRM = legalize(FirstVal, Legal_Mem | Legal_Reg); | 4631 Operand *FirstValRM = legalize(FirstVal, Legal_Mem | Legal_Reg); |
4628 if (Cttz) { | 4632 if (Cttz) { |
4629 _bsf(T, FirstValRM); | 4633 _bsf(T, FirstValRM); |
4630 } else { | 4634 } else { |
4631 _bsr(T, FirstValRM); | 4635 _bsr(T, FirstValRM); |
4632 } | 4636 } |
4633 Variable *T_Dest = makeReg(DestTy); | 4637 Variable *T_Dest = makeReg(DestTy); |
4634 Constant *_31 = Ctx->getConstantInt32(31); | 4638 Constant *_31 = Ctx->getConstantInt32(31); |
4635 Constant *_32 = Ctx->getConstantInt(DestTy, 32); | 4639 Constant *_32 = Ctx->getConstantInt(DestTy, 32); |
| 4640 Constant *_63 = Ctx->getConstantInt(DestTy, 63); |
| 4641 Constant *_64 = Ctx->getConstantInt(DestTy, 64); |
4636 if (Cttz) { | 4642 if (Cttz) { |
4637 _mov(T_Dest, _32); | 4643 if (DestTy == IceType_i64) { |
| 4644 _mov(T_Dest, _64); |
| 4645 } else { |
| 4646 _mov(T_Dest, _32); |
| 4647 } |
4638 } else { | 4648 } else { |
4639 Constant *_63 = Ctx->getConstantInt(DestTy, 63); | 4649 Constant *_127 = Ctx->getConstantInt(DestTy, 127); |
4640 _mov(T_Dest, _63); | 4650 if (DestTy == IceType_i64) { |
| 4651 _mov(T_Dest, _127); |
| 4652 } else { |
| 4653 _mov(T_Dest, _63); |
| 4654 } |
4641 } | 4655 } |
4642 _cmov(T_Dest, T, Traits::Cond::Br_ne); | 4656 _cmov(T_Dest, T, Traits::Cond::Br_ne); |
4643 if (!Cttz) { | 4657 if (!Cttz) { |
4644 _xor(T_Dest, _31); | 4658 if (DestTy == IceType_i64) { |
| 4659 // Even though there's a _63 available at this point, that constant might |
| 4660 // not be an i32, which will cause the xor emission to fail. |
| 4661 Constant *_63 = Ctx->getConstantInt32(63); |
| 4662 _xor(T_Dest, _63); |
| 4663 } else { |
| 4664 _xor(T_Dest, _31); |
| 4665 } |
4645 } | 4666 } |
4646 if (Traits::Is64Bit || Ty == IceType_i32) { | 4667 if (Traits::Is64Bit || Ty == IceType_i32) { |
4647 _mov(Dest, T_Dest); | 4668 _mov(Dest, T_Dest); |
4648 return; | 4669 return; |
4649 } | 4670 } |
4650 _add(T_Dest, _32); | 4671 _add(T_Dest, _32); |
4651 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 4672 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
4652 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 4673 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
4653 // Will be using "test" on this, so we need a registerized variable. | 4674 // Will be using "test" on this, so we need a registerized variable. |
4654 Variable *SecondVar = legalizeToReg(SecondVal); | 4675 Variable *SecondVar = legalizeToReg(SecondVal); |
(...skipping 2779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7434 emitGlobal(*Var, SectionSuffix); | 7455 emitGlobal(*Var, SectionSuffix); |
7435 } | 7456 } |
7436 } | 7457 } |
7437 } break; | 7458 } break; |
7438 } | 7459 } |
7439 } | 7460 } |
7440 } // end of namespace X86NAMESPACE | 7461 } // end of namespace X86NAMESPACE |
7441 } // end of namespace Ice | 7462 } // end of namespace Ice |
7442 | 7463 |
7443 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 7464 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |