OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
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 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 4572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4583 if (isVectorType(Ty)) { | 4583 if (isVectorType(Ty)) { |
4584 _movp(Reg, Src); | 4584 _movp(Reg, Src); |
4585 } else { | 4585 } else { |
4586 _mov(Reg, Src); | 4586 _mov(Reg, Src); |
4587 } | 4587 } |
4588 return Reg; | 4588 return Reg; |
4589 } | 4589 } |
4590 | 4590 |
4591 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, | 4591 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, |
4592 int32_t RegNum) { | 4592 int32_t RegNum) { |
| 4593 Type Ty = From->getType(); |
4593 // Assert that a physical register is allowed. To date, all calls | 4594 // Assert that a physical register is allowed. To date, all calls |
4594 // to legalize() allow a physical register. If a physical register | 4595 // to legalize() allow a physical register. If a physical register |
4595 // needs to be explicitly disallowed, then new code will need to be | 4596 // needs to be explicitly disallowed, then new code will need to be |
4596 // written to force a spill. | 4597 // written to force a spill. |
4597 assert(Allowed & Legal_Reg); | 4598 assert(Allowed & Legal_Reg); |
4598 // If we're asking for a specific physical register, make sure we're | 4599 // If we're asking for a specific physical register, make sure we're |
4599 // not allowing any other operand kinds. (This could be future | 4600 // not allowing any other operand kinds. (This could be future |
4600 // work, e.g. allow the shl shift amount to be either an immediate | 4601 // work, e.g. allow the shl shift amount to be either an immediate |
4601 // or in ecx.) | 4602 // or in ecx.) |
4602 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); | 4603 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); |
4603 if (auto Mem = llvm::dyn_cast<OperandX8632Mem>(From)) { | 4604 if (auto Mem = llvm::dyn_cast<OperandX8632Mem>(From)) { |
4604 // Before doing anything with a Mem operand, we need to ensure | 4605 // Before doing anything with a Mem operand, we need to ensure |
4605 // that the Base and Index components are in physical registers. | 4606 // that the Base and Index components are in physical registers. |
4606 Variable *Base = Mem->getBase(); | 4607 Variable *Base = Mem->getBase(); |
4607 Variable *Index = Mem->getIndex(); | 4608 Variable *Index = Mem->getIndex(); |
4608 Variable *RegBase = nullptr; | 4609 Variable *RegBase = nullptr; |
4609 Variable *RegIndex = nullptr; | 4610 Variable *RegIndex = nullptr; |
4610 if (Base) { | 4611 if (Base) { |
4611 RegBase = legalizeToVar(Base); | 4612 RegBase = legalizeToVar(Base); |
4612 } | 4613 } |
4613 if (Index) { | 4614 if (Index) { |
4614 RegIndex = legalizeToVar(Index); | 4615 RegIndex = legalizeToVar(Index); |
4615 } | 4616 } |
4616 if (Base != RegBase || Index != RegIndex) { | 4617 if (Base != RegBase || Index != RegIndex) { |
4617 From = OperandX8632Mem::create( | 4618 From = |
4618 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex, | 4619 OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex, |
4619 Mem->getShift(), Mem->getSegmentRegister()); | 4620 Mem->getShift(), Mem->getSegmentRegister()); |
4620 } | 4621 } |
4621 | 4622 |
4622 if (!(Allowed & Legal_Mem)) { | 4623 if (!(Allowed & Legal_Mem)) { |
4623 From = copyToReg(From, RegNum); | 4624 From = copyToReg(From, RegNum); |
4624 } | 4625 } |
4625 return From; | 4626 return From; |
4626 } | 4627 } |
4627 if (llvm::isa<Constant>(From)) { | 4628 if (llvm::isa<Constant>(From)) { |
4628 if (llvm::isa<ConstantUndef>(From)) { | 4629 if (llvm::isa<ConstantUndef>(From)) { |
4629 // Lower undefs to zero. Another option is to lower undefs to an | 4630 // Lower undefs to zero. Another option is to lower undefs to an |
4630 // uninitialized register; however, using an uninitialized register | 4631 // uninitialized register; however, using an uninitialized register |
4631 // results in less predictable code. | 4632 // results in less predictable code. |
4632 // | 4633 // |
4633 // If in the future the implementation is changed to lower undef | 4634 // If in the future the implementation is changed to lower undef |
4634 // values to uninitialized registers, a FakeDef will be needed: | 4635 // values to uninitialized registers, a FakeDef will be needed: |
4635 // Context.insert(InstFakeDef::create(Func, Reg)); | 4636 // Context.insert(InstFakeDef::create(Func, Reg)); |
4636 // This is in order to ensure that the live range of Reg is not | 4637 // This is in order to ensure that the live range of Reg is not |
4637 // overestimated. If the constant being lowered is a 64 bit value, | 4638 // overestimated. If the constant being lowered is a 64 bit value, |
4638 // then the result should be split and the lo and hi components will | 4639 // then the result should be split and the lo and hi components will |
4639 // need to go in uninitialized registers. | 4640 // need to go in uninitialized registers. |
4640 if (isVectorType(From->getType())) | 4641 if (isVectorType(Ty)) |
4641 return makeVectorOfZeros(From->getType(), RegNum); | 4642 return makeVectorOfZeros(Ty, RegNum); |
4642 From = Ctx->getConstantZero(From->getType()); | 4643 From = Ctx->getConstantZero(Ty); |
4643 } | 4644 } |
4644 // There should be no constants of vector type (other than undef). | 4645 // There should be no constants of vector type (other than undef). |
4645 assert(!isVectorType(From->getType())); | 4646 assert(!isVectorType(Ty)); |
| 4647 // Convert a scalar floating point constant into an explicit |
| 4648 // memory operand. |
| 4649 if (isScalarFloatingType(Ty)) { |
| 4650 Variable *Base = nullptr; |
| 4651 std::string Buffer; |
| 4652 llvm::raw_string_ostream StrBuf(Buffer); |
| 4653 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf); |
| 4654 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); |
| 4655 From = OperandX8632Mem::create(Func, Ty, Base, Offset); |
| 4656 } |
4646 bool NeedsReg = false; | 4657 bool NeedsReg = false; |
4647 if (!(Allowed & Legal_Imm)) | 4658 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) |
4648 // Immediate specifically not allowed | 4659 // Immediate specifically not allowed |
4649 NeedsReg = true; | 4660 NeedsReg = true; |
4650 if (!(Allowed & Legal_Mem) && isScalarFloatingType(From->getType())) | 4661 if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty)) |
4651 // On x86, FP constants are lowered to mem operands. | 4662 // On x86, FP constants are lowered to mem operands. |
4652 NeedsReg = true; | 4663 NeedsReg = true; |
4653 if (NeedsReg) { | 4664 if (NeedsReg) { |
4654 From = copyToReg(From, RegNum); | 4665 From = copyToReg(From, RegNum); |
4655 } | 4666 } |
4656 return From; | 4667 return From; |
4657 } | 4668 } |
4658 if (auto Var = llvm::dyn_cast<Variable>(From)) { | 4669 if (auto Var = llvm::dyn_cast<Variable>(From)) { |
4659 // Check if the variable is guaranteed a physical register. This | 4670 // Check if the variable is guaranteed a physical register. This |
4660 // can happen either when the variable is pre-colored or when it is | 4671 // can happen either when the variable is pre-colored or when it is |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5000 case FT_Asm: | 5011 case FT_Asm: |
5001 case FT_Iasm: { | 5012 case FT_Iasm: { |
5002 OstreamLocker L(Ctx); | 5013 OstreamLocker L(Ctx); |
5003 emitConstantPool<PoolTypeConverter<float>>(Ctx); | 5014 emitConstantPool<PoolTypeConverter<float>>(Ctx); |
5004 emitConstantPool<PoolTypeConverter<double>>(Ctx); | 5015 emitConstantPool<PoolTypeConverter<double>>(Ctx); |
5005 } break; | 5016 } break; |
5006 } | 5017 } |
5007 } | 5018 } |
5008 | 5019 |
5009 } // end of namespace Ice | 5020 } // end of namespace Ice |
OLD | NEW |