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 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
987 std::max(AlignmentParam, Traits::X86_STACK_ALIGNMENT_BYTES); | 987 std::max(AlignmentParam, Traits::X86_STACK_ALIGNMENT_BYTES); |
988 const bool OverAligned = Alignment > Traits::X86_STACK_ALIGNMENT_BYTES; | 988 const bool OverAligned = Alignment > Traits::X86_STACK_ALIGNMENT_BYTES; |
989 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; | 989 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; |
990 const bool AllocaWithKnownOffset = Inst->getKnownFrameOffset(); | 990 const bool AllocaWithKnownOffset = Inst->getKnownFrameOffset(); |
991 const bool UseFramePointer = | 991 const bool UseFramePointer = |
992 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1; | 992 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1; |
993 | 993 |
994 if (UseFramePointer) | 994 if (UseFramePointer) |
995 setHasFramePointer(); | 995 setHasFramePointer(); |
996 | 996 |
997 Variable *esp = getPhysicalRegister(getStackReg()); | 997 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType); |
998 if (OverAligned) { | 998 if (OverAligned) { |
999 _and(esp, Ctx->getConstantInt32(-Alignment)); | 999 _and(esp, Ctx->getConstantInt32(-Alignment)); |
1000 } | 1000 } |
1001 | 1001 |
1002 Variable *Dest = Inst->getDest(); | 1002 Variable *Dest = Inst->getDest(); |
1003 Operand *TotalSize = legalize(Inst->getSizeInBytes()); | 1003 Operand *TotalSize = legalize(Inst->getSizeInBytes()); |
1004 | 1004 |
1005 if (const auto *ConstantTotalSize = | 1005 if (const auto *ConstantTotalSize = |
1006 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { | 1006 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { |
1007 const uint32_t Value = | 1007 const uint32_t Value = |
1008 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment); | 1008 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment); |
1009 if (!UseFramePointer) { | 1009 if (!UseFramePointer) { |
1010 // If we don't need a Frame Pointer, this alloca has a known offset to the | 1010 // If we don't need a Frame Pointer, this alloca has a known offset to the |
1011 // stack pointer. We don't need adjust the stack pointer, nor assign any | 1011 // stack pointer. We don't need adjust the stack pointer, nor assign any |
1012 // value to Dest, as Dest is rematerializable. | 1012 // value to Dest, as Dest is rematerializable. |
1013 assert(Dest->isRematerializable()); | 1013 assert(Dest->isRematerializable()); |
1014 FixedAllocaSizeBytes += Value; | 1014 FixedAllocaSizeBytes += Value; |
1015 Context.insert<InstFakeDef>(Dest); | 1015 Context.insert<InstFakeDef>(Dest); |
1016 } else { | 1016 } else { |
1017 _sub(esp, Ctx->getConstantInt32(Value)); | 1017 _sub(esp, Ctx->getConstantInt32(Value)); |
1018 } | 1018 } |
1019 } else { | 1019 } else { |
1020 // Non-constant sizes need to be adjusted to the next highest multiple of | 1020 // Non-constant sizes need to be adjusted to the next highest multiple of |
1021 // the required alignment at runtime. | 1021 // the required alignment at runtime. |
1022 Variable *T = makeReg(IceType_i32); | 1022 Variable *T = makeReg(Traits::WordType); |
1023 _mov(T, TotalSize); | 1023 if (Traits::Is64Bit && TotalSize->getType() != IceType_i64) { |
1024 _movzx(T, TotalSize); | |
1025 } else { | |
1026 _mov(T, TotalSize); | |
1027 } | |
1024 _add(T, Ctx->getConstantInt32(Alignment - 1)); | 1028 _add(T, Ctx->getConstantInt32(Alignment - 1)); |
1025 _and(T, Ctx->getConstantInt32(-Alignment)); | 1029 _and(T, Ctx->getConstantInt32(-Alignment)); |
1026 _sub(esp, T); | 1030 _sub(esp, T); |
1027 } | 1031 } |
1028 // Add enough to the returned address to account for the out args area. | 1032 // Add enough to the returned address to account for the out args area. |
1029 uint32_t OutArgsSize = maxOutArgsSizeBytes(); | 1033 uint32_t OutArgsSize = maxOutArgsSizeBytes(); |
1030 if (OutArgsSize > 0) { | 1034 if (OutArgsSize > 0) { |
1031 Variable *T = makeReg(IceType_i32); | 1035 Variable *T = makeReg(IceType_i32); |
1032 typename Traits::X86OperandMem *CalculateOperand = | 1036 typename Traits::X86OperandMem *CalculateOperand = |
1033 Traits::X86OperandMem::create( | 1037 Traits::X86OperandMem::create( |
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1710 // immediates as the operand. | 1714 // immediates as the operand. |
1711 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1715 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
1712 uint32_t Eax; | 1716 uint32_t Eax; |
1713 uint32_t Edx; | 1717 uint32_t Edx; |
1714 switch (Ty) { | 1718 switch (Ty) { |
1715 default: | 1719 default: |
1716 llvm::report_fatal_error("Bad type for udiv"); | 1720 llvm::report_fatal_error("Bad type for udiv"); |
1717 case IceType_i64: | 1721 case IceType_i64: |
1718 Eax = Traits::getRaxOrDie(); | 1722 Eax = Traits::getRaxOrDie(); |
1719 Edx = Traits::getRdxOrDie(); | 1723 Edx = Traits::getRdxOrDie(); |
1724 break; | |
1720 case IceType_i32: | 1725 case IceType_i32: |
1721 Eax = Traits::RegisterSet::Reg_eax; | 1726 Eax = Traits::RegisterSet::Reg_eax; |
1722 Edx = Traits::RegisterSet::Reg_edx; | 1727 Edx = Traits::RegisterSet::Reg_edx; |
1723 break; | 1728 break; |
1724 case IceType_i16: | 1729 case IceType_i16: |
1725 Eax = Traits::RegisterSet::Reg_ax; | 1730 Eax = Traits::RegisterSet::Reg_ax; |
1726 Edx = Traits::RegisterSet::Reg_dx; | 1731 Edx = Traits::RegisterSet::Reg_dx; |
1727 break; | 1732 break; |
1728 case IceType_i8: | 1733 case IceType_i8: |
1729 Eax = Traits::RegisterSet::Reg_al; | 1734 Eax = Traits::RegisterSet::Reg_al; |
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3544 } | 3549 } |
3545 case Intrinsics::Sqrt: { | 3550 case Intrinsics::Sqrt: { |
3546 Operand *Src = legalize(Instr->getArg(0)); | 3551 Operand *Src = legalize(Instr->getArg(0)); |
3547 Variable *Dest = Instr->getDest(); | 3552 Variable *Dest = Instr->getDest(); |
3548 Variable *T = makeReg(Dest->getType()); | 3553 Variable *T = makeReg(Dest->getType()); |
3549 _sqrtss(T, Src); | 3554 _sqrtss(T, Src); |
3550 _mov(Dest, T); | 3555 _mov(Dest, T); |
3551 return; | 3556 return; |
3552 } | 3557 } |
3553 case Intrinsics::Stacksave: { | 3558 case Intrinsics::Stacksave: { |
3554 Variable *esp = Func->getTarget()->getPhysicalRegister(getStackReg()); | 3559 Variable *esp = |
3560 Func->getTarget()->getPhysicalRegister(getStackReg(), Traits::WordType); | |
3555 Variable *Dest = Instr->getDest(); | 3561 Variable *Dest = Instr->getDest(); |
3556 _mov(Dest, esp); | 3562 _mov(Dest, esp); |
3557 return; | 3563 return; |
3558 } | 3564 } |
3559 case Intrinsics::Stackrestore: { | 3565 case Intrinsics::Stackrestore: { |
3560 Variable *esp = Func->getTarget()->getPhysicalRegister(getStackReg()); | 3566 Operand *Src = Instr->getArg(0); |
3561 _redefined(_mov(esp, Instr->getArg(0))); | 3567 Variable *esp = |
3568 Func->getTarget()->getPhysicalRegister(getStackReg(), Src->getType()); | |
3569 _redefined(_mov(esp, Src)); | |
3562 return; | 3570 return; |
3563 } | 3571 } |
3564 case Intrinsics::Trap: | 3572 case Intrinsics::Trap: |
3565 _ud2(); | 3573 _ud2(); |
3566 return; | 3574 return; |
3567 case Intrinsics::UnknownIntrinsic: | 3575 case Intrinsics::UnknownIntrinsic: |
3568 Func->setError("Should not be lowering UnknownIntrinsic"); | 3576 Func->setError("Should not be lowering UnknownIntrinsic"); |
3569 return; | 3577 return; |
3570 } | 3578 } |
3571 return; | 3579 return; |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4254 ValExt = ValExtVar; | 4262 ValExt = ValExtVar; |
4255 } | 4263 } |
4256 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3); | 4264 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3); |
4257 Call->addArg(Dest); | 4265 Call->addArg(Dest); |
4258 Call->addArg(ValExt); | 4266 Call->addArg(ValExt); |
4259 Call->addArg(Count); | 4267 Call->addArg(Count); |
4260 lowerCall(Call); | 4268 lowerCall(Call); |
4261 } | 4269 } |
4262 | 4270 |
4263 template <class Machine> | 4271 template <class Machine> |
4264 void TargetX86Base<Machine>::lowerIndirectJump(Variable *Target) { | 4272 void TargetX86Base<Machine>::lowerIndirectJump(Variable *Target) { |
Jim Stichnoth
2015/12/22 20:38:07
While you're at it, could you rename this argument
John
2015/12/23 18:30:43
Done.
| |
4265 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); | 4273 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
4274 if (Traits::Is64Bit) { | |
4275 Variable *T = makeReg(IceType_i64); | |
4276 _movzx(T, Target); | |
4277 Target = T; | |
4278 } | |
4266 if (NeedSandboxing) { | 4279 if (NeedSandboxing) { |
4267 _bundle_lock(); | 4280 _bundle_lock(); |
4268 const SizeT BundleSize = | 4281 const SizeT BundleSize = |
4269 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); | 4282 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); |
4270 _and(Target, Ctx->getConstantInt32(~(BundleSize - 1))); | 4283 _and(Target, Ctx->getConstantInt32(~(BundleSize - 1))); |
4271 } | 4284 } |
4272 _jmp(Target); | 4285 _jmp(Target); |
4273 if (NeedSandboxing) | 4286 if (NeedSandboxing) |
4274 _bundle_unlock(); | 4287 _bundle_unlock(); |
4275 } | 4288 } |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4664 Opnd = Mem->getBase(); | 4677 Opnd = Mem->getBase(); |
4665 } | 4678 } |
4666 // At this point Opnd could be nullptr, or Variable, or Constant, or perhaps | 4679 // At this point Opnd could be nullptr, or Variable, or Constant, or perhaps |
4667 // something else. We only care if it is Variable. | 4680 // something else. We only care if it is Variable. |
4668 auto *Var = llvm::dyn_cast_or_null<Variable>(Opnd); | 4681 auto *Var = llvm::dyn_cast_or_null<Variable>(Opnd); |
4669 if (Var == nullptr) | 4682 if (Var == nullptr) |
4670 return; | 4683 return; |
4671 // We use lowerStore() to copy out-args onto the stack. This creates a memory | 4684 // We use lowerStore() to copy out-args onto the stack. This creates a memory |
4672 // operand with the stack pointer as the base register. Don't do bounds | 4685 // operand with the stack pointer as the base register. Don't do bounds |
4673 // checks on that. | 4686 // checks on that. |
4674 if (Var->getRegNum() == Traits::RegisterSet::Reg_esp) | 4687 if (Var->getRegNum() == static_cast<int32_t>(getStackReg())) |
4675 return; | 4688 return; |
4676 | 4689 |
4677 auto *Label = Traits::Insts::Label::create(Func, this); | 4690 auto *Label = Traits::Insts::Label::create(Func, this); |
4678 _cmp(Opnd, Ctx->getConstantZero(IceType_i32)); | 4691 _cmp(Opnd, Ctx->getConstantZero(IceType_i32)); |
4679 _br(Traits::Cond::Br_e, Label); | 4692 _br(Traits::Cond::Br_e, Label); |
4680 _cmp(Opnd, Ctx->getConstantInt32(1)); | 4693 _cmp(Opnd, Ctx->getConstantInt32(1)); |
4681 _br(Traits::Cond::Br_e, Label); | 4694 _br(Traits::Cond::Br_e, Label); |
4682 Context.insert(Label); | 4695 Context.insert(Label); |
4683 } | 4696 } |
4684 | 4697 |
(...skipping 1289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5974 return From; | 5987 return From; |
5975 Const = llvm::cast<Constant>(From); | 5988 Const = llvm::cast<Constant>(From); |
5976 } | 5989 } |
5977 // There should be no constants of vector type (other than undef). | 5990 // There should be no constants of vector type (other than undef). |
5978 assert(!isVectorType(Ty)); | 5991 assert(!isVectorType(Ty)); |
5979 | 5992 |
5980 // If the operand is a 64 bit constant integer we need to legalize it to a | 5993 // If the operand is a 64 bit constant integer we need to legalize it to a |
5981 // register in x86-64. | 5994 // register in x86-64. |
5982 if (Traits::Is64Bit) { | 5995 if (Traits::Is64Bit) { |
5983 if (llvm::isa<ConstantInteger64>(Const)) { | 5996 if (llvm::isa<ConstantInteger64>(Const)) { |
5984 Variable *V = copyToReg(Const, RegNum); | 5997 if (RegNum != Variable::NoRegister) { |
5985 return V; | 5998 assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum); |
5999 } | |
6000 return copyToReg(Const, RegNum); | |
5986 } | 6001 } |
5987 } | 6002 } |
5988 | 6003 |
5989 // If the operand is an 32 bit constant integer, we should check whether we | 6004 // If the operand is an 32 bit constant integer, we should check whether we |
5990 // need to randomize it or pool it. | 6005 // need to randomize it or pool it. |
5991 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) { | 6006 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) { |
5992 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); | 6007 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); |
5993 if (NewConst != Const) { | 6008 if (NewConst != Const) { |
5994 return NewConst; | 6009 return NewConst; |
5995 } | 6010 } |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6419 } | 6434 } |
6420 // the offset is not eligible for blinding or pooling, return the original | 6435 // the offset is not eligible for blinding or pooling, return the original |
6421 // mem operand | 6436 // mem operand |
6422 return MemOperand; | 6437 return MemOperand; |
6423 } | 6438 } |
6424 | 6439 |
6425 } // end of namespace X86Internal | 6440 } // end of namespace X86Internal |
6426 } // end of namespace Ice | 6441 } // end of namespace Ice |
6427 | 6442 |
6428 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 6443 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |