Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1408)

Side by Side Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1676123002: Subzero: Use a proper RegNumT type instead of int32_t/SizeT. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Make it possible to do "auto NewReg = RegNumT::NoRegister;" Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 TargetInstructionSet::BaseInstructionSet) { 370 TargetInstructionSet::BaseInstructionSet) {
371 InstructionSet = static_cast<InstructionSetEnum>( 371 InstructionSet = static_cast<InstructionSetEnum>(
372 (Func->getContext()->getFlags().getTargetInstructionSet() - 372 (Func->getContext()->getFlags().getTargetInstructionSet() -
373 TargetInstructionSet::X86InstructionSet_Begin) + 373 TargetInstructionSet::X86InstructionSet_Begin) +
374 Traits::InstructionSet::Begin); 374 Traits::InstructionSet::Begin);
375 } 375 }
376 } 376 }
377 377
378 template <typename TraitsType> 378 template <typename TraitsType>
379 void TargetX86Base<TraitsType>::staticInit(GlobalContext *Ctx) { 379 void TargetX86Base<TraitsType>::staticInit(GlobalContext *Ctx) {
380 RegNumT::setLimit(Traits::RegisterSet::Reg_NUM);
380 Traits::initRegisterSet(Ctx->getFlags(), &TypeToRegisterSet, 381 Traits::initRegisterSet(Ctx->getFlags(), &TypeToRegisterSet,
381 &RegisterAliases); 382 &RegisterAliases);
382 for (size_t i = 0; i < TypeToRegisterSet.size(); ++i) 383 for (size_t i = 0; i < TypeToRegisterSet.size(); ++i)
383 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; 384 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i];
384 filterTypeToRegisterSet(Ctx, Traits::RegisterSet::Reg_NUM, 385 filterTypeToRegisterSet(Ctx, Traits::RegisterSet::Reg_NUM,
385 TypeToRegisterSet.data(), TypeToRegisterSet.size(), 386 TypeToRegisterSet.data(), TypeToRegisterSet.size(),
386 Traits::getRegName, getRegClassName); 387 Traits::getRegName, getRegClassName);
387 PcRelFixup = Traits::FK_PcRel; 388 PcRelFixup = Traits::FK_PcRel;
388 AbsFixup = 389 AbsFixup =
389 Ctx->getFlags().getUseNonsfi() ? Traits::FK_Gotoff : Traits::FK_Abs; 390 Ctx->getFlags().getUseNonsfi() ? Traits::FK_Gotoff : Traits::FK_Abs;
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 836
836 template <typename TraitsType> 837 template <typename TraitsType>
837 bool TargetX86Base<TraitsType>::doBranchOpt(Inst *I, const CfgNode *NextNode) { 838 bool TargetX86Base<TraitsType>::doBranchOpt(Inst *I, const CfgNode *NextNode) {
838 if (auto *Br = llvm::dyn_cast<InstX86Br>(I)) { 839 if (auto *Br = llvm::dyn_cast<InstX86Br>(I)) {
839 return Br->optimizeBranch(NextNode); 840 return Br->optimizeBranch(NextNode);
840 } 841 }
841 return false; 842 return false;
842 } 843 }
843 844
844 template <typename TraitsType> 845 template <typename TraitsType>
845 Variable *TargetX86Base<TraitsType>::getPhysicalRegister(SizeT RegNum, 846 Variable *TargetX86Base<TraitsType>::getPhysicalRegister(RegNumT RegNum,
846 Type Ty) { 847 Type Ty) {
847 if (Ty == IceType_void) 848 if (Ty == IceType_void)
848 Ty = IceType_i32; 849 Ty = IceType_i32;
849 if (PhysicalRegisters[Ty].empty()) 850 if (PhysicalRegisters[Ty].empty())
850 PhysicalRegisters[Ty].resize(Traits::RegisterSet::Reg_NUM); 851 PhysicalRegisters[Ty].resize(Traits::RegisterSet::Reg_NUM);
851 assert(RegNum < PhysicalRegisters[Ty].size()); 852 assert(unsigned(RegNum) < PhysicalRegisters[Ty].size());
852 Variable *Reg = PhysicalRegisters[Ty][RegNum]; 853 Variable *Reg = PhysicalRegisters[Ty][RegNum];
853 if (Reg == nullptr) { 854 if (Reg == nullptr) {
854 Reg = Func->makeVariable(Ty); 855 Reg = Func->makeVariable(Ty);
855 Reg->setRegNum(RegNum); 856 Reg->setRegNum(RegNum);
856 PhysicalRegisters[Ty][RegNum] = Reg; 857 PhysicalRegisters[Ty][RegNum] = Reg;
857 // Specially mark a named physical register as an "argument" so that it is 858 // Specially mark a named physical register as an "argument" so that it is
858 // considered live upon function entry. Otherwise it's possible to get 859 // considered live upon function entry. Otherwise it's possible to get
859 // liveness validation errors for saving callee-save registers. 860 // liveness validation errors for saving callee-save registers.
860 Func->addImplicitArg(Reg); 861 Func->addImplicitArg(Reg);
861 // Don't bother tracking the live range of a named physical register. 862 // Don't bother tracking the live range of a named physical register.
862 Reg->setIgnoreLiveness(); 863 Reg->setIgnoreLiveness();
863 } 864 }
864 assert(Traits::getGprForType(Ty, RegNum) == static_cast<int32_t>(RegNum)); 865 assert(Traits::getGprForType(Ty, RegNum) == RegNum);
865 return Reg; 866 return Reg;
866 } 867 }
867 868
868 template <typename TraitsType> 869 template <typename TraitsType>
869 IceString TargetX86Base<TraitsType>::getRegName(SizeT RegNum, Type Ty) const { 870 IceString TargetX86Base<TraitsType>::getRegName(RegNumT RegNum, Type Ty) const {
870 return Traits::getRegName(Traits::getGprForType(Ty, RegNum)); 871 return Traits::getRegName(Traits::getGprForType(Ty, RegNum));
871 } 872 }
872 873
873 template <typename TraitsType> 874 template <typename TraitsType>
874 void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const { 875 void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const {
875 if (!BuildDefs::dump()) 876 if (!BuildDefs::dump())
876 return; 877 return;
877 Ostream &Str = Ctx->getStrEmit(); 878 Ostream &Str = Ctx->getStrEmit();
878 if (Var->hasReg()) { 879 if (Var->hasReg()) {
879 const bool Is64BitSandboxing = Traits::Is64Bit && NeedSandboxing; 880 const bool Is64BitSandboxing = Traits::Is64Bit && NeedSandboxing;
880 const Type VarType = (Var->isRematerializable() && Is64BitSandboxing) 881 const Type VarType = (Var->isRematerializable() && Is64BitSandboxing)
881 ? IceType_i64 882 ? IceType_i64
882 : Var->getType(); 883 : Var->getType();
883 Str << "%" << getRegName(Var->getRegNum(), VarType); 884 Str << "%" << getRegName(Var->getRegNum(), VarType);
884 return; 885 return;
885 } 886 }
886 if (Var->mustHaveReg()) { 887 if (Var->mustHaveReg()) {
887 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + 888 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) +
888 ") has no register assigned - function " + 889 ") has no register assigned - function " +
889 Func->getFunctionName()); 890 Func->getFunctionName());
890 } 891 }
891 const int32_t Offset = Var->getStackOffset(); 892 const int32_t Offset = Var->getStackOffset();
892 int32_t BaseRegNum = Var->getBaseRegNum(); 893 auto BaseRegNum = Var->getBaseRegNum();
893 if (BaseRegNum == Variable::NoRegister) 894 if (BaseRegNum == RegNumT::NoRegister)
894 BaseRegNum = getFrameOrStackReg(); 895 BaseRegNum = getFrameOrStackReg();
895 // Print in the form "Offset(%reg)", taking care that: 896 // Print in the form "Offset(%reg)", taking care that:
896 // - Offset is never printed when it is 0 897 // - Offset is never printed when it is 0
897 898
898 const bool DecorateAsm = Func->getContext()->getFlags().getDecorateAsm(); 899 const bool DecorateAsm = Func->getContext()->getFlags().getDecorateAsm();
899 // Only print Offset when it is nonzero, regardless of DecorateAsm. 900 // Only print Offset when it is nonzero, regardless of DecorateAsm.
900 if (Offset) { 901 if (Offset) {
901 if (DecorateAsm) { 902 if (DecorateAsm) {
902 Str << Var->getSymbolicStackOffset(Func); 903 Str << Var->getSymbolicStackOffset(Func);
903 } else { 904 } else {
904 Str << Offset; 905 Str << Offset;
905 } 906 }
906 } 907 }
907 const Type FrameSPTy = Traits::WordType; 908 const Type FrameSPTy = Traits::WordType;
908 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")"; 909 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")";
909 } 910 }
910 911
911 template <typename TraitsType> 912 template <typename TraitsType>
912 typename TargetX86Base<TraitsType>::X86Address 913 typename TargetX86Base<TraitsType>::X86Address
913 TargetX86Base<TraitsType>::stackVarToAsmOperand(const Variable *Var) const { 914 TargetX86Base<TraitsType>::stackVarToAsmOperand(const Variable *Var) const {
914 if (Var->hasReg()) 915 if (Var->hasReg())
915 llvm::report_fatal_error("Stack Variable has a register assigned"); 916 llvm::report_fatal_error("Stack Variable has a register assigned");
916 if (Var->mustHaveReg()) { 917 if (Var->mustHaveReg()) {
917 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + 918 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) +
918 ") has no register assigned - function " + 919 ") has no register assigned - function " +
919 Func->getFunctionName()); 920 Func->getFunctionName());
920 } 921 }
921 int32_t Offset = Var->getStackOffset(); 922 int32_t Offset = Var->getStackOffset();
922 int32_t BaseRegNum = Var->getBaseRegNum(); 923 auto BaseRegNum = Var->getBaseRegNum();
923 if (Var->getBaseRegNum() == Variable::NoRegister) 924 if (Var->getBaseRegNum() == RegNumT::NoRegister)
924 BaseRegNum = getFrameOrStackReg(); 925 BaseRegNum = getFrameOrStackReg();
925 return X86Address(Traits::getEncodedGPR(BaseRegNum), Offset, 926 return X86Address(Traits::getEncodedGPR(BaseRegNum), Offset,
926 AssemblerFixup::NoFixup); 927 AssemblerFixup::NoFixup);
927 } 928 }
928 929
929 template <typename TraitsType> 930 template <typename TraitsType>
930 void TargetX86Base<TraitsType>::addProlog(CfgNode *Node) { 931 void TargetX86Base<TraitsType>::addProlog(CfgNode *Node) {
931 // Stack frame layout: 932 // Stack frame layout:
932 // 933 //
933 // +------------------------+ 934 // +------------------------+
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize, 1008 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize,
1008 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes, 1009 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes,
1009 &LocalsSlotsAlignmentBytes, TargetVarHook); 1010 &LocalsSlotsAlignmentBytes, TargetVarHook);
1010 uint32_t LocalsSpillAreaSize = SpillAreaSizeBytes; 1011 uint32_t LocalsSpillAreaSize = SpillAreaSizeBytes;
1011 SpillAreaSizeBytes += GlobalsSize; 1012 SpillAreaSizeBytes += GlobalsSize;
1012 1013
1013 // Add push instructions for preserved registers. 1014 // Add push instructions for preserved registers.
1014 uint32_t NumCallee = 0; 1015 uint32_t NumCallee = 0;
1015 size_t PreservedRegsSizeBytes = 0; 1016 size_t PreservedRegsSizeBytes = 0;
1016 llvm::SmallBitVector Pushed(CalleeSaves.size()); 1017 llvm::SmallBitVector Pushed(CalleeSaves.size());
1017 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { 1018 for (RegNumT i : RegNumBVIter(CalleeSaves)) {
1018 const int32_t Canonical = Traits::getBaseReg(i); 1019 const auto Canonical = Traits::getBaseReg(i);
1019 assert(Canonical == Traits::getBaseReg(Canonical)); 1020 assert(Canonical == Traits::getBaseReg(Canonical));
1020 if (CalleeSaves[i] && RegsUsed[i]) { 1021 if (RegsUsed[i]) {
1021 Pushed[Canonical] = true; 1022 Pushed[Canonical] = true;
1022 } 1023 }
1023 } 1024 }
1024 for (SizeT i = 0; i < Pushed.size(); ++i) { 1025 for (RegNumT RegNum : RegNumBVIter(Pushed)) {
1025 if (!Pushed[i]) 1026 assert(RegNum == Traits::getBaseReg(RegNum));
1026 continue;
1027 assert(static_cast<int32_t>(i) == Traits::getBaseReg(i));
1028 ++NumCallee; 1027 ++NumCallee;
1029 PreservedRegsSizeBytes += typeWidthInBytes(Traits::WordType); 1028 PreservedRegsSizeBytes += typeWidthInBytes(Traits::WordType);
1030 _push_reg(getPhysicalRegister(i, Traits::WordType)); 1029 _push_reg(getPhysicalRegister(RegNum, Traits::WordType));
1031 } 1030 }
1032 Ctx->statsUpdateRegistersSaved(NumCallee); 1031 Ctx->statsUpdateRegistersSaved(NumCallee);
1033 1032
1034 // Generate "push frameptr; mov frameptr, stackptr" 1033 // Generate "push frameptr; mov frameptr, stackptr"
1035 if (IsEbpBasedFrame) { 1034 if (IsEbpBasedFrame) {
1036 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None)) 1035 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None))
1037 .count() == 0); 1036 .count() == 0);
1038 PreservedRegsSizeBytes += typeWidthInBytes(Traits::WordType); 1037 PreservedRegsSizeBytes += typeWidthInBytes(Traits::WordType);
1039 _link_bp(); 1038 _link_bp();
1040 } 1039 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 1116
1118 emitGetIP(Node); 1117 emitGetIP(Node);
1119 1118
1120 const VarList &Args = Func->getArgs(); 1119 const VarList &Args = Func->getArgs();
1121 size_t InArgsSizeBytes = 0; 1120 size_t InArgsSizeBytes = 0;
1122 unsigned NumXmmArgs = 0; 1121 unsigned NumXmmArgs = 0;
1123 unsigned NumGPRArgs = 0; 1122 unsigned NumGPRArgs = 0;
1124 for (Variable *Arg : Args) { 1123 for (Variable *Arg : Args) {
1125 // Skip arguments passed in registers. 1124 // Skip arguments passed in registers.
1126 if (isVectorType(Arg->getType())) { 1125 if (isVectorType(Arg->getType())) {
1127 if (Traits::getRegisterForXmmArgNum(NumXmmArgs) != Variable::NoRegister) { 1126 if (Traits::getRegisterForXmmArgNum(NumXmmArgs) != RegNumT::NoRegister) {
1128 ++NumXmmArgs; 1127 ++NumXmmArgs;
1129 continue; 1128 continue;
1130 } 1129 }
1131 } else if (isScalarFloatingType(Arg->getType())) { 1130 } else if (isScalarFloatingType(Arg->getType())) {
1132 if (Traits::X86_PASS_SCALAR_FP_IN_XMM && 1131 if (Traits::X86_PASS_SCALAR_FP_IN_XMM &&
1133 Traits::getRegisterForXmmArgNum(NumXmmArgs) != Variable::NoRegister) { 1132 Traits::getRegisterForXmmArgNum(NumXmmArgs) != RegNumT::NoRegister) {
1134 ++NumXmmArgs; 1133 ++NumXmmArgs;
1135 continue; 1134 continue;
1136 } 1135 }
1137 } else { 1136 } else {
1138 assert(isScalarIntegerType(Arg->getType())); 1137 assert(isScalarIntegerType(Arg->getType()));
1139 if (Traits::getRegisterForGprArgNum(Traits::WordType, NumGPRArgs) != 1138 if (Traits::getRegisterForGprArgNum(Traits::WordType, NumGPRArgs) !=
1140 Variable::NoRegister) { 1139 RegNumT::NoRegister) {
1141 ++NumGPRArgs; 1140 ++NumGPRArgs;
1142 continue; 1141 continue;
1143 } 1142 }
1144 } 1143 }
1145 // For esp-based frames where the allocas are done outside the prolog, the 1144 // For esp-based frames where the allocas are done outside the prolog, the
1146 // esp value may not stabilize to its home value until after all the 1145 // esp value may not stabilize to its home value until after all the
1147 // fixed-size alloca instructions have executed. In this case, a stack 1146 // fixed-size alloca instructions have executed. In this case, a stack
1148 // adjustment is needed when accessing in-args in order to copy them into 1147 // adjustment is needed when accessing in-args in order to copy them into
1149 // registers. 1148 // registers.
1150 size_t StackAdjBytes = 0; 1149 size_t StackAdjBytes = 0;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 if (SpillAreaSizeBytes != 0) { 1267 if (SpillAreaSizeBytes != 0) {
1269 _add_sp(Ctx->getConstantInt32(SpillAreaSizeBytes)); 1268 _add_sp(Ctx->getConstantInt32(SpillAreaSizeBytes));
1270 } 1269 }
1271 } 1270 }
1272 1271
1273 // Add pop instructions for preserved registers. 1272 // Add pop instructions for preserved registers.
1274 llvm::SmallBitVector CalleeSaves = 1273 llvm::SmallBitVector CalleeSaves =
1275 getRegisterSet(RegSet_CalleeSave, RegSet_None); 1274 getRegisterSet(RegSet_CalleeSave, RegSet_None);
1276 llvm::SmallBitVector Popped(CalleeSaves.size()); 1275 llvm::SmallBitVector Popped(CalleeSaves.size());
1277 for (int32_t i = CalleeSaves.size() - 1; i >= 0; --i) { 1276 for (int32_t i = CalleeSaves.size() - 1; i >= 0; --i) {
1278 if (static_cast<SizeT>(i) == getFrameReg() && IsEbpBasedFrame) 1277 const auto RegNum = RegNumT::fromInt(i);
1278 if (RegNum == getFrameReg() && IsEbpBasedFrame)
1279 continue; 1279 continue;
1280 const SizeT Canonical = Traits::getBaseReg(i); 1280 const RegNumT Canonical = Traits::getBaseReg(RegNum);
1281 if (CalleeSaves[i] && RegsUsed[i]) { 1281 if (CalleeSaves[i] && RegsUsed[i]) {
1282 Popped[Canonical] = true; 1282 Popped[Canonical] = true;
1283 } 1283 }
1284 } 1284 }
1285 for (int32_t i = Popped.size() - 1; i >= 0; --i) { 1285 for (int32_t i = Popped.size() - 1; i >= 0; --i) {
1286 if (!Popped[i]) 1286 if (!Popped[i])
1287 continue; 1287 continue;
1288 assert(i == Traits::getBaseReg(i)); 1288 const auto RegNum = RegNumT::fromInt(i);
1289 _pop(getPhysicalRegister(i, Traits::WordType)); 1289 assert(RegNum == Traits::getBaseReg(RegNum));
1290 _pop(getPhysicalRegister(RegNum, Traits::WordType));
1290 } 1291 }
1291 1292
1292 if (!NeedSandboxing) { 1293 if (!NeedSandboxing) {
1293 return; 1294 return;
1294 } 1295 }
1295 emitSandboxedReturn(); 1296 emitSandboxedReturn();
1296 if (RI->getSrcSize()) { 1297 if (RI->getSrcSize()) {
1297 auto *RetValue = llvm::cast<Variable>(RI->getSrc(0)); 1298 auto *RetValue = llvm::cast<Variable>(RI->getSrc(0));
1298 Context.insert<InstFakeUse>(RetValue); 1299 Context.insert<InstFakeUse>(RetValue);
1299 } 1300 }
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 bool GprSlotsRemain = true; 1469 bool GprSlotsRemain = true;
1469 1470
1470 Context.init(Func->getEntryNode()); 1471 Context.init(Func->getEntryNode());
1471 Context.setInsertPoint(Context.getCur()); 1472 Context.setInsertPoint(Context.getCur());
1472 1473
1473 for (SizeT i = 0, End = Args.size(); 1474 for (SizeT i = 0, End = Args.size();
1474 i < End && (XmmSlotsRemain || GprSlotsRemain); ++i) { 1475 i < End && (XmmSlotsRemain || GprSlotsRemain); ++i) {
1475 Variable *Arg = Args[i]; 1476 Variable *Arg = Args[i];
1476 Type Ty = Arg->getType(); 1477 Type Ty = Arg->getType();
1477 Variable *RegisterArg = nullptr; 1478 Variable *RegisterArg = nullptr;
1478 int32_t RegNum = Variable::NoRegister; 1479 auto RegNum = RegNumT::NoRegister;
1479 if (isVectorType(Ty)) { 1480 if (isVectorType(Ty)) {
1480 RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs); 1481 RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs);
1481 if (RegNum == Variable::NoRegister) { 1482 if (RegNum == RegNumT::NoRegister) {
1482 XmmSlotsRemain = false; 1483 XmmSlotsRemain = false;
1483 continue; 1484 continue;
1484 } 1485 }
1485 ++NumXmmArgs; 1486 ++NumXmmArgs;
1486 RegisterArg = Func->makeVariable(Ty); 1487 RegisterArg = Func->makeVariable(Ty);
1487 } else if (isScalarFloatingType(Ty)) { 1488 } else if (isScalarFloatingType(Ty)) {
1488 if (!Traits::X86_PASS_SCALAR_FP_IN_XMM) { 1489 if (!Traits::X86_PASS_SCALAR_FP_IN_XMM) {
1489 continue; 1490 continue;
1490 } 1491 }
1491 RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs); 1492 RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs);
1492 if (RegNum == Variable::NoRegister) { 1493 if (RegNum == RegNumT::NoRegister) {
1493 XmmSlotsRemain = false; 1494 XmmSlotsRemain = false;
1494 continue; 1495 continue;
1495 } 1496 }
1496 ++NumXmmArgs; 1497 ++NumXmmArgs;
1497 RegisterArg = Func->makeVariable(Ty); 1498 RegisterArg = Func->makeVariable(Ty);
1498 } else if (isScalarIntegerType(Ty)) { 1499 } else if (isScalarIntegerType(Ty)) {
1499 RegNum = Traits::getRegisterForGprArgNum(Ty, NumGprArgs); 1500 RegNum = Traits::getRegisterForGprArgNum(Ty, NumGprArgs);
1500 if (RegNum == Variable::NoRegister) { 1501 if (RegNum == RegNumT::NoRegister) {
1501 GprSlotsRemain = false; 1502 GprSlotsRemain = false;
1502 continue; 1503 continue;
1503 } 1504 }
1504 ++NumGprArgs; 1505 ++NumGprArgs;
1505 RegisterArg = Func->makeVariable(Ty); 1506 RegisterArg = Func->makeVariable(Ty);
1506 } 1507 }
1507 assert(RegNum != Variable::NoRegister); 1508 assert(RegNum != RegNumT::NoRegister);
1508 assert(RegisterArg != nullptr); 1509 assert(RegisterArg != nullptr);
1509 // Replace Arg in the argument list with the home register. Then generate 1510 // Replace Arg in the argument list with the home register. Then generate
1510 // an instruction in the prolog to copy the home register to the assigned 1511 // an instruction in the prolog to copy the home register to the assigned
1511 // location of Arg. 1512 // location of Arg.
1512 if (BuildDefs::dump()) 1513 if (BuildDefs::dump())
1513 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); 1514 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
1514 RegisterArg->setRegNum(RegNum); 1515 RegisterArg->setRegNum(RegNum);
1515 RegisterArg->setIsArg(); 1516 RegisterArg->setIsArg();
1516 Arg->setIsArg(false); 1517 Arg->setIsArg(false);
1517 1518
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
2186 _mov(T, Src0); 2187 _mov(T, Src0);
2187 if (!llvm::isa<ConstantInteger32>(Src1)) 2188 if (!llvm::isa<ConstantInteger32>(Src1))
2188 Src1 = copyToReg8(Src1, Traits::RegisterSet::Reg_cl); 2189 Src1 = copyToReg8(Src1, Traits::RegisterSet::Reg_cl);
2189 _sar(T, Src1); 2190 _sar(T, Src1);
2190 _mov(Dest, T); 2191 _mov(Dest, T);
2191 break; 2192 break;
2192 case InstArithmetic::Udiv: { 2193 case InstArithmetic::Udiv: {
2193 // div and idiv are the few arithmetic operators that do not allow 2194 // div and idiv are the few arithmetic operators that do not allow
2194 // immediates as the operand. 2195 // immediates as the operand.
2195 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 2196 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
2196 uint32_t Eax; 2197 RegNumT Eax;
2197 uint32_t Edx; 2198 RegNumT Edx;
2198 switch (Ty) { 2199 switch (Ty) {
2199 default: 2200 default:
2200 llvm::report_fatal_error("Bad type for udiv"); 2201 llvm::report_fatal_error("Bad type for udiv");
2201 case IceType_i64: 2202 case IceType_i64:
2202 Eax = Traits::getRaxOrDie(); 2203 Eax = Traits::getRaxOrDie();
2203 Edx = Traits::getRdxOrDie(); 2204 Edx = Traits::getRdxOrDie();
2204 break; 2205 break;
2205 case IceType_i32: 2206 case IceType_i32:
2206 Eax = Traits::RegisterSet::Reg_eax; 2207 Eax = Traits::RegisterSet::Reg_eax;
2207 Edx = Traits::RegisterSet::Reg_edx; 2208 Edx = Traits::RegisterSet::Reg_edx;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2276 T_edx = makeReg(IceType_i16, Traits::RegisterSet::Reg_ax); 2277 T_edx = makeReg(IceType_i16, Traits::RegisterSet::Reg_ax);
2277 _mov(T, Src0, Traits::RegisterSet::Reg_al); 2278 _mov(T, Src0, Traits::RegisterSet::Reg_al);
2278 break; 2279 break;
2279 } 2280 }
2280 _cbwdq(T_edx, T); 2281 _cbwdq(T_edx, T);
2281 _idiv(T, Src1, T_edx); 2282 _idiv(T, Src1, T_edx);
2282 _mov(Dest, T); 2283 _mov(Dest, T);
2283 break; 2284 break;
2284 case InstArithmetic::Urem: { 2285 case InstArithmetic::Urem: {
2285 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 2286 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
2286 uint32_t Eax; 2287 RegNumT Eax;
2287 uint32_t Edx; 2288 RegNumT Edx;
2288 switch (Ty) { 2289 switch (Ty) {
2289 default: 2290 default:
2290 llvm::report_fatal_error("Bad type for urem"); 2291 llvm::report_fatal_error("Bad type for urem");
2291 case IceType_i64: 2292 case IceType_i64:
2292 Eax = Traits::getRaxOrDie(); 2293 Eax = Traits::getRaxOrDie();
2293 Edx = Traits::getRdxOrDie(); 2294 Edx = Traits::getRdxOrDie();
2294 break; 2295 break;
2295 case IceType_i32: 2296 case IceType_i32:
2296 Eax = Traits::RegisterSet::Reg_eax; 2297 Eax = Traits::RegisterSet::Reg_eax;
2297 Edx = Traits::RegisterSet::Reg_edx; 2298 Edx = Traits::RegisterSet::Reg_edx;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2345 _add(T, Src0); 2346 _add(T, Src0);
2346 _and(T, Ctx->getConstantInt(Ty, -(1 << LogDiv))); 2347 _and(T, Ctx->getConstantInt(Ty, -(1 << LogDiv)));
2347 _sub(T, Src0); 2348 _sub(T, Src0);
2348 _neg(T); 2349 _neg(T);
2349 _mov(Dest, T); 2350 _mov(Dest, T);
2350 return; 2351 return;
2351 } 2352 }
2352 } 2353 }
2353 } 2354 }
2354 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 2355 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
2355 uint32_t Eax; 2356 RegNumT Eax;
2356 uint32_t Edx; 2357 RegNumT Edx;
2357 switch (Ty) { 2358 switch (Ty) {
2358 default: 2359 default:
2359 llvm::report_fatal_error("Bad type for srem"); 2360 llvm::report_fatal_error("Bad type for srem");
2360 case IceType_i64: 2361 case IceType_i64:
2361 Eax = Traits::getRaxOrDie(); 2362 Eax = Traits::getRaxOrDie();
2362 Edx = Traits::getRdxOrDie(); 2363 Edx = Traits::getRdxOrDie();
2363 break; 2364 break;
2364 case IceType_i32: 2365 case IceType_i32:
2365 Eax = Traits::RegisterSet::Reg_eax; 2366 Eax = Traits::RegisterSet::Reg_eax;
2366 Edx = Traits::RegisterSet::Reg_edx; 2367 Edx = Traits::RegisterSet::Reg_edx;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2483 uint32_t ParameterAreaSizeBytes = 0; 2484 uint32_t ParameterAreaSizeBytes = 0;
2484 2485
2485 // Classify each argument operand according to the location where the argument 2486 // Classify each argument operand according to the location where the argument
2486 // is passed. 2487 // is passed.
2487 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { 2488 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
2488 Operand *Arg = Instr->getArg(i); 2489 Operand *Arg = Instr->getArg(i);
2489 const Type Ty = Arg->getType(); 2490 const Type Ty = Arg->getType();
2490 // The PNaCl ABI requires the width of arguments to be at least 32 bits. 2491 // The PNaCl ABI requires the width of arguments to be at least 32 bits.
2491 assert(typeWidthInBytes(Ty) >= 4); 2492 assert(typeWidthInBytes(Ty) >= 4);
2492 if (isVectorType(Ty) && (Traits::getRegisterForXmmArgNum(XmmArgs.size()) != 2493 if (isVectorType(Ty) && (Traits::getRegisterForXmmArgNum(XmmArgs.size()) !=
2493 Variable::NoRegister)) { 2494 RegNumT::NoRegister)) {
2494 XmmArgs.push_back(Arg); 2495 XmmArgs.push_back(Arg);
2495 } else if (isScalarFloatingType(Ty) && Traits::X86_PASS_SCALAR_FP_IN_XMM && 2496 } else if (isScalarFloatingType(Ty) && Traits::X86_PASS_SCALAR_FP_IN_XMM &&
2496 (Traits::getRegisterForXmmArgNum(XmmArgs.size()) != 2497 (Traits::getRegisterForXmmArgNum(XmmArgs.size()) !=
2497 Variable::NoRegister)) { 2498 RegNumT::NoRegister)) {
2498 XmmArgs.push_back(Arg); 2499 XmmArgs.push_back(Arg);
2499 } else if (isScalarIntegerType(Ty) && 2500 } else if (isScalarIntegerType(Ty) &&
2500 (Traits::getRegisterForGprArgNum(Ty, GprArgs.size()) != 2501 (Traits::getRegisterForGprArgNum(Ty, GprArgs.size()) !=
2501 Variable::NoRegister)) { 2502 RegNumT::NoRegister)) {
2502 GprArgs.emplace_back(Ty, Arg); 2503 GprArgs.emplace_back(Ty, Arg);
2503 } else { 2504 } else {
2504 // Place on stack. 2505 // Place on stack.
2505 StackArgs.push_back(Arg); 2506 StackArgs.push_back(Arg);
2506 if (isVectorType(Arg->getType())) { 2507 if (isVectorType(Arg->getType())) {
2507 ParameterAreaSizeBytes = 2508 ParameterAreaSizeBytes =
2508 Traits::applyStackAlignment(ParameterAreaSizeBytes); 2509 Traits::applyStackAlignment(ParameterAreaSizeBytes);
2509 } 2510 }
2510 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType); 2511 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType);
2511 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes); 2512 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes);
(...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after
4267 _mov(T_ecx, hiOperand(Desired)); 4268 _mov(T_ecx, hiOperand(Desired));
4268 X86OperandMem *Addr = formMemoryOperand(Ptr, Ty); 4269 X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
4269 constexpr bool Locked = true; 4270 constexpr bool Locked = true;
4270 _cmpxchg8b(Addr, T_edx, T_eax, T_ecx, T_ebx, Locked); 4271 _cmpxchg8b(Addr, T_edx, T_eax, T_ecx, T_ebx, Locked);
4271 auto *DestLo = llvm::cast<Variable>(loOperand(DestPrev)); 4272 auto *DestLo = llvm::cast<Variable>(loOperand(DestPrev));
4272 auto *DestHi = llvm::cast<Variable>(hiOperand(DestPrev)); 4273 auto *DestHi = llvm::cast<Variable>(hiOperand(DestPrev));
4273 _mov(DestLo, T_eax); 4274 _mov(DestLo, T_eax);
4274 _mov(DestHi, T_edx); 4275 _mov(DestHi, T_edx);
4275 return; 4276 return;
4276 } 4277 }
4277 int32_t Eax; 4278 RegNumT Eax;
4278 switch (Ty) { 4279 switch (Ty) {
4279 default: 4280 default:
4280 llvm::report_fatal_error("Bad type for cmpxchg"); 4281 llvm::report_fatal_error("Bad type for cmpxchg");
4281 case IceType_i64: 4282 case IceType_i64:
4282 Eax = Traits::getRaxOrDie(); 4283 Eax = Traits::getRaxOrDie();
4283 break; 4284 break;
4284 case IceType_i32: 4285 case IceType_i32:
4285 Eax = Traits::RegisterSet::Reg_eax; 4286 Eax = Traits::RegisterSet::Reg_eax;
4286 break; 4287 break;
4287 case IceType_i16: 4288 case IceType_i16:
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
4538 // The address base (if any) is also reused in the loop. 4539 // The address base (if any) is also reused in the loop.
4539 if (Variable *Base = Addr->getBase()) 4540 if (Variable *Base = Addr->getBase())
4540 Context.insert<InstFakeUse>(Base); 4541 Context.insert<InstFakeUse>(Base);
4541 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 4542 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
4542 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 4543 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
4543 _mov(DestLo, T_eax); 4544 _mov(DestLo, T_eax);
4544 _mov(DestHi, T_edx); 4545 _mov(DestHi, T_edx);
4545 return; 4546 return;
4546 } 4547 }
4547 X86OperandMem *Addr = formMemoryOperand(Ptr, Ty); 4548 X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
4548 int32_t Eax; 4549 RegNumT Eax;
4549 switch (Ty) { 4550 switch (Ty) {
4550 default: 4551 default:
4551 llvm::report_fatal_error("Bad type for atomicRMW"); 4552 llvm::report_fatal_error("Bad type for atomicRMW");
4552 case IceType_i64: 4553 case IceType_i64:
4553 Eax = Traits::getRaxOrDie(); 4554 Eax = Traits::getRaxOrDie();
4554 break; 4555 break;
4555 case IceType_i32: 4556 case IceType_i32:
4556 Eax = Traits::RegisterSet::Reg_eax; 4557 Eax = Traits::RegisterSet::Reg_eax;
4557 break; 4558 break;
4558 case IceType_i16: 4559 case IceType_i16:
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after
5477 Opnd = Mem->getBase(); 5478 Opnd = Mem->getBase();
5478 } 5479 }
5479 // At this point Opnd could be nullptr, or Variable, or Constant, or perhaps 5480 // At this point Opnd could be nullptr, or Variable, or Constant, or perhaps
5480 // something else. We only care if it is Variable. 5481 // something else. We only care if it is Variable.
5481 auto *Var = llvm::dyn_cast_or_null<Variable>(Opnd); 5482 auto *Var = llvm::dyn_cast_or_null<Variable>(Opnd);
5482 if (Var == nullptr) 5483 if (Var == nullptr)
5483 return; 5484 return;
5484 // We use lowerStore() to copy out-args onto the stack. This creates a memory 5485 // We use lowerStore() to copy out-args onto the stack. This creates a memory
5485 // operand with the stack pointer as the base register. Don't do bounds 5486 // operand with the stack pointer as the base register. Don't do bounds
5486 // checks on that. 5487 // checks on that.
5487 if (Var->getRegNum() == static_cast<int32_t>(getStackReg())) 5488 if (Var->getRegNum() == getStackReg())
5488 return; 5489 return;
5489 5490
5490 auto *Label = InstX86Label::create(Func, this); 5491 auto *Label = InstX86Label::create(Func, this);
5491 _cmp(Opnd, Ctx->getConstantZero(IceType_i32)); 5492 _cmp(Opnd, Ctx->getConstantZero(IceType_i32));
5492 _br(Traits::Cond::Br_e, Label); 5493 _br(Traits::Cond::Br_e, Label);
5493 _cmp(Opnd, Ctx->getConstantInt32(1)); 5494 _cmp(Opnd, Ctx->getConstantInt32(1));
5494 _br(Traits::Cond::Br_e, Label); 5495 _br(Traits::Cond::Br_e, Label);
5495 Context.insert(Label); 5496 Context.insert(Label);
5496 } 5497 }
5497 5498
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after
6499 // Compute the return type (if any); 6500 // Compute the return type (if any);
6500 Type ReturnType = IceType_void; 6501 Type ReturnType = IceType_void;
6501 Variable *Dest = Instr->getDest(); 6502 Variable *Dest = Instr->getDest();
6502 if (Dest != nullptr) 6503 if (Dest != nullptr)
6503 ReturnType = Dest->getType(); 6504 ReturnType = Dest->getType();
6504 return getCallStackArgumentsSizeBytes(ArgTypes, ReturnType); 6505 return getCallStackArgumentsSizeBytes(ArgTypes, ReturnType);
6505 } 6506 }
6506 6507
6507 template <typename TraitsType> 6508 template <typename TraitsType>
6508 Variable *TargetX86Base<TraitsType>::makeZeroedRegister(Type Ty, 6509 Variable *TargetX86Base<TraitsType>::makeZeroedRegister(Type Ty,
6509 int32_t RegNum) { 6510 RegNumT RegNum) {
6510 Variable *Reg = makeReg(Ty, RegNum); 6511 Variable *Reg = makeReg(Ty, RegNum);
6511 switch (Ty) { 6512 switch (Ty) {
6512 case IceType_i1: 6513 case IceType_i1:
6513 case IceType_i8: 6514 case IceType_i8:
6514 case IceType_i16: 6515 case IceType_i16:
6515 case IceType_i32: 6516 case IceType_i32:
6516 case IceType_i64: 6517 case IceType_i64:
6517 // Conservatively do "mov reg, 0" to avoid modifying FLAGS. 6518 // Conservatively do "mov reg, 0" to avoid modifying FLAGS.
6518 _mov(Reg, Ctx->getConstantZero(Ty)); 6519 _mov(Reg, Ctx->getConstantZero(Ty));
6519 break; 6520 break;
(...skipping 14 matching lines...) Expand all
6534 6535
6535 // There is no support for loading or emitting vector constants, so the vector 6536 // There is no support for loading or emitting vector constants, so the vector
6536 // values returned from makeVectorOfZeros, makeVectorOfOnes, etc. are 6537 // values returned from makeVectorOfZeros, makeVectorOfOnes, etc. are
6537 // initialized with register operations. 6538 // initialized with register operations.
6538 // 6539 //
6539 // TODO(wala): Add limited support for vector constants so that complex 6540 // TODO(wala): Add limited support for vector constants so that complex
6540 // initialization in registers is unnecessary. 6541 // initialization in registers is unnecessary.
6541 6542
6542 template <typename TraitsType> 6543 template <typename TraitsType>
6543 Variable *TargetX86Base<TraitsType>::makeVectorOfZeros(Type Ty, 6544 Variable *TargetX86Base<TraitsType>::makeVectorOfZeros(Type Ty,
6544 int32_t RegNum) { 6545 RegNumT RegNum) {
6545 return makeZeroedRegister(Ty, RegNum); 6546 return makeZeroedRegister(Ty, RegNum);
6546 } 6547 }
6547 6548
6548 template <typename TraitsType> 6549 template <typename TraitsType>
6549 Variable *TargetX86Base<TraitsType>::makeVectorOfMinusOnes(Type Ty, 6550 Variable *TargetX86Base<TraitsType>::makeVectorOfMinusOnes(Type Ty,
6550 int32_t RegNum) { 6551 RegNumT RegNum) {
6551 Variable *MinusOnes = makeReg(Ty, RegNum); 6552 Variable *MinusOnes = makeReg(Ty, RegNum);
6552 // Insert a FakeDef so the live range of MinusOnes is not overestimated. 6553 // Insert a FakeDef so the live range of MinusOnes is not overestimated.
6553 Context.insert<InstFakeDef>(MinusOnes); 6554 Context.insert<InstFakeDef>(MinusOnes);
6554 if (Ty == IceType_f64) 6555 if (Ty == IceType_f64)
6555 // Making a vector of minus ones of type f64 is currently only used for the 6556 // Making a vector of minus ones of type f64 is currently only used for the
6556 // fabs intrinsic. To use the f64 type to create this mask with pcmpeqq 6557 // fabs intrinsic. To use the f64 type to create this mask with pcmpeqq
6557 // requires SSE 4.1. Since we're just creating a mask, pcmpeqd does the 6558 // requires SSE 4.1. Since we're just creating a mask, pcmpeqd does the
6558 // same job and only requires SSE2. 6559 // same job and only requires SSE2.
6559 _pcmpeq(MinusOnes, MinusOnes, IceType_f32); 6560 _pcmpeq(MinusOnes, MinusOnes, IceType_f32);
6560 else 6561 else
6561 _pcmpeq(MinusOnes, MinusOnes); 6562 _pcmpeq(MinusOnes, MinusOnes);
6562 return MinusOnes; 6563 return MinusOnes;
6563 } 6564 }
6564 6565
6565 template <typename TraitsType> 6566 template <typename TraitsType>
6566 Variable *TargetX86Base<TraitsType>::makeVectorOfOnes(Type Ty, int32_t RegNum) { 6567 Variable *TargetX86Base<TraitsType>::makeVectorOfOnes(Type Ty, RegNumT RegNum) {
6567 Variable *Dest = makeVectorOfZeros(Ty, RegNum); 6568 Variable *Dest = makeVectorOfZeros(Ty, RegNum);
6568 Variable *MinusOne = makeVectorOfMinusOnes(Ty); 6569 Variable *MinusOne = makeVectorOfMinusOnes(Ty);
6569 _psub(Dest, MinusOne); 6570 _psub(Dest, MinusOne);
6570 return Dest; 6571 return Dest;
6571 } 6572 }
6572 6573
6573 template <typename TraitsType> 6574 template <typename TraitsType>
6574 Variable *TargetX86Base<TraitsType>::makeVectorOfHighOrderBits(Type Ty, 6575 Variable *TargetX86Base<TraitsType>::makeVectorOfHighOrderBits(Type Ty,
6575 int32_t RegNum) { 6576 RegNumT RegNum) {
6576 assert(Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v8i16 || 6577 assert(Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v8i16 ||
6577 Ty == IceType_v16i8); 6578 Ty == IceType_v16i8);
6578 if (Ty == IceType_v4f32 || Ty == IceType_v4i32 || Ty == IceType_v8i16) { 6579 if (Ty == IceType_v4f32 || Ty == IceType_v4i32 || Ty == IceType_v8i16) {
6579 Variable *Reg = makeVectorOfOnes(Ty, RegNum); 6580 Variable *Reg = makeVectorOfOnes(Ty, RegNum);
6580 SizeT Shift = 6581 SizeT Shift =
6581 typeWidthInBytes(typeElementType(Ty)) * Traits::X86_CHAR_BIT - 1; 6582 typeWidthInBytes(typeElementType(Ty)) * Traits::X86_CHAR_BIT - 1;
6582 _psll(Reg, Ctx->getConstantInt8(Shift)); 6583 _psll(Reg, Ctx->getConstantInt8(Shift));
6583 return Reg; 6584 return Reg;
6584 } else { 6585 } else {
6585 // SSE has no left shift operation for vectors of 8 bit integers. 6586 // SSE has no left shift operation for vectors of 8 bit integers.
6586 constexpr uint32_t HIGH_ORDER_BITS_MASK = 0x80808080; 6587 constexpr uint32_t HIGH_ORDER_BITS_MASK = 0x80808080;
6587 Constant *ConstantMask = Ctx->getConstantInt32(HIGH_ORDER_BITS_MASK); 6588 Constant *ConstantMask = Ctx->getConstantInt32(HIGH_ORDER_BITS_MASK);
6588 Variable *Reg = makeReg(Ty, RegNum); 6589 Variable *Reg = makeReg(Ty, RegNum);
6589 _movd(Reg, legalize(ConstantMask, Legal_Reg | Legal_Mem)); 6590 _movd(Reg, legalize(ConstantMask, Legal_Reg | Legal_Mem));
6590 _pshufd(Reg, Reg, Ctx->getConstantZero(IceType_i8)); 6591 _pshufd(Reg, Reg, Ctx->getConstantZero(IceType_i8));
6591 return Reg; 6592 return Reg;
6592 } 6593 }
6593 } 6594 }
6594 6595
6595 /// Construct a mask in a register that can be and'ed with a floating-point 6596 /// Construct a mask in a register that can be and'ed with a floating-point
6596 /// value to mask off its sign bit. The value will be <4 x 0x7fffffff> for f32 6597 /// value to mask off its sign bit. The value will be <4 x 0x7fffffff> for f32
6597 /// and v4f32, and <2 x 0x7fffffffffffffff> for f64. Construct it as vector of 6598 /// and v4f32, and <2 x 0x7fffffffffffffff> for f64. Construct it as vector of
6598 /// ones logically right shifted one bit. 6599 /// ones logically right shifted one bit.
6599 // TODO(stichnot): Fix the wala 6600 // TODO(stichnot): Fix the wala
6600 // TODO: above, to represent vector constants in memory. 6601 // TODO: above, to represent vector constants in memory.
6601 template <typename TraitsType> 6602 template <typename TraitsType>
6602 Variable *TargetX86Base<TraitsType>::makeVectorOfFabsMask(Type Ty, 6603 Variable *TargetX86Base<TraitsType>::makeVectorOfFabsMask(Type Ty,
6603 int32_t RegNum) { 6604 RegNumT RegNum) {
6604 Variable *Reg = makeVectorOfMinusOnes(Ty, RegNum); 6605 Variable *Reg = makeVectorOfMinusOnes(Ty, RegNum);
6605 _psrl(Reg, Ctx->getConstantInt8(1)); 6606 _psrl(Reg, Ctx->getConstantInt8(1));
6606 return Reg; 6607 return Reg;
6607 } 6608 }
6608 6609
6609 template <typename TraitsType> 6610 template <typename TraitsType>
6610 typename TargetX86Base<TraitsType>::X86OperandMem * 6611 typename TargetX86Base<TraitsType>::X86OperandMem *
6611 TargetX86Base<TraitsType>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot, 6612 TargetX86Base<TraitsType>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
6612 uint32_t Offset) { 6613 uint32_t Offset) {
6613 // Ensure that Loc is a stack slot. 6614 // Ensure that Loc is a stack slot.
6614 assert(Slot->mustNotHaveReg()); 6615 assert(Slot->mustNotHaveReg());
6615 assert(Slot->getRegNum() == Variable::NoRegister); 6616 assert(Slot->getRegNum() == RegNumT::NoRegister);
6616 // Compute the location of Loc in memory. 6617 // Compute the location of Loc in memory.
6617 // TODO(wala,stichnot): lea should not 6618 // TODO(wala,stichnot): lea should not
6618 // be required. The address of the stack slot is known at compile time 6619 // be required. The address of the stack slot is known at compile time
6619 // (although not until after addProlog()). 6620 // (although not until after addProlog()).
6620 constexpr Type PointerType = IceType_i32; 6621 constexpr Type PointerType = IceType_i32;
6621 Variable *Loc = makeReg(PointerType); 6622 Variable *Loc = makeReg(PointerType);
6622 _lea(Loc, Slot); 6623 _lea(Loc, Slot);
6623 Constant *ConstantOffset = Ctx->getConstantInt32(Offset); 6624 Constant *ConstantOffset = Ctx->getConstantInt32(Offset);
6624 return X86OperandMem::create(Func, Ty, Loc, ConstantOffset); 6625 return X86OperandMem::create(Func, Ty, Loc, ConstantOffset);
6625 } 6626 }
(...skipping 20 matching lines...) Expand all
6646 /// 6647 ///
6647 /// Note #2. ConstantRelocatable operands are also put through this process 6648 /// Note #2. ConstantRelocatable operands are also put through this process
6648 /// (not truncated directly) because our ELF emitter does R_386_32 relocations 6649 /// (not truncated directly) because our ELF emitter does R_386_32 relocations
6649 /// but not R_386_8 relocations. 6650 /// but not R_386_8 relocations.
6650 /// 6651 ///
6651 /// Note #3. If Src is a Variable, the result will be an infinite-weight i8 6652 /// Note #3. If Src is a Variable, the result will be an infinite-weight i8
6652 /// Variable with the RCX86_IsTrunc8Rcvr register class. As such, this helper 6653 /// Variable with the RCX86_IsTrunc8Rcvr register class. As such, this helper
6653 /// is a convenient way to prevent ah/bh/ch/dh from being an (invalid) argument 6654 /// is a convenient way to prevent ah/bh/ch/dh from being an (invalid) argument
6654 /// to the pinsrb instruction. 6655 /// to the pinsrb instruction.
6655 template <typename TraitsType> 6656 template <typename TraitsType>
6656 Variable *TargetX86Base<TraitsType>::copyToReg8(Operand *Src, int32_t RegNum) { 6657 Variable *TargetX86Base<TraitsType>::copyToReg8(Operand *Src, RegNumT RegNum) {
6657 Type Ty = Src->getType(); 6658 Type Ty = Src->getType();
6658 assert(isScalarIntegerType(Ty)); 6659 assert(isScalarIntegerType(Ty));
6659 assert(Ty != IceType_i1); 6660 assert(Ty != IceType_i1);
6660 Variable *Reg = makeReg(IceType_i8, RegNum); 6661 Variable *Reg = makeReg(IceType_i8, RegNum);
6661 Reg->setRegClass(RCX86_IsTrunc8Rcvr); 6662 Reg->setRegClass(RCX86_IsTrunc8Rcvr);
6662 if (llvm::isa<Variable>(Src) || llvm::isa<ConstantRelocatable>(Src)) { 6663 if (llvm::isa<Variable>(Src) || llvm::isa<ConstantRelocatable>(Src)) {
6663 Variable *SrcTruncable = makeReg(Ty); 6664 Variable *SrcTruncable = makeReg(Ty);
6664 switch (Ty) { 6665 switch (Ty) {
6665 case IceType_i64: 6666 case IceType_i64:
6666 SrcTruncable->setRegClass(RCX86_Is64To8); 6667 SrcTruncable->setRegClass(RCX86_Is64To8);
(...skipping 14 matching lines...) Expand all
6681 _mov(SrcRcvr, SrcTruncable); 6682 _mov(SrcRcvr, SrcTruncable);
6682 Src = SrcRcvr; 6683 Src = SrcRcvr;
6683 } 6684 }
6684 _mov(Reg, Src); 6685 _mov(Reg, Src);
6685 return Reg; 6686 return Reg;
6686 } 6687 }
6687 6688
6688 /// Helper for legalize() to emit the right code to lower an operand to a 6689 /// Helper for legalize() to emit the right code to lower an operand to a
6689 /// register of the appropriate type. 6690 /// register of the appropriate type.
6690 template <typename TraitsType> 6691 template <typename TraitsType>
6691 Variable *TargetX86Base<TraitsType>::copyToReg(Operand *Src, int32_t RegNum) { 6692 Variable *TargetX86Base<TraitsType>::copyToReg(Operand *Src, RegNumT RegNum) {
6692 Type Ty = Src->getType(); 6693 Type Ty = Src->getType();
6693 Variable *Reg = makeReg(Ty, RegNum); 6694 Variable *Reg = makeReg(Ty, RegNum);
6694 if (isVectorType(Ty)) { 6695 if (isVectorType(Ty)) {
6695 _movp(Reg, Src); 6696 _movp(Reg, Src);
6696 } else { 6697 } else {
6697 _mov(Reg, Src); 6698 _mov(Reg, Src);
6698 } 6699 }
6699 return Reg; 6700 return Reg;
6700 } 6701 }
6701 6702
6702 template <typename TraitsType> 6703 template <typename TraitsType>
6703 Operand *TargetX86Base<TraitsType>::legalize(Operand *From, LegalMask Allowed, 6704 Operand *TargetX86Base<TraitsType>::legalize(Operand *From, LegalMask Allowed,
6704 int32_t RegNum) { 6705 RegNumT RegNum) {
6705 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); 6706 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi();
6706 const Type Ty = From->getType(); 6707 const Type Ty = From->getType();
6707 // Assert that a physical register is allowed. To date, all calls to 6708 // Assert that a physical register is allowed. To date, all calls to
6708 // legalize() allow a physical register. If a physical register needs to be 6709 // legalize() allow a physical register. If a physical register needs to be
6709 // explicitly disallowed, then new code will need to be written to force a 6710 // explicitly disallowed, then new code will need to be written to force a
6710 // spill. 6711 // spill.
6711 assert(Allowed & Legal_Reg); 6712 assert(Allowed & Legal_Reg);
6712 // If we're asking for a specific physical register, make sure we're not 6713 // If we're asking for a specific physical register, make sure we're not
6713 // allowing any other operand kinds. (This could be future work, e.g. allow 6714 // allowing any other operand kinds. (This could be future work, e.g. allow
6714 // the shl shift amount to be either an immediate or in ecx.) 6715 // the shl shift amount to be either an immediate or in ecx.)
6715 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); 6716 assert(RegNum == RegNumT::NoRegister || Allowed == Legal_Reg);
6716 6717
6717 // Substitute with an available infinite-weight variable if possible. Only do 6718 // Substitute with an available infinite-weight variable if possible. Only do
6718 // this when we are not asking for a specific register, and when the 6719 // this when we are not asking for a specific register, and when the
6719 // substitution is not locked to a specific register, and when the types 6720 // substitution is not locked to a specific register, and when the types
6720 // match, in order to capture the vast majority of opportunities and avoid 6721 // match, in order to capture the vast majority of opportunities and avoid
6721 // corner cases in the lowering. 6722 // corner cases in the lowering.
6722 if (RegNum == Variable::NoRegister) { 6723 if (RegNum == RegNumT::NoRegister) {
6723 if (Variable *Subst = getContext().availabilityGet(From)) { 6724 if (Variable *Subst = getContext().availabilityGet(From)) {
6724 // At this point we know there is a potential substitution available. 6725 // At this point we know there is a potential substitution available.
6725 if (Subst->mustHaveReg() && !Subst->hasReg()) { 6726 if (Subst->mustHaveReg() && !Subst->hasReg()) {
6726 // At this point we know the substitution will have a register. 6727 // At this point we know the substitution will have a register.
6727 if (From->getType() == Subst->getType()) { 6728 if (From->getType() == Subst->getType()) {
6728 // At this point we know the substitution's register is compatible. 6729 // At this point we know the substitution's register is compatible.
6729 return Subst; 6730 return Subst;
6730 } 6731 }
6731 } 6732 }
6732 } 6733 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
6773 return From; 6774 return From;
6774 Const = llvm::cast<Constant>(From); 6775 Const = llvm::cast<Constant>(From);
6775 } 6776 }
6776 // There should be no constants of vector type (other than undef). 6777 // There should be no constants of vector type (other than undef).
6777 assert(!isVectorType(Ty)); 6778 assert(!isVectorType(Ty));
6778 6779
6779 // If the operand is a 64 bit constant integer we need to legalize it to a 6780 // If the operand is a 64 bit constant integer we need to legalize it to a
6780 // register in x86-64. 6781 // register in x86-64.
6781 if (Traits::Is64Bit) { 6782 if (Traits::Is64Bit) {
6782 if (llvm::isa<ConstantInteger64>(Const)) { 6783 if (llvm::isa<ConstantInteger64>(Const)) {
6783 if (RegNum != Variable::NoRegister) { 6784 if (RegNum != RegNumT::NoRegister) {
6784 assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum); 6785 assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum);
6785 } 6786 }
6786 return copyToReg(Const, RegNum); 6787 return copyToReg(Const, RegNum);
6787 } 6788 }
6788 } 6789 }
6789 6790
6790 // If the operand is an 32 bit constant integer, we should check whether we 6791 // If the operand is an 32 bit constant integer, we should check whether we
6791 // need to randomize it or pool it. 6792 // need to randomize it or pool it.
6792 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) { 6793 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) {
6793 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); 6794 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
6856 if (MustRematerialize) { 6857 if (MustRematerialize) {
6857 assert(Ty == IceType_i32); 6858 assert(Ty == IceType_i32);
6858 Variable *NewVar = makeReg(Ty, RegNum); 6859 Variable *NewVar = makeReg(Ty, RegNum);
6859 // Since Var is rematerializable, the offset will be added when the lea is 6860 // Since Var is rematerializable, the offset will be added when the lea is
6860 // emitted. 6861 // emitted.
6861 constexpr Constant *NoOffset = nullptr; 6862 constexpr Constant *NoOffset = nullptr;
6862 auto *Mem = X86OperandMem::create(Func, Ty, Var, NoOffset); 6863 auto *Mem = X86OperandMem::create(Func, Ty, Var, NoOffset);
6863 _lea(NewVar, Mem); 6864 _lea(NewVar, Mem);
6864 From = NewVar; 6865 From = NewVar;
6865 } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || 6866 } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
6866 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { 6867 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) {
6867 From = copyToReg(From, RegNum); 6868 From = copyToReg(From, RegNum);
6868 } 6869 }
6869 return From; 6870 return From;
6870 } 6871 }
6871 6872
6872 llvm::report_fatal_error("Unhandled operand kind in legalize()"); 6873 llvm::report_fatal_error("Unhandled operand kind in legalize()");
6873 return From; 6874 return From;
6874 } 6875 }
6875 6876
6876 /// Provide a trivial wrapper to legalize() for this common usage. 6877 /// Provide a trivial wrapper to legalize() for this common usage.
6877 template <typename TraitsType> 6878 template <typename TraitsType>
6878 Variable *TargetX86Base<TraitsType>::legalizeToReg(Operand *From, 6879 Variable *TargetX86Base<TraitsType>::legalizeToReg(Operand *From,
6879 int32_t RegNum) { 6880 RegNumT RegNum) {
6880 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); 6881 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum));
6881 } 6882 }
6882 6883
6883 /// Legalize undef values to concrete values. 6884 /// Legalize undef values to concrete values.
6884 template <typename TraitsType> 6885 template <typename TraitsType>
6885 Operand *TargetX86Base<TraitsType>::legalizeUndef(Operand *From, 6886 Operand *TargetX86Base<TraitsType>::legalizeUndef(Operand *From,
6886 int32_t RegNum) { 6887 RegNumT RegNum) {
6887 Type Ty = From->getType(); 6888 Type Ty = From->getType();
6888 if (llvm::isa<ConstantUndef>(From)) { 6889 if (llvm::isa<ConstantUndef>(From)) {
6889 // Lower undefs to zero. Another option is to lower undefs to an 6890 // Lower undefs to zero. Another option is to lower undefs to an
6890 // uninitialized register; however, using an uninitialized register results 6891 // uninitialized register; however, using an uninitialized register results
6891 // in less predictable code. 6892 // in less predictable code.
6892 // 6893 //
6893 // If in the future the implementation is changed to lower undef values to 6894 // If in the future the implementation is changed to lower undef values to
6894 // uninitialized registers, a FakeDef will be needed: 6895 // uninitialized registers, a FakeDef will be needed:
6895 // Context.insert<InstFakeDef>(Reg); 6896 // Context.insert<InstFakeDef>(Reg);
6896 // This is in order to ensure that the live range of Reg is not 6897 // This is in order to ensure that the live range of Reg is not
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
6955 // assert that PIC legalization has been applied. 6956 // assert that PIC legalization has been applied.
6956 Mem = X86OperandMem::create(Func, Ty, Base, Offset); 6957 Mem = X86OperandMem::create(Func, Ty, Base, Offset);
6957 } 6958 }
6958 // Do legalization, which contains randomization/pooling or do 6959 // Do legalization, which contains randomization/pooling or do
6959 // randomization/pooling. 6960 // randomization/pooling.
6960 return llvm::cast<X86OperandMem>(DoLegalize ? legalize(Mem) 6961 return llvm::cast<X86OperandMem>(DoLegalize ? legalize(Mem)
6961 : randomizeOrPoolImmediate(Mem)); 6962 : randomizeOrPoolImmediate(Mem));
6962 } 6963 }
6963 6964
6964 template <typename TraitsType> 6965 template <typename TraitsType>
6965 Variable *TargetX86Base<TraitsType>::makeReg(Type Type, int32_t RegNum) { 6966 Variable *TargetX86Base<TraitsType>::makeReg(Type Type, RegNumT RegNum) {
6966 // There aren't any 64-bit integer registers for x86-32. 6967 // There aren't any 64-bit integer registers for x86-32.
6967 assert(Traits::Is64Bit || Type != IceType_i64); 6968 assert(Traits::Is64Bit || Type != IceType_i64);
6968 Variable *Reg = Func->makeVariable(Type); 6969 Variable *Reg = Func->makeVariable(Type);
6969 if (RegNum == Variable::NoRegister) 6970 if (RegNum == RegNumT::NoRegister)
6970 Reg->setMustHaveReg(); 6971 Reg->setMustHaveReg();
6971 else 6972 else
6972 Reg->setRegNum(RegNum); 6973 Reg->setRegNum(RegNum);
6973 return Reg; 6974 return Reg;
6974 } 6975 }
6975 6976
6976 template <typename TraitsType> 6977 template <typename TraitsType>
6977 const Type TargetX86Base<TraitsType>::TypeForSize[] = { 6978 const Type TargetX86Base<TraitsType>::TypeForSize[] = {
6978 IceType_i8, IceType_i16, IceType_i32, IceType_f64, IceType_v16i8}; 6979 IceType_i8, IceType_i16, IceType_i32, IceType_f64, IceType_v16i8};
6979 template <typename TraitsType> 6980 template <typename TraitsType>
(...skipping 22 matching lines...) Expand all
7002 7003
7003 template <typename TraitsType> void TargetX86Base<TraitsType>::postLower() { 7004 template <typename TraitsType> void TargetX86Base<TraitsType>::postLower() {
7004 if (Ctx->getFlags().getOptLevel() == Opt_m1) 7005 if (Ctx->getFlags().getOptLevel() == Opt_m1)
7005 return; 7006 return;
7006 markRedefinitions(); 7007 markRedefinitions();
7007 Context.availabilityUpdate(); 7008 Context.availabilityUpdate();
7008 } 7009 }
7009 7010
7010 template <typename TraitsType> 7011 template <typename TraitsType>
7011 void TargetX86Base<TraitsType>::makeRandomRegisterPermutation( 7012 void TargetX86Base<TraitsType>::makeRandomRegisterPermutation(
7012 llvm::SmallVectorImpl<int32_t> &Permutation, 7013 llvm::SmallVectorImpl<RegNumT> &Permutation,
7013 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { 7014 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
7014 Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation, 7015 Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation,
7015 ExcludeRegisters, Salt); 7016 ExcludeRegisters, Salt);
7016 } 7017 }
7017 7018
7018 template <typename TraitsType> 7019 template <typename TraitsType>
7019 void TargetX86Base<TraitsType>::emit(const ConstantInteger32 *C) const { 7020 void TargetX86Base<TraitsType>::emit(const ConstantInteger32 *C) const {
7020 if (!BuildDefs::dump()) 7021 if (!BuildDefs::dump())
7021 return; 7022 return;
7022 Ostream &Str = Ctx->getStrEmit(); 7023 Ostream &Str = Ctx->getStrEmit();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
7063 assert(!Ctx->getFlags().getUseNonsfi() || C->getName() == GlobalOffsetTable); 7064 assert(!Ctx->getFlags().getUseNonsfi() || C->getName() == GlobalOffsetTable);
7064 Ostream &Str = Ctx->getStrEmit(); 7065 Ostream &Str = Ctx->getStrEmit();
7065 Str << "$"; 7066 Str << "$";
7066 emitWithoutPrefix(C); 7067 emitWithoutPrefix(C);
7067 } 7068 }
7068 7069
7069 /// Randomize or pool an Immediate. 7070 /// Randomize or pool an Immediate.
7070 template <typename TraitsType> 7071 template <typename TraitsType>
7071 Operand * 7072 Operand *
7072 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(Constant *Immediate, 7073 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(Constant *Immediate,
7073 int32_t RegNum) { 7074 RegNumT RegNum) {
7074 assert(llvm::isa<ConstantInteger32>(Immediate) || 7075 assert(llvm::isa<ConstantInteger32>(Immediate) ||
7075 llvm::isa<ConstantRelocatable>(Immediate)); 7076 llvm::isa<ConstantRelocatable>(Immediate));
7076 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || 7077 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
7077 RandomizationPoolingPaused == true) { 7078 RandomizationPoolingPaused == true) {
7078 // Immediates randomization/pooling off or paused 7079 // Immediates randomization/pooling off or paused
7079 return Immediate; 7080 return Immediate;
7080 } 7081 }
7081 7082
7082 if (Traits::Is64Bit && NeedSandboxing) { 7083 if (Traits::Is64Bit && NeedSandboxing) {
7083 // Immediate randomization/pooling is currently disabled for x86-64 7084 // Immediate randomization/pooling is currently disabled for x86-64
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
7148 X86OperandMem::create(Func, Immediate->getType(), NoBase, Symbol); 7149 X86OperandMem::create(Func, Immediate->getType(), NoBase, Symbol);
7149 _mov(Reg, MemOperand); 7150 _mov(Reg, MemOperand);
7150 return Reg; 7151 return Reg;
7151 } 7152 }
7152 } 7153 }
7153 } 7154 }
7154 7155
7155 template <typename TraitsType> 7156 template <typename TraitsType>
7156 typename TargetX86Base<TraitsType>::X86OperandMem * 7157 typename TargetX86Base<TraitsType>::X86OperandMem *
7157 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(X86OperandMem *MemOperand, 7158 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(X86OperandMem *MemOperand,
7158 int32_t RegNum) { 7159 RegNumT RegNum) {
7159 assert(MemOperand); 7160 assert(MemOperand);
7160 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || 7161 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
7161 RandomizationPoolingPaused == true) { 7162 RandomizationPoolingPaused == true) {
7162 // immediates randomization/pooling is turned off 7163 // immediates randomization/pooling is turned off
7163 return MemOperand; 7164 return MemOperand;
7164 } 7165 }
7165 7166
7166 if (Traits::Is64Bit && NeedSandboxing) { 7167 if (Traits::Is64Bit && NeedSandboxing) {
7167 // Immediate randomization/pooling is currently disabled for x86-64 7168 // Immediate randomization/pooling is currently disabled for x86-64
7168 // sandboxing for it could generate invalid memory operands. 7169 // sandboxing for it could generate invalid memory operands.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
7233 // TO: 7234 // TO:
7234 // insert: mov $label, RegTemp 7235 // insert: mov $label, RegTemp
7235 // insert: lea [base, RegTemp], RegTemp 7236 // insert: lea [base, RegTemp], RegTemp
7236 // =>[RegTemp, index, shift] 7237 // =>[RegTemp, index, shift]
7237 7238
7238 // Memory operand should never exist as source operands in phi lowering 7239 // Memory operand should never exist as source operands in phi lowering
7239 // assignments, so there is no need to reuse any registers here. For 7240 // assignments, so there is no need to reuse any registers here. For
7240 // phi lowering, we should not ask for new physical registers in 7241 // phi lowering, we should not ask for new physical registers in
7241 // general. However, if we do meet Memory Operand during phi lowering, 7242 // general. However, if we do meet Memory Operand during phi lowering,
7242 // we should not blind or pool the immediates for now. 7243 // we should not blind or pool the immediates for now.
7243 if (RegNum != Variable::NoRegister) 7244 if (RegNum != RegNumT::NoRegister)
7244 return MemOperand; 7245 return MemOperand;
7245 Variable *RegTemp = makeReg(IceType_i32); 7246 Variable *RegTemp = makeReg(IceType_i32);
7246 IceString Label; 7247 IceString Label;
7247 llvm::raw_string_ostream Label_stream(Label); 7248 llvm::raw_string_ostream Label_stream(Label);
7248 MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx); 7249 MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx);
7249 MemOperand->getOffset()->setShouldBePooled(true); 7250 MemOperand->getOffset()->setShouldBePooled(true);
7250 constexpr RelocOffsetT SymOffset = 0; 7251 constexpr RelocOffsetT SymOffset = 0;
7251 constexpr bool SuppressMangling = true; 7252 constexpr bool SuppressMangling = true;
7252 Constant *Symbol = 7253 Constant *Symbol =
7253 Ctx->getConstantSym(SymOffset, Label_stream.str(), SuppressMangling); 7254 Ctx->getConstantSym(SymOffset, Label_stream.str(), SuppressMangling);
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
7418 emitGlobal(*Var, SectionSuffix); 7419 emitGlobal(*Var, SectionSuffix);
7419 } 7420 }
7420 } 7421 }
7421 } break; 7422 } break;
7422 } 7423 }
7423 } 7424 }
7424 } // end of namespace X86NAMESPACE 7425 } // end of namespace X86NAMESPACE
7425 } // end of namespace Ice 7426 } // end of namespace Ice
7426 7427
7427 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H 7428 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698