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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 1156713003: Subzero ARM: lower alloca instruction. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: trailing space Created 5 years, 7 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/IceTargetLoweringARM32.cpp ('k') | src/IceUtils.h » ('j') | 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/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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceTargetLoweringARM32.cpp ('k') | src/IceUtils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698