| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 const uint32_t X86_STACK_ALIGNMENT_BYTES = 16; | 131 const uint32_t X86_STACK_ALIGNMENT_BYTES = 16; |
| 132 // Size of the return address on the stack | 132 // Size of the return address on the stack |
| 133 const uint32_t X86_RET_IP_SIZE_BYTES = 4; | 133 const uint32_t X86_RET_IP_SIZE_BYTES = 4; |
| 134 // The base 2 logarithm of the width in bytes of the smallest stack slot | 134 // The base 2 logarithm of the width in bytes of the smallest stack slot |
| 135 const uint32_t X86_LOG2_OF_MIN_STACK_SLOT_SIZE = 2; | 135 const uint32_t X86_LOG2_OF_MIN_STACK_SLOT_SIZE = 2; |
| 136 // The base 2 logarithm of the width in bytes of the largest stack slot | 136 // The base 2 logarithm of the width in bytes of the largest stack slot |
| 137 const uint32_t X86_LOG2_OF_MAX_STACK_SLOT_SIZE = 4; | 137 const uint32_t X86_LOG2_OF_MAX_STACK_SLOT_SIZE = 4; |
| 138 // The number of different NOP instructions | 138 // The number of different NOP instructions |
| 139 const uint32_t X86_NUM_NOP_VARIANTS = 5; | 139 const uint32_t X86_NUM_NOP_VARIANTS = 5; |
| 140 | 140 |
| 141 // Value and Alignment are in bytes. Return Value adjusted to the next | |
| 142 // highest multiple of Alignment. | |
| 143 uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) { | |
| 144 // power of 2 | |
| 145 assert((Alignment & (Alignment - 1)) == 0); | |
| 146 return (Value + Alignment - 1) & -Alignment; | |
| 147 } | |
| 148 | |
| 149 // Value is in bytes. Return Value adjusted to the next highest multiple | 141 // Value is in bytes. Return Value adjusted to the next highest multiple |
| 150 // of the stack alignment. | 142 // of the stack alignment. |
| 151 uint32_t applyStackAlignment(uint32_t Value) { | 143 uint32_t applyStackAlignment(uint32_t Value) { |
| 152 return applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES); | 144 return Utils::applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES); |
| 153 } | 145 } |
| 154 | 146 |
| 155 // In some cases, there are x-macros tables for both high-level and | 147 // In some cases, there are x-macros tables for both high-level and |
| 156 // low-level instructions/operands that use the same enum key value. | 148 // low-level instructions/operands that use the same enum key value. |
| 157 // The tables are kept separate to maintain a proper separation | 149 // The tables are kept separate to maintain a proper separation |
| 158 // between abstraction layers. There is a risk that the tables could | 150 // between abstraction layers. There is a risk that the tables could |
| 159 // get out of sync if enum values are reordered or if entries are | 151 // get out of sync if enum values are reordered or if entries are |
| 160 // added or deleted. The following dummy namespaces use | 152 // added or deleted. The following dummy namespaces use |
| 161 // static_asserts to ensure everything is kept in sync. | 153 // static_asserts to ensure everything is kept in sync. |
| 162 | 154 |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 } | 942 } |
| 951 | 943 |
| 952 // Align the variables area. SpillAreaPaddingBytes is the size of | 944 // Align the variables area. SpillAreaPaddingBytes is the size of |
| 953 // the region after the preserved registers and before the spill | 945 // the region after the preserved registers and before the spill |
| 954 // areas. | 946 // areas. |
| 955 uint32_t SpillAreaPaddingBytes = 0; | 947 uint32_t SpillAreaPaddingBytes = 0; |
| 956 if (SpillAreaAlignmentBytes) { | 948 if (SpillAreaAlignmentBytes) { |
| 957 assert(SpillAreaAlignmentBytes <= X86_STACK_ALIGNMENT_BYTES); | 949 assert(SpillAreaAlignmentBytes <= X86_STACK_ALIGNMENT_BYTES); |
| 958 uint32_t PaddingStart = X86_RET_IP_SIZE_BYTES + PreservedRegsSizeBytes; | 950 uint32_t PaddingStart = X86_RET_IP_SIZE_BYTES + PreservedRegsSizeBytes; |
| 959 uint32_t SpillAreaStart = | 951 uint32_t SpillAreaStart = |
| 960 applyAlignment(PaddingStart, SpillAreaAlignmentBytes); | 952 Utils::applyAlignment(PaddingStart, SpillAreaAlignmentBytes); |
| 961 SpillAreaPaddingBytes = SpillAreaStart - PaddingStart; | 953 SpillAreaPaddingBytes = SpillAreaStart - PaddingStart; |
| 962 SpillAreaSizeBytes += SpillAreaPaddingBytes; | 954 SpillAreaSizeBytes += SpillAreaPaddingBytes; |
| 963 } | 955 } |
| 964 | 956 |
| 965 // If there are separate globals and locals areas, make sure the | 957 // If there are separate globals and locals areas, make sure the |
| 966 // locals area is aligned by padding the end of the globals area. | 958 // locals area is aligned by padding the end of the globals area. |
| 967 uint32_t GlobalsAndSubsequentPaddingSize = GlobalsSize; | 959 uint32_t GlobalsAndSubsequentPaddingSize = GlobalsSize; |
| 968 if (LocalsSlotsAlignmentBytes) { | 960 if (LocalsSlotsAlignmentBytes) { |
| 969 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes); | 961 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes); |
| 970 GlobalsAndSubsequentPaddingSize = | 962 GlobalsAndSubsequentPaddingSize = |
| 971 applyAlignment(GlobalsSize, LocalsSlotsAlignmentBytes); | 963 Utils::applyAlignment(GlobalsSize, LocalsSlotsAlignmentBytes); |
| 972 SpillAreaSizeBytes += GlobalsAndSubsequentPaddingSize - GlobalsSize; | 964 SpillAreaSizeBytes += GlobalsAndSubsequentPaddingSize - GlobalsSize; |
| 973 } | 965 } |
| 974 | 966 |
| 975 // Align esp if necessary. | 967 // Align esp if necessary. |
| 976 if (NeedsStackAlignment) { | 968 if (NeedsStackAlignment) { |
| 977 uint32_t StackOffset = X86_RET_IP_SIZE_BYTES + PreservedRegsSizeBytes; | 969 uint32_t StackOffset = X86_RET_IP_SIZE_BYTES + PreservedRegsSizeBytes; |
| 978 uint32_t StackSize = applyStackAlignment(StackOffset + SpillAreaSizeBytes); | 970 uint32_t StackSize = applyStackAlignment(StackOffset + SpillAreaSizeBytes); |
| 979 SpillAreaSizeBytes = StackSize - StackOffset; | 971 SpillAreaSizeBytes = StackSize - StackOffset; |
| 980 } | 972 } |
| 981 | 973 |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 | 1246 |
| 1255 void TargetX8632::lowerAlloca(const InstAlloca *Inst) { | 1247 void TargetX8632::lowerAlloca(const InstAlloca *Inst) { |
| 1256 IsEbpBasedFrame = true; | 1248 IsEbpBasedFrame = true; |
| 1257 // Conservatively require the stack to be aligned. Some stack | 1249 // Conservatively require the stack to be aligned. Some stack |
| 1258 // adjustment operations implemented below assume that the stack is | 1250 // adjustment operations implemented below assume that the stack is |
| 1259 // aligned before the alloca. All the alloca code ensures that the | 1251 // aligned before the alloca. All the alloca code ensures that the |
| 1260 // stack alignment is preserved after the alloca. The stack alignment | 1252 // stack alignment is preserved after the alloca. The stack alignment |
| 1261 // restriction can be relaxed in some cases. | 1253 // restriction can be relaxed in some cases. |
| 1262 NeedsStackAlignment = true; | 1254 NeedsStackAlignment = true; |
| 1263 | 1255 |
| 1264 // TODO(sehr,stichnot): minimize the number of adjustments of esp, etc. | 1256 // TODO(stichnot): minimize the number of adjustments of esp, etc. |
| 1265 Variable *esp = getPhysicalRegister(RegX8632::Reg_esp); | 1257 Variable *esp = getPhysicalRegister(RegX8632::Reg_esp); |
| 1266 Operand *TotalSize = legalize(Inst->getSizeInBytes()); | 1258 Operand *TotalSize = legalize(Inst->getSizeInBytes()); |
| 1267 Variable *Dest = Inst->getDest(); | 1259 Variable *Dest = Inst->getDest(); |
| 1268 uint32_t AlignmentParam = Inst->getAlignInBytes(); | 1260 uint32_t AlignmentParam = Inst->getAlignInBytes(); |
| 1269 // For default align=0, set it to the real value 1, to avoid any | 1261 // For default align=0, set it to the real value 1, to avoid any |
| 1270 // bit-manipulation problems below. | 1262 // bit-manipulation problems below. |
| 1271 AlignmentParam = std::max(AlignmentParam, 1u); | 1263 AlignmentParam = std::max(AlignmentParam, 1u); |
| 1272 | 1264 |
| 1273 // LLVM enforces power of 2 alignment. | 1265 // LLVM enforces power of 2 alignment. |
| 1274 assert((AlignmentParam & (AlignmentParam - 1)) == 0); | 1266 assert(llvm::isPowerOf2_32(AlignmentParam)); |
| 1275 assert((X86_STACK_ALIGNMENT_BYTES & (X86_STACK_ALIGNMENT_BYTES - 1)) == 0); | 1267 assert(llvm::isPowerOf2_32(X86_STACK_ALIGNMENT_BYTES)); |
| 1276 | 1268 |
| 1277 uint32_t Alignment = std::max(AlignmentParam, X86_STACK_ALIGNMENT_BYTES); | 1269 uint32_t Alignment = std::max(AlignmentParam, X86_STACK_ALIGNMENT_BYTES); |
| 1278 if (Alignment > X86_STACK_ALIGNMENT_BYTES) { | 1270 if (Alignment > X86_STACK_ALIGNMENT_BYTES) { |
| 1279 _and(esp, Ctx->getConstantInt32(-Alignment)); | 1271 _and(esp, Ctx->getConstantInt32(-Alignment)); |
| 1280 } | 1272 } |
| 1281 if (ConstantInteger32 *ConstantTotalSize = | 1273 if (const auto *ConstantTotalSize = |
| 1282 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { | 1274 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { |
| 1283 uint32_t Value = ConstantTotalSize->getValue(); | 1275 uint32_t Value = ConstantTotalSize->getValue(); |
| 1284 Value = applyAlignment(Value, Alignment); | 1276 Value = Utils::applyAlignment(Value, Alignment); |
| 1285 _sub(esp, Ctx->getConstantInt32(Value)); | 1277 _sub(esp, Ctx->getConstantInt32(Value)); |
| 1286 } else { | 1278 } else { |
| 1287 // Non-constant sizes need to be adjusted to the next highest | 1279 // Non-constant sizes need to be adjusted to the next highest |
| 1288 // multiple of the required alignment at runtime. | 1280 // multiple of the required alignment at runtime. |
| 1289 Variable *T = makeReg(IceType_i32); | 1281 Variable *T = makeReg(IceType_i32); |
| 1290 _mov(T, TotalSize); | 1282 _mov(T, TotalSize); |
| 1291 _add(T, Ctx->getConstantInt32(Alignment - 1)); | 1283 _add(T, Ctx->getConstantInt32(Alignment - 1)); |
| 1292 _and(T, Ctx->getConstantInt32(-Alignment)); | 1284 _and(T, Ctx->getConstantInt32(-Alignment)); |
| 1293 _sub(esp, T); | 1285 _sub(esp, T); |
| 1294 } | 1286 } |
| (...skipping 3746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5041 case FT_Asm: | 5033 case FT_Asm: |
| 5042 case FT_Iasm: { | 5034 case FT_Iasm: { |
| 5043 OstreamLocker L(Ctx); | 5035 OstreamLocker L(Ctx); |
| 5044 emitConstantPool<PoolTypeConverter<float>>(Ctx); | 5036 emitConstantPool<PoolTypeConverter<float>>(Ctx); |
| 5045 emitConstantPool<PoolTypeConverter<double>>(Ctx); | 5037 emitConstantPool<PoolTypeConverter<double>>(Ctx); |
| 5046 } break; | 5038 } break; |
| 5047 } | 5039 } |
| 5048 } | 5040 } |
| 5049 | 5041 |
| 5050 } // end of namespace Ice | 5042 } // end of namespace Ice |
| OLD | NEW |