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

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

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 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/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 } 150 }
151 Push(Immediate(static_cast<int32_t>(address))); 151 Push(Immediate(static_cast<int32_t>(address)));
152 return; 152 return;
153 } 153 }
154 LoadAddress(kScratchRegister, source); 154 LoadAddress(kScratchRegister, source);
155 Push(kScratchRegister); 155 Push(kScratchRegister);
156 } 156 }
157 157
158 158
159 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 159 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
160 ASSERT(root_array_available_); 160 DCHECK(root_array_available_);
161 movp(destination, Operand(kRootRegister, 161 movp(destination, Operand(kRootRegister,
162 (index << kPointerSizeLog2) - kRootRegisterBias)); 162 (index << kPointerSizeLog2) - kRootRegisterBias));
163 } 163 }
164 164
165 165
166 void MacroAssembler::LoadRootIndexed(Register destination, 166 void MacroAssembler::LoadRootIndexed(Register destination,
167 Register variable_offset, 167 Register variable_offset,
168 int fixed_offset) { 168 int fixed_offset) {
169 ASSERT(root_array_available_); 169 DCHECK(root_array_available_);
170 movp(destination, 170 movp(destination,
171 Operand(kRootRegister, 171 Operand(kRootRegister,
172 variable_offset, times_pointer_size, 172 variable_offset, times_pointer_size,
173 (fixed_offset << kPointerSizeLog2) - kRootRegisterBias)); 173 (fixed_offset << kPointerSizeLog2) - kRootRegisterBias));
174 } 174 }
175 175
176 176
177 void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) { 177 void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) {
178 ASSERT(root_array_available_); 178 DCHECK(root_array_available_);
179 movp(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias), 179 movp(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias),
180 source); 180 source);
181 } 181 }
182 182
183 183
184 void MacroAssembler::PushRoot(Heap::RootListIndex index) { 184 void MacroAssembler::PushRoot(Heap::RootListIndex index) {
185 ASSERT(root_array_available_); 185 DCHECK(root_array_available_);
186 Push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias)); 186 Push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias));
187 } 187 }
188 188
189 189
190 void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 190 void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
191 ASSERT(root_array_available_); 191 DCHECK(root_array_available_);
192 cmpp(with, Operand(kRootRegister, 192 cmpp(with, Operand(kRootRegister,
193 (index << kPointerSizeLog2) - kRootRegisterBias)); 193 (index << kPointerSizeLog2) - kRootRegisterBias));
194 } 194 }
195 195
196 196
197 void MacroAssembler::CompareRoot(const Operand& with, 197 void MacroAssembler::CompareRoot(const Operand& with,
198 Heap::RootListIndex index) { 198 Heap::RootListIndex index) {
199 ASSERT(root_array_available_); 199 DCHECK(root_array_available_);
200 ASSERT(!with.AddressUsesRegister(kScratchRegister)); 200 DCHECK(!with.AddressUsesRegister(kScratchRegister));
201 LoadRoot(kScratchRegister, index); 201 LoadRoot(kScratchRegister, index);
202 cmpp(with, kScratchRegister); 202 cmpp(with, kScratchRegister);
203 } 203 }
204 204
205 205
206 void MacroAssembler::RememberedSetHelper(Register object, // For debug tests. 206 void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
207 Register addr, 207 Register addr,
208 Register scratch, 208 Register scratch,
209 SaveFPRegsMode save_fp, 209 SaveFPRegsMode save_fp,
210 RememberedSetFinalAction and_then) { 210 RememberedSetFinalAction and_then) {
(...skipping 14 matching lines...) Expand all
225 // Call stub on end of buffer. 225 // Call stub on end of buffer.
226 Label done; 226 Label done;
227 // Check for end of buffer. 227 // Check for end of buffer.
228 testp(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit)); 228 testp(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit));
229 if (and_then == kReturnAtEnd) { 229 if (and_then == kReturnAtEnd) {
230 Label buffer_overflowed; 230 Label buffer_overflowed;
231 j(not_equal, &buffer_overflowed, Label::kNear); 231 j(not_equal, &buffer_overflowed, Label::kNear);
232 ret(0); 232 ret(0);
233 bind(&buffer_overflowed); 233 bind(&buffer_overflowed);
234 } else { 234 } else {
235 ASSERT(and_then == kFallThroughAtEnd); 235 DCHECK(and_then == kFallThroughAtEnd);
236 j(equal, &done, Label::kNear); 236 j(equal, &done, Label::kNear);
237 } 237 }
238 StoreBufferOverflowStub store_buffer_overflow = 238 StoreBufferOverflowStub store_buffer_overflow =
239 StoreBufferOverflowStub(isolate(), save_fp); 239 StoreBufferOverflowStub(isolate(), save_fp);
240 CallStub(&store_buffer_overflow); 240 CallStub(&store_buffer_overflow);
241 if (and_then == kReturnAtEnd) { 241 if (and_then == kReturnAtEnd) {
242 ret(0); 242 ret(0);
243 } else { 243 } else {
244 ASSERT(and_then == kFallThroughAtEnd); 244 DCHECK(and_then == kFallThroughAtEnd);
245 bind(&done); 245 bind(&done);
246 } 246 }
247 } 247 }
248 248
249 249
250 void MacroAssembler::InNewSpace(Register object, 250 void MacroAssembler::InNewSpace(Register object,
251 Register scratch, 251 Register scratch,
252 Condition cc, 252 Condition cc,
253 Label* branch, 253 Label* branch,
254 Label::Distance distance) { 254 Label::Distance distance) {
255 if (serializer_enabled()) { 255 if (serializer_enabled()) {
256 // Can't do arithmetic on external references if it might get serialized. 256 // Can't do arithmetic on external references if it might get serialized.
257 // The mask isn't really an address. We load it as an external reference in 257 // The mask isn't really an address. We load it as an external reference in
258 // case the size of the new space is different between the snapshot maker 258 // case the size of the new space is different between the snapshot maker
259 // and the running system. 259 // and the running system.
260 if (scratch.is(object)) { 260 if (scratch.is(object)) {
261 Move(kScratchRegister, ExternalReference::new_space_mask(isolate())); 261 Move(kScratchRegister, ExternalReference::new_space_mask(isolate()));
262 andp(scratch, kScratchRegister); 262 andp(scratch, kScratchRegister);
263 } else { 263 } else {
264 Move(scratch, ExternalReference::new_space_mask(isolate())); 264 Move(scratch, ExternalReference::new_space_mask(isolate()));
265 andp(scratch, object); 265 andp(scratch, object);
266 } 266 }
267 Move(kScratchRegister, ExternalReference::new_space_start(isolate())); 267 Move(kScratchRegister, ExternalReference::new_space_start(isolate()));
268 cmpp(scratch, kScratchRegister); 268 cmpp(scratch, kScratchRegister);
269 j(cc, branch, distance); 269 j(cc, branch, distance);
270 } else { 270 } else {
271 ASSERT(kPointerSize == kInt64Size 271 DCHECK(kPointerSize == kInt64Size
272 ? is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask())) 272 ? is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask()))
273 : kPointerSize == kInt32Size); 273 : kPointerSize == kInt32Size);
274 intptr_t new_space_start = 274 intptr_t new_space_start =
275 reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart()); 275 reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart());
276 Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start), 276 Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start),
277 Assembler::RelocInfoNone()); 277 Assembler::RelocInfoNone());
278 if (scratch.is(object)) { 278 if (scratch.is(object)) {
279 addp(scratch, kScratchRegister); 279 addp(scratch, kScratchRegister);
280 } else { 280 } else {
281 leap(scratch, Operand(object, kScratchRegister, times_1, 0)); 281 leap(scratch, Operand(object, kScratchRegister, times_1, 0));
(...skipping 18 matching lines...) Expand all
300 // catch stores of Smis. 300 // catch stores of Smis.
301 Label done; 301 Label done;
302 302
303 // Skip barrier if writing a smi. 303 // Skip barrier if writing a smi.
304 if (smi_check == INLINE_SMI_CHECK) { 304 if (smi_check == INLINE_SMI_CHECK) {
305 JumpIfSmi(value, &done); 305 JumpIfSmi(value, &done);
306 } 306 }
307 307
308 // Although the object register is tagged, the offset is relative to the start 308 // Although the object register is tagged, the offset is relative to the start
309 // of the object, so so offset must be a multiple of kPointerSize. 309 // of the object, so so offset must be a multiple of kPointerSize.
310 ASSERT(IsAligned(offset, kPointerSize)); 310 DCHECK(IsAligned(offset, kPointerSize));
311 311
312 leap(dst, FieldOperand(object, offset)); 312 leap(dst, FieldOperand(object, offset));
313 if (emit_debug_code()) { 313 if (emit_debug_code()) {
314 Label ok; 314 Label ok;
315 testb(dst, Immediate((1 << kPointerSizeLog2) - 1)); 315 testb(dst, Immediate((1 << kPointerSizeLog2) - 1));
316 j(zero, &ok, Label::kNear); 316 j(zero, &ok, Label::kNear);
317 int3(); 317 int3();
318 bind(&ok); 318 bind(&ok);
319 } 319 }
320 320
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 Move(value, kZapValue, Assembler::RelocInfoNone()); 365 Move(value, kZapValue, Assembler::RelocInfoNone());
366 Move(index, kZapValue, Assembler::RelocInfoNone()); 366 Move(index, kZapValue, Assembler::RelocInfoNone());
367 } 367 }
368 } 368 }
369 369
370 370
371 void MacroAssembler::RecordWriteForMap(Register object, 371 void MacroAssembler::RecordWriteForMap(Register object,
372 Register map, 372 Register map,
373 Register dst, 373 Register dst,
374 SaveFPRegsMode fp_mode) { 374 SaveFPRegsMode fp_mode) {
375 ASSERT(!object.is(kScratchRegister)); 375 DCHECK(!object.is(kScratchRegister));
376 ASSERT(!object.is(map)); 376 DCHECK(!object.is(map));
377 ASSERT(!object.is(dst)); 377 DCHECK(!object.is(dst));
378 ASSERT(!map.is(dst)); 378 DCHECK(!map.is(dst));
379 AssertNotSmi(object); 379 AssertNotSmi(object);
380 380
381 if (emit_debug_code()) { 381 if (emit_debug_code()) {
382 Label ok; 382 Label ok;
383 if (map.is(kScratchRegister)) pushq(map); 383 if (map.is(kScratchRegister)) pushq(map);
384 CompareMap(map, isolate()->factory()->meta_map()); 384 CompareMap(map, isolate()->factory()->meta_map());
385 if (map.is(kScratchRegister)) popq(map); 385 if (map.is(kScratchRegister)) popq(map);
386 j(equal, &ok, Label::kNear); 386 j(equal, &ok, Label::kNear);
387 int3(); 387 int3();
388 bind(&ok); 388 bind(&ok);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 440
441 441
442 void MacroAssembler::RecordWrite( 442 void MacroAssembler::RecordWrite(
443 Register object, 443 Register object,
444 Register address, 444 Register address,
445 Register value, 445 Register value,
446 SaveFPRegsMode fp_mode, 446 SaveFPRegsMode fp_mode,
447 RememberedSetAction remembered_set_action, 447 RememberedSetAction remembered_set_action,
448 SmiCheck smi_check, 448 SmiCheck smi_check,
449 PointersToHereCheck pointers_to_here_check_for_value) { 449 PointersToHereCheck pointers_to_here_check_for_value) {
450 ASSERT(!object.is(value)); 450 DCHECK(!object.is(value));
451 ASSERT(!object.is(address)); 451 DCHECK(!object.is(address));
452 ASSERT(!value.is(address)); 452 DCHECK(!value.is(address));
453 AssertNotSmi(object); 453 AssertNotSmi(object);
454 454
455 if (remembered_set_action == OMIT_REMEMBERED_SET && 455 if (remembered_set_action == OMIT_REMEMBERED_SET &&
456 !FLAG_incremental_marking) { 456 !FLAG_incremental_marking) {
457 return; 457 return;
458 } 458 }
459 459
460 if (emit_debug_code()) { 460 if (emit_debug_code()) {
461 Label ok; 461 Label ok;
462 cmpp(value, Operand(address, 0)); 462 cmpp(value, Operand(address, 0));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 Abort(reason); 538 Abort(reason);
539 // Control will not return here. 539 // Control will not return here.
540 bind(&L); 540 bind(&L);
541 } 541 }
542 542
543 543
544 void MacroAssembler::CheckStackAlignment() { 544 void MacroAssembler::CheckStackAlignment() {
545 int frame_alignment = base::OS::ActivationFrameAlignment(); 545 int frame_alignment = base::OS::ActivationFrameAlignment();
546 int frame_alignment_mask = frame_alignment - 1; 546 int frame_alignment_mask = frame_alignment - 1;
547 if (frame_alignment > kPointerSize) { 547 if (frame_alignment > kPointerSize) {
548 ASSERT(IsPowerOf2(frame_alignment)); 548 DCHECK(IsPowerOf2(frame_alignment));
549 Label alignment_as_expected; 549 Label alignment_as_expected;
550 testp(rsp, Immediate(frame_alignment_mask)); 550 testp(rsp, Immediate(frame_alignment_mask));
551 j(zero, &alignment_as_expected, Label::kNear); 551 j(zero, &alignment_as_expected, Label::kNear);
552 // Abort if stack is not aligned. 552 // Abort if stack is not aligned.
553 int3(); 553 int3();
554 bind(&alignment_as_expected); 554 bind(&alignment_as_expected);
555 } 555 }
556 } 556 }
557 557
558 558
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 CallRuntime(Runtime::kAbort, 1); 593 CallRuntime(Runtime::kAbort, 1);
594 } else { 594 } else {
595 CallRuntime(Runtime::kAbort, 1); 595 CallRuntime(Runtime::kAbort, 1);
596 } 596 }
597 // Control will not return here. 597 // Control will not return here.
598 int3(); 598 int3();
599 } 599 }
600 600
601 601
602 void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 602 void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
603 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs 603 DCHECK(AllowThisStubCall(stub)); // Calls are not allowed in some stubs
604 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 604 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
605 } 605 }
606 606
607 607
608 void MacroAssembler::TailCallStub(CodeStub* stub) { 608 void MacroAssembler::TailCallStub(CodeStub* stub) {
609 Jump(stub->GetCode(), RelocInfo::CODE_TARGET); 609 Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
610 } 610 }
611 611
612 612
613 void MacroAssembler::StubReturn(int argc) { 613 void MacroAssembler::StubReturn(int argc) {
614 ASSERT(argc >= 1 && generating_stub()); 614 DCHECK(argc >= 1 && generating_stub());
615 ret((argc - 1) * kPointerSize); 615 ret((argc - 1) * kPointerSize);
616 } 616 }
617 617
618 618
619 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 619 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
620 return has_frame_ || !stub->SometimesSetsUpAFrame(); 620 return has_frame_ || !stub->SometimesSetsUpAFrame();
621 } 621 }
622 622
623 623
624 void MacroAssembler::IndexFromHash(Register hash, Register index) { 624 void MacroAssembler::IndexFromHash(Register hash, Register index) {
625 // The assert checks that the constants for the maximum number of digits 625 // The assert checks that the constants for the maximum number of digits
626 // for an array index cached in the hash field and the number of bits 626 // for an array index cached in the hash field and the number of bits
627 // reserved for it does not conflict. 627 // reserved for it does not conflict.
628 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 628 DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
629 (1 << String::kArrayIndexValueBits)); 629 (1 << String::kArrayIndexValueBits));
630 if (!hash.is(index)) { 630 if (!hash.is(index)) {
631 movl(index, hash); 631 movl(index, hash);
632 } 632 }
633 DecodeFieldToSmi<String::ArrayIndexValueBits>(index); 633 DecodeFieldToSmi<String::ArrayIndexValueBits>(index);
634 } 634 }
635 635
636 636
637 void MacroAssembler::CallRuntime(const Runtime::Function* f, 637 void MacroAssembler::CallRuntime(const Runtime::Function* f,
638 int num_arguments, 638 int num_arguments,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 int result_size) { 687 int result_size) {
688 TailCallExternalReference(ExternalReference(fid, isolate()), 688 TailCallExternalReference(ExternalReference(fid, isolate()),
689 num_arguments, 689 num_arguments,
690 result_size); 690 result_size);
691 } 691 }
692 692
693 693
694 static int Offset(ExternalReference ref0, ExternalReference ref1) { 694 static int Offset(ExternalReference ref0, ExternalReference ref1) {
695 int64_t offset = (ref0.address() - ref1.address()); 695 int64_t offset = (ref0.address() - ref1.address());
696 // Check that fits into int. 696 // Check that fits into int.
697 ASSERT(static_cast<int>(offset) == offset); 697 DCHECK(static_cast<int>(offset) == offset);
698 return static_cast<int>(offset); 698 return static_cast<int>(offset);
699 } 699 }
700 700
701 701
702 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { 702 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
703 EnterApiExitFrame(arg_stack_space); 703 EnterApiExitFrame(arg_stack_space);
704 } 704 }
705 705
706 706
707 void MacroAssembler::CallApiFunctionAndReturn( 707 void MacroAssembler::CallApiFunctionAndReturn(
(...skipping 16 matching lines...) Expand all
724 const int kNextOffset = 0; 724 const int kNextOffset = 0;
725 const int kLimitOffset = Offset( 725 const int kLimitOffset = Offset(
726 ExternalReference::handle_scope_limit_address(isolate()), 726 ExternalReference::handle_scope_limit_address(isolate()),
727 next_address); 727 next_address);
728 const int kLevelOffset = Offset( 728 const int kLevelOffset = Offset(
729 ExternalReference::handle_scope_level_address(isolate()), 729 ExternalReference::handle_scope_level_address(isolate()),
730 next_address); 730 next_address);
731 ExternalReference scheduled_exception_address = 731 ExternalReference scheduled_exception_address =
732 ExternalReference::scheduled_exception_address(isolate()); 732 ExternalReference::scheduled_exception_address(isolate());
733 733
734 ASSERT(rdx.is(function_address) || r8.is(function_address)); 734 DCHECK(rdx.is(function_address) || r8.is(function_address));
735 // Allocate HandleScope in callee-save registers. 735 // Allocate HandleScope in callee-save registers.
736 Register prev_next_address_reg = r14; 736 Register prev_next_address_reg = r14;
737 Register prev_limit_reg = rbx; 737 Register prev_limit_reg = rbx;
738 Register base_reg = r15; 738 Register base_reg = r15;
739 Move(base_reg, next_address); 739 Move(base_reg, next_address);
740 movp(prev_next_address_reg, Operand(base_reg, kNextOffset)); 740 movp(prev_next_address_reg, Operand(base_reg, kNextOffset));
741 movp(prev_limit_reg, Operand(base_reg, kLimitOffset)); 741 movp(prev_limit_reg, Operand(base_reg, kLimitOffset));
742 addl(Operand(base_reg, kLevelOffset), Immediate(1)); 742 addl(Operand(base_reg, kLevelOffset), Immediate(1));
743 743
744 if (FLAG_log_timer_events) { 744 if (FLAG_log_timer_events) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 LoadAddress(rbx, ext); 866 LoadAddress(rbx, ext);
867 CEntryStub ces(isolate(), result_size); 867 CEntryStub ces(isolate(), result_size);
868 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 868 jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
869 } 869 }
870 870
871 871
872 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 872 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
873 InvokeFlag flag, 873 InvokeFlag flag,
874 const CallWrapper& call_wrapper) { 874 const CallWrapper& call_wrapper) {
875 // You can't call a builtin without a valid frame. 875 // You can't call a builtin without a valid frame.
876 ASSERT(flag == JUMP_FUNCTION || has_frame()); 876 DCHECK(flag == JUMP_FUNCTION || has_frame());
877 877
878 // Rely on the assertion to check that the number of provided 878 // Rely on the assertion to check that the number of provided
879 // arguments match the expected number of arguments. Fake a 879 // arguments match the expected number of arguments. Fake a
880 // parameter count to avoid emitting code to do the check. 880 // parameter count to avoid emitting code to do the check.
881 ParameterCount expected(0); 881 ParameterCount expected(0);
882 GetBuiltinEntry(rdx, id); 882 GetBuiltinEntry(rdx, id);
883 InvokeCode(rdx, expected, expected, flag, call_wrapper); 883 InvokeCode(rdx, expected, expected, flag, call_wrapper);
884 } 884 }
885 885
886 886
887 void MacroAssembler::GetBuiltinFunction(Register target, 887 void MacroAssembler::GetBuiltinFunction(Register target,
888 Builtins::JavaScript id) { 888 Builtins::JavaScript id) {
889 // Load the builtins object into target register. 889 // Load the builtins object into target register.
890 movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 890 movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
891 movp(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); 891 movp(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
892 movp(target, FieldOperand(target, 892 movp(target, FieldOperand(target,
893 JSBuiltinsObject::OffsetOfFunctionWithId(id))); 893 JSBuiltinsObject::OffsetOfFunctionWithId(id)));
894 } 894 }
895 895
896 896
897 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { 897 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
898 ASSERT(!target.is(rdi)); 898 DCHECK(!target.is(rdi));
899 // Load the JavaScript builtin function from the builtins object. 899 // Load the JavaScript builtin function from the builtins object.
900 GetBuiltinFunction(rdi, id); 900 GetBuiltinFunction(rdi, id);
901 movp(target, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 901 movp(target, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
902 } 902 }
903 903
904 904
905 #define REG(Name) { kRegister_ ## Name ## _Code } 905 #define REG(Name) { kRegister_ ## Name ## _Code }
906 906
907 static const Register saved_regs[] = { 907 static const Register saved_regs[] = {
908 REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), 908 REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8),
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 } 964 }
965 965
966 966
967 void MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) { 967 void MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) {
968 xorps(dst, dst); 968 xorps(dst, dst);
969 cvtlsi2sd(dst, src); 969 cvtlsi2sd(dst, src);
970 } 970 }
971 971
972 972
973 void MacroAssembler::Load(Register dst, const Operand& src, Representation r) { 973 void MacroAssembler::Load(Register dst, const Operand& src, Representation r) {
974 ASSERT(!r.IsDouble()); 974 DCHECK(!r.IsDouble());
975 if (r.IsInteger8()) { 975 if (r.IsInteger8()) {
976 movsxbq(dst, src); 976 movsxbq(dst, src);
977 } else if (r.IsUInteger8()) { 977 } else if (r.IsUInteger8()) {
978 movzxbl(dst, src); 978 movzxbl(dst, src);
979 } else if (r.IsInteger16()) { 979 } else if (r.IsInteger16()) {
980 movsxwq(dst, src); 980 movsxwq(dst, src);
981 } else if (r.IsUInteger16()) { 981 } else if (r.IsUInteger16()) {
982 movzxwl(dst, src); 982 movzxwl(dst, src);
983 } else if (r.IsInteger32()) { 983 } else if (r.IsInteger32()) {
984 movl(dst, src); 984 movl(dst, src);
985 } else { 985 } else {
986 movp(dst, src); 986 movp(dst, src);
987 } 987 }
988 } 988 }
989 989
990 990
991 void MacroAssembler::Store(const Operand& dst, Register src, Representation r) { 991 void MacroAssembler::Store(const Operand& dst, Register src, Representation r) {
992 ASSERT(!r.IsDouble()); 992 DCHECK(!r.IsDouble());
993 if (r.IsInteger8() || r.IsUInteger8()) { 993 if (r.IsInteger8() || r.IsUInteger8()) {
994 movb(dst, src); 994 movb(dst, src);
995 } else if (r.IsInteger16() || r.IsUInteger16()) { 995 } else if (r.IsInteger16() || r.IsUInteger16()) {
996 movw(dst, src); 996 movw(dst, src);
997 } else if (r.IsInteger32()) { 997 } else if (r.IsInteger32()) {
998 movl(dst, src); 998 movl(dst, src);
999 } else { 999 } else {
1000 if (r.IsHeapObject()) { 1000 if (r.IsHeapObject()) {
1001 AssertNotSmi(src); 1001 AssertNotSmi(src);
1002 } else if (r.IsSmi()) { 1002 } else if (r.IsSmi()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 // ---------------------------------------------------------------------------- 1037 // ----------------------------------------------------------------------------
1038 // Smi tagging, untagging and tag detection. 1038 // Smi tagging, untagging and tag detection.
1039 1039
1040 bool MacroAssembler::IsUnsafeInt(const int32_t x) { 1040 bool MacroAssembler::IsUnsafeInt(const int32_t x) {
1041 static const int kMaxBits = 17; 1041 static const int kMaxBits = 17;
1042 return !is_intn(x, kMaxBits); 1042 return !is_intn(x, kMaxBits);
1043 } 1043 }
1044 1044
1045 1045
1046 void MacroAssembler::SafeMove(Register dst, Smi* src) { 1046 void MacroAssembler::SafeMove(Register dst, Smi* src) {
1047 ASSERT(!dst.is(kScratchRegister)); 1047 DCHECK(!dst.is(kScratchRegister));
1048 if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1048 if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
1049 if (SmiValuesAre32Bits()) { 1049 if (SmiValuesAre32Bits()) {
1050 // JIT cookie can be converted to Smi. 1050 // JIT cookie can be converted to Smi.
1051 Move(dst, Smi::FromInt(src->value() ^ jit_cookie())); 1051 Move(dst, Smi::FromInt(src->value() ^ jit_cookie()));
1052 Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1052 Move(kScratchRegister, Smi::FromInt(jit_cookie()));
1053 xorp(dst, kScratchRegister); 1053 xorp(dst, kScratchRegister);
1054 } else { 1054 } else {
1055 ASSERT(SmiValuesAre31Bits()); 1055 DCHECK(SmiValuesAre31Bits());
1056 int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1056 int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src));
1057 movp(dst, Immediate(value ^ jit_cookie())); 1057 movp(dst, Immediate(value ^ jit_cookie()));
1058 xorp(dst, Immediate(jit_cookie())); 1058 xorp(dst, Immediate(jit_cookie()));
1059 } 1059 }
1060 } else { 1060 } else {
1061 Move(dst, src); 1061 Move(dst, src);
1062 } 1062 }
1063 } 1063 }
1064 1064
1065 1065
1066 void MacroAssembler::SafePush(Smi* src) { 1066 void MacroAssembler::SafePush(Smi* src) {
1067 if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1067 if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
1068 if (SmiValuesAre32Bits()) { 1068 if (SmiValuesAre32Bits()) {
1069 // JIT cookie can be converted to Smi. 1069 // JIT cookie can be converted to Smi.
1070 Push(Smi::FromInt(src->value() ^ jit_cookie())); 1070 Push(Smi::FromInt(src->value() ^ jit_cookie()));
1071 Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1071 Move(kScratchRegister, Smi::FromInt(jit_cookie()));
1072 xorp(Operand(rsp, 0), kScratchRegister); 1072 xorp(Operand(rsp, 0), kScratchRegister);
1073 } else { 1073 } else {
1074 ASSERT(SmiValuesAre31Bits()); 1074 DCHECK(SmiValuesAre31Bits());
1075 int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1075 int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src));
1076 Push(Immediate(value ^ jit_cookie())); 1076 Push(Immediate(value ^ jit_cookie()));
1077 xorp(Operand(rsp, 0), Immediate(jit_cookie())); 1077 xorp(Operand(rsp, 0), Immediate(jit_cookie()));
1078 } 1078 }
1079 } else { 1079 } else {
1080 Push(src); 1080 Push(src);
1081 } 1081 }
1082 } 1082 }
1083 1083
1084 1084
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { 1164 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) {
1165 if (emit_debug_code()) { 1165 if (emit_debug_code()) {
1166 testb(dst, Immediate(0x01)); 1166 testb(dst, Immediate(0x01));
1167 Label ok; 1167 Label ok;
1168 j(zero, &ok, Label::kNear); 1168 j(zero, &ok, Label::kNear);
1169 Abort(kInteger32ToSmiFieldWritingToNonSmiLocation); 1169 Abort(kInteger32ToSmiFieldWritingToNonSmiLocation);
1170 bind(&ok); 1170 bind(&ok);
1171 } 1171 }
1172 1172
1173 if (SmiValuesAre32Bits()) { 1173 if (SmiValuesAre32Bits()) {
1174 ASSERT(kSmiShift % kBitsPerByte == 0); 1174 DCHECK(kSmiShift % kBitsPerByte == 0);
1175 movl(Operand(dst, kSmiShift / kBitsPerByte), src); 1175 movl(Operand(dst, kSmiShift / kBitsPerByte), src);
1176 } else { 1176 } else {
1177 ASSERT(SmiValuesAre31Bits()); 1177 DCHECK(SmiValuesAre31Bits());
1178 Integer32ToSmi(kScratchRegister, src); 1178 Integer32ToSmi(kScratchRegister, src);
1179 movp(dst, kScratchRegister); 1179 movp(dst, kScratchRegister);
1180 } 1180 }
1181 } 1181 }
1182 1182
1183 1183
1184 void MacroAssembler::Integer64PlusConstantToSmi(Register dst, 1184 void MacroAssembler::Integer64PlusConstantToSmi(Register dst,
1185 Register src, 1185 Register src,
1186 int constant) { 1186 int constant) {
1187 if (dst.is(src)) { 1187 if (dst.is(src)) {
1188 addl(dst, Immediate(constant)); 1188 addl(dst, Immediate(constant));
1189 } else { 1189 } else {
1190 leal(dst, Operand(src, constant)); 1190 leal(dst, Operand(src, constant));
1191 } 1191 }
1192 shlp(dst, Immediate(kSmiShift)); 1192 shlp(dst, Immediate(kSmiShift));
1193 } 1193 }
1194 1194
1195 1195
1196 void MacroAssembler::SmiToInteger32(Register dst, Register src) { 1196 void MacroAssembler::SmiToInteger32(Register dst, Register src) {
1197 STATIC_ASSERT(kSmiTag == 0); 1197 STATIC_ASSERT(kSmiTag == 0);
1198 if (!dst.is(src)) { 1198 if (!dst.is(src)) {
1199 movp(dst, src); 1199 movp(dst, src);
1200 } 1200 }
1201 1201
1202 if (SmiValuesAre32Bits()) { 1202 if (SmiValuesAre32Bits()) {
1203 shrp(dst, Immediate(kSmiShift)); 1203 shrp(dst, Immediate(kSmiShift));
1204 } else { 1204 } else {
1205 ASSERT(SmiValuesAre31Bits()); 1205 DCHECK(SmiValuesAre31Bits());
1206 sarl(dst, Immediate(kSmiShift)); 1206 sarl(dst, Immediate(kSmiShift));
1207 } 1207 }
1208 } 1208 }
1209 1209
1210 1210
1211 void MacroAssembler::SmiToInteger32(Register dst, const Operand& src) { 1211 void MacroAssembler::SmiToInteger32(Register dst, const Operand& src) {
1212 if (SmiValuesAre32Bits()) { 1212 if (SmiValuesAre32Bits()) {
1213 movl(dst, Operand(src, kSmiShift / kBitsPerByte)); 1213 movl(dst, Operand(src, kSmiShift / kBitsPerByte));
1214 } else { 1214 } else {
1215 ASSERT(SmiValuesAre31Bits()); 1215 DCHECK(SmiValuesAre31Bits());
1216 movl(dst, src); 1216 movl(dst, src);
1217 sarl(dst, Immediate(kSmiShift)); 1217 sarl(dst, Immediate(kSmiShift));
1218 } 1218 }
1219 } 1219 }
1220 1220
1221 1221
1222 void MacroAssembler::SmiToInteger64(Register dst, Register src) { 1222 void MacroAssembler::SmiToInteger64(Register dst, Register src) {
1223 STATIC_ASSERT(kSmiTag == 0); 1223 STATIC_ASSERT(kSmiTag == 0);
1224 if (!dst.is(src)) { 1224 if (!dst.is(src)) {
1225 movp(dst, src); 1225 movp(dst, src);
1226 } 1226 }
1227 sarp(dst, Immediate(kSmiShift)); 1227 sarp(dst, Immediate(kSmiShift));
1228 if (kPointerSize == kInt32Size) { 1228 if (kPointerSize == kInt32Size) {
1229 // Sign extend to 64-bit. 1229 // Sign extend to 64-bit.
1230 movsxlq(dst, dst); 1230 movsxlq(dst, dst);
1231 } 1231 }
1232 } 1232 }
1233 1233
1234 1234
1235 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { 1235 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) {
1236 if (SmiValuesAre32Bits()) { 1236 if (SmiValuesAre32Bits()) {
1237 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); 1237 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
1238 } else { 1238 } else {
1239 ASSERT(SmiValuesAre31Bits()); 1239 DCHECK(SmiValuesAre31Bits());
1240 movp(dst, src); 1240 movp(dst, src);
1241 SmiToInteger64(dst, dst); 1241 SmiToInteger64(dst, dst);
1242 } 1242 }
1243 } 1243 }
1244 1244
1245 1245
1246 void MacroAssembler::SmiTest(Register src) { 1246 void MacroAssembler::SmiTest(Register src) {
1247 AssertSmi(src); 1247 AssertSmi(src);
1248 testp(src, src); 1248 testp(src, src);
1249 } 1249 }
1250 1250
1251 1251
1252 void MacroAssembler::SmiCompare(Register smi1, Register smi2) { 1252 void MacroAssembler::SmiCompare(Register smi1, Register smi2) {
1253 AssertSmi(smi1); 1253 AssertSmi(smi1);
1254 AssertSmi(smi2); 1254 AssertSmi(smi2);
1255 cmpp(smi1, smi2); 1255 cmpp(smi1, smi2);
1256 } 1256 }
1257 1257
1258 1258
1259 void MacroAssembler::SmiCompare(Register dst, Smi* src) { 1259 void MacroAssembler::SmiCompare(Register dst, Smi* src) {
1260 AssertSmi(dst); 1260 AssertSmi(dst);
1261 Cmp(dst, src); 1261 Cmp(dst, src);
1262 } 1262 }
1263 1263
1264 1264
1265 void MacroAssembler::Cmp(Register dst, Smi* src) { 1265 void MacroAssembler::Cmp(Register dst, Smi* src) {
1266 ASSERT(!dst.is(kScratchRegister)); 1266 DCHECK(!dst.is(kScratchRegister));
1267 if (src->value() == 0) { 1267 if (src->value() == 0) {
1268 testp(dst, dst); 1268 testp(dst, dst);
1269 } else { 1269 } else {
1270 Register constant_reg = GetSmiConstant(src); 1270 Register constant_reg = GetSmiConstant(src);
1271 cmpp(dst, constant_reg); 1271 cmpp(dst, constant_reg);
1272 } 1272 }
1273 } 1273 }
1274 1274
1275 1275
1276 void MacroAssembler::SmiCompare(Register dst, const Operand& src) { 1276 void MacroAssembler::SmiCompare(Register dst, const Operand& src) {
1277 AssertSmi(dst); 1277 AssertSmi(dst);
1278 AssertSmi(src); 1278 AssertSmi(src);
1279 cmpp(dst, src); 1279 cmpp(dst, src);
1280 } 1280 }
1281 1281
1282 1282
1283 void MacroAssembler::SmiCompare(const Operand& dst, Register src) { 1283 void MacroAssembler::SmiCompare(const Operand& dst, Register src) {
1284 AssertSmi(dst); 1284 AssertSmi(dst);
1285 AssertSmi(src); 1285 AssertSmi(src);
1286 cmpp(dst, src); 1286 cmpp(dst, src);
1287 } 1287 }
1288 1288
1289 1289
1290 void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) { 1290 void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) {
1291 AssertSmi(dst); 1291 AssertSmi(dst);
1292 if (SmiValuesAre32Bits()) { 1292 if (SmiValuesAre32Bits()) {
1293 cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value())); 1293 cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value()));
1294 } else { 1294 } else {
1295 ASSERT(SmiValuesAre31Bits()); 1295 DCHECK(SmiValuesAre31Bits());
1296 cmpl(dst, Immediate(src)); 1296 cmpl(dst, Immediate(src));
1297 } 1297 }
1298 } 1298 }
1299 1299
1300 1300
1301 void MacroAssembler::Cmp(const Operand& dst, Smi* src) { 1301 void MacroAssembler::Cmp(const Operand& dst, Smi* src) {
1302 // The Operand cannot use the smi register. 1302 // The Operand cannot use the smi register.
1303 Register smi_reg = GetSmiConstant(src); 1303 Register smi_reg = GetSmiConstant(src);
1304 ASSERT(!dst.AddressUsesRegister(smi_reg)); 1304 DCHECK(!dst.AddressUsesRegister(smi_reg));
1305 cmpp(dst, smi_reg); 1305 cmpp(dst, smi_reg);
1306 } 1306 }
1307 1307
1308 1308
1309 void MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) { 1309 void MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) {
1310 if (SmiValuesAre32Bits()) { 1310 if (SmiValuesAre32Bits()) {
1311 cmpl(Operand(dst, kSmiShift / kBitsPerByte), src); 1311 cmpl(Operand(dst, kSmiShift / kBitsPerByte), src);
1312 } else { 1312 } else {
1313 ASSERT(SmiValuesAre31Bits()); 1313 DCHECK(SmiValuesAre31Bits());
1314 SmiToInteger32(kScratchRegister, dst); 1314 SmiToInteger32(kScratchRegister, dst);
1315 cmpl(kScratchRegister, src); 1315 cmpl(kScratchRegister, src);
1316 } 1316 }
1317 } 1317 }
1318 1318
1319 1319
1320 void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 1320 void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
1321 Register src, 1321 Register src,
1322 int power) { 1322 int power) {
1323 ASSERT(power >= 0); 1323 DCHECK(power >= 0);
1324 ASSERT(power < 64); 1324 DCHECK(power < 64);
1325 if (power == 0) { 1325 if (power == 0) {
1326 SmiToInteger64(dst, src); 1326 SmiToInteger64(dst, src);
1327 return; 1327 return;
1328 } 1328 }
1329 if (!dst.is(src)) { 1329 if (!dst.is(src)) {
1330 movp(dst, src); 1330 movp(dst, src);
1331 } 1331 }
1332 if (power < kSmiShift) { 1332 if (power < kSmiShift) {
1333 sarp(dst, Immediate(kSmiShift - power)); 1333 sarp(dst, Immediate(kSmiShift - power));
1334 } else if (power > kSmiShift) { 1334 } else if (power > kSmiShift) {
1335 shlp(dst, Immediate(power - kSmiShift)); 1335 shlp(dst, Immediate(power - kSmiShift));
1336 } 1336 }
1337 } 1337 }
1338 1338
1339 1339
1340 void MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst, 1340 void MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst,
1341 Register src, 1341 Register src,
1342 int power) { 1342 int power) {
1343 ASSERT((0 <= power) && (power < 32)); 1343 DCHECK((0 <= power) && (power < 32));
1344 if (dst.is(src)) { 1344 if (dst.is(src)) {
1345 shrp(dst, Immediate(power + kSmiShift)); 1345 shrp(dst, Immediate(power + kSmiShift));
1346 } else { 1346 } else {
1347 UNIMPLEMENTED(); // Not used. 1347 UNIMPLEMENTED(); // Not used.
1348 } 1348 }
1349 } 1349 }
1350 1350
1351 1351
1352 void MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2, 1352 void MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2,
1353 Label* on_not_smis, 1353 Label* on_not_smis,
1354 Label::Distance near_jump) { 1354 Label::Distance near_jump) {
1355 if (dst.is(src1) || dst.is(src2)) { 1355 if (dst.is(src1) || dst.is(src2)) {
1356 ASSERT(!src1.is(kScratchRegister)); 1356 DCHECK(!src1.is(kScratchRegister));
1357 ASSERT(!src2.is(kScratchRegister)); 1357 DCHECK(!src2.is(kScratchRegister));
1358 movp(kScratchRegister, src1); 1358 movp(kScratchRegister, src1);
1359 orp(kScratchRegister, src2); 1359 orp(kScratchRegister, src2);
1360 JumpIfNotSmi(kScratchRegister, on_not_smis, near_jump); 1360 JumpIfNotSmi(kScratchRegister, on_not_smis, near_jump);
1361 movp(dst, kScratchRegister); 1361 movp(dst, kScratchRegister);
1362 } else { 1362 } else {
1363 movp(dst, src1); 1363 movp(dst, src1);
1364 orp(dst, src2); 1364 orp(dst, src2);
1365 JumpIfNotSmi(dst, on_not_smis, near_jump); 1365 JumpIfNotSmi(dst, on_not_smis, near_jump);
1366 } 1366 }
1367 } 1367 }
(...skipping 25 matching lines...) Expand all
1393 1393
1394 Condition MacroAssembler::CheckBothSmi(Register first, Register second) { 1394 Condition MacroAssembler::CheckBothSmi(Register first, Register second) {
1395 if (first.is(second)) { 1395 if (first.is(second)) {
1396 return CheckSmi(first); 1396 return CheckSmi(first);
1397 } 1397 }
1398 STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); 1398 STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3);
1399 if (SmiValuesAre32Bits()) { 1399 if (SmiValuesAre32Bits()) {
1400 leal(kScratchRegister, Operand(first, second, times_1, 0)); 1400 leal(kScratchRegister, Operand(first, second, times_1, 0));
1401 testb(kScratchRegister, Immediate(0x03)); 1401 testb(kScratchRegister, Immediate(0x03));
1402 } else { 1402 } else {
1403 ASSERT(SmiValuesAre31Bits()); 1403 DCHECK(SmiValuesAre31Bits());
1404 movl(kScratchRegister, first); 1404 movl(kScratchRegister, first);
1405 orl(kScratchRegister, second); 1405 orl(kScratchRegister, second);
1406 testb(kScratchRegister, Immediate(kSmiTagMask)); 1406 testb(kScratchRegister, Immediate(kSmiTagMask));
1407 } 1407 }
1408 return zero; 1408 return zero;
1409 } 1409 }
1410 1410
1411 1411
1412 Condition MacroAssembler::CheckBothNonNegativeSmi(Register first, 1412 Condition MacroAssembler::CheckBothNonNegativeSmi(Register first,
1413 Register second) { 1413 Register second) {
(...skipping 21 matching lines...) Expand all
1435 movl(scratch, first); 1435 movl(scratch, first);
1436 } 1436 }
1437 andl(scratch, second); 1437 andl(scratch, second);
1438 } 1438 }
1439 testb(scratch, Immediate(kSmiTagMask)); 1439 testb(scratch, Immediate(kSmiTagMask));
1440 return zero; 1440 return zero;
1441 } 1441 }
1442 1442
1443 1443
1444 Condition MacroAssembler::CheckIsMinSmi(Register src) { 1444 Condition MacroAssembler::CheckIsMinSmi(Register src) {
1445 ASSERT(!src.is(kScratchRegister)); 1445 DCHECK(!src.is(kScratchRegister));
1446 // If we overflow by subtracting one, it's the minimal smi value. 1446 // If we overflow by subtracting one, it's the minimal smi value.
1447 cmpp(src, kSmiConstantRegister); 1447 cmpp(src, kSmiConstantRegister);
1448 return overflow; 1448 return overflow;
1449 } 1449 }
1450 1450
1451 1451
1452 Condition MacroAssembler::CheckInteger32ValidSmiValue(Register src) { 1452 Condition MacroAssembler::CheckInteger32ValidSmiValue(Register src) {
1453 if (SmiValuesAre32Bits()) { 1453 if (SmiValuesAre32Bits()) {
1454 // A 32-bit integer value can always be converted to a smi. 1454 // A 32-bit integer value can always be converted to a smi.
1455 return always; 1455 return always;
1456 } else { 1456 } else {
1457 ASSERT(SmiValuesAre31Bits()); 1457 DCHECK(SmiValuesAre31Bits());
1458 cmpl(src, Immediate(0xc0000000)); 1458 cmpl(src, Immediate(0xc0000000));
1459 return positive; 1459 return positive;
1460 } 1460 }
1461 } 1461 }
1462 1462
1463 1463
1464 Condition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) { 1464 Condition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) {
1465 if (SmiValuesAre32Bits()) { 1465 if (SmiValuesAre32Bits()) {
1466 // An unsigned 32-bit integer value is valid as long as the high bit 1466 // An unsigned 32-bit integer value is valid as long as the high bit
1467 // is not set. 1467 // is not set.
1468 testl(src, src); 1468 testl(src, src);
1469 return positive; 1469 return positive;
1470 } else { 1470 } else {
1471 ASSERT(SmiValuesAre31Bits()); 1471 DCHECK(SmiValuesAre31Bits());
1472 testl(src, Immediate(0xc0000000)); 1472 testl(src, Immediate(0xc0000000));
1473 return zero; 1473 return zero;
1474 } 1474 }
1475 } 1475 }
1476 1476
1477 1477
1478 void MacroAssembler::CheckSmiToIndicator(Register dst, Register src) { 1478 void MacroAssembler::CheckSmiToIndicator(Register dst, Register src) {
1479 if (dst.is(src)) { 1479 if (dst.is(src)) {
1480 andl(dst, Immediate(kSmiTagMask)); 1480 andl(dst, Immediate(kSmiTagMask));
1481 } else { 1481 } else {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 } 1579 }
1580 1580
1581 1581
1582 void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { 1582 void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) {
1583 if (constant->value() == 0) { 1583 if (constant->value() == 0) {
1584 if (!dst.is(src)) { 1584 if (!dst.is(src)) {
1585 movp(dst, src); 1585 movp(dst, src);
1586 } 1586 }
1587 return; 1587 return;
1588 } else if (dst.is(src)) { 1588 } else if (dst.is(src)) {
1589 ASSERT(!dst.is(kScratchRegister)); 1589 DCHECK(!dst.is(kScratchRegister));
1590 switch (constant->value()) { 1590 switch (constant->value()) {
1591 case 1: 1591 case 1:
1592 addp(dst, kSmiConstantRegister); 1592 addp(dst, kSmiConstantRegister);
1593 return; 1593 return;
1594 case 2: 1594 case 2:
1595 leap(dst, Operand(src, kSmiConstantRegister, times_2, 0)); 1595 leap(dst, Operand(src, kSmiConstantRegister, times_2, 0));
1596 return; 1596 return;
1597 case 4: 1597 case 4:
1598 leap(dst, Operand(src, kSmiConstantRegister, times_4, 0)); 1598 leap(dst, Operand(src, kSmiConstantRegister, times_4, 0));
1599 return; 1599 return;
(...skipping 27 matching lines...) Expand all
1627 } 1627 }
1628 } 1628 }
1629 1629
1630 1630
1631 void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) { 1631 void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) {
1632 if (constant->value() != 0) { 1632 if (constant->value() != 0) {
1633 if (SmiValuesAre32Bits()) { 1633 if (SmiValuesAre32Bits()) {
1634 addl(Operand(dst, kSmiShift / kBitsPerByte), 1634 addl(Operand(dst, kSmiShift / kBitsPerByte),
1635 Immediate(constant->value())); 1635 Immediate(constant->value()));
1636 } else { 1636 } else {
1637 ASSERT(SmiValuesAre31Bits()); 1637 DCHECK(SmiValuesAre31Bits());
1638 addp(dst, Immediate(constant)); 1638 addp(dst, Immediate(constant));
1639 } 1639 }
1640 } 1640 }
1641 } 1641 }
1642 1642
1643 1643
1644 void MacroAssembler::SmiAddConstant(Register dst, 1644 void MacroAssembler::SmiAddConstant(Register dst,
1645 Register src, 1645 Register src,
1646 Smi* constant, 1646 Smi* constant,
1647 SmiOperationExecutionMode mode, 1647 SmiOperationExecutionMode mode,
1648 Label* bailout_label, 1648 Label* bailout_label,
1649 Label::Distance near_jump) { 1649 Label::Distance near_jump) {
1650 if (constant->value() == 0) { 1650 if (constant->value() == 0) {
1651 if (!dst.is(src)) { 1651 if (!dst.is(src)) {
1652 movp(dst, src); 1652 movp(dst, src);
1653 } 1653 }
1654 } else if (dst.is(src)) { 1654 } else if (dst.is(src)) {
1655 ASSERT(!dst.is(kScratchRegister)); 1655 DCHECK(!dst.is(kScratchRegister));
1656 LoadSmiConstant(kScratchRegister, constant); 1656 LoadSmiConstant(kScratchRegister, constant);
1657 addp(dst, kScratchRegister); 1657 addp(dst, kScratchRegister);
1658 if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) { 1658 if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) {
1659 j(no_overflow, bailout_label, near_jump); 1659 j(no_overflow, bailout_label, near_jump);
1660 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1660 DCHECK(mode.Contains(PRESERVE_SOURCE_REGISTER));
1661 subp(dst, kScratchRegister); 1661 subp(dst, kScratchRegister);
1662 } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) { 1662 } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) {
1663 if (mode.Contains(PRESERVE_SOURCE_REGISTER)) { 1663 if (mode.Contains(PRESERVE_SOURCE_REGISTER)) {
1664 Label done; 1664 Label done;
1665 j(no_overflow, &done, Label::kNear); 1665 j(no_overflow, &done, Label::kNear);
1666 subp(dst, kScratchRegister); 1666 subp(dst, kScratchRegister);
1667 jmp(bailout_label, near_jump); 1667 jmp(bailout_label, near_jump);
1668 bind(&done); 1668 bind(&done);
1669 } else { 1669 } else {
1670 // Bailout if overflow without reserving src. 1670 // Bailout if overflow without reserving src.
1671 j(overflow, bailout_label, near_jump); 1671 j(overflow, bailout_label, near_jump);
1672 } 1672 }
1673 } else { 1673 } else {
1674 CHECK(mode.IsEmpty()); 1674 CHECK(mode.IsEmpty());
1675 } 1675 }
1676 } else { 1676 } else {
1677 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1677 DCHECK(mode.Contains(PRESERVE_SOURCE_REGISTER));
1678 ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW)); 1678 DCHECK(mode.Contains(BAILOUT_ON_OVERFLOW));
1679 LoadSmiConstant(dst, constant); 1679 LoadSmiConstant(dst, constant);
1680 addp(dst, src); 1680 addp(dst, src);
1681 j(overflow, bailout_label, near_jump); 1681 j(overflow, bailout_label, near_jump);
1682 } 1682 }
1683 } 1683 }
1684 1684
1685 1685
1686 void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) { 1686 void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) {
1687 if (constant->value() == 0) { 1687 if (constant->value() == 0) {
1688 if (!dst.is(src)) { 1688 if (!dst.is(src)) {
1689 movp(dst, src); 1689 movp(dst, src);
1690 } 1690 }
1691 } else if (dst.is(src)) { 1691 } else if (dst.is(src)) {
1692 ASSERT(!dst.is(kScratchRegister)); 1692 DCHECK(!dst.is(kScratchRegister));
1693 Register constant_reg = GetSmiConstant(constant); 1693 Register constant_reg = GetSmiConstant(constant);
1694 subp(dst, constant_reg); 1694 subp(dst, constant_reg);
1695 } else { 1695 } else {
1696 if (constant->value() == Smi::kMinValue) { 1696 if (constant->value() == Smi::kMinValue) {
1697 LoadSmiConstant(dst, constant); 1697 LoadSmiConstant(dst, constant);
1698 // Adding and subtracting the min-value gives the same result, it only 1698 // Adding and subtracting the min-value gives the same result, it only
1699 // differs on the overflow bit, which we don't check here. 1699 // differs on the overflow bit, which we don't check here.
1700 addp(dst, src); 1700 addp(dst, src);
1701 } else { 1701 } else {
1702 // Subtract by adding the negation. 1702 // Subtract by adding the negation.
1703 LoadSmiConstant(dst, Smi::FromInt(-constant->value())); 1703 LoadSmiConstant(dst, Smi::FromInt(-constant->value()));
1704 addp(dst, src); 1704 addp(dst, src);
1705 } 1705 }
1706 } 1706 }
1707 } 1707 }
1708 1708
1709 1709
1710 void MacroAssembler::SmiSubConstant(Register dst, 1710 void MacroAssembler::SmiSubConstant(Register dst,
1711 Register src, 1711 Register src,
1712 Smi* constant, 1712 Smi* constant,
1713 SmiOperationExecutionMode mode, 1713 SmiOperationExecutionMode mode,
1714 Label* bailout_label, 1714 Label* bailout_label,
1715 Label::Distance near_jump) { 1715 Label::Distance near_jump) {
1716 if (constant->value() == 0) { 1716 if (constant->value() == 0) {
1717 if (!dst.is(src)) { 1717 if (!dst.is(src)) {
1718 movp(dst, src); 1718 movp(dst, src);
1719 } 1719 }
1720 } else if (dst.is(src)) { 1720 } else if (dst.is(src)) {
1721 ASSERT(!dst.is(kScratchRegister)); 1721 DCHECK(!dst.is(kScratchRegister));
1722 LoadSmiConstant(kScratchRegister, constant); 1722 LoadSmiConstant(kScratchRegister, constant);
1723 subp(dst, kScratchRegister); 1723 subp(dst, kScratchRegister);
1724 if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) { 1724 if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) {
1725 j(no_overflow, bailout_label, near_jump); 1725 j(no_overflow, bailout_label, near_jump);
1726 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1726 DCHECK(mode.Contains(PRESERVE_SOURCE_REGISTER));
1727 addp(dst, kScratchRegister); 1727 addp(dst, kScratchRegister);
1728 } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) { 1728 } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) {
1729 if (mode.Contains(PRESERVE_SOURCE_REGISTER)) { 1729 if (mode.Contains(PRESERVE_SOURCE_REGISTER)) {
1730 Label done; 1730 Label done;
1731 j(no_overflow, &done, Label::kNear); 1731 j(no_overflow, &done, Label::kNear);
1732 addp(dst, kScratchRegister); 1732 addp(dst, kScratchRegister);
1733 jmp(bailout_label, near_jump); 1733 jmp(bailout_label, near_jump);
1734 bind(&done); 1734 bind(&done);
1735 } else { 1735 } else {
1736 // Bailout if overflow without reserving src. 1736 // Bailout if overflow without reserving src.
1737 j(overflow, bailout_label, near_jump); 1737 j(overflow, bailout_label, near_jump);
1738 } 1738 }
1739 } else { 1739 } else {
1740 CHECK(mode.IsEmpty()); 1740 CHECK(mode.IsEmpty());
1741 } 1741 }
1742 } else { 1742 } else {
1743 ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1743 DCHECK(mode.Contains(PRESERVE_SOURCE_REGISTER));
1744 ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW)); 1744 DCHECK(mode.Contains(BAILOUT_ON_OVERFLOW));
1745 if (constant->value() == Smi::kMinValue) { 1745 if (constant->value() == Smi::kMinValue) {
1746 ASSERT(!dst.is(kScratchRegister)); 1746 DCHECK(!dst.is(kScratchRegister));
1747 movp(dst, src); 1747 movp(dst, src);
1748 LoadSmiConstant(kScratchRegister, constant); 1748 LoadSmiConstant(kScratchRegister, constant);
1749 subp(dst, kScratchRegister); 1749 subp(dst, kScratchRegister);
1750 j(overflow, bailout_label, near_jump); 1750 j(overflow, bailout_label, near_jump);
1751 } else { 1751 } else {
1752 // Subtract by adding the negation. 1752 // Subtract by adding the negation.
1753 LoadSmiConstant(dst, Smi::FromInt(-(constant->value()))); 1753 LoadSmiConstant(dst, Smi::FromInt(-(constant->value())));
1754 addp(dst, src); 1754 addp(dst, src);
1755 j(overflow, bailout_label, near_jump); 1755 j(overflow, bailout_label, near_jump);
1756 } 1756 }
1757 } 1757 }
1758 } 1758 }
1759 1759
1760 1760
1761 void MacroAssembler::SmiNeg(Register dst, 1761 void MacroAssembler::SmiNeg(Register dst,
1762 Register src, 1762 Register src,
1763 Label* on_smi_result, 1763 Label* on_smi_result,
1764 Label::Distance near_jump) { 1764 Label::Distance near_jump) {
1765 if (dst.is(src)) { 1765 if (dst.is(src)) {
1766 ASSERT(!dst.is(kScratchRegister)); 1766 DCHECK(!dst.is(kScratchRegister));
1767 movp(kScratchRegister, src); 1767 movp(kScratchRegister, src);
1768 negp(dst); // Low 32 bits are retained as zero by negation. 1768 negp(dst); // Low 32 bits are retained as zero by negation.
1769 // Test if result is zero or Smi::kMinValue. 1769 // Test if result is zero or Smi::kMinValue.
1770 cmpp(dst, kScratchRegister); 1770 cmpp(dst, kScratchRegister);
1771 j(not_equal, on_smi_result, near_jump); 1771 j(not_equal, on_smi_result, near_jump);
1772 movp(src, kScratchRegister); 1772 movp(src, kScratchRegister);
1773 } else { 1773 } else {
1774 movp(dst, src); 1774 movp(dst, src);
1775 negp(dst); 1775 negp(dst);
1776 cmpp(dst, src); 1776 cmpp(dst, src);
(...skipping 24 matching lines...) Expand all
1801 masm->j(overflow, on_not_smi_result, near_jump); 1801 masm->j(overflow, on_not_smi_result, near_jump);
1802 } 1802 }
1803 } 1803 }
1804 1804
1805 1805
1806 void MacroAssembler::SmiAdd(Register dst, 1806 void MacroAssembler::SmiAdd(Register dst,
1807 Register src1, 1807 Register src1,
1808 Register src2, 1808 Register src2,
1809 Label* on_not_smi_result, 1809 Label* on_not_smi_result,
1810 Label::Distance near_jump) { 1810 Label::Distance near_jump) {
1811 ASSERT_NOT_NULL(on_not_smi_result); 1811 DCHECK_NOT_NULL(on_not_smi_result);
1812 ASSERT(!dst.is(src2)); 1812 DCHECK(!dst.is(src2));
1813 SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 1813 SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
1814 } 1814 }
1815 1815
1816 1816
1817 void MacroAssembler::SmiAdd(Register dst, 1817 void MacroAssembler::SmiAdd(Register dst,
1818 Register src1, 1818 Register src1,
1819 const Operand& src2, 1819 const Operand& src2,
1820 Label* on_not_smi_result, 1820 Label* on_not_smi_result,
1821 Label::Distance near_jump) { 1821 Label::Distance near_jump) {
1822 ASSERT_NOT_NULL(on_not_smi_result); 1822 DCHECK_NOT_NULL(on_not_smi_result);
1823 ASSERT(!src2.AddressUsesRegister(dst)); 1823 DCHECK(!src2.AddressUsesRegister(dst));
1824 SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 1824 SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
1825 } 1825 }
1826 1826
1827 1827
1828 void MacroAssembler::SmiAdd(Register dst, 1828 void MacroAssembler::SmiAdd(Register dst,
1829 Register src1, 1829 Register src1,
1830 Register src2) { 1830 Register src2) {
1831 // No overflow checking. Use only when it's known that 1831 // No overflow checking. Use only when it's known that
1832 // overflowing is impossible. 1832 // overflowing is impossible.
1833 if (!dst.is(src1)) { 1833 if (!dst.is(src1)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1865 masm->j(overflow, on_not_smi_result, near_jump); 1865 masm->j(overflow, on_not_smi_result, near_jump);
1866 } 1866 }
1867 } 1867 }
1868 1868
1869 1869
1870 void MacroAssembler::SmiSub(Register dst, 1870 void MacroAssembler::SmiSub(Register dst,
1871 Register src1, 1871 Register src1,
1872 Register src2, 1872 Register src2,
1873 Label* on_not_smi_result, 1873 Label* on_not_smi_result,
1874 Label::Distance near_jump) { 1874 Label::Distance near_jump) {
1875 ASSERT_NOT_NULL(on_not_smi_result); 1875 DCHECK_NOT_NULL(on_not_smi_result);
1876 ASSERT(!dst.is(src2)); 1876 DCHECK(!dst.is(src2));
1877 SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 1877 SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
1878 } 1878 }
1879 1879
1880 1880
1881 void MacroAssembler::SmiSub(Register dst, 1881 void MacroAssembler::SmiSub(Register dst,
1882 Register src1, 1882 Register src1,
1883 const Operand& src2, 1883 const Operand& src2,
1884 Label* on_not_smi_result, 1884 Label* on_not_smi_result,
1885 Label::Distance near_jump) { 1885 Label::Distance near_jump) {
1886 ASSERT_NOT_NULL(on_not_smi_result); 1886 DCHECK_NOT_NULL(on_not_smi_result);
1887 ASSERT(!src2.AddressUsesRegister(dst)); 1887 DCHECK(!src2.AddressUsesRegister(dst));
1888 SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 1888 SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
1889 } 1889 }
1890 1890
1891 1891
1892 template<class T> 1892 template<class T>
1893 static void SmiSubNoOverflowHelper(MacroAssembler* masm, 1893 static void SmiSubNoOverflowHelper(MacroAssembler* masm,
1894 Register dst, 1894 Register dst,
1895 Register src1, 1895 Register src1,
1896 T src2) { 1896 T src2) {
1897 // No overflow checking. Use only when it's known that 1897 // No overflow checking. Use only when it's known that
1898 // overflowing is impossible (e.g., subtracting two positive smis). 1898 // overflowing is impossible (e.g., subtracting two positive smis).
1899 if (!dst.is(src1)) { 1899 if (!dst.is(src1)) {
1900 masm->movp(dst, src1); 1900 masm->movp(dst, src1);
1901 } 1901 }
1902 masm->subp(dst, src2); 1902 masm->subp(dst, src2);
1903 masm->Assert(no_overflow, kSmiSubtractionOverflow); 1903 masm->Assert(no_overflow, kSmiSubtractionOverflow);
1904 } 1904 }
1905 1905
1906 1906
1907 void MacroAssembler::SmiSub(Register dst, Register src1, Register src2) { 1907 void MacroAssembler::SmiSub(Register dst, Register src1, Register src2) {
1908 ASSERT(!dst.is(src2)); 1908 DCHECK(!dst.is(src2));
1909 SmiSubNoOverflowHelper<Register>(this, dst, src1, src2); 1909 SmiSubNoOverflowHelper<Register>(this, dst, src1, src2);
1910 } 1910 }
1911 1911
1912 1912
1913 void MacroAssembler::SmiSub(Register dst, 1913 void MacroAssembler::SmiSub(Register dst,
1914 Register src1, 1914 Register src1,
1915 const Operand& src2) { 1915 const Operand& src2) {
1916 SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2); 1916 SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2);
1917 } 1917 }
1918 1918
1919 1919
1920 void MacroAssembler::SmiMul(Register dst, 1920 void MacroAssembler::SmiMul(Register dst,
1921 Register src1, 1921 Register src1,
1922 Register src2, 1922 Register src2,
1923 Label* on_not_smi_result, 1923 Label* on_not_smi_result,
1924 Label::Distance near_jump) { 1924 Label::Distance near_jump) {
1925 ASSERT(!dst.is(src2)); 1925 DCHECK(!dst.is(src2));
1926 ASSERT(!dst.is(kScratchRegister)); 1926 DCHECK(!dst.is(kScratchRegister));
1927 ASSERT(!src1.is(kScratchRegister)); 1927 DCHECK(!src1.is(kScratchRegister));
1928 ASSERT(!src2.is(kScratchRegister)); 1928 DCHECK(!src2.is(kScratchRegister));
1929 1929
1930 if (dst.is(src1)) { 1930 if (dst.is(src1)) {
1931 Label failure, zero_correct_result; 1931 Label failure, zero_correct_result;
1932 movp(kScratchRegister, src1); // Create backup for later testing. 1932 movp(kScratchRegister, src1); // Create backup for later testing.
1933 SmiToInteger64(dst, src1); 1933 SmiToInteger64(dst, src1);
1934 imulp(dst, src2); 1934 imulp(dst, src2);
1935 j(overflow, &failure, Label::kNear); 1935 j(overflow, &failure, Label::kNear);
1936 1936
1937 // Check for negative zero result. If product is zero, and one 1937 // Check for negative zero result. If product is zero, and one
1938 // argument is negative, go to slow case. 1938 // argument is negative, go to slow case.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1970 bind(&correct_result); 1970 bind(&correct_result);
1971 } 1971 }
1972 } 1972 }
1973 1973
1974 1974
1975 void MacroAssembler::SmiDiv(Register dst, 1975 void MacroAssembler::SmiDiv(Register dst,
1976 Register src1, 1976 Register src1,
1977 Register src2, 1977 Register src2,
1978 Label* on_not_smi_result, 1978 Label* on_not_smi_result,
1979 Label::Distance near_jump) { 1979 Label::Distance near_jump) {
1980 ASSERT(!src1.is(kScratchRegister)); 1980 DCHECK(!src1.is(kScratchRegister));
1981 ASSERT(!src2.is(kScratchRegister)); 1981 DCHECK(!src2.is(kScratchRegister));
1982 ASSERT(!dst.is(kScratchRegister)); 1982 DCHECK(!dst.is(kScratchRegister));
1983 ASSERT(!src2.is(rax)); 1983 DCHECK(!src2.is(rax));
1984 ASSERT(!src2.is(rdx)); 1984 DCHECK(!src2.is(rdx));
1985 ASSERT(!src1.is(rdx)); 1985 DCHECK(!src1.is(rdx));
1986 1986
1987 // Check for 0 divisor (result is +/-Infinity). 1987 // Check for 0 divisor (result is +/-Infinity).
1988 testp(src2, src2); 1988 testp(src2, src2);
1989 j(zero, on_not_smi_result, near_jump); 1989 j(zero, on_not_smi_result, near_jump);
1990 1990
1991 if (src1.is(rax)) { 1991 if (src1.is(rax)) {
1992 movp(kScratchRegister, src1); 1992 movp(kScratchRegister, src1);
1993 } 1993 }
1994 SmiToInteger32(rax, src1); 1994 SmiToInteger32(rax, src1);
1995 // We need to rule out dividing Smi::kMinValue by -1, since that would 1995 // We need to rule out dividing Smi::kMinValue by -1, since that would
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2033 } 2033 }
2034 Integer32ToSmi(dst, rax); 2034 Integer32ToSmi(dst, rax);
2035 } 2035 }
2036 2036
2037 2037
2038 void MacroAssembler::SmiMod(Register dst, 2038 void MacroAssembler::SmiMod(Register dst,
2039 Register src1, 2039 Register src1,
2040 Register src2, 2040 Register src2,
2041 Label* on_not_smi_result, 2041 Label* on_not_smi_result,
2042 Label::Distance near_jump) { 2042 Label::Distance near_jump) {
2043 ASSERT(!dst.is(kScratchRegister)); 2043 DCHECK(!dst.is(kScratchRegister));
2044 ASSERT(!src1.is(kScratchRegister)); 2044 DCHECK(!src1.is(kScratchRegister));
2045 ASSERT(!src2.is(kScratchRegister)); 2045 DCHECK(!src2.is(kScratchRegister));
2046 ASSERT(!src2.is(rax)); 2046 DCHECK(!src2.is(rax));
2047 ASSERT(!src2.is(rdx)); 2047 DCHECK(!src2.is(rdx));
2048 ASSERT(!src1.is(rdx)); 2048 DCHECK(!src1.is(rdx));
2049 ASSERT(!src1.is(src2)); 2049 DCHECK(!src1.is(src2));
2050 2050
2051 testp(src2, src2); 2051 testp(src2, src2);
2052 j(zero, on_not_smi_result, near_jump); 2052 j(zero, on_not_smi_result, near_jump);
2053 2053
2054 if (src1.is(rax)) { 2054 if (src1.is(rax)) {
2055 movp(kScratchRegister, src1); 2055 movp(kScratchRegister, src1);
2056 } 2056 }
2057 SmiToInteger32(rax, src1); 2057 SmiToInteger32(rax, src1);
2058 SmiToInteger32(src2, src2); 2058 SmiToInteger32(src2, src2);
2059 2059
(...skipping 25 matching lines...) Expand all
2085 testl(rdx, rdx); 2085 testl(rdx, rdx);
2086 j(not_zero, &smi_result, Label::kNear); 2086 j(not_zero, &smi_result, Label::kNear);
2087 testp(src1, src1); 2087 testp(src1, src1);
2088 j(negative, on_not_smi_result, near_jump); 2088 j(negative, on_not_smi_result, near_jump);
2089 bind(&smi_result); 2089 bind(&smi_result);
2090 Integer32ToSmi(dst, rdx); 2090 Integer32ToSmi(dst, rdx);
2091 } 2091 }
2092 2092
2093 2093
2094 void MacroAssembler::SmiNot(Register dst, Register src) { 2094 void MacroAssembler::SmiNot(Register dst, Register src) {
2095 ASSERT(!dst.is(kScratchRegister)); 2095 DCHECK(!dst.is(kScratchRegister));
2096 ASSERT(!src.is(kScratchRegister)); 2096 DCHECK(!src.is(kScratchRegister));
2097 if (SmiValuesAre32Bits()) { 2097 if (SmiValuesAre32Bits()) {
2098 // Set tag and padding bits before negating, so that they are zero 2098 // Set tag and padding bits before negating, so that they are zero
2099 // afterwards. 2099 // afterwards.
2100 movl(kScratchRegister, Immediate(~0)); 2100 movl(kScratchRegister, Immediate(~0));
2101 } else { 2101 } else {
2102 ASSERT(SmiValuesAre31Bits()); 2102 DCHECK(SmiValuesAre31Bits());
2103 movl(kScratchRegister, Immediate(1)); 2103 movl(kScratchRegister, Immediate(1));
2104 } 2104 }
2105 if (dst.is(src)) { 2105 if (dst.is(src)) {
2106 xorp(dst, kScratchRegister); 2106 xorp(dst, kScratchRegister);
2107 } else { 2107 } else {
2108 leap(dst, Operand(src, kScratchRegister, times_1, 0)); 2108 leap(dst, Operand(src, kScratchRegister, times_1, 0));
2109 } 2109 }
2110 notp(dst); 2110 notp(dst);
2111 } 2111 }
2112 2112
2113 2113
2114 void MacroAssembler::SmiAnd(Register dst, Register src1, Register src2) { 2114 void MacroAssembler::SmiAnd(Register dst, Register src1, Register src2) {
2115 ASSERT(!dst.is(src2)); 2115 DCHECK(!dst.is(src2));
2116 if (!dst.is(src1)) { 2116 if (!dst.is(src1)) {
2117 movp(dst, src1); 2117 movp(dst, src1);
2118 } 2118 }
2119 andp(dst, src2); 2119 andp(dst, src2);
2120 } 2120 }
2121 2121
2122 2122
2123 void MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) { 2123 void MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) {
2124 if (constant->value() == 0) { 2124 if (constant->value() == 0) {
2125 Set(dst, 0); 2125 Set(dst, 0);
2126 } else if (dst.is(src)) { 2126 } else if (dst.is(src)) {
2127 ASSERT(!dst.is(kScratchRegister)); 2127 DCHECK(!dst.is(kScratchRegister));
2128 Register constant_reg = GetSmiConstant(constant); 2128 Register constant_reg = GetSmiConstant(constant);
2129 andp(dst, constant_reg); 2129 andp(dst, constant_reg);
2130 } else { 2130 } else {
2131 LoadSmiConstant(dst, constant); 2131 LoadSmiConstant(dst, constant);
2132 andp(dst, src); 2132 andp(dst, src);
2133 } 2133 }
2134 } 2134 }
2135 2135
2136 2136
2137 void MacroAssembler::SmiOr(Register dst, Register src1, Register src2) { 2137 void MacroAssembler::SmiOr(Register dst, Register src1, Register src2) {
2138 if (!dst.is(src1)) { 2138 if (!dst.is(src1)) {
2139 ASSERT(!src1.is(src2)); 2139 DCHECK(!src1.is(src2));
2140 movp(dst, src1); 2140 movp(dst, src1);
2141 } 2141 }
2142 orp(dst, src2); 2142 orp(dst, src2);
2143 } 2143 }
2144 2144
2145 2145
2146 void MacroAssembler::SmiOrConstant(Register dst, Register src, Smi* constant) { 2146 void MacroAssembler::SmiOrConstant(Register dst, Register src, Smi* constant) {
2147 if (dst.is(src)) { 2147 if (dst.is(src)) {
2148 ASSERT(!dst.is(kScratchRegister)); 2148 DCHECK(!dst.is(kScratchRegister));
2149 Register constant_reg = GetSmiConstant(constant); 2149 Register constant_reg = GetSmiConstant(constant);
2150 orp(dst, constant_reg); 2150 orp(dst, constant_reg);
2151 } else { 2151 } else {
2152 LoadSmiConstant(dst, constant); 2152 LoadSmiConstant(dst, constant);
2153 orp(dst, src); 2153 orp(dst, src);
2154 } 2154 }
2155 } 2155 }
2156 2156
2157 2157
2158 void MacroAssembler::SmiXor(Register dst, Register src1, Register src2) { 2158 void MacroAssembler::SmiXor(Register dst, Register src1, Register src2) {
2159 if (!dst.is(src1)) { 2159 if (!dst.is(src1)) {
2160 ASSERT(!src1.is(src2)); 2160 DCHECK(!src1.is(src2));
2161 movp(dst, src1); 2161 movp(dst, src1);
2162 } 2162 }
2163 xorp(dst, src2); 2163 xorp(dst, src2);
2164 } 2164 }
2165 2165
2166 2166
2167 void MacroAssembler::SmiXorConstant(Register dst, Register src, Smi* constant) { 2167 void MacroAssembler::SmiXorConstant(Register dst, Register src, Smi* constant) {
2168 if (dst.is(src)) { 2168 if (dst.is(src)) {
2169 ASSERT(!dst.is(kScratchRegister)); 2169 DCHECK(!dst.is(kScratchRegister));
2170 Register constant_reg = GetSmiConstant(constant); 2170 Register constant_reg = GetSmiConstant(constant);
2171 xorp(dst, constant_reg); 2171 xorp(dst, constant_reg);
2172 } else { 2172 } else {
2173 LoadSmiConstant(dst, constant); 2173 LoadSmiConstant(dst, constant);
2174 xorp(dst, src); 2174 xorp(dst, src);
2175 } 2175 }
2176 } 2176 }
2177 2177
2178 2178
2179 void MacroAssembler::SmiShiftArithmeticRightConstant(Register dst, 2179 void MacroAssembler::SmiShiftArithmeticRightConstant(Register dst,
2180 Register src, 2180 Register src,
2181 int shift_value) { 2181 int shift_value) {
2182 ASSERT(is_uint5(shift_value)); 2182 DCHECK(is_uint5(shift_value));
2183 if (shift_value > 0) { 2183 if (shift_value > 0) {
2184 if (dst.is(src)) { 2184 if (dst.is(src)) {
2185 sarp(dst, Immediate(shift_value + kSmiShift)); 2185 sarp(dst, Immediate(shift_value + kSmiShift));
2186 shlp(dst, Immediate(kSmiShift)); 2186 shlp(dst, Immediate(kSmiShift));
2187 } else { 2187 } else {
2188 UNIMPLEMENTED(); // Not used. 2188 UNIMPLEMENTED(); // Not used.
2189 } 2189 }
2190 } 2190 }
2191 } 2191 }
2192 2192
2193 2193
2194 void MacroAssembler::SmiShiftLeftConstant(Register dst, 2194 void MacroAssembler::SmiShiftLeftConstant(Register dst,
2195 Register src, 2195 Register src,
2196 int shift_value, 2196 int shift_value,
2197 Label* on_not_smi_result, 2197 Label* on_not_smi_result,
2198 Label::Distance near_jump) { 2198 Label::Distance near_jump) {
2199 if (SmiValuesAre32Bits()) { 2199 if (SmiValuesAre32Bits()) {
2200 if (!dst.is(src)) { 2200 if (!dst.is(src)) {
2201 movp(dst, src); 2201 movp(dst, src);
2202 } 2202 }
2203 if (shift_value > 0) { 2203 if (shift_value > 0) {
2204 // Shift amount specified by lower 5 bits, not six as the shl opcode. 2204 // Shift amount specified by lower 5 bits, not six as the shl opcode.
2205 shlq(dst, Immediate(shift_value & 0x1f)); 2205 shlq(dst, Immediate(shift_value & 0x1f));
2206 } 2206 }
2207 } else { 2207 } else {
2208 ASSERT(SmiValuesAre31Bits()); 2208 DCHECK(SmiValuesAre31Bits());
2209 if (dst.is(src)) { 2209 if (dst.is(src)) {
2210 UNIMPLEMENTED(); // Not used. 2210 UNIMPLEMENTED(); // Not used.
2211 } else { 2211 } else {
2212 SmiToInteger32(dst, src); 2212 SmiToInteger32(dst, src);
2213 shll(dst, Immediate(shift_value)); 2213 shll(dst, Immediate(shift_value));
2214 JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump); 2214 JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump);
2215 Integer32ToSmi(dst, dst); 2215 Integer32ToSmi(dst, dst);
2216 } 2216 }
2217 } 2217 }
2218 } 2218 }
2219 2219
2220 2220
2221 void MacroAssembler::SmiShiftLogicalRightConstant( 2221 void MacroAssembler::SmiShiftLogicalRightConstant(
2222 Register dst, Register src, int shift_value, 2222 Register dst, Register src, int shift_value,
2223 Label* on_not_smi_result, Label::Distance near_jump) { 2223 Label* on_not_smi_result, Label::Distance near_jump) {
2224 // Logic right shift interprets its result as an *unsigned* number. 2224 // Logic right shift interprets its result as an *unsigned* number.
2225 if (dst.is(src)) { 2225 if (dst.is(src)) {
2226 UNIMPLEMENTED(); // Not used. 2226 UNIMPLEMENTED(); // Not used.
2227 } else { 2227 } else {
2228 if (shift_value == 0) { 2228 if (shift_value == 0) {
2229 testp(src, src); 2229 testp(src, src);
2230 j(negative, on_not_smi_result, near_jump); 2230 j(negative, on_not_smi_result, near_jump);
2231 } 2231 }
2232 if (SmiValuesAre32Bits()) { 2232 if (SmiValuesAre32Bits()) {
2233 movp(dst, src); 2233 movp(dst, src);
2234 shrp(dst, Immediate(shift_value + kSmiShift)); 2234 shrp(dst, Immediate(shift_value + kSmiShift));
2235 shlp(dst, Immediate(kSmiShift)); 2235 shlp(dst, Immediate(kSmiShift));
2236 } else { 2236 } else {
2237 ASSERT(SmiValuesAre31Bits()); 2237 DCHECK(SmiValuesAre31Bits());
2238 SmiToInteger32(dst, src); 2238 SmiToInteger32(dst, src);
2239 shrp(dst, Immediate(shift_value)); 2239 shrp(dst, Immediate(shift_value));
2240 JumpIfUIntNotValidSmiValue(dst, on_not_smi_result, near_jump); 2240 JumpIfUIntNotValidSmiValue(dst, on_not_smi_result, near_jump);
2241 Integer32ToSmi(dst, dst); 2241 Integer32ToSmi(dst, dst);
2242 } 2242 }
2243 } 2243 }
2244 } 2244 }
2245 2245
2246 2246
2247 void MacroAssembler::SmiShiftLeft(Register dst, 2247 void MacroAssembler::SmiShiftLeft(Register dst,
2248 Register src1, 2248 Register src1,
2249 Register src2, 2249 Register src2,
2250 Label* on_not_smi_result, 2250 Label* on_not_smi_result,
2251 Label::Distance near_jump) { 2251 Label::Distance near_jump) {
2252 if (SmiValuesAre32Bits()) { 2252 if (SmiValuesAre32Bits()) {
2253 ASSERT(!dst.is(rcx)); 2253 DCHECK(!dst.is(rcx));
2254 if (!dst.is(src1)) { 2254 if (!dst.is(src1)) {
2255 movp(dst, src1); 2255 movp(dst, src1);
2256 } 2256 }
2257 // Untag shift amount. 2257 // Untag shift amount.
2258 SmiToInteger32(rcx, src2); 2258 SmiToInteger32(rcx, src2);
2259 // Shift amount specified by lower 5 bits, not six as the shl opcode. 2259 // Shift amount specified by lower 5 bits, not six as the shl opcode.
2260 andp(rcx, Immediate(0x1f)); 2260 andp(rcx, Immediate(0x1f));
2261 shlq_cl(dst); 2261 shlq_cl(dst);
2262 } else { 2262 } else {
2263 ASSERT(SmiValuesAre31Bits()); 2263 DCHECK(SmiValuesAre31Bits());
2264 ASSERT(!dst.is(kScratchRegister)); 2264 DCHECK(!dst.is(kScratchRegister));
2265 ASSERT(!src1.is(kScratchRegister)); 2265 DCHECK(!src1.is(kScratchRegister));
2266 ASSERT(!src2.is(kScratchRegister)); 2266 DCHECK(!src2.is(kScratchRegister));
2267 ASSERT(!dst.is(src2)); 2267 DCHECK(!dst.is(src2));
2268 ASSERT(!dst.is(rcx)); 2268 DCHECK(!dst.is(rcx));
2269 2269
2270 if (src1.is(rcx) || src2.is(rcx)) { 2270 if (src1.is(rcx) || src2.is(rcx)) {
2271 movq(kScratchRegister, rcx); 2271 movq(kScratchRegister, rcx);
2272 } 2272 }
2273 if (dst.is(src1)) { 2273 if (dst.is(src1)) {
2274 UNIMPLEMENTED(); // Not used. 2274 UNIMPLEMENTED(); // Not used.
2275 } else { 2275 } else {
2276 Label valid_result; 2276 Label valid_result;
2277 SmiToInteger32(dst, src1); 2277 SmiToInteger32(dst, src1);
2278 SmiToInteger32(rcx, src2); 2278 SmiToInteger32(rcx, src2);
(...skipping 14 matching lines...) Expand all
2293 } 2293 }
2294 } 2294 }
2295 } 2295 }
2296 2296
2297 2297
2298 void MacroAssembler::SmiShiftLogicalRight(Register dst, 2298 void MacroAssembler::SmiShiftLogicalRight(Register dst,
2299 Register src1, 2299 Register src1,
2300 Register src2, 2300 Register src2,
2301 Label* on_not_smi_result, 2301 Label* on_not_smi_result,
2302 Label::Distance near_jump) { 2302 Label::Distance near_jump) {
2303 ASSERT(!dst.is(kScratchRegister)); 2303 DCHECK(!dst.is(kScratchRegister));
2304 ASSERT(!src1.is(kScratchRegister)); 2304 DCHECK(!src1.is(kScratchRegister));
2305 ASSERT(!src2.is(kScratchRegister)); 2305 DCHECK(!src2.is(kScratchRegister));
2306 ASSERT(!dst.is(src2)); 2306 DCHECK(!dst.is(src2));
2307 ASSERT(!dst.is(rcx)); 2307 DCHECK(!dst.is(rcx));
2308 if (src1.is(rcx) || src2.is(rcx)) { 2308 if (src1.is(rcx) || src2.is(rcx)) {
2309 movq(kScratchRegister, rcx); 2309 movq(kScratchRegister, rcx);
2310 } 2310 }
2311 if (dst.is(src1)) { 2311 if (dst.is(src1)) {
2312 UNIMPLEMENTED(); // Not used. 2312 UNIMPLEMENTED(); // Not used.
2313 } else { 2313 } else {
2314 Label valid_result; 2314 Label valid_result;
2315 SmiToInteger32(dst, src1); 2315 SmiToInteger32(dst, src1);
2316 SmiToInteger32(rcx, src2); 2316 SmiToInteger32(rcx, src2);
2317 shrl_cl(dst); 2317 shrl_cl(dst);
(...skipping 10 matching lines...) Expand all
2328 jmp(on_not_smi_result, near_jump); 2328 jmp(on_not_smi_result, near_jump);
2329 bind(&valid_result); 2329 bind(&valid_result);
2330 Integer32ToSmi(dst, dst); 2330 Integer32ToSmi(dst, dst);
2331 } 2331 }
2332 } 2332 }
2333 2333
2334 2334
2335 void MacroAssembler::SmiShiftArithmeticRight(Register dst, 2335 void MacroAssembler::SmiShiftArithmeticRight(Register dst,
2336 Register src1, 2336 Register src1,
2337 Register src2) { 2337 Register src2) {
2338 ASSERT(!dst.is(kScratchRegister)); 2338 DCHECK(!dst.is(kScratchRegister));
2339 ASSERT(!src1.is(kScratchRegister)); 2339 DCHECK(!src1.is(kScratchRegister));
2340 ASSERT(!src2.is(kScratchRegister)); 2340 DCHECK(!src2.is(kScratchRegister));
2341 ASSERT(!dst.is(rcx)); 2341 DCHECK(!dst.is(rcx));
2342 2342
2343 SmiToInteger32(rcx, src2); 2343 SmiToInteger32(rcx, src2);
2344 if (!dst.is(src1)) { 2344 if (!dst.is(src1)) {
2345 movp(dst, src1); 2345 movp(dst, src1);
2346 } 2346 }
2347 SmiToInteger32(dst, dst); 2347 SmiToInteger32(dst, dst);
2348 sarl_cl(dst); 2348 sarl_cl(dst);
2349 Integer32ToSmi(dst, dst); 2349 Integer32ToSmi(dst, dst);
2350 } 2350 }
2351 2351
2352 2352
2353 void MacroAssembler::SelectNonSmi(Register dst, 2353 void MacroAssembler::SelectNonSmi(Register dst,
2354 Register src1, 2354 Register src1,
2355 Register src2, 2355 Register src2,
2356 Label* on_not_smis, 2356 Label* on_not_smis,
2357 Label::Distance near_jump) { 2357 Label::Distance near_jump) {
2358 ASSERT(!dst.is(kScratchRegister)); 2358 DCHECK(!dst.is(kScratchRegister));
2359 ASSERT(!src1.is(kScratchRegister)); 2359 DCHECK(!src1.is(kScratchRegister));
2360 ASSERT(!src2.is(kScratchRegister)); 2360 DCHECK(!src2.is(kScratchRegister));
2361 ASSERT(!dst.is(src1)); 2361 DCHECK(!dst.is(src1));
2362 ASSERT(!dst.is(src2)); 2362 DCHECK(!dst.is(src2));
2363 // Both operands must not be smis. 2363 // Both operands must not be smis.
2364 #ifdef DEBUG 2364 #ifdef DEBUG
2365 Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2)); 2365 Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2));
2366 Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi); 2366 Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi);
2367 #endif 2367 #endif
2368 STATIC_ASSERT(kSmiTag == 0); 2368 STATIC_ASSERT(kSmiTag == 0);
2369 ASSERT_EQ(0, Smi::FromInt(0)); 2369 DCHECK_EQ(0, Smi::FromInt(0));
2370 movl(kScratchRegister, Immediate(kSmiTagMask)); 2370 movl(kScratchRegister, Immediate(kSmiTagMask));
2371 andp(kScratchRegister, src1); 2371 andp(kScratchRegister, src1);
2372 testl(kScratchRegister, src2); 2372 testl(kScratchRegister, src2);
2373 // If non-zero then both are smis. 2373 // If non-zero then both are smis.
2374 j(not_zero, on_not_smis, near_jump); 2374 j(not_zero, on_not_smis, near_jump);
2375 2375
2376 // Exactly one operand is a smi. 2376 // Exactly one operand is a smi.
2377 ASSERT_EQ(1, static_cast<int>(kSmiTagMask)); 2377 DCHECK_EQ(1, static_cast<int>(kSmiTagMask));
2378 // kScratchRegister still holds src1 & kSmiTag, which is either zero or one. 2378 // kScratchRegister still holds src1 & kSmiTag, which is either zero or one.
2379 subp(kScratchRegister, Immediate(1)); 2379 subp(kScratchRegister, Immediate(1));
2380 // If src1 is a smi, then scratch register all 1s, else it is all 0s. 2380 // If src1 is a smi, then scratch register all 1s, else it is all 0s.
2381 movp(dst, src1); 2381 movp(dst, src1);
2382 xorp(dst, src2); 2382 xorp(dst, src2);
2383 andp(dst, kScratchRegister); 2383 andp(dst, kScratchRegister);
2384 // If src1 is a smi, dst holds src1 ^ src2, else it is zero. 2384 // If src1 is a smi, dst holds src1 ^ src2, else it is zero.
2385 xorp(dst, src1); 2385 xorp(dst, src1);
2386 // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi. 2386 // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi.
2387 } 2387 }
2388 2388
2389 2389
2390 SmiIndex MacroAssembler::SmiToIndex(Register dst, 2390 SmiIndex MacroAssembler::SmiToIndex(Register dst,
2391 Register src, 2391 Register src,
2392 int shift) { 2392 int shift) {
2393 if (SmiValuesAre32Bits()) { 2393 if (SmiValuesAre32Bits()) {
2394 ASSERT(is_uint6(shift)); 2394 DCHECK(is_uint6(shift));
2395 // There is a possible optimization if shift is in the range 60-63, but that 2395 // There is a possible optimization if shift is in the range 60-63, but that
2396 // will (and must) never happen. 2396 // will (and must) never happen.
2397 if (!dst.is(src)) { 2397 if (!dst.is(src)) {
2398 movp(dst, src); 2398 movp(dst, src);
2399 } 2399 }
2400 if (shift < kSmiShift) { 2400 if (shift < kSmiShift) {
2401 sarp(dst, Immediate(kSmiShift - shift)); 2401 sarp(dst, Immediate(kSmiShift - shift));
2402 } else { 2402 } else {
2403 shlp(dst, Immediate(shift - kSmiShift)); 2403 shlp(dst, Immediate(shift - kSmiShift));
2404 } 2404 }
2405 return SmiIndex(dst, times_1); 2405 return SmiIndex(dst, times_1);
2406 } else { 2406 } else {
2407 ASSERT(SmiValuesAre31Bits()); 2407 DCHECK(SmiValuesAre31Bits());
2408 ASSERT(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2408 DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1));
2409 if (!dst.is(src)) { 2409 if (!dst.is(src)) {
2410 movp(dst, src); 2410 movp(dst, src);
2411 } 2411 }
2412 // We have to sign extend the index register to 64-bit as the SMI might 2412 // We have to sign extend the index register to 64-bit as the SMI might
2413 // be negative. 2413 // be negative.
2414 movsxlq(dst, dst); 2414 movsxlq(dst, dst);
2415 if (shift == times_1) { 2415 if (shift == times_1) {
2416 sarq(dst, Immediate(kSmiShift)); 2416 sarq(dst, Immediate(kSmiShift));
2417 return SmiIndex(dst, times_1); 2417 return SmiIndex(dst, times_1);
2418 } 2418 }
2419 return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 2419 return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1));
2420 } 2420 }
2421 } 2421 }
2422 2422
2423 2423
2424 SmiIndex MacroAssembler::SmiToNegativeIndex(Register dst, 2424 SmiIndex MacroAssembler::SmiToNegativeIndex(Register dst,
2425 Register src, 2425 Register src,
2426 int shift) { 2426 int shift) {
2427 if (SmiValuesAre32Bits()) { 2427 if (SmiValuesAre32Bits()) {
2428 // Register src holds a positive smi. 2428 // Register src holds a positive smi.
2429 ASSERT(is_uint6(shift)); 2429 DCHECK(is_uint6(shift));
2430 if (!dst.is(src)) { 2430 if (!dst.is(src)) {
2431 movp(dst, src); 2431 movp(dst, src);
2432 } 2432 }
2433 negp(dst); 2433 negp(dst);
2434 if (shift < kSmiShift) { 2434 if (shift < kSmiShift) {
2435 sarp(dst, Immediate(kSmiShift - shift)); 2435 sarp(dst, Immediate(kSmiShift - shift));
2436 } else { 2436 } else {
2437 shlp(dst, Immediate(shift - kSmiShift)); 2437 shlp(dst, Immediate(shift - kSmiShift));
2438 } 2438 }
2439 return SmiIndex(dst, times_1); 2439 return SmiIndex(dst, times_1);
2440 } else { 2440 } else {
2441 ASSERT(SmiValuesAre31Bits()); 2441 DCHECK(SmiValuesAre31Bits());
2442 ASSERT(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2442 DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1));
2443 if (!dst.is(src)) { 2443 if (!dst.is(src)) {
2444 movp(dst, src); 2444 movp(dst, src);
2445 } 2445 }
2446 negq(dst); 2446 negq(dst);
2447 if (shift == times_1) { 2447 if (shift == times_1) {
2448 sarq(dst, Immediate(kSmiShift)); 2448 sarq(dst, Immediate(kSmiShift));
2449 return SmiIndex(dst, times_1); 2449 return SmiIndex(dst, times_1);
2450 } 2450 }
2451 return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 2451 return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1));
2452 } 2452 }
2453 } 2453 }
2454 2454
2455 2455
2456 void MacroAssembler::AddSmiField(Register dst, const Operand& src) { 2456 void MacroAssembler::AddSmiField(Register dst, const Operand& src) {
2457 if (SmiValuesAre32Bits()) { 2457 if (SmiValuesAre32Bits()) {
2458 ASSERT_EQ(0, kSmiShift % kBitsPerByte); 2458 DCHECK_EQ(0, kSmiShift % kBitsPerByte);
2459 addl(dst, Operand(src, kSmiShift / kBitsPerByte)); 2459 addl(dst, Operand(src, kSmiShift / kBitsPerByte));
2460 } else { 2460 } else {
2461 ASSERT(SmiValuesAre31Bits()); 2461 DCHECK(SmiValuesAre31Bits());
2462 SmiToInteger32(kScratchRegister, src); 2462 SmiToInteger32(kScratchRegister, src);
2463 addl(dst, kScratchRegister); 2463 addl(dst, kScratchRegister);
2464 } 2464 }
2465 } 2465 }
2466 2466
2467 2467
2468 void MacroAssembler::Push(Smi* source) { 2468 void MacroAssembler::Push(Smi* source) {
2469 intptr_t smi = reinterpret_cast<intptr_t>(source); 2469 intptr_t smi = reinterpret_cast<intptr_t>(source);
2470 if (is_int32(smi)) { 2470 if (is_int32(smi)) {
2471 Push(Immediate(static_cast<int32_t>(smi))); 2471 Push(Immediate(static_cast<int32_t>(smi)));
2472 } else { 2472 } else {
2473 Register constant = GetSmiConstant(source); 2473 Register constant = GetSmiConstant(source);
2474 Push(constant); 2474 Push(constant);
2475 } 2475 }
2476 } 2476 }
2477 2477
2478 2478
2479 void MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) { 2479 void MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) {
2480 ASSERT(!src.is(scratch)); 2480 DCHECK(!src.is(scratch));
2481 movp(scratch, src); 2481 movp(scratch, src);
2482 // High bits. 2482 // High bits.
2483 shrp(src, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 2483 shrp(src, Immediate(kPointerSize * kBitsPerByte - kSmiShift));
2484 shlp(src, Immediate(kSmiShift)); 2484 shlp(src, Immediate(kSmiShift));
2485 Push(src); 2485 Push(src);
2486 // Low bits. 2486 // Low bits.
2487 shlp(scratch, Immediate(kSmiShift)); 2487 shlp(scratch, Immediate(kSmiShift));
2488 Push(scratch); 2488 Push(scratch);
2489 } 2489 }
2490 2490
2491 2491
2492 void MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) { 2492 void MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) {
2493 ASSERT(!dst.is(scratch)); 2493 DCHECK(!dst.is(scratch));
2494 Pop(scratch); 2494 Pop(scratch);
2495 // Low bits. 2495 // Low bits.
2496 shrp(scratch, Immediate(kSmiShift)); 2496 shrp(scratch, Immediate(kSmiShift));
2497 Pop(dst); 2497 Pop(dst);
2498 shrp(dst, Immediate(kSmiShift)); 2498 shrp(dst, Immediate(kSmiShift));
2499 // High bits. 2499 // High bits.
2500 shlp(dst, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 2500 shlp(dst, Immediate(kPointerSize * kBitsPerByte - kSmiShift));
2501 orp(dst, scratch); 2501 orp(dst, scratch);
2502 } 2502 }
2503 2503
2504 2504
2505 void MacroAssembler::Test(const Operand& src, Smi* source) { 2505 void MacroAssembler::Test(const Operand& src, Smi* source) {
2506 if (SmiValuesAre32Bits()) { 2506 if (SmiValuesAre32Bits()) {
2507 testl(Operand(src, kIntSize), Immediate(source->value())); 2507 testl(Operand(src, kIntSize), Immediate(source->value()));
2508 } else { 2508 } else {
2509 ASSERT(SmiValuesAre31Bits()); 2509 DCHECK(SmiValuesAre31Bits());
2510 testl(src, Immediate(source)); 2510 testl(src, Immediate(source));
2511 } 2511 }
2512 } 2512 }
2513 2513
2514 2514
2515 // ---------------------------------------------------------------------------- 2515 // ----------------------------------------------------------------------------
2516 2516
2517 2517
2518 void MacroAssembler::LookupNumberStringCache(Register object, 2518 void MacroAssembler::LookupNumberStringCache(Register object,
2519 Register result, 2519 Register result,
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2621 Condition either_smi = CheckEitherSmi(first_object, second_object); 2621 Condition either_smi = CheckEitherSmi(first_object, second_object);
2622 j(either_smi, on_fail, near_jump); 2622 j(either_smi, on_fail, near_jump);
2623 2623
2624 // Load instance type for both strings. 2624 // Load instance type for both strings.
2625 movp(scratch1, FieldOperand(first_object, HeapObject::kMapOffset)); 2625 movp(scratch1, FieldOperand(first_object, HeapObject::kMapOffset));
2626 movp(scratch2, FieldOperand(second_object, HeapObject::kMapOffset)); 2626 movp(scratch2, FieldOperand(second_object, HeapObject::kMapOffset));
2627 movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); 2627 movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset));
2628 movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); 2628 movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset));
2629 2629
2630 // Check that both are flat ASCII strings. 2630 // Check that both are flat ASCII strings.
2631 ASSERT(kNotStringTag != 0); 2631 DCHECK(kNotStringTag != 0);
2632 const int kFlatAsciiStringMask = 2632 const int kFlatAsciiStringMask =
2633 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2633 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
2634 const int kFlatAsciiStringTag = 2634 const int kFlatAsciiStringTag =
2635 kStringTag | kOneByteStringTag | kSeqStringTag; 2635 kStringTag | kOneByteStringTag | kSeqStringTag;
2636 2636
2637 andl(scratch1, Immediate(kFlatAsciiStringMask)); 2637 andl(scratch1, Immediate(kFlatAsciiStringMask));
2638 andl(scratch2, Immediate(kFlatAsciiStringMask)); 2638 andl(scratch2, Immediate(kFlatAsciiStringMask));
2639 // Interleave the bits to check both scratch1 and scratch2 in one test. 2639 // Interleave the bits to check both scratch1 and scratch2 in one test.
2640 ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); 2640 DCHECK_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
2641 leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); 2641 leap(scratch1, Operand(scratch1, scratch2, times_8, 0));
2642 cmpl(scratch1, 2642 cmpl(scratch1,
2643 Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3))); 2643 Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3)));
2644 j(not_equal, on_fail, near_jump); 2644 j(not_equal, on_fail, near_jump);
2645 } 2645 }
2646 2646
2647 2647
2648 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii( 2648 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(
2649 Register instance_type, 2649 Register instance_type,
2650 Register scratch, 2650 Register scratch,
(...skipping 17 matching lines...) Expand all
2668 Register second_object_instance_type, 2668 Register second_object_instance_type,
2669 Register scratch1, 2669 Register scratch1,
2670 Register scratch2, 2670 Register scratch2,
2671 Label* on_fail, 2671 Label* on_fail,
2672 Label::Distance near_jump) { 2672 Label::Distance near_jump) {
2673 // Load instance type for both strings. 2673 // Load instance type for both strings.
2674 movp(scratch1, first_object_instance_type); 2674 movp(scratch1, first_object_instance_type);
2675 movp(scratch2, second_object_instance_type); 2675 movp(scratch2, second_object_instance_type);
2676 2676
2677 // Check that both are flat ASCII strings. 2677 // Check that both are flat ASCII strings.
2678 ASSERT(kNotStringTag != 0); 2678 DCHECK(kNotStringTag != 0);
2679 const int kFlatAsciiStringMask = 2679 const int kFlatAsciiStringMask =
2680 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2680 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
2681 const int kFlatAsciiStringTag = 2681 const int kFlatAsciiStringTag =
2682 kStringTag | kOneByteStringTag | kSeqStringTag; 2682 kStringTag | kOneByteStringTag | kSeqStringTag;
2683 2683
2684 andl(scratch1, Immediate(kFlatAsciiStringMask)); 2684 andl(scratch1, Immediate(kFlatAsciiStringMask));
2685 andl(scratch2, Immediate(kFlatAsciiStringMask)); 2685 andl(scratch2, Immediate(kFlatAsciiStringMask));
2686 // Interleave the bits to check both scratch1 and scratch2 in one test. 2686 // Interleave the bits to check both scratch1 and scratch2 in one test.
2687 ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); 2687 DCHECK_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
2688 leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); 2688 leap(scratch1, Operand(scratch1, scratch2, times_8, 0));
2689 cmpl(scratch1, 2689 cmpl(scratch1,
2690 Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3))); 2690 Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3)));
2691 j(not_equal, on_fail, near_jump); 2691 j(not_equal, on_fail, near_jump);
2692 } 2692 }
2693 2693
2694 2694
2695 template<class T> 2695 template<class T>
2696 static void JumpIfNotUniqueNameHelper(MacroAssembler* masm, 2696 static void JumpIfNotUniqueNameHelper(MacroAssembler* masm,
2697 T operand_or_register, 2697 T operand_or_register,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2780 } else { 2780 } else {
2781 MoveHeapObject(kScratchRegister, source); 2781 MoveHeapObject(kScratchRegister, source);
2782 Push(kScratchRegister); 2782 Push(kScratchRegister);
2783 } 2783 }
2784 } 2784 }
2785 2785
2786 2786
2787 void MacroAssembler::MoveHeapObject(Register result, 2787 void MacroAssembler::MoveHeapObject(Register result,
2788 Handle<Object> object) { 2788 Handle<Object> object) {
2789 AllowDeferredHandleDereference using_raw_address; 2789 AllowDeferredHandleDereference using_raw_address;
2790 ASSERT(object->IsHeapObject()); 2790 DCHECK(object->IsHeapObject());
2791 if (isolate()->heap()->InNewSpace(*object)) { 2791 if (isolate()->heap()->InNewSpace(*object)) {
2792 Handle<Cell> cell = isolate()->factory()->NewCell(object); 2792 Handle<Cell> cell = isolate()->factory()->NewCell(object);
2793 Move(result, cell, RelocInfo::CELL); 2793 Move(result, cell, RelocInfo::CELL);
2794 movp(result, Operand(result, 0)); 2794 movp(result, Operand(result, 0));
2795 } else { 2795 } else {
2796 Move(result, object, RelocInfo::EMBEDDED_OBJECT); 2796 Move(result, object, RelocInfo::EMBEDDED_OBJECT);
2797 } 2797 }
2798 } 2798 }
2799 2799
2800 2800
(...skipping 10 matching lines...) Expand all
2811 2811
2812 void MacroAssembler::Drop(int stack_elements) { 2812 void MacroAssembler::Drop(int stack_elements) {
2813 if (stack_elements > 0) { 2813 if (stack_elements > 0) {
2814 addp(rsp, Immediate(stack_elements * kPointerSize)); 2814 addp(rsp, Immediate(stack_elements * kPointerSize));
2815 } 2815 }
2816 } 2816 }
2817 2817
2818 2818
2819 void MacroAssembler::DropUnderReturnAddress(int stack_elements, 2819 void MacroAssembler::DropUnderReturnAddress(int stack_elements,
2820 Register scratch) { 2820 Register scratch) {
2821 ASSERT(stack_elements > 0); 2821 DCHECK(stack_elements > 0);
2822 if (kPointerSize == kInt64Size && stack_elements == 1) { 2822 if (kPointerSize == kInt64Size && stack_elements == 1) {
2823 popq(MemOperand(rsp, 0)); 2823 popq(MemOperand(rsp, 0));
2824 return; 2824 return;
2825 } 2825 }
2826 2826
2827 PopReturnAddressTo(scratch); 2827 PopReturnAddressTo(scratch);
2828 Drop(stack_elements); 2828 Drop(stack_elements);
2829 PushReturnAddressFrom(scratch); 2829 PushReturnAddressFrom(scratch);
2830 } 2830 }
2831 2831
2832 2832
2833 void MacroAssembler::Push(Register src) { 2833 void MacroAssembler::Push(Register src) {
2834 if (kPointerSize == kInt64Size) { 2834 if (kPointerSize == kInt64Size) {
2835 pushq(src); 2835 pushq(src);
2836 } else { 2836 } else {
2837 // x32 uses 64-bit push for rbp in the prologue. 2837 // x32 uses 64-bit push for rbp in the prologue.
2838 ASSERT(src.code() != rbp.code()); 2838 DCHECK(src.code() != rbp.code());
2839 leal(rsp, Operand(rsp, -4)); 2839 leal(rsp, Operand(rsp, -4));
2840 movp(Operand(rsp, 0), src); 2840 movp(Operand(rsp, 0), src);
2841 } 2841 }
2842 } 2842 }
2843 2843
2844 2844
2845 void MacroAssembler::Push(const Operand& src) { 2845 void MacroAssembler::Push(const Operand& src) {
2846 if (kPointerSize == kInt64Size) { 2846 if (kPointerSize == kInt64Size) {
2847 pushq(src); 2847 pushq(src);
2848 } else { 2848 } else {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2881 movp(Operand(rsp, 0), Immediate(imm32)); 2881 movp(Operand(rsp, 0), Immediate(imm32));
2882 } 2882 }
2883 } 2883 }
2884 2884
2885 2885
2886 void MacroAssembler::Pop(Register dst) { 2886 void MacroAssembler::Pop(Register dst) {
2887 if (kPointerSize == kInt64Size) { 2887 if (kPointerSize == kInt64Size) {
2888 popq(dst); 2888 popq(dst);
2889 } else { 2889 } else {
2890 // x32 uses 64-bit pop for rbp in the epilogue. 2890 // x32 uses 64-bit pop for rbp in the epilogue.
2891 ASSERT(dst.code() != rbp.code()); 2891 DCHECK(dst.code() != rbp.code());
2892 movp(dst, Operand(rsp, 0)); 2892 movp(dst, Operand(rsp, 0));
2893 leal(rsp, Operand(rsp, 4)); 2893 leal(rsp, Operand(rsp, 4));
2894 } 2894 }
2895 } 2895 }
2896 2896
2897 2897
2898 void MacroAssembler::Pop(const Operand& dst) { 2898 void MacroAssembler::Pop(const Operand& dst) {
2899 if (kPointerSize == kInt64Size) { 2899 if (kPointerSize == kInt64Size) {
2900 popq(dst); 2900 popq(dst);
2901 } else { 2901 } else {
(...skipping 18 matching lines...) Expand all
2920 } else { 2920 } else {
2921 popq(kScratchRegister); 2921 popq(kScratchRegister);
2922 movp(dst, kScratchRegister); 2922 movp(dst, kScratchRegister);
2923 } 2923 }
2924 } 2924 }
2925 2925
2926 2926
2927 void MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst, 2927 void MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst,
2928 Register base, 2928 Register base,
2929 int offset) { 2929 int offset) {
2930 ASSERT(offset > SharedFunctionInfo::kLengthOffset && 2930 DCHECK(offset > SharedFunctionInfo::kLengthOffset &&
2931 offset <= SharedFunctionInfo::kSize && 2931 offset <= SharedFunctionInfo::kSize &&
2932 (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 2932 (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1));
2933 if (kPointerSize == kInt64Size) { 2933 if (kPointerSize == kInt64Size) {
2934 movsxlq(dst, FieldOperand(base, offset)); 2934 movsxlq(dst, FieldOperand(base, offset));
2935 } else { 2935 } else {
2936 movp(dst, FieldOperand(base, offset)); 2936 movp(dst, FieldOperand(base, offset));
2937 SmiToInteger32(dst, dst); 2937 SmiToInteger32(dst, dst);
2938 } 2938 }
2939 } 2939 }
2940 2940
2941 2941
2942 void MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base, 2942 void MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base,
2943 int offset, 2943 int offset,
2944 int bits) { 2944 int bits) {
2945 ASSERT(offset > SharedFunctionInfo::kLengthOffset && 2945 DCHECK(offset > SharedFunctionInfo::kLengthOffset &&
2946 offset <= SharedFunctionInfo::kSize && 2946 offset <= SharedFunctionInfo::kSize &&
2947 (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 2947 (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1));
2948 if (kPointerSize == kInt32Size) { 2948 if (kPointerSize == kInt32Size) {
2949 // On x32, this field is represented by SMI. 2949 // On x32, this field is represented by SMI.
2950 bits += kSmiShift; 2950 bits += kSmiShift;
2951 } 2951 }
2952 int byte_offset = bits / kBitsPerByte; 2952 int byte_offset = bits / kBitsPerByte;
2953 int bit_in_byte = bits & (kBitsPerByte - 1); 2953 int bit_in_byte = bits & (kBitsPerByte - 1);
2954 testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte)); 2954 testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte));
2955 } 2955 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3023 #endif 3023 #endif
3024 } 3024 }
3025 3025
3026 3026
3027 void MacroAssembler::Call(Handle<Code> code_object, 3027 void MacroAssembler::Call(Handle<Code> code_object,
3028 RelocInfo::Mode rmode, 3028 RelocInfo::Mode rmode,
3029 TypeFeedbackId ast_id) { 3029 TypeFeedbackId ast_id) {
3030 #ifdef DEBUG 3030 #ifdef DEBUG
3031 int end_position = pc_offset() + CallSize(code_object); 3031 int end_position = pc_offset() + CallSize(code_object);
3032 #endif 3032 #endif
3033 ASSERT(RelocInfo::IsCodeTarget(rmode) || 3033 DCHECK(RelocInfo::IsCodeTarget(rmode) ||
3034 rmode == RelocInfo::CODE_AGE_SEQUENCE); 3034 rmode == RelocInfo::CODE_AGE_SEQUENCE);
3035 call(code_object, rmode, ast_id); 3035 call(code_object, rmode, ast_id);
3036 #ifdef DEBUG 3036 #ifdef DEBUG
3037 CHECK_EQ(end_position, pc_offset()); 3037 CHECK_EQ(end_position, pc_offset());
3038 #endif 3038 #endif
3039 } 3039 }
3040 3040
3041 3041
3042 void MacroAssembler::Pushad() { 3042 void MacroAssembler::Pushad() {
3043 Push(rax); 3043 Push(rax);
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
3552 } 3552 }
3553 3553
3554 3554
3555 void MacroAssembler::TaggedToI(Register result_reg, 3555 void MacroAssembler::TaggedToI(Register result_reg,
3556 Register input_reg, 3556 Register input_reg,
3557 XMMRegister temp, 3557 XMMRegister temp,
3558 MinusZeroMode minus_zero_mode, 3558 MinusZeroMode minus_zero_mode,
3559 Label* lost_precision, 3559 Label* lost_precision,
3560 Label::Distance dst) { 3560 Label::Distance dst) {
3561 Label done; 3561 Label done;
3562 ASSERT(!temp.is(xmm0)); 3562 DCHECK(!temp.is(xmm0));
3563 3563
3564 // Heap number map check. 3564 // Heap number map check.
3565 CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 3565 CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
3566 Heap::kHeapNumberMapRootIndex); 3566 Heap::kHeapNumberMapRootIndex);
3567 j(not_equal, lost_precision, dst); 3567 j(not_equal, lost_precision, dst);
3568 3568
3569 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3569 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
3570 cvttsd2si(result_reg, xmm0); 3570 cvttsd2si(result_reg, xmm0);
3571 Cvtlsi2sd(temp, result_reg); 3571 Cvtlsi2sd(temp, result_reg);
3572 ucomisd(xmm0, temp); 3572 ucomisd(xmm0, temp);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3653 void MacroAssembler::AssertSmi(const Operand& object) { 3653 void MacroAssembler::AssertSmi(const Operand& object) {
3654 if (emit_debug_code()) { 3654 if (emit_debug_code()) {
3655 Condition is_smi = CheckSmi(object); 3655 Condition is_smi = CheckSmi(object);
3656 Check(is_smi, kOperandIsNotASmi); 3656 Check(is_smi, kOperandIsNotASmi);
3657 } 3657 }
3658 } 3658 }
3659 3659
3660 3660
3661 void MacroAssembler::AssertZeroExtended(Register int32_register) { 3661 void MacroAssembler::AssertZeroExtended(Register int32_register) {
3662 if (emit_debug_code()) { 3662 if (emit_debug_code()) {
3663 ASSERT(!int32_register.is(kScratchRegister)); 3663 DCHECK(!int32_register.is(kScratchRegister));
3664 movq(kScratchRegister, V8_INT64_C(0x0000000100000000)); 3664 movq(kScratchRegister, V8_INT64_C(0x0000000100000000));
3665 cmpq(kScratchRegister, int32_register); 3665 cmpq(kScratchRegister, int32_register);
3666 Check(above_equal, k32BitValueInRegisterIsNotZeroExtended); 3666 Check(above_equal, k32BitValueInRegisterIsNotZeroExtended);
3667 } 3667 }
3668 } 3668 }
3669 3669
3670 3670
3671 void MacroAssembler::AssertString(Register object) { 3671 void MacroAssembler::AssertString(Register object) {
3672 if (emit_debug_code()) { 3672 if (emit_debug_code()) {
3673 testb(object, Immediate(kSmiTagMask)); 3673 testb(object, Immediate(kSmiTagMask));
(...skipping 30 matching lines...) Expand all
3704 Assert(equal, kExpectedUndefinedOrCell); 3704 Assert(equal, kExpectedUndefinedOrCell);
3705 bind(&done_checking); 3705 bind(&done_checking);
3706 } 3706 }
3707 } 3707 }
3708 3708
3709 3709
3710 void MacroAssembler::AssertRootValue(Register src, 3710 void MacroAssembler::AssertRootValue(Register src,
3711 Heap::RootListIndex root_value_index, 3711 Heap::RootListIndex root_value_index,
3712 BailoutReason reason) { 3712 BailoutReason reason) {
3713 if (emit_debug_code()) { 3713 if (emit_debug_code()) {
3714 ASSERT(!src.is(kScratchRegister)); 3714 DCHECK(!src.is(kScratchRegister));
3715 LoadRoot(kScratchRegister, root_value_index); 3715 LoadRoot(kScratchRegister, root_value_index);
3716 cmpp(src, kScratchRegister); 3716 cmpp(src, kScratchRegister);
3717 Check(equal, reason); 3717 Check(equal, reason);
3718 } 3718 }
3719 } 3719 }
3720 3720
3721 3721
3722 3722
3723 Condition MacroAssembler::IsObjectStringType(Register heap_object, 3723 Condition MacroAssembler::IsObjectStringType(Register heap_object,
3724 Register map, 3724 Register map,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3804 3804
3805 void MacroAssembler::SetCounter(StatsCounter* counter, int value) { 3805 void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
3806 if (FLAG_native_code_counters && counter->Enabled()) { 3806 if (FLAG_native_code_counters && counter->Enabled()) {
3807 Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3807 Operand counter_operand = ExternalOperand(ExternalReference(counter));
3808 movl(counter_operand, Immediate(value)); 3808 movl(counter_operand, Immediate(value));
3809 } 3809 }
3810 } 3810 }
3811 3811
3812 3812
3813 void MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 3813 void MacroAssembler::IncrementCounter(StatsCounter* counter, int value) {
3814 ASSERT(value > 0); 3814 DCHECK(value > 0);
3815 if (FLAG_native_code_counters && counter->Enabled()) { 3815 if (FLAG_native_code_counters && counter->Enabled()) {
3816 Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3816 Operand counter_operand = ExternalOperand(ExternalReference(counter));
3817 if (value == 1) { 3817 if (value == 1) {
3818 incl(counter_operand); 3818 incl(counter_operand);
3819 } else { 3819 } else {
3820 addl(counter_operand, Immediate(value)); 3820 addl(counter_operand, Immediate(value));
3821 } 3821 }
3822 } 3822 }
3823 } 3823 }
3824 3824
3825 3825
3826 void MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 3826 void MacroAssembler::DecrementCounter(StatsCounter* counter, int value) {
3827 ASSERT(value > 0); 3827 DCHECK(value > 0);
3828 if (FLAG_native_code_counters && counter->Enabled()) { 3828 if (FLAG_native_code_counters && counter->Enabled()) {
3829 Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3829 Operand counter_operand = ExternalOperand(ExternalReference(counter));
3830 if (value == 1) { 3830 if (value == 1) {
3831 decl(counter_operand); 3831 decl(counter_operand);
3832 } else { 3832 } else {
3833 subl(counter_operand, Immediate(value)); 3833 subl(counter_operand, Immediate(value));
3834 } 3834 }
3835 } 3835 }
3836 } 3836 }
3837 3837
3838 3838
3839 void MacroAssembler::DebugBreak() { 3839 void MacroAssembler::DebugBreak() {
3840 Set(rax, 0); // No arguments. 3840 Set(rax, 0); // No arguments.
3841 LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate())); 3841 LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate()));
3842 CEntryStub ces(isolate(), 1); 3842 CEntryStub ces(isolate(), 1);
3843 ASSERT(AllowThisStubCall(&ces)); 3843 DCHECK(AllowThisStubCall(&ces));
3844 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); 3844 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
3845 } 3845 }
3846 3846
3847 3847
3848 void MacroAssembler::InvokeCode(Register code, 3848 void MacroAssembler::InvokeCode(Register code,
3849 const ParameterCount& expected, 3849 const ParameterCount& expected,
3850 const ParameterCount& actual, 3850 const ParameterCount& actual,
3851 InvokeFlag flag, 3851 InvokeFlag flag,
3852 const CallWrapper& call_wrapper) { 3852 const CallWrapper& call_wrapper) {
3853 // You can't call a function without a valid frame. 3853 // You can't call a function without a valid frame.
3854 ASSERT(flag == JUMP_FUNCTION || has_frame()); 3854 DCHECK(flag == JUMP_FUNCTION || has_frame());
3855 3855
3856 Label done; 3856 Label done;
3857 bool definitely_mismatches = false; 3857 bool definitely_mismatches = false;
3858 InvokePrologue(expected, 3858 InvokePrologue(expected,
3859 actual, 3859 actual,
3860 Handle<Code>::null(), 3860 Handle<Code>::null(),
3861 code, 3861 code,
3862 &done, 3862 &done,
3863 &definitely_mismatches, 3863 &definitely_mismatches,
3864 flag, 3864 flag,
3865 Label::kNear, 3865 Label::kNear,
3866 call_wrapper); 3866 call_wrapper);
3867 if (!definitely_mismatches) { 3867 if (!definitely_mismatches) {
3868 if (flag == CALL_FUNCTION) { 3868 if (flag == CALL_FUNCTION) {
3869 call_wrapper.BeforeCall(CallSize(code)); 3869 call_wrapper.BeforeCall(CallSize(code));
3870 call(code); 3870 call(code);
3871 call_wrapper.AfterCall(); 3871 call_wrapper.AfterCall();
3872 } else { 3872 } else {
3873 ASSERT(flag == JUMP_FUNCTION); 3873 DCHECK(flag == JUMP_FUNCTION);
3874 jmp(code); 3874 jmp(code);
3875 } 3875 }
3876 bind(&done); 3876 bind(&done);
3877 } 3877 }
3878 } 3878 }
3879 3879
3880 3880
3881 void MacroAssembler::InvokeFunction(Register function, 3881 void MacroAssembler::InvokeFunction(Register function,
3882 const ParameterCount& actual, 3882 const ParameterCount& actual,
3883 InvokeFlag flag, 3883 InvokeFlag flag,
3884 const CallWrapper& call_wrapper) { 3884 const CallWrapper& call_wrapper) {
3885 // You can't call a function without a valid frame. 3885 // You can't call a function without a valid frame.
3886 ASSERT(flag == JUMP_FUNCTION || has_frame()); 3886 DCHECK(flag == JUMP_FUNCTION || has_frame());
3887 3887
3888 ASSERT(function.is(rdi)); 3888 DCHECK(function.is(rdi));
3889 movp(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3889 movp(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
3890 movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 3890 movp(rsi, FieldOperand(function, JSFunction::kContextOffset));
3891 LoadSharedFunctionInfoSpecialField(rbx, rdx, 3891 LoadSharedFunctionInfoSpecialField(rbx, rdx,
3892 SharedFunctionInfo::kFormalParameterCountOffset); 3892 SharedFunctionInfo::kFormalParameterCountOffset);
3893 // Advances rdx to the end of the Code object header, to the start of 3893 // Advances rdx to the end of the Code object header, to the start of
3894 // the executable code. 3894 // the executable code.
3895 movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 3895 movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
3896 3896
3897 ParameterCount expected(rbx); 3897 ParameterCount expected(rbx);
3898 InvokeCode(rdx, expected, actual, flag, call_wrapper); 3898 InvokeCode(rdx, expected, actual, flag, call_wrapper);
3899 } 3899 }
3900 3900
3901 3901
3902 void MacroAssembler::InvokeFunction(Register function, 3902 void MacroAssembler::InvokeFunction(Register function,
3903 const ParameterCount& expected, 3903 const ParameterCount& expected,
3904 const ParameterCount& actual, 3904 const ParameterCount& actual,
3905 InvokeFlag flag, 3905 InvokeFlag flag,
3906 const CallWrapper& call_wrapper) { 3906 const CallWrapper& call_wrapper) {
3907 // You can't call a function without a valid frame. 3907 // You can't call a function without a valid frame.
3908 ASSERT(flag == JUMP_FUNCTION || has_frame()); 3908 DCHECK(flag == JUMP_FUNCTION || has_frame());
3909 3909
3910 ASSERT(function.is(rdi)); 3910 DCHECK(function.is(rdi));
3911 movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 3911 movp(rsi, FieldOperand(function, JSFunction::kContextOffset));
3912 // Advances rdx to the end of the Code object header, to the start of 3912 // Advances rdx to the end of the Code object header, to the start of
3913 // the executable code. 3913 // the executable code.
3914 movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 3914 movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
3915 3915
3916 InvokeCode(rdx, expected, actual, flag, call_wrapper); 3916 InvokeCode(rdx, expected, actual, flag, call_wrapper);
3917 } 3917 }
3918 3918
3919 3919
3920 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, 3920 void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
(...skipping 12 matching lines...) Expand all
3933 Register code_register, 3933 Register code_register,
3934 Label* done, 3934 Label* done,
3935 bool* definitely_mismatches, 3935 bool* definitely_mismatches,
3936 InvokeFlag flag, 3936 InvokeFlag flag,
3937 Label::Distance near_jump, 3937 Label::Distance near_jump,
3938 const CallWrapper& call_wrapper) { 3938 const CallWrapper& call_wrapper) {
3939 bool definitely_matches = false; 3939 bool definitely_matches = false;
3940 *definitely_mismatches = false; 3940 *definitely_mismatches = false;
3941 Label invoke; 3941 Label invoke;
3942 if (expected.is_immediate()) { 3942 if (expected.is_immediate()) {
3943 ASSERT(actual.is_immediate()); 3943 DCHECK(actual.is_immediate());
3944 if (expected.immediate() == actual.immediate()) { 3944 if (expected.immediate() == actual.immediate()) {
3945 definitely_matches = true; 3945 definitely_matches = true;
3946 } else { 3946 } else {
3947 Set(rax, actual.immediate()); 3947 Set(rax, actual.immediate());
3948 if (expected.immediate() == 3948 if (expected.immediate() ==
3949 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 3949 SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
3950 // Don't worry about adapting arguments for built-ins that 3950 // Don't worry about adapting arguments for built-ins that
3951 // don't want that done. Skip adaption code by making it look 3951 // don't want that done. Skip adaption code by making it look
3952 // like we have a match between expected and actual number of 3952 // like we have a match between expected and actual number of
3953 // arguments. 3953 // arguments.
3954 definitely_matches = true; 3954 definitely_matches = true;
3955 } else { 3955 } else {
3956 *definitely_mismatches = true; 3956 *definitely_mismatches = true;
3957 Set(rbx, expected.immediate()); 3957 Set(rbx, expected.immediate());
3958 } 3958 }
3959 } 3959 }
3960 } else { 3960 } else {
3961 if (actual.is_immediate()) { 3961 if (actual.is_immediate()) {
3962 // Expected is in register, actual is immediate. This is the 3962 // Expected is in register, actual is immediate. This is the
3963 // case when we invoke function values without going through the 3963 // case when we invoke function values without going through the
3964 // IC mechanism. 3964 // IC mechanism.
3965 cmpp(expected.reg(), Immediate(actual.immediate())); 3965 cmpp(expected.reg(), Immediate(actual.immediate()));
3966 j(equal, &invoke, Label::kNear); 3966 j(equal, &invoke, Label::kNear);
3967 ASSERT(expected.reg().is(rbx)); 3967 DCHECK(expected.reg().is(rbx));
3968 Set(rax, actual.immediate()); 3968 Set(rax, actual.immediate());
3969 } else if (!expected.reg().is(actual.reg())) { 3969 } else if (!expected.reg().is(actual.reg())) {
3970 // Both expected and actual are in (different) registers. This 3970 // Both expected and actual are in (different) registers. This
3971 // is the case when we invoke functions using call and apply. 3971 // is the case when we invoke functions using call and apply.
3972 cmpp(expected.reg(), actual.reg()); 3972 cmpp(expected.reg(), actual.reg());
3973 j(equal, &invoke, Label::kNear); 3973 j(equal, &invoke, Label::kNear);
3974 ASSERT(actual.reg().is(rax)); 3974 DCHECK(actual.reg().is(rax));
3975 ASSERT(expected.reg().is(rbx)); 3975 DCHECK(expected.reg().is(rbx));
3976 } 3976 }
3977 } 3977 }
3978 3978
3979 if (!definitely_matches) { 3979 if (!definitely_matches) {
3980 Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); 3980 Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
3981 if (!code_constant.is_null()) { 3981 if (!code_constant.is_null()) {
3982 Move(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); 3982 Move(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT);
3983 addp(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 3983 addp(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
3984 } else if (!code_register.is(rdx)) { 3984 } else if (!code_register.is(rdx)) {
3985 movp(rdx, code_register); 3985 movp(rdx, code_register);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
4049 Check(equal, kStackFrameTypesMustMatch); 4049 Check(equal, kStackFrameTypesMustMatch);
4050 } 4050 }
4051 movp(rsp, rbp); 4051 movp(rsp, rbp);
4052 popq(rbp); 4052 popq(rbp);
4053 } 4053 }
4054 4054
4055 4055
4056 void MacroAssembler::EnterExitFramePrologue(bool save_rax) { 4056 void MacroAssembler::EnterExitFramePrologue(bool save_rax) {
4057 // Set up the frame structure on the stack. 4057 // Set up the frame structure on the stack.
4058 // All constants are relative to the frame pointer of the exit frame. 4058 // All constants are relative to the frame pointer of the exit frame.
4059 ASSERT(ExitFrameConstants::kCallerSPDisplacement == 4059 DCHECK(ExitFrameConstants::kCallerSPDisplacement ==
4060 kFPOnStackSize + kPCOnStackSize); 4060 kFPOnStackSize + kPCOnStackSize);
4061 ASSERT(ExitFrameConstants::kCallerPCOffset == kFPOnStackSize); 4061 DCHECK(ExitFrameConstants::kCallerPCOffset == kFPOnStackSize);
4062 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 4062 DCHECK(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize);
4063 pushq(rbp); 4063 pushq(rbp);
4064 movp(rbp, rsp); 4064 movp(rbp, rsp);
4065 4065
4066 // Reserve room for entry stack pointer and push the code object. 4066 // Reserve room for entry stack pointer and push the code object.
4067 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 4067 DCHECK(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
4068 Push(Immediate(0)); // Saved entry sp, patched before call. 4068 Push(Immediate(0)); // Saved entry sp, patched before call.
4069 Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 4069 Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
4070 Push(kScratchRegister); // Accessed from EditFrame::code_slot. 4070 Push(kScratchRegister); // Accessed from EditFrame::code_slot.
4071 4071
4072 // Save the frame pointer and the context in top. 4072 // Save the frame pointer and the context in top.
4073 if (save_rax) { 4073 if (save_rax) {
4074 movp(r14, rax); // Backup rax in callee-save register. 4074 movp(r14, rax); // Backup rax in callee-save register.
4075 } 4075 }
4076 4076
4077 Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp); 4077 Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp);
(...skipping 17 matching lines...) Expand all
4095 XMMRegister reg = XMMRegister::FromAllocationIndex(i); 4095 XMMRegister reg = XMMRegister::FromAllocationIndex(i);
4096 movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); 4096 movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg);
4097 } 4097 }
4098 } else if (arg_stack_space > 0) { 4098 } else if (arg_stack_space > 0) {
4099 subp(rsp, Immediate(arg_stack_space * kRegisterSize)); 4099 subp(rsp, Immediate(arg_stack_space * kRegisterSize));
4100 } 4100 }
4101 4101
4102 // Get the required frame alignment for the OS. 4102 // Get the required frame alignment for the OS.
4103 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); 4103 const int kFrameAlignment = base::OS::ActivationFrameAlignment();
4104 if (kFrameAlignment > 0) { 4104 if (kFrameAlignment > 0) {
4105 ASSERT(IsPowerOf2(kFrameAlignment)); 4105 DCHECK(IsPowerOf2(kFrameAlignment));
4106 ASSERT(is_int8(kFrameAlignment)); 4106 DCHECK(is_int8(kFrameAlignment));
4107 andp(rsp, Immediate(-kFrameAlignment)); 4107 andp(rsp, Immediate(-kFrameAlignment));
4108 } 4108 }
4109 4109
4110 // Patch the saved entry sp. 4110 // Patch the saved entry sp.
4111 movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 4111 movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
4112 } 4112 }
4113 4113
4114 4114
4115 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { 4115 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) {
4116 EnterExitFramePrologue(true); 4116 EnterExitFramePrologue(true);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4179 Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); 4179 Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address);
4180 movp(c_entry_fp_operand, Immediate(0)); 4180 movp(c_entry_fp_operand, Immediate(0));
4181 } 4181 }
4182 4182
4183 4183
4184 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 4184 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
4185 Register scratch, 4185 Register scratch,
4186 Label* miss) { 4186 Label* miss) {
4187 Label same_contexts; 4187 Label same_contexts;
4188 4188
4189 ASSERT(!holder_reg.is(scratch)); 4189 DCHECK(!holder_reg.is(scratch));
4190 ASSERT(!scratch.is(kScratchRegister)); 4190 DCHECK(!scratch.is(kScratchRegister));
4191 // Load current lexical context from the stack frame. 4191 // Load current lexical context from the stack frame.
4192 movp(scratch, Operand(rbp, StandardFrameConstants::kContextOffset)); 4192 movp(scratch, Operand(rbp, StandardFrameConstants::kContextOffset));
4193 4193
4194 // When generating debug code, make sure the lexical context is set. 4194 // When generating debug code, make sure the lexical context is set.
4195 if (emit_debug_code()) { 4195 if (emit_debug_code()) {
4196 cmpp(scratch, Immediate(0)); 4196 cmpp(scratch, Immediate(0));
4197 Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); 4197 Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext);
4198 } 4198 }
4199 // Load the native context of the current context. 4199 // Load the native context of the current context.
4200 int offset = 4200 int offset =
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
4326 for (int i = 0; i < kNumberDictionaryProbes; i++) { 4326 for (int i = 0; i < kNumberDictionaryProbes; i++) {
4327 // Use r2 for index calculations and keep the hash intact in r0. 4327 // Use r2 for index calculations and keep the hash intact in r0.
4328 movp(r2, r0); 4328 movp(r2, r0);
4329 // Compute the masked index: (hash + i + i * i) & mask. 4329 // Compute the masked index: (hash + i + i * i) & mask.
4330 if (i > 0) { 4330 if (i > 0) {
4331 addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 4331 addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i)));
4332 } 4332 }
4333 andp(r2, r1); 4333 andp(r2, r1);
4334 4334
4335 // Scale the index by multiplying by the entry size. 4335 // Scale the index by multiplying by the entry size.
4336 ASSERT(SeededNumberDictionary::kEntrySize == 3); 4336 DCHECK(SeededNumberDictionary::kEntrySize == 3);
4337 leap(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 4337 leap(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
4338 4338
4339 // Check if the key matches. 4339 // Check if the key matches.
4340 cmpp(key, FieldOperand(elements, 4340 cmpp(key, FieldOperand(elements,
4341 r2, 4341 r2,
4342 times_pointer_size, 4342 times_pointer_size,
4343 SeededNumberDictionary::kElementsStartOffset)); 4343 SeededNumberDictionary::kElementsStartOffset));
4344 if (i != (kNumberDictionaryProbes - 1)) { 4344 if (i != (kNumberDictionaryProbes - 1)) {
4345 j(equal, &done); 4345 j(equal, &done);
4346 } else { 4346 } else {
4347 j(not_equal, miss); 4347 j(not_equal, miss);
4348 } 4348 }
4349 } 4349 }
4350 4350
4351 bind(&done); 4351 bind(&done);
4352 // Check that the value is a normal propety. 4352 // Check that the value is a normal propety.
4353 const int kDetailsOffset = 4353 const int kDetailsOffset =
4354 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 4354 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
4355 ASSERT_EQ(NORMAL, 0); 4355 DCHECK_EQ(NORMAL, 0);
4356 Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 4356 Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
4357 Smi::FromInt(PropertyDetails::TypeField::kMask)); 4357 Smi::FromInt(PropertyDetails::TypeField::kMask));
4358 j(not_zero, miss); 4358 j(not_zero, miss);
4359 4359
4360 // Get the value at the masked, scaled index. 4360 // Get the value at the masked, scaled index.
4361 const int kValueOffset = 4361 const int kValueOffset =
4362 SeededNumberDictionary::kElementsStartOffset + kPointerSize; 4362 SeededNumberDictionary::kElementsStartOffset + kPointerSize;
4363 movp(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 4363 movp(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
4364 } 4364 }
4365 4365
4366 4366
4367 void MacroAssembler::LoadAllocationTopHelper(Register result, 4367 void MacroAssembler::LoadAllocationTopHelper(Register result,
4368 Register scratch, 4368 Register scratch,
4369 AllocationFlags flags) { 4369 AllocationFlags flags) {
4370 ExternalReference allocation_top = 4370 ExternalReference allocation_top =
4371 AllocationUtils::GetAllocationTopReference(isolate(), flags); 4371 AllocationUtils::GetAllocationTopReference(isolate(), flags);
4372 4372
4373 // Just return if allocation top is already known. 4373 // Just return if allocation top is already known.
4374 if ((flags & RESULT_CONTAINS_TOP) != 0) { 4374 if ((flags & RESULT_CONTAINS_TOP) != 0) {
4375 // No use of scratch if allocation top is provided. 4375 // No use of scratch if allocation top is provided.
4376 ASSERT(!scratch.is_valid()); 4376 DCHECK(!scratch.is_valid());
4377 #ifdef DEBUG 4377 #ifdef DEBUG
4378 // Assert that result actually contains top on entry. 4378 // Assert that result actually contains top on entry.
4379 Operand top_operand = ExternalOperand(allocation_top); 4379 Operand top_operand = ExternalOperand(allocation_top);
4380 cmpp(result, top_operand); 4380 cmpp(result, top_operand);
4381 Check(equal, kUnexpectedAllocationTop); 4381 Check(equal, kUnexpectedAllocationTop);
4382 #endif 4382 #endif
4383 return; 4383 return;
4384 } 4384 }
4385 4385
4386 // Move address of new object to result. Use scratch register if available, 4386 // Move address of new object to result. Use scratch register if available,
(...skipping 12 matching lines...) Expand all
4399 Label* gc_required, 4399 Label* gc_required,
4400 AllocationFlags flags) { 4400 AllocationFlags flags) {
4401 if (kPointerSize == kDoubleSize) { 4401 if (kPointerSize == kDoubleSize) {
4402 if (FLAG_debug_code) { 4402 if (FLAG_debug_code) {
4403 testl(result, Immediate(kDoubleAlignmentMask)); 4403 testl(result, Immediate(kDoubleAlignmentMask));
4404 Check(zero, kAllocationIsNotDoubleAligned); 4404 Check(zero, kAllocationIsNotDoubleAligned);
4405 } 4405 }
4406 } else { 4406 } else {
4407 // Align the next allocation. Storing the filler map without checking top 4407 // Align the next allocation. Storing the filler map without checking top
4408 // is safe in new-space because the limit of the heap is aligned there. 4408 // is safe in new-space because the limit of the heap is aligned there.
4409 ASSERT(kPointerSize * 2 == kDoubleSize); 4409 DCHECK(kPointerSize * 2 == kDoubleSize);
4410 ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 4410 DCHECK((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
4411 ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 4411 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
4412 // Make sure scratch is not clobbered by this function as it might be 4412 // Make sure scratch is not clobbered by this function as it might be
4413 // used in UpdateAllocationTopHelper later. 4413 // used in UpdateAllocationTopHelper later.
4414 ASSERT(!scratch.is(kScratchRegister)); 4414 DCHECK(!scratch.is(kScratchRegister));
4415 Label aligned; 4415 Label aligned;
4416 testl(result, Immediate(kDoubleAlignmentMask)); 4416 testl(result, Immediate(kDoubleAlignmentMask));
4417 j(zero, &aligned, Label::kNear); 4417 j(zero, &aligned, Label::kNear);
4418 if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 4418 if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
4419 ExternalReference allocation_limit = 4419 ExternalReference allocation_limit =
4420 AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4420 AllocationUtils::GetAllocationLimitReference(isolate(), flags);
4421 cmpp(result, ExternalOperand(allocation_limit)); 4421 cmpp(result, ExternalOperand(allocation_limit));
4422 j(above_equal, gc_required); 4422 j(above_equal, gc_required);
4423 } 4423 }
4424 LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex); 4424 LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex);
(...skipping 24 matching lines...) Expand all
4449 } 4449 }
4450 } 4450 }
4451 4451
4452 4452
4453 void MacroAssembler::Allocate(int object_size, 4453 void MacroAssembler::Allocate(int object_size,
4454 Register result, 4454 Register result,
4455 Register result_end, 4455 Register result_end,
4456 Register scratch, 4456 Register scratch,
4457 Label* gc_required, 4457 Label* gc_required,
4458 AllocationFlags flags) { 4458 AllocationFlags flags) {
4459 ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 4459 DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
4460 ASSERT(object_size <= Page::kMaxRegularHeapObjectSize); 4460 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
4461 if (!FLAG_inline_new) { 4461 if (!FLAG_inline_new) {
4462 if (emit_debug_code()) { 4462 if (emit_debug_code()) {
4463 // Trash the registers to simulate an allocation failure. 4463 // Trash the registers to simulate an allocation failure.
4464 movl(result, Immediate(0x7091)); 4464 movl(result, Immediate(0x7091));
4465 if (result_end.is_valid()) { 4465 if (result_end.is_valid()) {
4466 movl(result_end, Immediate(0x7191)); 4466 movl(result_end, Immediate(0x7191));
4467 } 4467 }
4468 if (scratch.is_valid()) { 4468 if (scratch.is_valid()) {
4469 movl(scratch, Immediate(0x7291)); 4469 movl(scratch, Immediate(0x7291));
4470 } 4470 }
4471 } 4471 }
4472 jmp(gc_required); 4472 jmp(gc_required);
4473 return; 4473 return;
4474 } 4474 }
4475 ASSERT(!result.is(result_end)); 4475 DCHECK(!result.is(result_end));
4476 4476
4477 // Load address of new object into result. 4477 // Load address of new object into result.
4478 LoadAllocationTopHelper(result, scratch, flags); 4478 LoadAllocationTopHelper(result, scratch, flags);
4479 4479
4480 if ((flags & DOUBLE_ALIGNMENT) != 0) { 4480 if ((flags & DOUBLE_ALIGNMENT) != 0) {
4481 MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4481 MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags);
4482 } 4482 }
4483 4483
4484 // Calculate new top and bail out if new space is exhausted. 4484 // Calculate new top and bail out if new space is exhausted.
4485 ExternalReference allocation_limit = 4485 ExternalReference allocation_limit =
(...skipping 15 matching lines...) Expand all
4501 4501
4502 bool tag_result = (flags & TAG_OBJECT) != 0; 4502 bool tag_result = (flags & TAG_OBJECT) != 0;
4503 if (top_reg.is(result)) { 4503 if (top_reg.is(result)) {
4504 if (tag_result) { 4504 if (tag_result) {
4505 subp(result, Immediate(object_size - kHeapObjectTag)); 4505 subp(result, Immediate(object_size - kHeapObjectTag));
4506 } else { 4506 } else {
4507 subp(result, Immediate(object_size)); 4507 subp(result, Immediate(object_size));
4508 } 4508 }
4509 } else if (tag_result) { 4509 } else if (tag_result) {
4510 // Tag the result if requested. 4510 // Tag the result if requested.
4511 ASSERT(kHeapObjectTag == 1); 4511 DCHECK(kHeapObjectTag == 1);
4512 incp(result); 4512 incp(result);
4513 } 4513 }
4514 } 4514 }
4515 4515
4516 4516
4517 void MacroAssembler::Allocate(int header_size, 4517 void MacroAssembler::Allocate(int header_size,
4518 ScaleFactor element_size, 4518 ScaleFactor element_size,
4519 Register element_count, 4519 Register element_count,
4520 Register result, 4520 Register result,
4521 Register result_end, 4521 Register result_end,
4522 Register scratch, 4522 Register scratch,
4523 Label* gc_required, 4523 Label* gc_required,
4524 AllocationFlags flags) { 4524 AllocationFlags flags) {
4525 ASSERT((flags & SIZE_IN_WORDS) == 0); 4525 DCHECK((flags & SIZE_IN_WORDS) == 0);
4526 leap(result_end, Operand(element_count, element_size, header_size)); 4526 leap(result_end, Operand(element_count, element_size, header_size));
4527 Allocate(result_end, result, result_end, scratch, gc_required, flags); 4527 Allocate(result_end, result, result_end, scratch, gc_required, flags);
4528 } 4528 }
4529 4529
4530 4530
4531 void MacroAssembler::Allocate(Register object_size, 4531 void MacroAssembler::Allocate(Register object_size,
4532 Register result, 4532 Register result,
4533 Register result_end, 4533 Register result_end,
4534 Register scratch, 4534 Register scratch,
4535 Label* gc_required, 4535 Label* gc_required,
4536 AllocationFlags flags) { 4536 AllocationFlags flags) {
4537 ASSERT((flags & SIZE_IN_WORDS) == 0); 4537 DCHECK((flags & SIZE_IN_WORDS) == 0);
4538 if (!FLAG_inline_new) { 4538 if (!FLAG_inline_new) {
4539 if (emit_debug_code()) { 4539 if (emit_debug_code()) {
4540 // Trash the registers to simulate an allocation failure. 4540 // Trash the registers to simulate an allocation failure.
4541 movl(result, Immediate(0x7091)); 4541 movl(result, Immediate(0x7091));
4542 movl(result_end, Immediate(0x7191)); 4542 movl(result_end, Immediate(0x7191));
4543 if (scratch.is_valid()) { 4543 if (scratch.is_valid()) {
4544 movl(scratch, Immediate(0x7291)); 4544 movl(scratch, Immediate(0x7291));
4545 } 4545 }
4546 // object_size is left unchanged by this function. 4546 // object_size is left unchanged by this function.
4547 } 4547 }
4548 jmp(gc_required); 4548 jmp(gc_required);
4549 return; 4549 return;
4550 } 4550 }
4551 ASSERT(!result.is(result_end)); 4551 DCHECK(!result.is(result_end));
4552 4552
4553 // Load address of new object into result. 4553 // Load address of new object into result.
4554 LoadAllocationTopHelper(result, scratch, flags); 4554 LoadAllocationTopHelper(result, scratch, flags);
4555 4555
4556 if ((flags & DOUBLE_ALIGNMENT) != 0) { 4556 if ((flags & DOUBLE_ALIGNMENT) != 0) {
4557 MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4557 MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags);
4558 } 4558 }
4559 4559
4560 // Calculate new top and bail out if new space is exhausted. 4560 // Calculate new top and bail out if new space is exhausted.
4561 ExternalReference allocation_limit = 4561 ExternalReference allocation_limit =
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4614 void MacroAssembler::AllocateTwoByteString(Register result, 4614 void MacroAssembler::AllocateTwoByteString(Register result,
4615 Register length, 4615 Register length,
4616 Register scratch1, 4616 Register scratch1,
4617 Register scratch2, 4617 Register scratch2,
4618 Register scratch3, 4618 Register scratch3,
4619 Label* gc_required) { 4619 Label* gc_required) {
4620 // Calculate the number of bytes needed for the characters in the string while 4620 // Calculate the number of bytes needed for the characters in the string while
4621 // observing object alignment. 4621 // observing object alignment.
4622 const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & 4622 const int kHeaderAlignment = SeqTwoByteString::kHeaderSize &
4623 kObjectAlignmentMask; 4623 kObjectAlignmentMask;
4624 ASSERT(kShortSize == 2); 4624 DCHECK(kShortSize == 2);
4625 // scratch1 = length * 2 + kObjectAlignmentMask. 4625 // scratch1 = length * 2 + kObjectAlignmentMask.
4626 leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + 4626 leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask +
4627 kHeaderAlignment)); 4627 kHeaderAlignment));
4628 andp(scratch1, Immediate(~kObjectAlignmentMask)); 4628 andp(scratch1, Immediate(~kObjectAlignmentMask));
4629 if (kHeaderAlignment > 0) { 4629 if (kHeaderAlignment > 0) {
4630 subp(scratch1, Immediate(kHeaderAlignment)); 4630 subp(scratch1, Immediate(kHeaderAlignment));
4631 } 4631 }
4632 4632
4633 // Allocate two byte string in new space. 4633 // Allocate two byte string in new space.
4634 Allocate(SeqTwoByteString::kHeaderSize, 4634 Allocate(SeqTwoByteString::kHeaderSize,
(...skipping 19 matching lines...) Expand all
4654 Register length, 4654 Register length,
4655 Register scratch1, 4655 Register scratch1,
4656 Register scratch2, 4656 Register scratch2,
4657 Register scratch3, 4657 Register scratch3,
4658 Label* gc_required) { 4658 Label* gc_required) {
4659 // Calculate the number of bytes needed for the characters in the string while 4659 // Calculate the number of bytes needed for the characters in the string while
4660 // observing object alignment. 4660 // observing object alignment.
4661 const int kHeaderAlignment = SeqOneByteString::kHeaderSize & 4661 const int kHeaderAlignment = SeqOneByteString::kHeaderSize &
4662 kObjectAlignmentMask; 4662 kObjectAlignmentMask;
4663 movl(scratch1, length); 4663 movl(scratch1, length);
4664 ASSERT(kCharSize == 1); 4664 DCHECK(kCharSize == 1);
4665 addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); 4665 addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment));
4666 andp(scratch1, Immediate(~kObjectAlignmentMask)); 4666 andp(scratch1, Immediate(~kObjectAlignmentMask));
4667 if (kHeaderAlignment > 0) { 4667 if (kHeaderAlignment > 0) {
4668 subp(scratch1, Immediate(kHeaderAlignment)); 4668 subp(scratch1, Immediate(kHeaderAlignment));
4669 } 4669 }
4670 4670
4671 // Allocate ASCII string in new space. 4671 // Allocate ASCII string in new space.
4672 Allocate(SeqOneByteString::kHeaderSize, 4672 Allocate(SeqOneByteString::kHeaderSize,
4673 times_1, 4673 times_1,
4674 scratch1, 4674 scratch1,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
4752 // Destination is incremented by length, source, length and scratch are 4752 // Destination is incremented by length, source, length and scratch are
4753 // clobbered. 4753 // clobbered.
4754 // A simpler loop is faster on small copies, but slower on large ones. 4754 // A simpler loop is faster on small copies, but slower on large ones.
4755 // The cld() instruction must have been emitted, to set the direction flag(), 4755 // The cld() instruction must have been emitted, to set the direction flag(),
4756 // before calling this function. 4756 // before calling this function.
4757 void MacroAssembler::CopyBytes(Register destination, 4757 void MacroAssembler::CopyBytes(Register destination,
4758 Register source, 4758 Register source,
4759 Register length, 4759 Register length,
4760 int min_length, 4760 int min_length,
4761 Register scratch) { 4761 Register scratch) {
4762 ASSERT(min_length >= 0); 4762 DCHECK(min_length >= 0);
4763 if (emit_debug_code()) { 4763 if (emit_debug_code()) {
4764 cmpl(length, Immediate(min_length)); 4764 cmpl(length, Immediate(min_length));
4765 Assert(greater_equal, kInvalidMinLength); 4765 Assert(greater_equal, kInvalidMinLength);
4766 } 4766 }
4767 Label short_loop, len8, len16, len24, done, short_string; 4767 Label short_loop, len8, len16, len24, done, short_string;
4768 4768
4769 const int kLongStringLimit = 4 * kPointerSize; 4769 const int kLongStringLimit = 4 * kPointerSize;
4770 if (min_length <= kLongStringLimit) { 4770 if (min_length <= kLongStringLimit) {
4771 cmpl(length, Immediate(kPointerSize)); 4771 cmpl(length, Immediate(kPointerSize));
4772 j(below, &short_string, Label::kNear); 4772 j(below, &short_string, Label::kNear);
4773 } 4773 }
4774 4774
4775 ASSERT(source.is(rsi)); 4775 DCHECK(source.is(rsi));
4776 ASSERT(destination.is(rdi)); 4776 DCHECK(destination.is(rdi));
4777 ASSERT(length.is(rcx)); 4777 DCHECK(length.is(rcx));
4778 4778
4779 if (min_length <= kLongStringLimit) { 4779 if (min_length <= kLongStringLimit) {
4780 cmpl(length, Immediate(2 * kPointerSize)); 4780 cmpl(length, Immediate(2 * kPointerSize));
4781 j(below_equal, &len8, Label::kNear); 4781 j(below_equal, &len8, Label::kNear);
4782 cmpl(length, Immediate(3 * kPointerSize)); 4782 cmpl(length, Immediate(3 * kPointerSize));
4783 j(below_equal, &len16, Label::kNear); 4783 j(below_equal, &len16, Label::kNear);
4784 cmpl(length, Immediate(4 * kPointerSize)); 4784 cmpl(length, Immediate(4 * kPointerSize));
4785 j(below_equal, &len24, Label::kNear); 4785 j(below_equal, &len24, Label::kNear);
4786 } 4786 }
4787 4787
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4932 } 4932 }
4933 4933
4934 4934
4935 int MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) { 4935 int MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) {
4936 // On Windows 64 stack slots are reserved by the caller for all arguments 4936 // On Windows 64 stack slots are reserved by the caller for all arguments
4937 // including the ones passed in registers, and space is always allocated for 4937 // including the ones passed in registers, and space is always allocated for
4938 // the four register arguments even if the function takes fewer than four 4938 // the four register arguments even if the function takes fewer than four
4939 // arguments. 4939 // arguments.
4940 // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers 4940 // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers
4941 // and the caller does not reserve stack slots for them. 4941 // and the caller does not reserve stack slots for them.
4942 ASSERT(num_arguments >= 0); 4942 DCHECK(num_arguments >= 0);
4943 #ifdef _WIN64 4943 #ifdef _WIN64
4944 const int kMinimumStackSlots = kRegisterPassedArguments; 4944 const int kMinimumStackSlots = kRegisterPassedArguments;
4945 if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots; 4945 if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots;
4946 return num_arguments; 4946 return num_arguments;
4947 #else 4947 #else
4948 if (num_arguments < kRegisterPassedArguments) return 0; 4948 if (num_arguments < kRegisterPassedArguments) return 0;
4949 return num_arguments - kRegisterPassedArguments; 4949 return num_arguments - kRegisterPassedArguments;
4950 #endif 4950 #endif
4951 } 4951 }
4952 4952
(...skipping 26 matching lines...) Expand all
4979 SmiCompare(index, Smi::FromInt(0)); 4979 SmiCompare(index, Smi::FromInt(0));
4980 Check(greater_equal, kIndexIsNegative); 4980 Check(greater_equal, kIndexIsNegative);
4981 4981
4982 // Restore the index 4982 // Restore the index
4983 SmiToInteger32(index, index); 4983 SmiToInteger32(index, index);
4984 } 4984 }
4985 4985
4986 4986
4987 void MacroAssembler::PrepareCallCFunction(int num_arguments) { 4987 void MacroAssembler::PrepareCallCFunction(int num_arguments) {
4988 int frame_alignment = base::OS::ActivationFrameAlignment(); 4988 int frame_alignment = base::OS::ActivationFrameAlignment();
4989 ASSERT(frame_alignment != 0); 4989 DCHECK(frame_alignment != 0);
4990 ASSERT(num_arguments >= 0); 4990 DCHECK(num_arguments >= 0);
4991 4991
4992 // Make stack end at alignment and allocate space for arguments and old rsp. 4992 // Make stack end at alignment and allocate space for arguments and old rsp.
4993 movp(kScratchRegister, rsp); 4993 movp(kScratchRegister, rsp);
4994 ASSERT(IsPowerOf2(frame_alignment)); 4994 DCHECK(IsPowerOf2(frame_alignment));
4995 int argument_slots_on_stack = 4995 int argument_slots_on_stack =
4996 ArgumentStackSlotsForCFunctionCall(num_arguments); 4996 ArgumentStackSlotsForCFunctionCall(num_arguments);
4997 subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize)); 4997 subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize));
4998 andp(rsp, Immediate(-frame_alignment)); 4998 andp(rsp, Immediate(-frame_alignment));
4999 movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister); 4999 movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister);
5000 } 5000 }
5001 5001
5002 5002
5003 void MacroAssembler::CallCFunction(ExternalReference function, 5003 void MacroAssembler::CallCFunction(ExternalReference function,
5004 int num_arguments) { 5004 int num_arguments) {
5005 LoadAddress(rax, function); 5005 LoadAddress(rax, function);
5006 CallCFunction(rax, num_arguments); 5006 CallCFunction(rax, num_arguments);
5007 } 5007 }
5008 5008
5009 5009
5010 void MacroAssembler::CallCFunction(Register function, int num_arguments) { 5010 void MacroAssembler::CallCFunction(Register function, int num_arguments) {
5011 ASSERT(has_frame()); 5011 DCHECK(has_frame());
5012 // Check stack alignment. 5012 // Check stack alignment.
5013 if (emit_debug_code()) { 5013 if (emit_debug_code()) {
5014 CheckStackAlignment(); 5014 CheckStackAlignment();
5015 } 5015 }
5016 5016
5017 call(function); 5017 call(function);
5018 ASSERT(base::OS::ActivationFrameAlignment() != 0); 5018 DCHECK(base::OS::ActivationFrameAlignment() != 0);
5019 ASSERT(num_arguments >= 0); 5019 DCHECK(num_arguments >= 0);
5020 int argument_slots_on_stack = 5020 int argument_slots_on_stack =
5021 ArgumentStackSlotsForCFunctionCall(num_arguments); 5021 ArgumentStackSlotsForCFunctionCall(num_arguments);
5022 movp(rsp, Operand(rsp, argument_slots_on_stack * kRegisterSize)); 5022 movp(rsp, Operand(rsp, argument_slots_on_stack * kRegisterSize));
5023 } 5023 }
5024 5024
5025 5025
5026 #ifdef DEBUG 5026 #ifdef DEBUG
5027 bool AreAliased(Register reg1, 5027 bool AreAliased(Register reg1,
5028 Register reg2, 5028 Register reg2,
5029 Register reg3, 5029 Register reg3,
(...skipping 22 matching lines...) Expand all
5052 #endif 5052 #endif
5053 5053
5054 5054
5055 CodePatcher::CodePatcher(byte* address, int size) 5055 CodePatcher::CodePatcher(byte* address, int size)
5056 : address_(address), 5056 : address_(address),
5057 size_(size), 5057 size_(size),
5058 masm_(NULL, address, size + Assembler::kGap) { 5058 masm_(NULL, address, size + Assembler::kGap) {
5059 // Create a new macro assembler pointing to the address of the code to patch. 5059 // Create a new macro assembler pointing to the address of the code to patch.
5060 // The size is adjusted with kGap on order for the assembler to generate size 5060 // The size is adjusted with kGap on order for the assembler to generate size
5061 // bytes of instructions without failing with buffer size constraints. 5061 // bytes of instructions without failing with buffer size constraints.
5062 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5062 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
5063 } 5063 }
5064 5064
5065 5065
5066 CodePatcher::~CodePatcher() { 5066 CodePatcher::~CodePatcher() {
5067 // Indicate that code has changed. 5067 // Indicate that code has changed.
5068 CpuFeatures::FlushICache(address_, size_); 5068 CpuFeatures::FlushICache(address_, size_);
5069 5069
5070 // Check that the code was patched as expected. 5070 // Check that the code was patched as expected.
5071 ASSERT(masm_.pc_ == address_ + size_); 5071 DCHECK(masm_.pc_ == address_ + size_);
5072 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5072 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
5073 } 5073 }
5074 5074
5075 5075
5076 void MacroAssembler::CheckPageFlag( 5076 void MacroAssembler::CheckPageFlag(
5077 Register object, 5077 Register object,
5078 Register scratch, 5078 Register scratch,
5079 int mask, 5079 int mask,
5080 Condition cc, 5080 Condition cc,
5081 Label* condition_met, 5081 Label* condition_met,
5082 Label::Distance condition_met_distance) { 5082 Label::Distance condition_met_distance) {
5083 ASSERT(cc == zero || cc == not_zero); 5083 DCHECK(cc == zero || cc == not_zero);
5084 if (scratch.is(object)) { 5084 if (scratch.is(object)) {
5085 andp(scratch, Immediate(~Page::kPageAlignmentMask)); 5085 andp(scratch, Immediate(~Page::kPageAlignmentMask));
5086 } else { 5086 } else {
5087 movp(scratch, Immediate(~Page::kPageAlignmentMask)); 5087 movp(scratch, Immediate(~Page::kPageAlignmentMask));
5088 andp(scratch, object); 5088 andp(scratch, object);
5089 } 5089 }
5090 if (mask < (1 << kBitsPerByte)) { 5090 if (mask < (1 << kBitsPerByte)) {
5091 testb(Operand(scratch, MemoryChunk::kFlagsOffset), 5091 testb(Operand(scratch, MemoryChunk::kFlagsOffset),
5092 Immediate(static_cast<uint8_t>(mask))); 5092 Immediate(static_cast<uint8_t>(mask)));
5093 } else { 5093 } else {
(...skipping 13 matching lines...) Expand all
5107 j(not_zero, if_deprecated); 5107 j(not_zero, if_deprecated);
5108 } 5108 }
5109 } 5109 }
5110 5110
5111 5111
5112 void MacroAssembler::JumpIfBlack(Register object, 5112 void MacroAssembler::JumpIfBlack(Register object,
5113 Register bitmap_scratch, 5113 Register bitmap_scratch,
5114 Register mask_scratch, 5114 Register mask_scratch,
5115 Label* on_black, 5115 Label* on_black,
5116 Label::Distance on_black_distance) { 5116 Label::Distance on_black_distance) {
5117 ASSERT(!AreAliased(object, bitmap_scratch, mask_scratch, rcx)); 5117 DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, rcx));
5118 GetMarkBits(object, bitmap_scratch, mask_scratch); 5118 GetMarkBits(object, bitmap_scratch, mask_scratch);
5119 5119
5120 ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 5120 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
5121 // The mask_scratch register contains a 1 at the position of the first bit 5121 // The mask_scratch register contains a 1 at the position of the first bit
5122 // and a 0 at all other positions, including the position of the second bit. 5122 // and a 0 at all other positions, including the position of the second bit.
5123 movp(rcx, mask_scratch); 5123 movp(rcx, mask_scratch);
5124 // Make rcx into a mask that covers both marking bits using the operation 5124 // Make rcx into a mask that covers both marking bits using the operation
5125 // rcx = mask | (mask << 1). 5125 // rcx = mask | (mask << 1).
5126 leap(rcx, Operand(mask_scratch, mask_scratch, times_2, 0)); 5126 leap(rcx, Operand(mask_scratch, mask_scratch, times_2, 0));
5127 // Note that we are using a 4-byte aligned 8-byte load. 5127 // Note that we are using a 4-byte aligned 8-byte load.
5128 andp(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 5128 andp(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize));
5129 cmpp(mask_scratch, rcx); 5129 cmpp(mask_scratch, rcx);
5130 j(equal, on_black, on_black_distance); 5130 j(equal, on_black, on_black_distance);
5131 } 5131 }
5132 5132
5133 5133
5134 // Detect some, but not all, common pointer-free objects. This is used by the 5134 // Detect some, but not all, common pointer-free objects. This is used by the
5135 // incremental write barrier which doesn't care about oddballs (they are always 5135 // incremental write barrier which doesn't care about oddballs (they are always
5136 // marked black immediately so this code is not hit). 5136 // marked black immediately so this code is not hit).
5137 void MacroAssembler::JumpIfDataObject( 5137 void MacroAssembler::JumpIfDataObject(
5138 Register value, 5138 Register value,
5139 Register scratch, 5139 Register scratch,
5140 Label* not_data_object, 5140 Label* not_data_object,
5141 Label::Distance not_data_object_distance) { 5141 Label::Distance not_data_object_distance) {
5142 Label is_data_object; 5142 Label is_data_object;
5143 movp(scratch, FieldOperand(value, HeapObject::kMapOffset)); 5143 movp(scratch, FieldOperand(value, HeapObject::kMapOffset));
5144 CompareRoot(scratch, Heap::kHeapNumberMapRootIndex); 5144 CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
5145 j(equal, &is_data_object, Label::kNear); 5145 j(equal, &is_data_object, Label::kNear);
5146 ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); 5146 DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
5147 ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); 5147 DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
5148 // If it's a string and it's not a cons string then it's an object containing 5148 // If it's a string and it's not a cons string then it's an object containing
5149 // no GC pointers. 5149 // no GC pointers.
5150 testb(FieldOperand(scratch, Map::kInstanceTypeOffset), 5150 testb(FieldOperand(scratch, Map::kInstanceTypeOffset),
5151 Immediate(kIsIndirectStringMask | kIsNotStringMask)); 5151 Immediate(kIsIndirectStringMask | kIsNotStringMask));
5152 j(not_zero, not_data_object, not_data_object_distance); 5152 j(not_zero, not_data_object, not_data_object_distance);
5153 bind(&is_data_object); 5153 bind(&is_data_object);
5154 } 5154 }
5155 5155
5156 5156
5157 void MacroAssembler::GetMarkBits(Register addr_reg, 5157 void MacroAssembler::GetMarkBits(Register addr_reg,
5158 Register bitmap_reg, 5158 Register bitmap_reg,
5159 Register mask_reg) { 5159 Register mask_reg) {
5160 ASSERT(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx)); 5160 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx));
5161 movp(bitmap_reg, addr_reg); 5161 movp(bitmap_reg, addr_reg);
5162 // Sign extended 32 bit immediate. 5162 // Sign extended 32 bit immediate.
5163 andp(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 5163 andp(bitmap_reg, Immediate(~Page::kPageAlignmentMask));
5164 movp(rcx, addr_reg); 5164 movp(rcx, addr_reg);
5165 int shift = 5165 int shift =
5166 Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 5166 Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2;
5167 shrl(rcx, Immediate(shift)); 5167 shrl(rcx, Immediate(shift));
5168 andp(rcx, 5168 andp(rcx,
5169 Immediate((Page::kPageAlignmentMask >> shift) & 5169 Immediate((Page::kPageAlignmentMask >> shift) &
5170 ~(Bitmap::kBytesPerCell - 1))); 5170 ~(Bitmap::kBytesPerCell - 1)));
5171 5171
5172 addp(bitmap_reg, rcx); 5172 addp(bitmap_reg, rcx);
5173 movp(rcx, addr_reg); 5173 movp(rcx, addr_reg);
5174 shrl(rcx, Immediate(kPointerSizeLog2)); 5174 shrl(rcx, Immediate(kPointerSizeLog2));
5175 andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 5175 andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1));
5176 movl(mask_reg, Immediate(1)); 5176 movl(mask_reg, Immediate(1));
5177 shlp_cl(mask_reg); 5177 shlp_cl(mask_reg);
5178 } 5178 }
5179 5179
5180 5180
5181 void MacroAssembler::EnsureNotWhite( 5181 void MacroAssembler::EnsureNotWhite(
5182 Register value, 5182 Register value,
5183 Register bitmap_scratch, 5183 Register bitmap_scratch,
5184 Register mask_scratch, 5184 Register mask_scratch,
5185 Label* value_is_white_and_not_data, 5185 Label* value_is_white_and_not_data,
5186 Label::Distance distance) { 5186 Label::Distance distance) {
5187 ASSERT(!AreAliased(value, bitmap_scratch, mask_scratch, rcx)); 5187 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, rcx));
5188 GetMarkBits(value, bitmap_scratch, mask_scratch); 5188 GetMarkBits(value, bitmap_scratch, mask_scratch);
5189 5189
5190 // If the value is black or grey we don't need to do anything. 5190 // If the value is black or grey we don't need to do anything.
5191 ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); 5191 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
5192 ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 5192 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
5193 ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); 5193 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0);
5194 ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 5194 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
5195 5195
5196 Label done; 5196 Label done;
5197 5197
5198 // Since both black and grey have a 1 in the first position and white does 5198 // Since both black and grey have a 1 in the first position and white does
5199 // not have a 1 there we only need to check one bit. 5199 // not have a 1 there we only need to check one bit.
5200 testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 5200 testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
5201 j(not_zero, &done, Label::kNear); 5201 j(not_zero, &done, Label::kNear);
5202 5202
5203 if (emit_debug_code()) { 5203 if (emit_debug_code()) {
5204 // Check for impossible bit pattern. 5204 // Check for impossible bit pattern.
(...skipping 17 matching lines...) Expand all
5222 5222
5223 // Check for heap-number 5223 // Check for heap-number
5224 movp(map, FieldOperand(value, HeapObject::kMapOffset)); 5224 movp(map, FieldOperand(value, HeapObject::kMapOffset));
5225 CompareRoot(map, Heap::kHeapNumberMapRootIndex); 5225 CompareRoot(map, Heap::kHeapNumberMapRootIndex);
5226 j(not_equal, &not_heap_number, Label::kNear); 5226 j(not_equal, &not_heap_number, Label::kNear);
5227 movp(length, Immediate(HeapNumber::kSize)); 5227 movp(length, Immediate(HeapNumber::kSize));
5228 jmp(&is_data_object, Label::kNear); 5228 jmp(&is_data_object, Label::kNear);
5229 5229
5230 bind(&not_heap_number); 5230 bind(&not_heap_number);
5231 // Check for strings. 5231 // Check for strings.
5232 ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); 5232 DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
5233 ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); 5233 DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
5234 // If it's a string and it's not a cons string then it's an object containing 5234 // If it's a string and it's not a cons string then it's an object containing
5235 // no GC pointers. 5235 // no GC pointers.
5236 Register instance_type = rcx; 5236 Register instance_type = rcx;
5237 movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 5237 movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset));
5238 testb(instance_type, Immediate(kIsIndirectStringMask | kIsNotStringMask)); 5238 testb(instance_type, Immediate(kIsIndirectStringMask | kIsNotStringMask));
5239 j(not_zero, value_is_white_and_not_data); 5239 j(not_zero, value_is_white_and_not_data);
5240 // It's a non-indirect (non-cons and non-slice) string. 5240 // It's a non-indirect (non-cons and non-slice) string.
5241 // If it's external, the length is just ExternalString::kSize. 5241 // If it's external, the length is just ExternalString::kSize.
5242 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). 5242 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2).
5243 Label not_external; 5243 Label not_external;
5244 // External strings are the only ones with the kExternalStringTag bit 5244 // External strings are the only ones with the kExternalStringTag bit
5245 // set. 5245 // set.
5246 ASSERT_EQ(0, kSeqStringTag & kExternalStringTag); 5246 DCHECK_EQ(0, kSeqStringTag & kExternalStringTag);
5247 ASSERT_EQ(0, kConsStringTag & kExternalStringTag); 5247 DCHECK_EQ(0, kConsStringTag & kExternalStringTag);
5248 testb(instance_type, Immediate(kExternalStringTag)); 5248 testb(instance_type, Immediate(kExternalStringTag));
5249 j(zero, &not_external, Label::kNear); 5249 j(zero, &not_external, Label::kNear);
5250 movp(length, Immediate(ExternalString::kSize)); 5250 movp(length, Immediate(ExternalString::kSize));
5251 jmp(&is_data_object, Label::kNear); 5251 jmp(&is_data_object, Label::kNear);
5252 5252
5253 bind(&not_external); 5253 bind(&not_external);
5254 // Sequential string, either ASCII or UC16. 5254 // Sequential string, either ASCII or UC16.
5255 ASSERT(kOneByteStringTag == 0x04); 5255 DCHECK(kOneByteStringTag == 0x04);
5256 andp(length, Immediate(kStringEncodingMask)); 5256 andp(length, Immediate(kStringEncodingMask));
5257 xorp(length, Immediate(kStringEncodingMask)); 5257 xorp(length, Immediate(kStringEncodingMask));
5258 addp(length, Immediate(0x04)); 5258 addp(length, Immediate(0x04));
5259 // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2. 5259 // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2.
5260 imulp(length, FieldOperand(value, String::kLengthOffset)); 5260 imulp(length, FieldOperand(value, String::kLengthOffset));
5261 shrp(length, Immediate(2 + kSmiTagSize + kSmiShiftSize)); 5261 shrp(length, Immediate(2 + kSmiTagSize + kSmiShiftSize));
5262 addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask)); 5262 addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask));
5263 andp(length, Immediate(~kObjectAlignmentMask)); 5263 andp(length, Immediate(~kObjectAlignmentMask));
5264 5264
5265 bind(&is_data_object); 5265 bind(&is_data_object);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
5338 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), 5338 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize),
5339 Heap::kAllocationMementoMapRootIndex); 5339 Heap::kAllocationMementoMapRootIndex);
5340 } 5340 }
5341 5341
5342 5342
5343 void MacroAssembler::JumpIfDictionaryInPrototypeChain( 5343 void MacroAssembler::JumpIfDictionaryInPrototypeChain(
5344 Register object, 5344 Register object,
5345 Register scratch0, 5345 Register scratch0,
5346 Register scratch1, 5346 Register scratch1,
5347 Label* found) { 5347 Label* found) {
5348 ASSERT(!(scratch0.is(kScratchRegister) && scratch1.is(kScratchRegister))); 5348 DCHECK(!(scratch0.is(kScratchRegister) && scratch1.is(kScratchRegister)));
5349 ASSERT(!scratch1.is(scratch0)); 5349 DCHECK(!scratch1.is(scratch0));
5350 Register current = scratch0; 5350 Register current = scratch0;
5351 Label loop_again; 5351 Label loop_again;
5352 5352
5353 movp(current, object); 5353 movp(current, object);
5354 5354
5355 // Loop based on the map going up the prototype chain. 5355 // Loop based on the map going up the prototype chain.
5356 bind(&loop_again); 5356 bind(&loop_again);
5357 movp(current, FieldOperand(current, HeapObject::kMapOffset)); 5357 movp(current, FieldOperand(current, HeapObject::kMapOffset));
5358 movp(scratch1, FieldOperand(current, Map::kBitField2Offset)); 5358 movp(scratch1, FieldOperand(current, Map::kBitField2Offset));
5359 DecodeField<Map::ElementsKindBits>(scratch1); 5359 DecodeField<Map::ElementsKindBits>(scratch1);
5360 cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS)); 5360 cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS));
5361 j(equal, found); 5361 j(equal, found);
5362 movp(current, FieldOperand(current, Map::kPrototypeOffset)); 5362 movp(current, FieldOperand(current, Map::kPrototypeOffset));
5363 CompareRoot(current, Heap::kNullValueRootIndex); 5363 CompareRoot(current, Heap::kNullValueRootIndex);
5364 j(not_equal, &loop_again); 5364 j(not_equal, &loop_again);
5365 } 5365 }
5366 5366
5367 5367
5368 void MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { 5368 void MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) {
5369 ASSERT(!dividend.is(rax)); 5369 DCHECK(!dividend.is(rax));
5370 ASSERT(!dividend.is(rdx)); 5370 DCHECK(!dividend.is(rdx));
5371 MultiplierAndShift ms(divisor); 5371 MultiplierAndShift ms(divisor);
5372 movl(rax, Immediate(ms.multiplier())); 5372 movl(rax, Immediate(ms.multiplier()));
5373 imull(dividend); 5373 imull(dividend);
5374 if (divisor > 0 && ms.multiplier() < 0) addl(rdx, dividend); 5374 if (divisor > 0 && ms.multiplier() < 0) addl(rdx, dividend);
5375 if (divisor < 0 && ms.multiplier() > 0) subl(rdx, dividend); 5375 if (divisor < 0 && ms.multiplier() > 0) subl(rdx, dividend);
5376 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift())); 5376 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift()));
5377 movl(rax, dividend); 5377 movl(rax, dividend);
5378 shrl(rax, Immediate(31)); 5378 shrl(rax, Immediate(31));
5379 addl(rdx, rax); 5379 addl(rdx, rax);
5380 } 5380 }
5381 5381
5382 5382
5383 } } // namespace v8::internal 5383 } } // namespace v8::internal
5384 5384
5385 #endif // V8_TARGET_ARCH_X64 5385 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698