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 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
835 | 835 |
836 template <typename TraitsType> | 836 template <typename TraitsType> |
837 bool TargetX86Base<TraitsType>::doBranchOpt(Inst *I, const CfgNode *NextNode) { | 837 bool TargetX86Base<TraitsType>::doBranchOpt(Inst *I, const CfgNode *NextNode) { |
838 if (auto *Br = llvm::dyn_cast<InstX86Br>(I)) { | 838 if (auto *Br = llvm::dyn_cast<InstX86Br>(I)) { |
839 return Br->optimizeBranch(NextNode); | 839 return Br->optimizeBranch(NextNode); |
840 } | 840 } |
841 return false; | 841 return false; |
842 } | 842 } |
843 | 843 |
844 template <typename TraitsType> | 844 template <typename TraitsType> |
845 Variable *TargetX86Base<TraitsType>::getPhysicalRegister(SizeT RegNum, | 845 Variable *TargetX86Base<TraitsType>::getPhysicalRegister(RegNumT RegNum, |
846 Type Ty) { | 846 Type Ty) { |
847 if (Ty == IceType_void) | 847 if (Ty == IceType_void) |
848 Ty = IceType_i32; | 848 Ty = IceType_i32; |
849 if (PhysicalRegisters[Ty].empty()) | 849 if (PhysicalRegisters[Ty].empty()) |
850 PhysicalRegisters[Ty].resize(Traits::RegisterSet::Reg_NUM); | 850 PhysicalRegisters[Ty].resize(Traits::RegisterSet::Reg_NUM); |
851 assert(RegNum < PhysicalRegisters[Ty].size()); | 851 assert(unsigned(RegNum) < PhysicalRegisters[Ty].size()); |
852 Variable *Reg = PhysicalRegisters[Ty][RegNum]; | 852 Variable *Reg = PhysicalRegisters[Ty][RegNum]; |
853 if (Reg == nullptr) { | 853 if (Reg == nullptr) { |
854 Reg = Func->makeVariable(Ty); | 854 Reg = Func->makeVariable(Ty); |
855 Reg->setRegNum(RegNum); | 855 Reg->setRegNum(RegNum); |
856 PhysicalRegisters[Ty][RegNum] = Reg; | 856 PhysicalRegisters[Ty][RegNum] = Reg; |
857 // Specially mark a named physical register as an "argument" so that it is | 857 // 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 | 858 // considered live upon function entry. Otherwise it's possible to get |
859 // liveness validation errors for saving callee-save registers. | 859 // liveness validation errors for saving callee-save registers. |
860 Func->addImplicitArg(Reg); | 860 Func->addImplicitArg(Reg); |
861 // Don't bother tracking the live range of a named physical register. | 861 // Don't bother tracking the live range of a named physical register. |
862 Reg->setIgnoreLiveness(); | 862 Reg->setIgnoreLiveness(); |
863 } | 863 } |
864 assert(Traits::getGprForType(Ty, RegNum) == static_cast<int32_t>(RegNum)); | 864 assert(Traits::getGprForType(Ty, RegNum) == RegNum); |
865 return Reg; | 865 return Reg; |
866 } | 866 } |
867 | 867 |
868 template <typename TraitsType> | 868 template <typename TraitsType> |
869 IceString TargetX86Base<TraitsType>::getRegName(SizeT RegNum, Type Ty) const { | 869 IceString TargetX86Base<TraitsType>::getRegName(RegNumT RegNum, Type Ty) const { |
870 return Traits::getRegName(Traits::getGprForType(Ty, RegNum)); | 870 return Traits::getRegName(Traits::getGprForType(Ty, RegNum)); |
871 } | 871 } |
872 | 872 |
873 template <typename TraitsType> | 873 template <typename TraitsType> |
874 void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const { | 874 void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const { |
875 if (!BuildDefs::dump()) | 875 if (!BuildDefs::dump()) |
876 return; | 876 return; |
877 Ostream &Str = Ctx->getStrEmit(); | 877 Ostream &Str = Ctx->getStrEmit(); |
878 if (Var->hasReg()) { | 878 if (Var->hasReg()) { |
879 const bool Is64BitSandboxing = Traits::Is64Bit && NeedSandboxing; | 879 const bool Is64BitSandboxing = Traits::Is64Bit && NeedSandboxing; |
880 const Type VarType = (Var->isRematerializable() && Is64BitSandboxing) | 880 const Type VarType = (Var->isRematerializable() && Is64BitSandboxing) |
881 ? IceType_i64 | 881 ? IceType_i64 |
882 : Var->getType(); | 882 : Var->getType(); |
883 Str << "%" << getRegName(Var->getRegNum(), VarType); | 883 Str << "%" << getRegName(Var->getRegNum(), VarType); |
884 return; | 884 return; |
885 } | 885 } |
886 if (Var->mustHaveReg()) { | 886 if (Var->mustHaveReg()) { |
887 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + | 887 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + |
888 ") has no register assigned - function " + | 888 ") has no register assigned - function " + |
889 Func->getFunctionName()); | 889 Func->getFunctionName()); |
890 } | 890 } |
891 const int32_t Offset = Var->getStackOffset(); | 891 const int32_t Offset = Var->getStackOffset(); |
892 int32_t BaseRegNum = Var->getBaseRegNum(); | 892 RegNumT BaseRegNum = Var->getBaseRegNum(); |
893 if (BaseRegNum == Variable::NoRegister) | 893 if (BaseRegNum == RegNumT::NoRegister) |
894 BaseRegNum = getFrameOrStackReg(); | 894 BaseRegNum = getFrameOrStackReg(); |
895 // Print in the form "Offset(%reg)", taking care that: | 895 // Print in the form "Offset(%reg)", taking care that: |
896 // - Offset is never printed when it is 0 | 896 // - Offset is never printed when it is 0 |
897 | 897 |
898 const bool DecorateAsm = Func->getContext()->getFlags().getDecorateAsm(); | 898 const bool DecorateAsm = Func->getContext()->getFlags().getDecorateAsm(); |
899 // Only print Offset when it is nonzero, regardless of DecorateAsm. | 899 // Only print Offset when it is nonzero, regardless of DecorateAsm. |
900 if (Offset) { | 900 if (Offset) { |
901 if (DecorateAsm) { | 901 if (DecorateAsm) { |
902 Str << Var->getSymbolicStackOffset(Func); | 902 Str << Var->getSymbolicStackOffset(Func); |
903 } else { | 903 } else { |
904 Str << Offset; | 904 Str << Offset; |
905 } | 905 } |
906 } | 906 } |
907 const Type FrameSPTy = Traits::WordType; | 907 const Type FrameSPTy = Traits::WordType; |
908 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")"; | 908 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")"; |
909 } | 909 } |
910 | 910 |
911 template <typename TraitsType> | 911 template <typename TraitsType> |
912 typename TargetX86Base<TraitsType>::X86Address | 912 typename TargetX86Base<TraitsType>::X86Address |
913 TargetX86Base<TraitsType>::stackVarToAsmOperand(const Variable *Var) const { | 913 TargetX86Base<TraitsType>::stackVarToAsmOperand(const Variable *Var) const { |
914 if (Var->hasReg()) | 914 if (Var->hasReg()) |
915 llvm::report_fatal_error("Stack Variable has a register assigned"); | 915 llvm::report_fatal_error("Stack Variable has a register assigned"); |
916 if (Var->mustHaveReg()) { | 916 if (Var->mustHaveReg()) { |
917 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + | 917 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + |
918 ") has no register assigned - function " + | 918 ") has no register assigned - function " + |
919 Func->getFunctionName()); | 919 Func->getFunctionName()); |
920 } | 920 } |
921 int32_t Offset = Var->getStackOffset(); | 921 int32_t Offset = Var->getStackOffset(); |
922 int32_t BaseRegNum = Var->getBaseRegNum(); | 922 RegNumT BaseRegNum = Var->getBaseRegNum(); |
923 if (Var->getBaseRegNum() == Variable::NoRegister) | 923 if (Var->getBaseRegNum() == RegNumT::NoRegister) |
924 BaseRegNum = getFrameOrStackReg(); | 924 BaseRegNum = getFrameOrStackReg(); |
925 return X86Address(Traits::getEncodedGPR(BaseRegNum), Offset, | 925 return X86Address(Traits::getEncodedGPR(BaseRegNum), Offset, |
926 AssemblerFixup::NoFixup); | 926 AssemblerFixup::NoFixup); |
927 } | 927 } |
928 | 928 |
929 template <typename TraitsType> | 929 template <typename TraitsType> |
930 void TargetX86Base<TraitsType>::addProlog(CfgNode *Node) { | 930 void TargetX86Base<TraitsType>::addProlog(CfgNode *Node) { |
931 // Stack frame layout: | 931 // Stack frame layout: |
932 // | 932 // |
933 // +------------------------+ | 933 // +------------------------+ |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1007 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize, | 1007 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize, |
1008 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes, | 1008 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes, |
1009 &LocalsSlotsAlignmentBytes, TargetVarHook); | 1009 &LocalsSlotsAlignmentBytes, TargetVarHook); |
1010 uint32_t LocalsSpillAreaSize = SpillAreaSizeBytes; | 1010 uint32_t LocalsSpillAreaSize = SpillAreaSizeBytes; |
1011 SpillAreaSizeBytes += GlobalsSize; | 1011 SpillAreaSizeBytes += GlobalsSize; |
1012 | 1012 |
1013 // Add push instructions for preserved registers. | 1013 // Add push instructions for preserved registers. |
1014 uint32_t NumCallee = 0; | 1014 uint32_t NumCallee = 0; |
1015 size_t PreservedRegsSizeBytes = 0; | 1015 size_t PreservedRegsSizeBytes = 0; |
1016 llvm::SmallBitVector Pushed(CalleeSaves.size()); | 1016 llvm::SmallBitVector Pushed(CalleeSaves.size()); |
1017 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { | 1017 for (int i = CalleeSaves.find_first(); i != -1; |
1018 const int32_t Canonical = Traits::getBaseReg(i); | 1018 i = CalleeSaves.find_next(i)) { |
1019 const RegNumT 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 (int i = Pushed.find_first(); i != -1; i = Pushed.find_next(i)) { |
1025 if (!Pushed[i]) | 1026 assert(RegNumT(i) == Traits::getBaseReg(i)); |
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(i, 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); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 RegNumT RegNum = RegNumT(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 RegNumT RegNum = RegNumT(i); |
Eric Holk
2016/02/08 19:37:10
Using auto would let us get rid of at least one Re
Jim Stichnoth
2016/02/09 19:33:40
Yeah, I was thinking of making another pass and ch
Eric Holk
2016/02/10 01:11:31
Acknowledged.
| |
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 Loading... | |
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 RegNumT 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6534 // Compute the return type (if any); | 6535 // Compute the return type (if any); |
6535 Type ReturnType = IceType_void; | 6536 Type ReturnType = IceType_void; |
6536 Variable *Dest = Instr->getDest(); | 6537 Variable *Dest = Instr->getDest(); |
6537 if (Dest != nullptr) | 6538 if (Dest != nullptr) |
6538 ReturnType = Dest->getType(); | 6539 ReturnType = Dest->getType(); |
6539 return getCallStackArgumentsSizeBytes(ArgTypes, ReturnType); | 6540 return getCallStackArgumentsSizeBytes(ArgTypes, ReturnType); |
6540 } | 6541 } |
6541 | 6542 |
6542 template <typename TraitsType> | 6543 template <typename TraitsType> |
6543 Variable *TargetX86Base<TraitsType>::makeZeroedRegister(Type Ty, | 6544 Variable *TargetX86Base<TraitsType>::makeZeroedRegister(Type Ty, |
6544 int32_t RegNum) { | 6545 RegNumT RegNum) { |
6545 Variable *Reg = makeReg(Ty, RegNum); | 6546 Variable *Reg = makeReg(Ty, RegNum); |
6546 switch (Ty) { | 6547 switch (Ty) { |
6547 case IceType_i1: | 6548 case IceType_i1: |
6548 case IceType_i8: | 6549 case IceType_i8: |
6549 case IceType_i16: | 6550 case IceType_i16: |
6550 case IceType_i32: | 6551 case IceType_i32: |
6551 case IceType_i64: | 6552 case IceType_i64: |
6552 // Conservatively do "mov reg, 0" to avoid modifying FLAGS. | 6553 // Conservatively do "mov reg, 0" to avoid modifying FLAGS. |
6553 _mov(Reg, Ctx->getConstantZero(Ty)); | 6554 _mov(Reg, Ctx->getConstantZero(Ty)); |
6554 break; | 6555 break; |
(...skipping 14 matching lines...) Expand all Loading... | |
6569 | 6570 |
6570 // There is no support for loading or emitting vector constants, so the vector | 6571 // There is no support for loading or emitting vector constants, so the vector |
6571 // values returned from makeVectorOfZeros, makeVectorOfOnes, etc. are | 6572 // values returned from makeVectorOfZeros, makeVectorOfOnes, etc. are |
6572 // initialized with register operations. | 6573 // initialized with register operations. |
6573 // | 6574 // |
6574 // TODO(wala): Add limited support for vector constants so that complex | 6575 // TODO(wala): Add limited support for vector constants so that complex |
6575 // initialization in registers is unnecessary. | 6576 // initialization in registers is unnecessary. |
6576 | 6577 |
6577 template <typename TraitsType> | 6578 template <typename TraitsType> |
6578 Variable *TargetX86Base<TraitsType>::makeVectorOfZeros(Type Ty, | 6579 Variable *TargetX86Base<TraitsType>::makeVectorOfZeros(Type Ty, |
6579 int32_t RegNum) { | 6580 RegNumT RegNum) { |
6580 return makeZeroedRegister(Ty, RegNum); | 6581 return makeZeroedRegister(Ty, RegNum); |
6581 } | 6582 } |
6582 | 6583 |
6583 template <typename TraitsType> | 6584 template <typename TraitsType> |
6584 Variable *TargetX86Base<TraitsType>::makeVectorOfMinusOnes(Type Ty, | 6585 Variable *TargetX86Base<TraitsType>::makeVectorOfMinusOnes(Type Ty, |
6585 int32_t RegNum) { | 6586 RegNumT RegNum) { |
6586 Variable *MinusOnes = makeReg(Ty, RegNum); | 6587 Variable *MinusOnes = makeReg(Ty, RegNum); |
6587 // Insert a FakeDef so the live range of MinusOnes is not overestimated. | 6588 // Insert a FakeDef so the live range of MinusOnes is not overestimated. |
6588 Context.insert<InstFakeDef>(MinusOnes); | 6589 Context.insert<InstFakeDef>(MinusOnes); |
6589 if (Ty == IceType_f64) | 6590 if (Ty == IceType_f64) |
6590 // Making a vector of minus ones of type f64 is currently only used for the | 6591 // Making a vector of minus ones of type f64 is currently only used for the |
6591 // fabs intrinsic. To use the f64 type to create this mask with pcmpeqq | 6592 // fabs intrinsic. To use the f64 type to create this mask with pcmpeqq |
6592 // requires SSE 4.1. Since we're just creating a mask, pcmpeqd does the | 6593 // requires SSE 4.1. Since we're just creating a mask, pcmpeqd does the |
6593 // same job and only requires SSE2. | 6594 // same job and only requires SSE2. |
6594 _pcmpeq(MinusOnes, MinusOnes, IceType_f32); | 6595 _pcmpeq(MinusOnes, MinusOnes, IceType_f32); |
6595 else | 6596 else |
6596 _pcmpeq(MinusOnes, MinusOnes); | 6597 _pcmpeq(MinusOnes, MinusOnes); |
6597 return MinusOnes; | 6598 return MinusOnes; |
6598 } | 6599 } |
6599 | 6600 |
6600 template <typename TraitsType> | 6601 template <typename TraitsType> |
6601 Variable *TargetX86Base<TraitsType>::makeVectorOfOnes(Type Ty, int32_t RegNum) { | 6602 Variable *TargetX86Base<TraitsType>::makeVectorOfOnes(Type Ty, RegNumT RegNum) { |
6602 Variable *Dest = makeVectorOfZeros(Ty, RegNum); | 6603 Variable *Dest = makeVectorOfZeros(Ty, RegNum); |
6603 Variable *MinusOne = makeVectorOfMinusOnes(Ty); | 6604 Variable *MinusOne = makeVectorOfMinusOnes(Ty); |
6604 _psub(Dest, MinusOne); | 6605 _psub(Dest, MinusOne); |
6605 return Dest; | 6606 return Dest; |
6606 } | 6607 } |
6607 | 6608 |
6608 template <typename TraitsType> | 6609 template <typename TraitsType> |
6609 Variable *TargetX86Base<TraitsType>::makeVectorOfHighOrderBits(Type Ty, | 6610 Variable *TargetX86Base<TraitsType>::makeVectorOfHighOrderBits(Type Ty, |
6610 int32_t RegNum) { | 6611 RegNumT RegNum) { |
6611 assert(Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v8i16 || | 6612 assert(Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v8i16 || |
6612 Ty == IceType_v16i8); | 6613 Ty == IceType_v16i8); |
6613 if (Ty == IceType_v4f32 || Ty == IceType_v4i32 || Ty == IceType_v8i16) { | 6614 if (Ty == IceType_v4f32 || Ty == IceType_v4i32 || Ty == IceType_v8i16) { |
6614 Variable *Reg = makeVectorOfOnes(Ty, RegNum); | 6615 Variable *Reg = makeVectorOfOnes(Ty, RegNum); |
6615 SizeT Shift = | 6616 SizeT Shift = |
6616 typeWidthInBytes(typeElementType(Ty)) * Traits::X86_CHAR_BIT - 1; | 6617 typeWidthInBytes(typeElementType(Ty)) * Traits::X86_CHAR_BIT - 1; |
6617 _psll(Reg, Ctx->getConstantInt8(Shift)); | 6618 _psll(Reg, Ctx->getConstantInt8(Shift)); |
6618 return Reg; | 6619 return Reg; |
6619 } else { | 6620 } else { |
6620 // SSE has no left shift operation for vectors of 8 bit integers. | 6621 // SSE has no left shift operation for vectors of 8 bit integers. |
6621 constexpr uint32_t HIGH_ORDER_BITS_MASK = 0x80808080; | 6622 constexpr uint32_t HIGH_ORDER_BITS_MASK = 0x80808080; |
6622 Constant *ConstantMask = Ctx->getConstantInt32(HIGH_ORDER_BITS_MASK); | 6623 Constant *ConstantMask = Ctx->getConstantInt32(HIGH_ORDER_BITS_MASK); |
6623 Variable *Reg = makeReg(Ty, RegNum); | 6624 Variable *Reg = makeReg(Ty, RegNum); |
6624 _movd(Reg, legalize(ConstantMask, Legal_Reg | Legal_Mem)); | 6625 _movd(Reg, legalize(ConstantMask, Legal_Reg | Legal_Mem)); |
6625 _pshufd(Reg, Reg, Ctx->getConstantZero(IceType_i8)); | 6626 _pshufd(Reg, Reg, Ctx->getConstantZero(IceType_i8)); |
6626 return Reg; | 6627 return Reg; |
6627 } | 6628 } |
6628 } | 6629 } |
6629 | 6630 |
6630 /// Construct a mask in a register that can be and'ed with a floating-point | 6631 /// Construct a mask in a register that can be and'ed with a floating-point |
6631 /// value to mask off its sign bit. The value will be <4 x 0x7fffffff> for f32 | 6632 /// value to mask off its sign bit. The value will be <4 x 0x7fffffff> for f32 |
6632 /// and v4f32, and <2 x 0x7fffffffffffffff> for f64. Construct it as vector of | 6633 /// and v4f32, and <2 x 0x7fffffffffffffff> for f64. Construct it as vector of |
6633 /// ones logically right shifted one bit. | 6634 /// ones logically right shifted one bit. |
6634 // TODO(stichnot): Fix the wala | 6635 // TODO(stichnot): Fix the wala |
6635 // TODO: above, to represent vector constants in memory. | 6636 // TODO: above, to represent vector constants in memory. |
6636 template <typename TraitsType> | 6637 template <typename TraitsType> |
6637 Variable *TargetX86Base<TraitsType>::makeVectorOfFabsMask(Type Ty, | 6638 Variable *TargetX86Base<TraitsType>::makeVectorOfFabsMask(Type Ty, |
6638 int32_t RegNum) { | 6639 RegNumT RegNum) { |
6639 Variable *Reg = makeVectorOfMinusOnes(Ty, RegNum); | 6640 Variable *Reg = makeVectorOfMinusOnes(Ty, RegNum); |
6640 _psrl(Reg, Ctx->getConstantInt8(1)); | 6641 _psrl(Reg, Ctx->getConstantInt8(1)); |
6641 return Reg; | 6642 return Reg; |
6642 } | 6643 } |
6643 | 6644 |
6644 template <typename TraitsType> | 6645 template <typename TraitsType> |
6645 typename TargetX86Base<TraitsType>::X86OperandMem * | 6646 typename TargetX86Base<TraitsType>::X86OperandMem * |
6646 TargetX86Base<TraitsType>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot, | 6647 TargetX86Base<TraitsType>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot, |
6647 uint32_t Offset) { | 6648 uint32_t Offset) { |
6648 // Ensure that Loc is a stack slot. | 6649 // Ensure that Loc is a stack slot. |
6649 assert(Slot->mustNotHaveReg()); | 6650 assert(Slot->mustNotHaveReg()); |
6650 assert(Slot->getRegNum() == Variable::NoRegister); | 6651 assert(Slot->getRegNum() == RegNumT::NoRegister); |
6651 // Compute the location of Loc in memory. | 6652 // Compute the location of Loc in memory. |
6652 // TODO(wala,stichnot): lea should not | 6653 // TODO(wala,stichnot): lea should not |
6653 // be required. The address of the stack slot is known at compile time | 6654 // be required. The address of the stack slot is known at compile time |
6654 // (although not until after addProlog()). | 6655 // (although not until after addProlog()). |
6655 constexpr Type PointerType = IceType_i32; | 6656 constexpr Type PointerType = IceType_i32; |
6656 Variable *Loc = makeReg(PointerType); | 6657 Variable *Loc = makeReg(PointerType); |
6657 _lea(Loc, Slot); | 6658 _lea(Loc, Slot); |
6658 Constant *ConstantOffset = Ctx->getConstantInt32(Offset); | 6659 Constant *ConstantOffset = Ctx->getConstantInt32(Offset); |
6659 return X86OperandMem::create(Func, Ty, Loc, ConstantOffset); | 6660 return X86OperandMem::create(Func, Ty, Loc, ConstantOffset); |
6660 } | 6661 } |
(...skipping 20 matching lines...) Expand all Loading... | |
6681 /// | 6682 /// |
6682 /// Note #2. ConstantRelocatable operands are also put through this process | 6683 /// Note #2. ConstantRelocatable operands are also put through this process |
6683 /// (not truncated directly) because our ELF emitter does R_386_32 relocations | 6684 /// (not truncated directly) because our ELF emitter does R_386_32 relocations |
6684 /// but not R_386_8 relocations. | 6685 /// but not R_386_8 relocations. |
6685 /// | 6686 /// |
6686 /// Note #3. If Src is a Variable, the result will be an infinite-weight i8 | 6687 /// Note #3. If Src is a Variable, the result will be an infinite-weight i8 |
6687 /// Variable with the RCX86_IsTrunc8Rcvr register class. As such, this helper | 6688 /// Variable with the RCX86_IsTrunc8Rcvr register class. As such, this helper |
6688 /// is a convenient way to prevent ah/bh/ch/dh from being an (invalid) argument | 6689 /// is a convenient way to prevent ah/bh/ch/dh from being an (invalid) argument |
6689 /// to the pinsrb instruction. | 6690 /// to the pinsrb instruction. |
6690 template <typename TraitsType> | 6691 template <typename TraitsType> |
6691 Variable *TargetX86Base<TraitsType>::copyToReg8(Operand *Src, int32_t RegNum) { | 6692 Variable *TargetX86Base<TraitsType>::copyToReg8(Operand *Src, RegNumT RegNum) { |
6692 Type Ty = Src->getType(); | 6693 Type Ty = Src->getType(); |
6693 assert(isScalarIntegerType(Ty)); | 6694 assert(isScalarIntegerType(Ty)); |
6694 assert(Ty != IceType_i1); | 6695 assert(Ty != IceType_i1); |
6695 Variable *Reg = makeReg(IceType_i8, RegNum); | 6696 Variable *Reg = makeReg(IceType_i8, RegNum); |
6696 Reg->setRegClass(RCX86_IsTrunc8Rcvr); | 6697 Reg->setRegClass(RCX86_IsTrunc8Rcvr); |
6697 if (llvm::isa<Variable>(Src) || llvm::isa<ConstantRelocatable>(Src)) { | 6698 if (llvm::isa<Variable>(Src) || llvm::isa<ConstantRelocatable>(Src)) { |
6698 Variable *SrcTruncable = makeReg(Ty); | 6699 Variable *SrcTruncable = makeReg(Ty); |
6699 switch (Ty) { | 6700 switch (Ty) { |
6700 case IceType_i64: | 6701 case IceType_i64: |
6701 SrcTruncable->setRegClass(RCX86_Is64To8); | 6702 SrcTruncable->setRegClass(RCX86_Is64To8); |
(...skipping 14 matching lines...) Expand all Loading... | |
6716 _mov(SrcRcvr, SrcTruncable); | 6717 _mov(SrcRcvr, SrcTruncable); |
6717 Src = SrcRcvr; | 6718 Src = SrcRcvr; |
6718 } | 6719 } |
6719 _mov(Reg, Src); | 6720 _mov(Reg, Src); |
6720 return Reg; | 6721 return Reg; |
6721 } | 6722 } |
6722 | 6723 |
6723 /// Helper for legalize() to emit the right code to lower an operand to a | 6724 /// Helper for legalize() to emit the right code to lower an operand to a |
6724 /// register of the appropriate type. | 6725 /// register of the appropriate type. |
6725 template <typename TraitsType> | 6726 template <typename TraitsType> |
6726 Variable *TargetX86Base<TraitsType>::copyToReg(Operand *Src, int32_t RegNum) { | 6727 Variable *TargetX86Base<TraitsType>::copyToReg(Operand *Src, RegNumT RegNum) { |
6727 Type Ty = Src->getType(); | 6728 Type Ty = Src->getType(); |
6728 Variable *Reg = makeReg(Ty, RegNum); | 6729 Variable *Reg = makeReg(Ty, RegNum); |
6729 if (isVectorType(Ty)) { | 6730 if (isVectorType(Ty)) { |
6730 _movp(Reg, Src); | 6731 _movp(Reg, Src); |
6731 } else { | 6732 } else { |
6732 _mov(Reg, Src); | 6733 _mov(Reg, Src); |
6733 } | 6734 } |
6734 return Reg; | 6735 return Reg; |
6735 } | 6736 } |
6736 | 6737 |
6737 template <typename TraitsType> | 6738 template <typename TraitsType> |
6738 Operand *TargetX86Base<TraitsType>::legalize(Operand *From, LegalMask Allowed, | 6739 Operand *TargetX86Base<TraitsType>::legalize(Operand *From, LegalMask Allowed, |
6739 int32_t RegNum) { | 6740 RegNumT RegNum) { |
6740 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); | 6741 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); |
6741 const Type Ty = From->getType(); | 6742 const Type Ty = From->getType(); |
6742 // Assert that a physical register is allowed. To date, all calls to | 6743 // Assert that a physical register is allowed. To date, all calls to |
6743 // legalize() allow a physical register. If a physical register needs to be | 6744 // legalize() allow a physical register. If a physical register needs to be |
6744 // explicitly disallowed, then new code will need to be written to force a | 6745 // explicitly disallowed, then new code will need to be written to force a |
6745 // spill. | 6746 // spill. |
6746 assert(Allowed & Legal_Reg); | 6747 assert(Allowed & Legal_Reg); |
6747 // If we're asking for a specific physical register, make sure we're not | 6748 // If we're asking for a specific physical register, make sure we're not |
6748 // allowing any other operand kinds. (This could be future work, e.g. allow | 6749 // allowing any other operand kinds. (This could be future work, e.g. allow |
6749 // the shl shift amount to be either an immediate or in ecx.) | 6750 // the shl shift amount to be either an immediate or in ecx.) |
6750 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); | 6751 assert(RegNum == RegNumT::NoRegister || Allowed == Legal_Reg); |
6751 | 6752 |
6752 // Substitute with an available infinite-weight variable if possible. Only do | 6753 // Substitute with an available infinite-weight variable if possible. Only do |
6753 // this when we are not asking for a specific register, and when the | 6754 // this when we are not asking for a specific register, and when the |
6754 // substitution is not locked to a specific register, and when the types | 6755 // substitution is not locked to a specific register, and when the types |
6755 // match, in order to capture the vast majority of opportunities and avoid | 6756 // match, in order to capture the vast majority of opportunities and avoid |
6756 // corner cases in the lowering. | 6757 // corner cases in the lowering. |
6757 if (RegNum == Variable::NoRegister) { | 6758 if (RegNum == RegNumT::NoRegister) { |
6758 if (Variable *Subst = getContext().availabilityGet(From)) { | 6759 if (Variable *Subst = getContext().availabilityGet(From)) { |
6759 // At this point we know there is a potential substitution available. | 6760 // At this point we know there is a potential substitution available. |
6760 if (Subst->mustHaveReg() && !Subst->hasReg()) { | 6761 if (Subst->mustHaveReg() && !Subst->hasReg()) { |
6761 // At this point we know the substitution will have a register. | 6762 // At this point we know the substitution will have a register. |
6762 if (From->getType() == Subst->getType()) { | 6763 if (From->getType() == Subst->getType()) { |
6763 // At this point we know the substitution's register is compatible. | 6764 // At this point we know the substitution's register is compatible. |
6764 return Subst; | 6765 return Subst; |
6765 } | 6766 } |
6766 } | 6767 } |
6767 } | 6768 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6808 return From; | 6809 return From; |
6809 Const = llvm::cast<Constant>(From); | 6810 Const = llvm::cast<Constant>(From); |
6810 } | 6811 } |
6811 // There should be no constants of vector type (other than undef). | 6812 // There should be no constants of vector type (other than undef). |
6812 assert(!isVectorType(Ty)); | 6813 assert(!isVectorType(Ty)); |
6813 | 6814 |
6814 // If the operand is a 64 bit constant integer we need to legalize it to a | 6815 // If the operand is a 64 bit constant integer we need to legalize it to a |
6815 // register in x86-64. | 6816 // register in x86-64. |
6816 if (Traits::Is64Bit) { | 6817 if (Traits::Is64Bit) { |
6817 if (llvm::isa<ConstantInteger64>(Const)) { | 6818 if (llvm::isa<ConstantInteger64>(Const)) { |
6818 if (RegNum != Variable::NoRegister) { | 6819 if (RegNum != RegNumT::NoRegister) { |
6819 assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum); | 6820 assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum); |
6820 } | 6821 } |
6821 return copyToReg(Const, RegNum); | 6822 return copyToReg(Const, RegNum); |
6822 } | 6823 } |
6823 } | 6824 } |
6824 | 6825 |
6825 // If the operand is an 32 bit constant integer, we should check whether we | 6826 // If the operand is an 32 bit constant integer, we should check whether we |
6826 // need to randomize it or pool it. | 6827 // need to randomize it or pool it. |
6827 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) { | 6828 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) { |
6828 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); | 6829 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6891 if (MustRematerialize) { | 6892 if (MustRematerialize) { |
6892 assert(Ty == IceType_i32); | 6893 assert(Ty == IceType_i32); |
6893 Variable *NewVar = makeReg(Ty, RegNum); | 6894 Variable *NewVar = makeReg(Ty, RegNum); |
6894 // Since Var is rematerializable, the offset will be added when the lea is | 6895 // Since Var is rematerializable, the offset will be added when the lea is |
6895 // emitted. | 6896 // emitted. |
6896 constexpr Constant *NoOffset = nullptr; | 6897 constexpr Constant *NoOffset = nullptr; |
6897 auto *Mem = X86OperandMem::create(Func, Ty, Var, NoOffset); | 6898 auto *Mem = X86OperandMem::create(Func, Ty, Var, NoOffset); |
6898 _lea(NewVar, Mem); | 6899 _lea(NewVar, Mem); |
6899 From = NewVar; | 6900 From = NewVar; |
6900 } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 6901 } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
6901 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { | 6902 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) { |
6902 From = copyToReg(From, RegNum); | 6903 From = copyToReg(From, RegNum); |
6903 } | 6904 } |
6904 return From; | 6905 return From; |
6905 } | 6906 } |
6906 | 6907 |
6907 llvm::report_fatal_error("Unhandled operand kind in legalize()"); | 6908 llvm::report_fatal_error("Unhandled operand kind in legalize()"); |
6908 return From; | 6909 return From; |
6909 } | 6910 } |
6910 | 6911 |
6911 /// Provide a trivial wrapper to legalize() for this common usage. | 6912 /// Provide a trivial wrapper to legalize() for this common usage. |
6912 template <typename TraitsType> | 6913 template <typename TraitsType> |
6913 Variable *TargetX86Base<TraitsType>::legalizeToReg(Operand *From, | 6914 Variable *TargetX86Base<TraitsType>::legalizeToReg(Operand *From, |
6914 int32_t RegNum) { | 6915 RegNumT RegNum) { |
6915 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); | 6916 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); |
6916 } | 6917 } |
6917 | 6918 |
6918 /// Legalize undef values to concrete values. | 6919 /// Legalize undef values to concrete values. |
6919 template <typename TraitsType> | 6920 template <typename TraitsType> |
6920 Operand *TargetX86Base<TraitsType>::legalizeUndef(Operand *From, | 6921 Operand *TargetX86Base<TraitsType>::legalizeUndef(Operand *From, |
6921 int32_t RegNum) { | 6922 RegNumT RegNum) { |
6922 Type Ty = From->getType(); | 6923 Type Ty = From->getType(); |
6923 if (llvm::isa<ConstantUndef>(From)) { | 6924 if (llvm::isa<ConstantUndef>(From)) { |
6924 // Lower undefs to zero. Another option is to lower undefs to an | 6925 // Lower undefs to zero. Another option is to lower undefs to an |
6925 // uninitialized register; however, using an uninitialized register results | 6926 // uninitialized register; however, using an uninitialized register results |
6926 // in less predictable code. | 6927 // in less predictable code. |
6927 // | 6928 // |
6928 // If in the future the implementation is changed to lower undef values to | 6929 // If in the future the implementation is changed to lower undef values to |
6929 // uninitialized registers, a FakeDef will be needed: | 6930 // uninitialized registers, a FakeDef will be needed: |
6930 // Context.insert<InstFakeDef>(Reg); | 6931 // Context.insert<InstFakeDef>(Reg); |
6931 // This is in order to ensure that the live range of Reg is not | 6932 // 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 Loading... | |
6990 // assert that PIC legalization has been applied. | 6991 // assert that PIC legalization has been applied. |
6991 Mem = X86OperandMem::create(Func, Ty, Base, Offset); | 6992 Mem = X86OperandMem::create(Func, Ty, Base, Offset); |
6992 } | 6993 } |
6993 // Do legalization, which contains randomization/pooling or do | 6994 // Do legalization, which contains randomization/pooling or do |
6994 // randomization/pooling. | 6995 // randomization/pooling. |
6995 return llvm::cast<X86OperandMem>(DoLegalize ? legalize(Mem) | 6996 return llvm::cast<X86OperandMem>(DoLegalize ? legalize(Mem) |
6996 : randomizeOrPoolImmediate(Mem)); | 6997 : randomizeOrPoolImmediate(Mem)); |
6997 } | 6998 } |
6998 | 6999 |
6999 template <typename TraitsType> | 7000 template <typename TraitsType> |
7000 Variable *TargetX86Base<TraitsType>::makeReg(Type Type, int32_t RegNum) { | 7001 Variable *TargetX86Base<TraitsType>::makeReg(Type Type, RegNumT RegNum) { |
7001 // There aren't any 64-bit integer registers for x86-32. | 7002 // There aren't any 64-bit integer registers for x86-32. |
7002 assert(Traits::Is64Bit || Type != IceType_i64); | 7003 assert(Traits::Is64Bit || Type != IceType_i64); |
7003 Variable *Reg = Func->makeVariable(Type); | 7004 Variable *Reg = Func->makeVariable(Type); |
7004 if (RegNum == Variable::NoRegister) | 7005 if (RegNum == RegNumT::NoRegister) |
7005 Reg->setMustHaveReg(); | 7006 Reg->setMustHaveReg(); |
7006 else | 7007 else |
7007 Reg->setRegNum(RegNum); | 7008 Reg->setRegNum(RegNum); |
7008 return Reg; | 7009 return Reg; |
7009 } | 7010 } |
7010 | 7011 |
7011 template <typename TraitsType> | 7012 template <typename TraitsType> |
7012 const Type TargetX86Base<TraitsType>::TypeForSize[] = { | 7013 const Type TargetX86Base<TraitsType>::TypeForSize[] = { |
7013 IceType_i8, IceType_i16, IceType_i32, IceType_f64, IceType_v16i8}; | 7014 IceType_i8, IceType_i16, IceType_i32, IceType_f64, IceType_v16i8}; |
7014 template <typename TraitsType> | 7015 template <typename TraitsType> |
(...skipping 22 matching lines...) Expand all Loading... | |
7037 | 7038 |
7038 template <typename TraitsType> void TargetX86Base<TraitsType>::postLower() { | 7039 template <typename TraitsType> void TargetX86Base<TraitsType>::postLower() { |
7039 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 7040 if (Ctx->getFlags().getOptLevel() == Opt_m1) |
7040 return; | 7041 return; |
7041 markRedefinitions(); | 7042 markRedefinitions(); |
7042 Context.availabilityUpdate(); | 7043 Context.availabilityUpdate(); |
7043 } | 7044 } |
7044 | 7045 |
7045 template <typename TraitsType> | 7046 template <typename TraitsType> |
7046 void TargetX86Base<TraitsType>::makeRandomRegisterPermutation( | 7047 void TargetX86Base<TraitsType>::makeRandomRegisterPermutation( |
7047 llvm::SmallVectorImpl<int32_t> &Permutation, | 7048 llvm::SmallVectorImpl<RegNumT> &Permutation, |
7048 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { | 7049 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { |
7049 Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation, | 7050 Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation, |
7050 ExcludeRegisters, Salt); | 7051 ExcludeRegisters, Salt); |
7051 } | 7052 } |
7052 | 7053 |
7053 template <typename TraitsType> | 7054 template <typename TraitsType> |
7054 void TargetX86Base<TraitsType>::emit(const ConstantInteger32 *C) const { | 7055 void TargetX86Base<TraitsType>::emit(const ConstantInteger32 *C) const { |
7055 if (!BuildDefs::dump()) | 7056 if (!BuildDefs::dump()) |
7056 return; | 7057 return; |
7057 Ostream &Str = Ctx->getStrEmit(); | 7058 Ostream &Str = Ctx->getStrEmit(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7098 assert(!Ctx->getFlags().getUseNonsfi() || C->getName() == GlobalOffsetTable); | 7099 assert(!Ctx->getFlags().getUseNonsfi() || C->getName() == GlobalOffsetTable); |
7099 Ostream &Str = Ctx->getStrEmit(); | 7100 Ostream &Str = Ctx->getStrEmit(); |
7100 Str << "$"; | 7101 Str << "$"; |
7101 emitWithoutPrefix(C); | 7102 emitWithoutPrefix(C); |
7102 } | 7103 } |
7103 | 7104 |
7104 /// Randomize or pool an Immediate. | 7105 /// Randomize or pool an Immediate. |
7105 template <typename TraitsType> | 7106 template <typename TraitsType> |
7106 Operand * | 7107 Operand * |
7107 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(Constant *Immediate, | 7108 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(Constant *Immediate, |
7108 int32_t RegNum) { | 7109 RegNumT RegNum) { |
7109 assert(llvm::isa<ConstantInteger32>(Immediate) || | 7110 assert(llvm::isa<ConstantInteger32>(Immediate) || |
7110 llvm::isa<ConstantRelocatable>(Immediate)); | 7111 llvm::isa<ConstantRelocatable>(Immediate)); |
7111 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || | 7112 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || |
7112 RandomizationPoolingPaused == true) { | 7113 RandomizationPoolingPaused == true) { |
7113 // Immediates randomization/pooling off or paused | 7114 // Immediates randomization/pooling off or paused |
7114 return Immediate; | 7115 return Immediate; |
7115 } | 7116 } |
7116 | 7117 |
7117 if (Traits::Is64Bit && NeedSandboxing) { | 7118 if (Traits::Is64Bit && NeedSandboxing) { |
7118 // Immediate randomization/pooling is currently disabled for x86-64 | 7119 // Immediate randomization/pooling is currently disabled for x86-64 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7183 X86OperandMem::create(Func, Immediate->getType(), NoBase, Symbol); | 7184 X86OperandMem::create(Func, Immediate->getType(), NoBase, Symbol); |
7184 _mov(Reg, MemOperand); | 7185 _mov(Reg, MemOperand); |
7185 return Reg; | 7186 return Reg; |
7186 } | 7187 } |
7187 } | 7188 } |
7188 } | 7189 } |
7189 | 7190 |
7190 template <typename TraitsType> | 7191 template <typename TraitsType> |
7191 typename TargetX86Base<TraitsType>::X86OperandMem * | 7192 typename TargetX86Base<TraitsType>::X86OperandMem * |
7192 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(X86OperandMem *MemOperand, | 7193 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(X86OperandMem *MemOperand, |
7193 int32_t RegNum) { | 7194 RegNumT RegNum) { |
7194 assert(MemOperand); | 7195 assert(MemOperand); |
7195 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || | 7196 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || |
7196 RandomizationPoolingPaused == true) { | 7197 RandomizationPoolingPaused == true) { |
7197 // immediates randomization/pooling is turned off | 7198 // immediates randomization/pooling is turned off |
7198 return MemOperand; | 7199 return MemOperand; |
7199 } | 7200 } |
7200 | 7201 |
7201 if (Traits::Is64Bit && NeedSandboxing) { | 7202 if (Traits::Is64Bit && NeedSandboxing) { |
7202 // Immediate randomization/pooling is currently disabled for x86-64 | 7203 // Immediate randomization/pooling is currently disabled for x86-64 |
7203 // sandboxing for it could generate invalid memory operands. | 7204 // sandboxing for it could generate invalid memory operands. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7268 // TO: | 7269 // TO: |
7269 // insert: mov $label, RegTemp | 7270 // insert: mov $label, RegTemp |
7270 // insert: lea [base, RegTemp], RegTemp | 7271 // insert: lea [base, RegTemp], RegTemp |
7271 // =>[RegTemp, index, shift] | 7272 // =>[RegTemp, index, shift] |
7272 | 7273 |
7273 // Memory operand should never exist as source operands in phi lowering | 7274 // Memory operand should never exist as source operands in phi lowering |
7274 // assignments, so there is no need to reuse any registers here. For | 7275 // assignments, so there is no need to reuse any registers here. For |
7275 // phi lowering, we should not ask for new physical registers in | 7276 // phi lowering, we should not ask for new physical registers in |
7276 // general. However, if we do meet Memory Operand during phi lowering, | 7277 // general. However, if we do meet Memory Operand during phi lowering, |
7277 // we should not blind or pool the immediates for now. | 7278 // we should not blind or pool the immediates for now. |
7278 if (RegNum != Variable::NoRegister) | 7279 if (RegNum != RegNumT::NoRegister) |
7279 return MemOperand; | 7280 return MemOperand; |
7280 Variable *RegTemp = makeReg(IceType_i32); | 7281 Variable *RegTemp = makeReg(IceType_i32); |
7281 IceString Label; | 7282 IceString Label; |
7282 llvm::raw_string_ostream Label_stream(Label); | 7283 llvm::raw_string_ostream Label_stream(Label); |
7283 MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx); | 7284 MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx); |
7284 MemOperand->getOffset()->setShouldBePooled(true); | 7285 MemOperand->getOffset()->setShouldBePooled(true); |
7285 constexpr RelocOffsetT SymOffset = 0; | 7286 constexpr RelocOffsetT SymOffset = 0; |
7286 constexpr bool SuppressMangling = true; | 7287 constexpr bool SuppressMangling = true; |
7287 Constant *Symbol = | 7288 Constant *Symbol = |
7288 Ctx->getConstantSym(SymOffset, Label_stream.str(), SuppressMangling); | 7289 Ctx->getConstantSym(SymOffset, Label_stream.str(), SuppressMangling); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7453 emitGlobal(*Var, SectionSuffix); | 7454 emitGlobal(*Var, SectionSuffix); |
7454 } | 7455 } |
7455 } | 7456 } |
7456 } break; | 7457 } break; |
7457 } | 7458 } |
7458 } | 7459 } |
7459 } // end of namespace X86NAMESPACE | 7460 } // end of namespace X86NAMESPACE |
7460 } // end of namespace Ice | 7461 } // end of namespace Ice |
7461 | 7462 |
7462 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 7463 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |