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 |