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

Side by Side Diff: src/arm/macro-assembler-arm.cc

Issue 6677076: Merge up to bleeding_edge r7201 to isolates branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/isolates
Patch Set: Fix lint. Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/simulator-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 int MacroAssembler::CallSize(Register target, Condition cond) { 106 int MacroAssembler::CallSize(Register target, Condition cond) {
107 #if USE_BLX 107 #if USE_BLX
108 return kInstrSize; 108 return kInstrSize;
109 #else 109 #else
110 return 2 * kInstrSize; 110 return 2 * kInstrSize;
111 #endif 111 #endif
112 } 112 }
113 113
114 114
115 void MacroAssembler::Call(Register target, Condition cond) { 115 void MacroAssembler::Call(Register target, Condition cond) {
116 // Block constant pool for the call instruction sequence.
117 BlockConstPoolScope block_const_pool(this);
116 #ifdef DEBUG 118 #ifdef DEBUG
117 int pre_position = pc_offset(); 119 int pre_position = pc_offset();
118 #endif 120 #endif
119 121
120 #if USE_BLX 122 #if USE_BLX
121 blx(target, cond); 123 blx(target, cond);
122 #else 124 #else
123 // set lr for return at current pc + 8 125 // set lr for return at current pc + 8
124 { BlockConstPoolScope block_const_pool(this); 126 mov(lr, Operand(pc), LeaveCC, cond);
125 mov(lr, Operand(pc), LeaveCC, cond); 127 mov(pc, Operand(target), LeaveCC, cond);
126 mov(pc, Operand(target), LeaveCC, cond);
127 }
128 #endif 128 #endif
129 129
130 #ifdef DEBUG 130 #ifdef DEBUG
131 int post_position = pc_offset(); 131 int post_position = pc_offset();
132 CHECK_EQ(pre_position + CallSize(target, cond), post_position); 132 CHECK_EQ(pre_position + CallSize(target, cond), post_position);
133 #endif 133 #endif
134 } 134 }
135 135
136 136
137 int MacroAssembler::CallSize( 137 int MacroAssembler::CallSize(
138 intptr_t target, RelocInfo::Mode rmode, Condition cond) { 138 intptr_t target, RelocInfo::Mode rmode, Condition cond) {
139 int size = 2 * kInstrSize; 139 int size = 2 * kInstrSize;
140 Instr mov_instr = cond | MOV | LeaveCC; 140 Instr mov_instr = cond | MOV | LeaveCC;
141 if (!Operand(target, rmode).is_single_instruction(mov_instr)) { 141 if (!Operand(target, rmode).is_single_instruction(mov_instr)) {
142 size += kInstrSize; 142 size += kInstrSize;
143 } 143 }
144 return size; 144 return size;
145 } 145 }
146 146
147 147
148 void MacroAssembler::Call( 148 void MacroAssembler::Call(
149 intptr_t target, RelocInfo::Mode rmode, Condition cond) { 149 intptr_t target, RelocInfo::Mode rmode, Condition cond) {
150 // Block constant pool for the call instruction sequence.
151 BlockConstPoolScope block_const_pool(this);
150 #ifdef DEBUG 152 #ifdef DEBUG
151 int pre_position = pc_offset(); 153 int pre_position = pc_offset();
152 #endif 154 #endif
153 155
154 #if USE_BLX 156 #if USE_BLX
155 // On ARMv5 and after the recommended call sequence is: 157 // On ARMv5 and after the recommended call sequence is:
156 // ldr ip, [pc, #...] 158 // ldr ip, [pc, #...]
157 // blx ip 159 // blx ip
158 160
159 // The two instructions (ldr and blx) could be separated by a constant 161 // Statement positions are expected to be recorded when the target
160 // pool and the code would still work. The issue comes from the 162 // address is loaded. The mov method will automatically record
161 // patching code which expect the ldr to be just above the blx. 163 // positions when pc is the target, since this is not the case here
162 { BlockConstPoolScope block_const_pool(this); 164 // we have to do it explicitly.
163 // Statement positions are expected to be recorded when the target 165 positions_recorder()->WriteRecordedPositions();
164 // address is loaded. The mov method will automatically record
165 // positions when pc is the target, since this is not the case here
166 // we have to do it explicitly.
167 positions_recorder()->WriteRecordedPositions();
168 166
169 mov(ip, Operand(target, rmode), LeaveCC, cond); 167 mov(ip, Operand(target, rmode), LeaveCC, cond);
170 blx(ip, cond); 168 blx(ip, cond);
171 }
172 169
173 ASSERT(kCallTargetAddressOffset == 2 * kInstrSize); 170 ASSERT(kCallTargetAddressOffset == 2 * kInstrSize);
174 #else 171 #else
175 { BlockConstPoolScope block_const_pool(this); 172 // Set lr for return at current pc + 8.
176 // Set lr for return at current pc + 8. 173 mov(lr, Operand(pc), LeaveCC, cond);
177 mov(lr, Operand(pc), LeaveCC, cond); 174 // Emit a ldr<cond> pc, [pc + offset of target in constant pool].
178 // Emit a ldr<cond> pc, [pc + offset of target in constant pool]. 175 mov(pc, Operand(target, rmode), LeaveCC, cond);
179 mov(pc, Operand(target, rmode), LeaveCC, cond);
180 }
181 ASSERT(kCallTargetAddressOffset == kInstrSize); 176 ASSERT(kCallTargetAddressOffset == kInstrSize);
182 #endif 177 #endif
183 178
184 #ifdef DEBUG 179 #ifdef DEBUG
185 int post_position = pc_offset(); 180 int post_position = pc_offset();
186 CHECK_EQ(pre_position + CallSize(target, rmode, cond), post_position); 181 CHECK_EQ(pre_position + CallSize(target, rmode, cond), post_position);
187 #endif 182 #endif
188 } 183 }
189 184
190 185
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 void MacroAssembler::StoreRoot(Register source, 426 void MacroAssembler::StoreRoot(Register source,
432 Heap::RootListIndex index, 427 Heap::RootListIndex index,
433 Condition cond) { 428 Condition cond) {
434 str(source, MemOperand(roots, index << kPointerSizeLog2), cond); 429 str(source, MemOperand(roots, index << kPointerSizeLog2), cond);
435 } 430 }
436 431
437 432
438 void MacroAssembler::RecordWriteHelper(Register object, 433 void MacroAssembler::RecordWriteHelper(Register object,
439 Register address, 434 Register address,
440 Register scratch) { 435 Register scratch) {
441 if (FLAG_debug_code) { 436 if (emit_debug_code()) {
442 // Check that the object is not in new space. 437 // Check that the object is not in new space.
443 Label not_in_new_space; 438 Label not_in_new_space;
444 InNewSpace(object, scratch, ne, &not_in_new_space); 439 InNewSpace(object, scratch, ne, &not_in_new_space);
445 Abort("new-space object passed to RecordWriteHelper"); 440 Abort("new-space object passed to RecordWriteHelper");
446 bind(&not_in_new_space); 441 bind(&not_in_new_space);
447 } 442 }
448 443
449 // Calculate page address. 444 // Calculate page address.
450 Bfc(object, 0, kPageSizeBits); 445 Bfc(object, 0, kPageSizeBits);
451 446
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 // Add offset into the object. 488 // Add offset into the object.
494 add(scratch0, object, offset); 489 add(scratch0, object, offset);
495 490
496 // Record the actual write. 491 // Record the actual write.
497 RecordWriteHelper(object, scratch0, scratch1); 492 RecordWriteHelper(object, scratch0, scratch1);
498 493
499 bind(&done); 494 bind(&done);
500 495
501 // Clobber all input registers when running with the debug-code flag 496 // Clobber all input registers when running with the debug-code flag
502 // turned on to provoke errors. 497 // turned on to provoke errors.
503 if (FLAG_debug_code) { 498 if (emit_debug_code()) {
504 mov(object, Operand(BitCast<int32_t>(kZapValue))); 499 mov(object, Operand(BitCast<int32_t>(kZapValue)));
505 mov(scratch0, Operand(BitCast<int32_t>(kZapValue))); 500 mov(scratch0, Operand(BitCast<int32_t>(kZapValue)));
506 mov(scratch1, Operand(BitCast<int32_t>(kZapValue))); 501 mov(scratch1, Operand(BitCast<int32_t>(kZapValue)));
507 } 502 }
508 } 503 }
509 504
510 505
511 // Will clobber 4 registers: object, address, scratch, ip. The 506 // Will clobber 4 registers: object, address, scratch, ip. The
512 // register 'object' contains a heap object pointer. The heap object 507 // register 'object' contains a heap object pointer. The heap object
513 // tag is shifted away. 508 // tag is shifted away.
(...skipping 11 matching lines...) Expand all
525 // region marks for new space pages. 520 // region marks for new space pages.
526 InNewSpace(object, scratch, eq, &done); 521 InNewSpace(object, scratch, eq, &done);
527 522
528 // Record the actual write. 523 // Record the actual write.
529 RecordWriteHelper(object, address, scratch); 524 RecordWriteHelper(object, address, scratch);
530 525
531 bind(&done); 526 bind(&done);
532 527
533 // Clobber all input registers when running with the debug-code flag 528 // Clobber all input registers when running with the debug-code flag
534 // turned on to provoke errors. 529 // turned on to provoke errors.
535 if (FLAG_debug_code) { 530 if (emit_debug_code()) {
536 mov(object, Operand(BitCast<int32_t>(kZapValue))); 531 mov(object, Operand(BitCast<int32_t>(kZapValue)));
537 mov(address, Operand(BitCast<int32_t>(kZapValue))); 532 mov(address, Operand(BitCast<int32_t>(kZapValue)));
538 mov(scratch, Operand(BitCast<int32_t>(kZapValue))); 533 mov(scratch, Operand(BitCast<int32_t>(kZapValue)));
539 } 534 }
540 } 535 }
541 536
542 537
543 // Push and pop all registers that can hold pointers. 538 // Push and pop all registers that can hold pointers.
544 void MacroAssembler::PushSafepointRegisters() { 539 void MacroAssembler::PushSafepointRegisters() {
545 // Safepoints expect a block of contiguous register values starting with r0: 540 // Safepoints expect a block of contiguous register values starting with r0:
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 724
730 void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { 725 void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
731 // Setup the frame structure on the stack. 726 // Setup the frame structure on the stack.
732 ASSERT_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); 727 ASSERT_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement);
733 ASSERT_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); 728 ASSERT_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset);
734 ASSERT_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); 729 ASSERT_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset);
735 Push(lr, fp); 730 Push(lr, fp);
736 mov(fp, Operand(sp)); // Setup new frame pointer. 731 mov(fp, Operand(sp)); // Setup new frame pointer.
737 // Reserve room for saved entry sp and code object. 732 // Reserve room for saved entry sp and code object.
738 sub(sp, sp, Operand(2 * kPointerSize)); 733 sub(sp, sp, Operand(2 * kPointerSize));
739 if (FLAG_debug_code) { 734 if (emit_debug_code()) {
740 mov(ip, Operand(0)); 735 mov(ip, Operand(0));
741 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); 736 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
742 } 737 }
743 mov(ip, Operand(CodeObject())); 738 mov(ip, Operand(CodeObject()));
744 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); 739 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
745 740
746 // Save the frame pointer and the context in top. 741 // Save the frame pointer and the context in top.
747 mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address))); 742 mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address)));
748 str(fp, MemOperand(ip)); 743 str(fp, MemOperand(ip));
749 mov(ip, Operand(ExternalReference(Isolate::k_context_address))); 744 mov(ip, Operand(ExternalReference(Isolate::k_context_address)));
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 1131
1137 // Before returning we restore the context from the frame pointer if 1132 // Before returning we restore the context from the frame pointer if
1138 // not NULL. The frame pointer is NULL in the exception handler of a 1133 // not NULL. The frame pointer is NULL in the exception handler of a
1139 // JS entry frame. 1134 // JS entry frame.
1140 cmp(fp, Operand(0, RelocInfo::NONE)); 1135 cmp(fp, Operand(0, RelocInfo::NONE));
1141 // Set cp to NULL if fp is NULL. 1136 // Set cp to NULL if fp is NULL.
1142 mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq); 1137 mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq);
1143 // Restore cp otherwise. 1138 // Restore cp otherwise.
1144 ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); 1139 ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
1145 #ifdef DEBUG 1140 #ifdef DEBUG
1146 if (FLAG_debug_code) { 1141 if (emit_debug_code()) {
1147 mov(lr, Operand(pc)); 1142 mov(lr, Operand(pc));
1148 } 1143 }
1149 #endif 1144 #endif
1150 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); 1145 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
1151 pop(pc); 1146 pop(pc);
1152 } 1147 }
1153 1148
1154 1149
1155 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, 1150 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
1156 Register value) { 1151 Register value) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state. 1205 ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state.
1211 // Before returning we restore the context from the frame pointer if 1206 // Before returning we restore the context from the frame pointer if
1212 // not NULL. The frame pointer is NULL in the exception handler of a 1207 // not NULL. The frame pointer is NULL in the exception handler of a
1213 // JS entry frame. 1208 // JS entry frame.
1214 cmp(fp, Operand(0, RelocInfo::NONE)); 1209 cmp(fp, Operand(0, RelocInfo::NONE));
1215 // Set cp to NULL if fp is NULL. 1210 // Set cp to NULL if fp is NULL.
1216 mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq); 1211 mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq);
1217 // Restore cp otherwise. 1212 // Restore cp otherwise.
1218 ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); 1213 ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
1219 #ifdef DEBUG 1214 #ifdef DEBUG
1220 if (FLAG_debug_code) { 1215 if (emit_debug_code()) {
1221 mov(lr, Operand(pc)); 1216 mov(lr, Operand(pc));
1222 } 1217 }
1223 #endif 1218 #endif
1224 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); 1219 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
1225 pop(pc); 1220 pop(pc);
1226 } 1221 }
1227 1222
1228 1223
1229 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 1224 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
1230 Register scratch, 1225 Register scratch,
(...skipping 11 matching lines...) Expand all
1242 cmp(scratch, Operand(0, RelocInfo::NONE)); 1237 cmp(scratch, Operand(0, RelocInfo::NONE));
1243 Check(ne, "we should not have an empty lexical context"); 1238 Check(ne, "we should not have an empty lexical context");
1244 #endif 1239 #endif
1245 1240
1246 // Load the global context of the current context. 1241 // Load the global context of the current context.
1247 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; 1242 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
1248 ldr(scratch, FieldMemOperand(scratch, offset)); 1243 ldr(scratch, FieldMemOperand(scratch, offset));
1249 ldr(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset)); 1244 ldr(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
1250 1245
1251 // Check the context is a global context. 1246 // Check the context is a global context.
1252 if (FLAG_debug_code) { 1247 if (emit_debug_code()) {
1253 // TODO(119): avoid push(holder_reg)/pop(holder_reg) 1248 // TODO(119): avoid push(holder_reg)/pop(holder_reg)
1254 // Cannot use ip as a temporary in this verification code. Due to the fact 1249 // Cannot use ip as a temporary in this verification code. Due to the fact
1255 // that ip is clobbered as part of cmp with an object Operand. 1250 // that ip is clobbered as part of cmp with an object Operand.
1256 push(holder_reg); // Temporarily save holder on the stack. 1251 push(holder_reg); // Temporarily save holder on the stack.
1257 // Read the first word and compare to the global_context_map. 1252 // Read the first word and compare to the global_context_map.
1258 ldr(holder_reg, FieldMemOperand(scratch, HeapObject::kMapOffset)); 1253 ldr(holder_reg, FieldMemOperand(scratch, HeapObject::kMapOffset));
1259 LoadRoot(ip, Heap::kGlobalContextMapRootIndex); 1254 LoadRoot(ip, Heap::kGlobalContextMapRootIndex);
1260 cmp(holder_reg, ip); 1255 cmp(holder_reg, ip);
1261 Check(eq, "JSGlobalObject::global_context should be a global context."); 1256 Check(eq, "JSGlobalObject::global_context should be a global context.");
1262 pop(holder_reg); // Restore holder. 1257 pop(holder_reg); // Restore holder.
1263 } 1258 }
1264 1259
1265 // Check if both contexts are the same. 1260 // Check if both contexts are the same.
1266 ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset)); 1261 ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset));
1267 cmp(scratch, Operand(ip)); 1262 cmp(scratch, Operand(ip));
1268 b(eq, &same_contexts); 1263 b(eq, &same_contexts);
1269 1264
1270 // Check the context is a global context. 1265 // Check the context is a global context.
1271 if (FLAG_debug_code) { 1266 if (emit_debug_code()) {
1272 // TODO(119): avoid push(holder_reg)/pop(holder_reg) 1267 // TODO(119): avoid push(holder_reg)/pop(holder_reg)
1273 // Cannot use ip as a temporary in this verification code. Due to the fact 1268 // Cannot use ip as a temporary in this verification code. Due to the fact
1274 // that ip is clobbered as part of cmp with an object Operand. 1269 // that ip is clobbered as part of cmp with an object Operand.
1275 push(holder_reg); // Temporarily save holder on the stack. 1270 push(holder_reg); // Temporarily save holder on the stack.
1276 mov(holder_reg, ip); // Move ip to its holding place. 1271 mov(holder_reg, ip); // Move ip to its holding place.
1277 LoadRoot(ip, Heap::kNullValueRootIndex); 1272 LoadRoot(ip, Heap::kNullValueRootIndex);
1278 cmp(holder_reg, ip); 1273 cmp(holder_reg, ip);
1279 Check(ne, "JSGlobalProxy::context() should not be null."); 1274 Check(ne, "JSGlobalProxy::context() should not be null.");
1280 1275
1281 ldr(holder_reg, FieldMemOperand(holder_reg, HeapObject::kMapOffset)); 1276 ldr(holder_reg, FieldMemOperand(holder_reg, HeapObject::kMapOffset));
(...skipping 21 matching lines...) Expand all
1303 } 1298 }
1304 1299
1305 1300
1306 void MacroAssembler::AllocateInNewSpace(int object_size, 1301 void MacroAssembler::AllocateInNewSpace(int object_size,
1307 Register result, 1302 Register result,
1308 Register scratch1, 1303 Register scratch1,
1309 Register scratch2, 1304 Register scratch2,
1310 Label* gc_required, 1305 Label* gc_required,
1311 AllocationFlags flags) { 1306 AllocationFlags flags) {
1312 if (!FLAG_inline_new) { 1307 if (!FLAG_inline_new) {
1313 if (FLAG_debug_code) { 1308 if (emit_debug_code()) {
1314 // Trash the registers to simulate an allocation failure. 1309 // Trash the registers to simulate an allocation failure.
1315 mov(result, Operand(0x7091)); 1310 mov(result, Operand(0x7091));
1316 mov(scratch1, Operand(0x7191)); 1311 mov(scratch1, Operand(0x7191));
1317 mov(scratch2, Operand(0x7291)); 1312 mov(scratch2, Operand(0x7291));
1318 } 1313 }
1319 jmp(gc_required); 1314 jmp(gc_required);
1320 return; 1315 return;
1321 } 1316 }
1322 1317
1323 ASSERT(!result.is(scratch1)); 1318 ASSERT(!result.is(scratch1));
(...skipping 28 matching lines...) Expand all
1352 Register obj_size_reg = scratch2; 1347 Register obj_size_reg = scratch2;
1353 mov(topaddr, Operand(new_space_allocation_top)); 1348 mov(topaddr, Operand(new_space_allocation_top));
1354 mov(obj_size_reg, Operand(object_size)); 1349 mov(obj_size_reg, Operand(object_size));
1355 1350
1356 // This code stores a temporary value in ip. This is OK, as the code below 1351 // This code stores a temporary value in ip. This is OK, as the code below
1357 // does not need ip for implicit literal generation. 1352 // does not need ip for implicit literal generation.
1358 if ((flags & RESULT_CONTAINS_TOP) == 0) { 1353 if ((flags & RESULT_CONTAINS_TOP) == 0) {
1359 // Load allocation top into result and allocation limit into ip. 1354 // Load allocation top into result and allocation limit into ip.
1360 ldm(ia, topaddr, result.bit() | ip.bit()); 1355 ldm(ia, topaddr, result.bit() | ip.bit());
1361 } else { 1356 } else {
1362 if (FLAG_debug_code) { 1357 if (emit_debug_code()) {
1363 // Assert that result actually contains top on entry. ip is used 1358 // Assert that result actually contains top on entry. ip is used
1364 // immediately below so this use of ip does not cause difference with 1359 // immediately below so this use of ip does not cause difference with
1365 // respect to register content between debug and release mode. 1360 // respect to register content between debug and release mode.
1366 ldr(ip, MemOperand(topaddr)); 1361 ldr(ip, MemOperand(topaddr));
1367 cmp(result, ip); 1362 cmp(result, ip);
1368 Check(eq, "Unexpected allocation top"); 1363 Check(eq, "Unexpected allocation top");
1369 } 1364 }
1370 // Load allocation limit into ip. Result already contains allocation top. 1365 // Load allocation limit into ip. Result already contains allocation top.
1371 ldr(ip, MemOperand(topaddr, limit - top)); 1366 ldr(ip, MemOperand(topaddr, limit - top));
1372 } 1367 }
(...skipping 13 matching lines...) Expand all
1386 } 1381 }
1387 1382
1388 1383
1389 void MacroAssembler::AllocateInNewSpace(Register object_size, 1384 void MacroAssembler::AllocateInNewSpace(Register object_size,
1390 Register result, 1385 Register result,
1391 Register scratch1, 1386 Register scratch1,
1392 Register scratch2, 1387 Register scratch2,
1393 Label* gc_required, 1388 Label* gc_required,
1394 AllocationFlags flags) { 1389 AllocationFlags flags) {
1395 if (!FLAG_inline_new) { 1390 if (!FLAG_inline_new) {
1396 if (FLAG_debug_code) { 1391 if (emit_debug_code()) {
1397 // Trash the registers to simulate an allocation failure. 1392 // Trash the registers to simulate an allocation failure.
1398 mov(result, Operand(0x7091)); 1393 mov(result, Operand(0x7091));
1399 mov(scratch1, Operand(0x7191)); 1394 mov(scratch1, Operand(0x7191));
1400 mov(scratch2, Operand(0x7291)); 1395 mov(scratch2, Operand(0x7291));
1401 } 1396 }
1402 jmp(gc_required); 1397 jmp(gc_required);
1403 return; 1398 return;
1404 } 1399 }
1405 1400
1406 // Assert that the register arguments are different and that none of 1401 // Assert that the register arguments are different and that none of
(...skipping 23 matching lines...) Expand all
1430 // Set up allocation top address. 1425 // Set up allocation top address.
1431 Register topaddr = scratch1; 1426 Register topaddr = scratch1;
1432 mov(topaddr, Operand(new_space_allocation_top)); 1427 mov(topaddr, Operand(new_space_allocation_top));
1433 1428
1434 // This code stores a temporary value in ip. This is OK, as the code below 1429 // This code stores a temporary value in ip. This is OK, as the code below
1435 // does not need ip for implicit literal generation. 1430 // does not need ip for implicit literal generation.
1436 if ((flags & RESULT_CONTAINS_TOP) == 0) { 1431 if ((flags & RESULT_CONTAINS_TOP) == 0) {
1437 // Load allocation top into result and allocation limit into ip. 1432 // Load allocation top into result and allocation limit into ip.
1438 ldm(ia, topaddr, result.bit() | ip.bit()); 1433 ldm(ia, topaddr, result.bit() | ip.bit());
1439 } else { 1434 } else {
1440 if (FLAG_debug_code) { 1435 if (emit_debug_code()) {
1441 // Assert that result actually contains top on entry. ip is used 1436 // Assert that result actually contains top on entry. ip is used
1442 // immediately below so this use of ip does not cause difference with 1437 // immediately below so this use of ip does not cause difference with
1443 // respect to register content between debug and release mode. 1438 // respect to register content between debug and release mode.
1444 ldr(ip, MemOperand(topaddr)); 1439 ldr(ip, MemOperand(topaddr));
1445 cmp(result, ip); 1440 cmp(result, ip);
1446 Check(eq, "Unexpected allocation top"); 1441 Check(eq, "Unexpected allocation top");
1447 } 1442 }
1448 // Load allocation limit into ip. Result already contains allocation top. 1443 // Load allocation limit into ip. Result already contains allocation top.
1449 ldr(ip, MemOperand(topaddr, limit - top)); 1444 ldr(ip, MemOperand(topaddr, limit - top));
1450 } 1445 }
1451 1446
1452 // Calculate new top and bail out if new space is exhausted. Use result 1447 // Calculate new top and bail out if new space is exhausted. Use result
1453 // to calculate the new top. Object size may be in words so a shift is 1448 // to calculate the new top. Object size may be in words so a shift is
1454 // required to get the number of bytes. 1449 // required to get the number of bytes.
1455 if ((flags & SIZE_IN_WORDS) != 0) { 1450 if ((flags & SIZE_IN_WORDS) != 0) {
1456 add(scratch2, result, Operand(object_size, LSL, kPointerSizeLog2), SetCC); 1451 add(scratch2, result, Operand(object_size, LSL, kPointerSizeLog2), SetCC);
1457 } else { 1452 } else {
1458 add(scratch2, result, Operand(object_size), SetCC); 1453 add(scratch2, result, Operand(object_size), SetCC);
1459 } 1454 }
1460 b(cs, gc_required); 1455 b(cs, gc_required);
1461 cmp(scratch2, Operand(ip)); 1456 cmp(scratch2, Operand(ip));
1462 b(hi, gc_required); 1457 b(hi, gc_required);
1463 1458
1464 // Update allocation top. result temporarily holds the new top. 1459 // Update allocation top. result temporarily holds the new top.
1465 if (FLAG_debug_code) { 1460 if (emit_debug_code()) {
1466 tst(scratch2, Operand(kObjectAlignmentMask)); 1461 tst(scratch2, Operand(kObjectAlignmentMask));
1467 Check(eq, "Unaligned allocation in new space"); 1462 Check(eq, "Unaligned allocation in new space");
1468 } 1463 }
1469 str(scratch2, MemOperand(topaddr)); 1464 str(scratch2, MemOperand(topaddr));
1470 1465
1471 // Tag object if requested. 1466 // Tag object if requested.
1472 if ((flags & TAG_OBJECT) != 0) { 1467 if ((flags & TAG_OBJECT) != 0) {
1473 add(result, result, Operand(kHeapObjectTag)); 1468 add(result, result, Operand(kHeapObjectTag));
1474 } 1469 }
1475 } 1470 }
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1759 1754
1760 // If result is non-zero, dereference to get the result value 1755 // If result is non-zero, dereference to get the result value
1761 // otherwise set it to undefined. 1756 // otherwise set it to undefined.
1762 cmp(r0, Operand(0)); 1757 cmp(r0, Operand(0));
1763 LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 1758 LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1764 ldr(r0, MemOperand(r0), ne); 1759 ldr(r0, MemOperand(r0), ne);
1765 1760
1766 // No more valid handles (the result handle was the last one). Restore 1761 // No more valid handles (the result handle was the last one). Restore
1767 // previous handle scope. 1762 // previous handle scope.
1768 str(r4, MemOperand(r7, kNextOffset)); 1763 str(r4, MemOperand(r7, kNextOffset));
1769 if (FLAG_debug_code) { 1764 if (emit_debug_code()) {
1770 ldr(r1, MemOperand(r7, kLevelOffset)); 1765 ldr(r1, MemOperand(r7, kLevelOffset));
1771 cmp(r1, r6); 1766 cmp(r1, r6);
1772 Check(eq, "Unexpected level after return from api call"); 1767 Check(eq, "Unexpected level after return from api call");
1773 } 1768 }
1774 sub(r6, r6, Operand(1)); 1769 sub(r6, r6, Operand(1));
1775 str(r6, MemOperand(r7, kLevelOffset)); 1770 str(r6, MemOperand(r7, kLevelOffset));
1776 ldr(ip, MemOperand(r7, kLimitOffset)); 1771 ldr(ip, MemOperand(r7, kLimitOffset));
1777 cmp(r5, ip); 1772 cmp(r5, ip);
1778 b(ne, &delete_allocated_handles); 1773 b(ne, &delete_allocated_handles);
1779 1774
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 2027
2033 // Retrieve FPSCR. 2028 // Retrieve FPSCR.
2034 vmrs(scratch); 2029 vmrs(scratch);
2035 // Restore FPSCR. 2030 // Restore FPSCR.
2036 vmsr(prev_fpscr); 2031 vmsr(prev_fpscr);
2037 // Check for vfp exceptions. 2032 // Check for vfp exceptions.
2038 tst(scratch, Operand(kVFPExceptionMask | check_inexact_conversion)); 2033 tst(scratch, Operand(kVFPExceptionMask | check_inexact_conversion));
2039 } 2034 }
2040 2035
2041 2036
2037 void MacroAssembler::EmitOutOfInt32RangeTruncate(Register result,
2038 Register input_high,
2039 Register input_low,
2040 Register scratch) {
2041 Label done, normal_exponent, restore_sign;
2042
2043 // Extract the biased exponent in result.
2044 Ubfx(result,
2045 input_high,
2046 HeapNumber::kExponentShift,
2047 HeapNumber::kExponentBits);
2048
2049 // Check for Infinity and NaNs, which should return 0.
2050 cmp(result, Operand(HeapNumber::kExponentMask));
2051 mov(result, Operand(0), LeaveCC, eq);
2052 b(eq, &done);
2053
2054 // Express exponent as delta to (number of mantissa bits + 31).
2055 sub(result,
2056 result,
2057 Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits + 31),
2058 SetCC);
2059
2060 // If the delta is strictly positive, all bits would be shifted away,
2061 // which means that we can return 0.
2062 b(le, &normal_exponent);
2063 mov(result, Operand(0));
2064 b(&done);
2065
2066 bind(&normal_exponent);
2067 const int kShiftBase = HeapNumber::kNonMantissaBitsInTopWord - 1;
2068 // Calculate shift.
2069 add(scratch, result, Operand(kShiftBase + HeapNumber::kMantissaBits), SetCC);
2070
2071 // Save the sign.
2072 Register sign = result;
2073 result = no_reg;
2074 and_(sign, input_high, Operand(HeapNumber::kSignMask));
2075
2076 // Set the implicit 1 before the mantissa part in input_high.
2077 orr(input_high,
2078 input_high,
2079 Operand(1 << HeapNumber::kMantissaBitsInTopWord));
2080 // Shift the mantissa bits to the correct position.
2081 // We don't need to clear non-mantissa bits as they will be shifted away.
2082 // If they weren't, it would mean that the answer is in the 32bit range.
2083 mov(input_high, Operand(input_high, LSL, scratch));
2084
2085 // Replace the shifted bits with bits from the lower mantissa word.
2086 Label pos_shift, shift_done;
2087 rsb(scratch, scratch, Operand(32), SetCC);
2088 b(&pos_shift, ge);
2089
2090 // Negate scratch.
2091 rsb(scratch, scratch, Operand(0));
2092 mov(input_low, Operand(input_low, LSL, scratch));
2093 b(&shift_done);
2094
2095 bind(&pos_shift);
2096 mov(input_low, Operand(input_low, LSR, scratch));
2097
2098 bind(&shift_done);
2099 orr(input_high, input_high, Operand(input_low));
2100 // Restore sign if necessary.
2101 cmp(sign, Operand(0));
2102 result = sign;
2103 sign = no_reg;
2104 rsb(result, input_high, Operand(0), LeaveCC, ne);
2105 mov(result, input_high, LeaveCC, eq);
2106 bind(&done);
2107 }
2108
2109
2110 void MacroAssembler::EmitECMATruncate(Register result,
2111 DwVfpRegister double_input,
2112 SwVfpRegister single_scratch,
2113 Register scratch,
2114 Register input_high,
2115 Register input_low) {
2116 CpuFeatures::Scope scope(VFP3);
2117 ASSERT(!input_high.is(result));
2118 ASSERT(!input_low.is(result));
2119 ASSERT(!input_low.is(input_high));
2120 ASSERT(!scratch.is(result) &&
2121 !scratch.is(input_high) &&
2122 !scratch.is(input_low));
2123 ASSERT(!single_scratch.is(double_input.low()) &&
2124 !single_scratch.is(double_input.high()));
2125
2126 Label done;
2127
2128 // Clear cumulative exception flags.
2129 ClearFPSCRBits(kVFPExceptionMask, scratch);
2130 // Try a conversion to a signed integer.
2131 vcvt_s32_f64(single_scratch, double_input);
2132 vmov(result, single_scratch);
2133 // Retrieve he FPSCR.
2134 vmrs(scratch);
2135 // Check for overflow and NaNs.
2136 tst(scratch, Operand(kVFPOverflowExceptionBit |
2137 kVFPUnderflowExceptionBit |
2138 kVFPInvalidOpExceptionBit));
2139 // If we had no exceptions we are done.
2140 b(eq, &done);
2141
2142 // Load the double value and perform a manual truncation.
2143 vmov(input_low, input_high, double_input);
2144 EmitOutOfInt32RangeTruncate(result,
2145 input_high,
2146 input_low,
2147 scratch);
2148 bind(&done);
2149 }
2150
2151
2042 void MacroAssembler::GetLeastBitsFromSmi(Register dst, 2152 void MacroAssembler::GetLeastBitsFromSmi(Register dst,
2043 Register src, 2153 Register src,
2044 int num_least_bits) { 2154 int num_least_bits) {
2045 if (Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { 2155 if (Isolate::Current()->cpu_features()->IsSupported(ARMv7)) {
2046 ubfx(dst, src, kSmiTagSize, num_least_bits); 2156 ubfx(dst, src, kSmiTagSize, num_least_bits);
2047 } else { 2157 } else {
2048 mov(dst, Operand(src, ASR, kSmiTagSize)); 2158 mov(dst, Operand(src, ASR, kSmiTagSize));
2049 and_(dst, dst, Operand((1 << num_least_bits) - 1)); 2159 and_(dst, dst, Operand((1 << num_least_bits) - 1));
2050 } 2160 }
2051 } 2161 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2221 if (FLAG_native_code_counters && counter->Enabled()) { 2331 if (FLAG_native_code_counters && counter->Enabled()) {
2222 mov(scratch2, Operand(ExternalReference(counter))); 2332 mov(scratch2, Operand(ExternalReference(counter)));
2223 ldr(scratch1, MemOperand(scratch2)); 2333 ldr(scratch1, MemOperand(scratch2));
2224 sub(scratch1, scratch1, Operand(value)); 2334 sub(scratch1, scratch1, Operand(value));
2225 str(scratch1, MemOperand(scratch2)); 2335 str(scratch1, MemOperand(scratch2));
2226 } 2336 }
2227 } 2337 }
2228 2338
2229 2339
2230 void MacroAssembler::Assert(Condition cond, const char* msg) { 2340 void MacroAssembler::Assert(Condition cond, const char* msg) {
2231 if (FLAG_debug_code) 2341 if (emit_debug_code())
2232 Check(cond, msg); 2342 Check(cond, msg);
2233 } 2343 }
2234 2344
2235 2345
2236 void MacroAssembler::AssertRegisterIsRoot(Register reg, 2346 void MacroAssembler::AssertRegisterIsRoot(Register reg,
2237 Heap::RootListIndex index) { 2347 Heap::RootListIndex index) {
2238 if (FLAG_debug_code) { 2348 if (emit_debug_code()) {
2239 LoadRoot(ip, index); 2349 LoadRoot(ip, index);
2240 cmp(reg, ip); 2350 cmp(reg, ip);
2241 Check(eq, "Register did not match expected root"); 2351 Check(eq, "Register did not match expected root");
2242 } 2352 }
2243 } 2353 }
2244 2354
2245 2355
2246 void MacroAssembler::AssertFastElements(Register elements) { 2356 void MacroAssembler::AssertFastElements(Register elements) {
2247 if (FLAG_debug_code) { 2357 if (emit_debug_code()) {
2248 ASSERT(!elements.is(ip)); 2358 ASSERT(!elements.is(ip));
2249 Label ok; 2359 Label ok;
2250 push(elements); 2360 push(elements);
2251 ldr(elements, FieldMemOperand(elements, HeapObject::kMapOffset)); 2361 ldr(elements, FieldMemOperand(elements, HeapObject::kMapOffset));
2252 LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 2362 LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
2253 cmp(elements, ip); 2363 cmp(elements, ip);
2254 b(eq, &ok); 2364 b(eq, &ok);
2255 LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex); 2365 LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
2256 cmp(elements, ip); 2366 cmp(elements, ip);
2257 b(eq, &ok); 2367 b(eq, &ok);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 // Slot is in the current function context. Move it into the 2435 // Slot is in the current function context. Move it into the
2326 // destination register in case we store into it (the write barrier 2436 // destination register in case we store into it (the write barrier
2327 // cannot be allowed to destroy the context in esi). 2437 // cannot be allowed to destroy the context in esi).
2328 mov(dst, cp); 2438 mov(dst, cp);
2329 } 2439 }
2330 2440
2331 // We should not have found a 'with' context by walking the context chain 2441 // We should not have found a 'with' context by walking the context chain
2332 // (i.e., the static scope chain and runtime context chain do not agree). 2442 // (i.e., the static scope chain and runtime context chain do not agree).
2333 // A variable occurring in such a scope should have slot type LOOKUP and 2443 // A variable occurring in such a scope should have slot type LOOKUP and
2334 // not CONTEXT. 2444 // not CONTEXT.
2335 if (FLAG_debug_code) { 2445 if (emit_debug_code()) {
2336 ldr(ip, MemOperand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX))); 2446 ldr(ip, MemOperand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
2337 cmp(dst, ip); 2447 cmp(dst, ip);
2338 Check(eq, "Yo dawg, I heard you liked function contexts " 2448 Check(eq, "Yo dawg, I heard you liked function contexts "
2339 "so I put function contexts in all your contexts"); 2449 "so I put function contexts in all your contexts");
2340 } 2450 }
2341 } 2451 }
2342 2452
2343 2453
2344 void MacroAssembler::LoadGlobalFunction(int index, Register function) { 2454 void MacroAssembler::LoadGlobalFunction(int index, Register function) {
2345 // Load the global or builtins object from the current context. 2455 // Load the global or builtins object from the current context.
2346 ldr(function, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); 2456 ldr(function, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
2347 // Load the global context from the global or builtins object. 2457 // Load the global context from the global or builtins object.
2348 ldr(function, FieldMemOperand(function, 2458 ldr(function, FieldMemOperand(function,
2349 GlobalObject::kGlobalContextOffset)); 2459 GlobalObject::kGlobalContextOffset));
2350 // Load the function from the global context. 2460 // Load the function from the global context.
2351 ldr(function, MemOperand(function, Context::SlotOffset(index))); 2461 ldr(function, MemOperand(function, Context::SlotOffset(index)));
2352 } 2462 }
2353 2463
2354 2464
2355 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 2465 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
2356 Register map, 2466 Register map,
2357 Register scratch) { 2467 Register scratch) {
2358 // Load the initial map. The global functions all have initial maps. 2468 // Load the initial map. The global functions all have initial maps.
2359 ldr(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2469 ldr(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
2360 if (FLAG_debug_code) { 2470 if (emit_debug_code()) {
2361 Label ok, fail; 2471 Label ok, fail;
2362 CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, false); 2472 CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, false);
2363 b(&ok); 2473 b(&ok);
2364 bind(&fail); 2474 bind(&fail);
2365 Abort("Global functions must have initial map"); 2475 Abort("Global functions must have initial map");
2366 bind(&ok); 2476 bind(&ok);
2367 } 2477 }
2368 } 2478 }
2369 2479
2370 2480
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 bind(&align_loop_1); 2668 bind(&align_loop_1);
2559 tst(src, Operand(kPointerSize - 1)); 2669 tst(src, Operand(kPointerSize - 1));
2560 b(eq, &word_loop); 2670 b(eq, &word_loop);
2561 ldrb(scratch, MemOperand(src, 1, PostIndex)); 2671 ldrb(scratch, MemOperand(src, 1, PostIndex));
2562 strb(scratch, MemOperand(dst, 1, PostIndex)); 2672 strb(scratch, MemOperand(dst, 1, PostIndex));
2563 sub(length, length, Operand(1), SetCC); 2673 sub(length, length, Operand(1), SetCC);
2564 b(ne, &byte_loop_1); 2674 b(ne, &byte_loop_1);
2565 2675
2566 // Copy bytes in word size chunks. 2676 // Copy bytes in word size chunks.
2567 bind(&word_loop); 2677 bind(&word_loop);
2568 if (FLAG_debug_code) { 2678 if (emit_debug_code()) {
2569 tst(src, Operand(kPointerSize - 1)); 2679 tst(src, Operand(kPointerSize - 1));
2570 Assert(eq, "Expecting alignment for CopyBytes"); 2680 Assert(eq, "Expecting alignment for CopyBytes");
2571 } 2681 }
2572 cmp(length, Operand(kPointerSize)); 2682 cmp(length, Operand(kPointerSize));
2573 b(lt, &byte_loop); 2683 b(lt, &byte_loop);
2574 ldr(scratch, MemOperand(src, kPointerSize, PostIndex)); 2684 ldr(scratch, MemOperand(src, kPointerSize, PostIndex));
2575 #if CAN_USE_UNALIGNED_ACCESSES 2685 #if CAN_USE_UNALIGNED_ACCESSES
2576 str(scratch, MemOperand(dst, kPointerSize, PostIndex)); 2686 str(scratch, MemOperand(dst, kPointerSize, PostIndex));
2577 #else 2687 #else
2578 strb(scratch, MemOperand(dst, 1, PostIndex)); 2688 strb(scratch, MemOperand(dst, 1, PostIndex));
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2718 // Push Isolate address on the stack after the arguments. 2828 // Push Isolate address on the stack after the arguments.
2719 mov(scratch, Operand(ExternalReference::isolate_address())); 2829 mov(scratch, Operand(ExternalReference::isolate_address()));
2720 str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize)); 2830 str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
2721 } 2831 }
2722 num_arguments += 1; 2832 num_arguments += 1;
2723 2833
2724 // Make sure that the stack is aligned before calling a C function unless 2834 // Make sure that the stack is aligned before calling a C function unless
2725 // running in the simulator. The simulator has its own alignment check which 2835 // running in the simulator. The simulator has its own alignment check which
2726 // provides more information. 2836 // provides more information.
2727 #if defined(V8_HOST_ARCH_ARM) 2837 #if defined(V8_HOST_ARCH_ARM)
2728 if (FLAG_debug_code) { 2838 if (emit_debug_code()) {
2729 int frame_alignment = OS::ActivationFrameAlignment(); 2839 int frame_alignment = OS::ActivationFrameAlignment();
2730 int frame_alignment_mask = frame_alignment - 1; 2840 int frame_alignment_mask = frame_alignment - 1;
2731 if (frame_alignment > kPointerSize) { 2841 if (frame_alignment > kPointerSize) {
2732 ASSERT(IsPowerOf2(frame_alignment)); 2842 ASSERT(IsPowerOf2(frame_alignment));
2733 Label alignment_as_expected; 2843 Label alignment_as_expected;
2734 tst(sp, Operand(frame_alignment_mask)); 2844 tst(sp, Operand(frame_alignment_mask));
2735 b(eq, &alignment_as_expected); 2845 b(eq, &alignment_as_expected);
2736 // Don't use Check here, as it will call Runtime_Abort possibly 2846 // Don't use Check here, as it will call Runtime_Abort possibly
2737 // re-entering here. 2847 // re-entering here.
2738 stop("Unexpected alignment"); 2848 stop("Unexpected alignment");
(...skipping 18 matching lines...) Expand all
2757 add(sp, sp, Operand(stack_passed_arguments * sizeof(kPointerSize))); 2867 add(sp, sp, Operand(stack_passed_arguments * sizeof(kPointerSize)));
2758 } 2868 }
2759 } 2869 }
2760 2870
2761 2871
2762 void MacroAssembler::GetRelocatedValueLocation(Register ldr_location, 2872 void MacroAssembler::GetRelocatedValueLocation(Register ldr_location,
2763 Register result) { 2873 Register result) {
2764 const uint32_t kLdrOffsetMask = (1 << 12) - 1; 2874 const uint32_t kLdrOffsetMask = (1 << 12) - 1;
2765 const int32_t kPCRegOffset = 2 * kPointerSize; 2875 const int32_t kPCRegOffset = 2 * kPointerSize;
2766 ldr(result, MemOperand(ldr_location)); 2876 ldr(result, MemOperand(ldr_location));
2767 if (FLAG_debug_code) { 2877 if (emit_debug_code()) {
2768 // Check that the instruction is a ldr reg, [pc + offset] . 2878 // Check that the instruction is a ldr reg, [pc + offset] .
2769 and_(result, result, Operand(kLdrPCPattern)); 2879 and_(result, result, Operand(kLdrPCPattern));
2770 cmp(result, Operand(kLdrPCPattern)); 2880 cmp(result, Operand(kLdrPCPattern));
2771 Check(eq, "The instruction to patch should be a load from pc."); 2881 Check(eq, "The instruction to patch should be a load from pc.");
2772 // Result was clobbered. Restore it. 2882 // Result was clobbered. Restore it.
2773 ldr(result, MemOperand(ldr_location)); 2883 ldr(result, MemOperand(ldr_location));
2774 } 2884 }
2775 // Get the address of the constant. 2885 // Get the address of the constant.
2776 and_(result, result, Operand(kLdrOffsetMask)); 2886 and_(result, result, Operand(kLdrOffsetMask));
2777 add(result, ldr_location, Operand(result)); 2887 add(result, ldr_location, Operand(result));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2814 void CodePatcher::EmitCondition(Condition cond) { 2924 void CodePatcher::EmitCondition(Condition cond) {
2815 Instr instr = Assembler::instr_at(masm_.pc_); 2925 Instr instr = Assembler::instr_at(masm_.pc_);
2816 instr = (instr & ~kCondMask) | cond; 2926 instr = (instr & ~kCondMask) | cond;
2817 masm_.emit(instr); 2927 masm_.emit(instr);
2818 } 2928 }
2819 2929
2820 2930
2821 } } // namespace v8::internal 2931 } } // namespace v8::internal
2822 2932
2823 #endif // V8_TARGET_ARCH_ARM 2933 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/simulator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698