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

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

Issue 275433004: Require SSE2 support for the ia32 port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.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 "v8.h" 5 #include "v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "bootstrapper.h" 9 #include "bootstrapper.h"
10 #include "codegen.h" 10 #include "codegen.h"
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 j(no_overflow, &done, Label::kNear); 237 j(no_overflow, &done, Label::kNear);
238 238
239 sub(esp, Immediate(kDoubleSize)); 239 sub(esp, Immediate(kDoubleSize));
240 movsd(MemOperand(esp, 0), input_reg); 240 movsd(MemOperand(esp, 0), input_reg);
241 SlowTruncateToI(result_reg, esp, 0); 241 SlowTruncateToI(result_reg, esp, 0);
242 add(esp, Immediate(kDoubleSize)); 242 add(esp, Immediate(kDoubleSize));
243 bind(&done); 243 bind(&done);
244 } 244 }
245 245
246 246
247 void MacroAssembler::TruncateX87TOSToI(Register result_reg) {
248 sub(esp, Immediate(kDoubleSize));
249 fst_d(MemOperand(esp, 0));
250 SlowTruncateToI(result_reg, esp, 0);
251 add(esp, Immediate(kDoubleSize));
252 }
253
254
255 void MacroAssembler::X87TOSToI(Register result_reg,
256 MinusZeroMode minus_zero_mode,
257 Label* conversion_failed,
258 Label::Distance dst) {
259 Label done;
260 sub(esp, Immediate(kPointerSize));
261 fld(0);
262 fist_s(MemOperand(esp, 0));
263 fild_s(MemOperand(esp, 0));
264 pop(result_reg);
265 FCmp();
266 j(not_equal, conversion_failed, dst);
267 j(parity_even, conversion_failed, dst);
268 if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
269 test(result_reg, Operand(result_reg));
270 j(not_zero, &done, Label::kNear);
271 // To check for minus zero, we load the value again as float, and check
272 // if that is still 0.
273 sub(esp, Immediate(kPointerSize));
274 fst_s(MemOperand(esp, 0));
275 pop(result_reg);
276 test(result_reg, Operand(result_reg));
277 j(not_zero, conversion_failed, dst);
278 }
279 bind(&done);
280 }
281
282
283 void MacroAssembler::DoubleToI(Register result_reg, 247 void MacroAssembler::DoubleToI(Register result_reg,
284 XMMRegister input_reg, 248 XMMRegister input_reg,
285 XMMRegister scratch, 249 XMMRegister scratch,
286 MinusZeroMode minus_zero_mode, 250 MinusZeroMode minus_zero_mode,
287 Label* conversion_failed, 251 Label* conversion_failed,
288 Label::Distance dst) { 252 Label::Distance dst) {
289 ASSERT(!input_reg.is(scratch)); 253 ASSERT(!input_reg.is(scratch));
290 cvttsd2si(result_reg, Operand(input_reg)); 254 cvttsd2si(result_reg, Operand(input_reg));
291 Cvtsi2sd(scratch, Operand(result_reg)); 255 Cvtsi2sd(scratch, Operand(result_reg));
292 ucomisd(scratch, input_reg); 256 ucomisd(scratch, input_reg);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 if (input_reg.is(result_reg)) { 304 if (input_reg.is(result_reg)) {
341 // Input is clobbered. Restore number from fpu stack 305 // Input is clobbered. Restore number from fpu stack
342 sub(Operand(esp), Immediate(kDoubleSize)); 306 sub(Operand(esp), Immediate(kDoubleSize));
343 fstp_d(Operand(esp, 0)); 307 fstp_d(Operand(esp, 0));
344 SlowTruncateToI(result_reg, esp, 0); 308 SlowTruncateToI(result_reg, esp, 0);
345 add(esp, Immediate(kDoubleSize)); 309 add(esp, Immediate(kDoubleSize));
346 } else { 310 } else {
347 fstp(0); 311 fstp(0);
348 SlowTruncateToI(result_reg, input_reg); 312 SlowTruncateToI(result_reg, input_reg);
349 } 313 }
350 } else if (CpuFeatures::IsSupported(SSE2)) { 314 } else {
351 CpuFeatureScope scope(this, SSE2);
352 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 315 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
353 cvttsd2si(result_reg, Operand(xmm0)); 316 cvttsd2si(result_reg, Operand(xmm0));
354 cmp(result_reg, 0x1); 317 cmp(result_reg, 0x1);
355 j(no_overflow, &done, Label::kNear); 318 j(no_overflow, &done, Label::kNear);
356 // Check if the input was 0x8000000 (kMinInt). 319 // Check if the input was 0x8000000 (kMinInt).
357 // If no, then we got an overflow and we deoptimize. 320 // If no, then we got an overflow and we deoptimize.
358 ExternalReference min_int = ExternalReference::address_of_min_int(); 321 ExternalReference min_int = ExternalReference::address_of_min_int();
359 ucomisd(xmm0, Operand::StaticVariable(min_int)); 322 ucomisd(xmm0, Operand::StaticVariable(min_int));
360 j(not_equal, &slow_case, Label::kNear); 323 j(not_equal, &slow_case, Label::kNear);
361 j(parity_even, &slow_case, Label::kNear); // NaN. 324 j(parity_even, &slow_case, Label::kNear); // NaN.
362 jmp(&done, Label::kNear); 325 jmp(&done, Label::kNear);
363 326
364 // Slow case. 327 // Slow case.
365 bind(&slow_case); 328 bind(&slow_case);
366 if (input_reg.is(result_reg)) { 329 if (input_reg.is(result_reg)) {
367 // Input is clobbered. Restore number from double scratch. 330 // Input is clobbered. Restore number from double scratch.
368 sub(esp, Immediate(kDoubleSize)); 331 sub(esp, Immediate(kDoubleSize));
369 movsd(MemOperand(esp, 0), xmm0); 332 movsd(MemOperand(esp, 0), xmm0);
370 SlowTruncateToI(result_reg, esp, 0); 333 SlowTruncateToI(result_reg, esp, 0);
371 add(esp, Immediate(kDoubleSize)); 334 add(esp, Immediate(kDoubleSize));
372 } else { 335 } else {
373 SlowTruncateToI(result_reg, input_reg); 336 SlowTruncateToI(result_reg, input_reg);
374 } 337 }
375 } else {
376 SlowTruncateToI(result_reg, input_reg);
377 } 338 }
378 bind(&done); 339 bind(&done);
379 } 340 }
380 341
381 342
382 void MacroAssembler::TaggedToI(Register result_reg, 343 void MacroAssembler::TaggedToI(Register result_reg,
383 Register input_reg, 344 Register input_reg,
384 XMMRegister temp, 345 XMMRegister temp,
385 MinusZeroMode minus_zero_mode, 346 MinusZeroMode minus_zero_mode,
386 Label* lost_precision) { 347 Label* lost_precision) {
387 Label done; 348 Label done;
388 ASSERT(!temp.is(xmm0)); 349 ASSERT(!temp.is(xmm0));
389 350
390 cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 351 cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
391 isolate()->factory()->heap_number_map()); 352 isolate()->factory()->heap_number_map());
392 j(not_equal, lost_precision, Label::kNear); 353 j(not_equal, lost_precision, Label::kNear);
393 354
394 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { 355 ASSERT(!temp.is(no_xmm_reg));
395 ASSERT(!temp.is(no_xmm_reg));
396 CpuFeatureScope scope(this, SSE2);
397 356
398 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 357 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
399 cvttsd2si(result_reg, Operand(xmm0)); 358 cvttsd2si(result_reg, Operand(xmm0));
400 Cvtsi2sd(temp, Operand(result_reg)); 359 Cvtsi2sd(temp, Operand(result_reg));
401 ucomisd(xmm0, temp); 360 ucomisd(xmm0, temp);
402 RecordComment("Deferred TaggedToI: lost precision"); 361 RecordComment("Deferred TaggedToI: lost precision");
403 j(not_equal, lost_precision, Label::kNear); 362 j(not_equal, lost_precision, Label::kNear);
404 RecordComment("Deferred TaggedToI: NaN"); 363 RecordComment("Deferred TaggedToI: NaN");
405 j(parity_even, lost_precision, Label::kNear); 364 j(parity_even, lost_precision, Label::kNear);
406 if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 365 if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
407 test(result_reg, Operand(result_reg)); 366 test(result_reg, Operand(result_reg));
408 j(not_zero, &done, Label::kNear); 367 j(not_zero, &done, Label::kNear);
409 movmskpd(result_reg, xmm0); 368 movmskpd(result_reg, xmm0);
410 and_(result_reg, 1); 369 and_(result_reg, 1);
411 RecordComment("Deferred TaggedToI: minus zero"); 370 RecordComment("Deferred TaggedToI: minus zero");
412 j(not_zero, lost_precision, Label::kNear); 371 j(not_zero, lost_precision, Label::kNear);
413 }
414 } else {
415 // TODO(olivf) Converting a number on the fpu is actually quite slow. We
416 // should first try a fast conversion and then bailout to this slow case.
417 Label lost_precision_pop, zero_check;
418 Label* lost_precision_int = (minus_zero_mode == FAIL_ON_MINUS_ZERO)
419 ? &lost_precision_pop : lost_precision;
420 sub(esp, Immediate(kPointerSize));
421 fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
422 if (minus_zero_mode == FAIL_ON_MINUS_ZERO) fld(0);
423 fist_s(MemOperand(esp, 0));
424 fild_s(MemOperand(esp, 0));
425 FCmp();
426 pop(result_reg);
427 j(not_equal, lost_precision_int, Label::kNear);
428 j(parity_even, lost_precision_int, Label::kNear); // NaN.
429 if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
430 test(result_reg, Operand(result_reg));
431 j(zero, &zero_check, Label::kNear);
432 fstp(0);
433 jmp(&done, Label::kNear);
434 bind(&zero_check);
435 // To check for minus zero, we load the value again as float, and check
436 // if that is still 0.
437 sub(esp, Immediate(kPointerSize));
438 fstp_s(Operand(esp, 0));
439 pop(result_reg);
440 test(result_reg, Operand(result_reg));
441 j(zero, &done, Label::kNear);
442 jmp(lost_precision, Label::kNear);
443
444 bind(&lost_precision_pop);
445 fstp(0);
446 jmp(lost_precision, Label::kNear);
447 }
448 } 372 }
449 bind(&done); 373 bind(&done);
450 } 374 }
451 375
452 376
453 void MacroAssembler::LoadUint32(XMMRegister dst, 377 void MacroAssembler::LoadUint32(XMMRegister dst,
454 Register src, 378 Register src,
455 XMMRegister scratch) { 379 XMMRegister scratch) {
456 Label done; 380 Label done;
457 cmp(src, Immediate(0)); 381 cmp(src, Immediate(0));
458 ExternalReference uint32_bias = 382 ExternalReference uint32_bias =
459 ExternalReference::address_of_uint32_bias(); 383 ExternalReference::address_of_uint32_bias();
460 movsd(scratch, Operand::StaticVariable(uint32_bias)); 384 movsd(scratch, Operand::StaticVariable(uint32_bias));
461 Cvtsi2sd(dst, src); 385 Cvtsi2sd(dst, src);
462 j(not_sign, &done, Label::kNear); 386 j(not_sign, &done, Label::kNear);
463 addsd(dst, scratch); 387 addsd(dst, scratch);
464 bind(&done); 388 bind(&done);
465 } 389 }
466 390
467 391
468 void MacroAssembler::LoadUint32NoSSE2(Register src) {
469 Label done;
470 push(src);
471 fild_s(Operand(esp, 0));
472 cmp(src, Immediate(0));
473 j(not_sign, &done, Label::kNear);
474 ExternalReference uint32_bias =
475 ExternalReference::address_of_uint32_bias();
476 fld_d(Operand::StaticVariable(uint32_bias));
477 faddp(1);
478 bind(&done);
479 add(esp, Immediate(kPointerSize));
480 }
481
482
483 void MacroAssembler::RecordWriteArray(Register object, 392 void MacroAssembler::RecordWriteArray(Register object,
484 Register value, 393 Register value,
485 Register index, 394 Register index,
486 SaveFPRegsMode save_fp, 395 SaveFPRegsMode save_fp,
487 RememberedSetAction remembered_set_action, 396 RememberedSetAction remembered_set_action,
488 SmiCheck smi_check) { 397 SmiCheck smi_check) {
489 // First, check if a write barrier is even needed. The tests below 398 // First, check if a write barrier is even needed. The tests below
490 // catch stores of Smis. 399 // catch stores of Smis.
491 Label done; 400 Label done;
492 401
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 } 696 }
788 697
789 698
790 void MacroAssembler::StoreNumberToDoubleElements( 699 void MacroAssembler::StoreNumberToDoubleElements(
791 Register maybe_number, 700 Register maybe_number,
792 Register elements, 701 Register elements,
793 Register key, 702 Register key,
794 Register scratch1, 703 Register scratch1,
795 XMMRegister scratch2, 704 XMMRegister scratch2,
796 Label* fail, 705 Label* fail,
797 bool specialize_for_processor,
798 int elements_offset) { 706 int elements_offset) {
799 Label smi_value, done, maybe_nan, not_nan, is_nan, have_double_value; 707 Label smi_value, done, maybe_nan, not_nan, is_nan, have_double_value;
800 JumpIfSmi(maybe_number, &smi_value, Label::kNear); 708 JumpIfSmi(maybe_number, &smi_value, Label::kNear);
801 709
802 CheckMap(maybe_number, 710 CheckMap(maybe_number,
803 isolate()->factory()->heap_number_map(), 711 isolate()->factory()->heap_number_map(),
804 fail, 712 fail,
805 DONT_DO_SMI_CHECK); 713 DONT_DO_SMI_CHECK);
806 714
807 // Double value, canonicalize NaN. 715 // Double value, canonicalize NaN.
808 uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); 716 uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32);
809 cmp(FieldOperand(maybe_number, offset), 717 cmp(FieldOperand(maybe_number, offset),
810 Immediate(kNaNOrInfinityLowerBoundUpper32)); 718 Immediate(kNaNOrInfinityLowerBoundUpper32));
811 j(greater_equal, &maybe_nan, Label::kNear); 719 j(greater_equal, &maybe_nan, Label::kNear);
812 720
813 bind(&not_nan); 721 bind(&not_nan);
814 ExternalReference canonical_nan_reference = 722 ExternalReference canonical_nan_reference =
815 ExternalReference::address_of_canonical_non_hole_nan(); 723 ExternalReference::address_of_canonical_non_hole_nan();
816 if (CpuFeatures::IsSupported(SSE2) && specialize_for_processor) { 724 movsd(scratch2, FieldOperand(maybe_number, HeapNumber::kValueOffset));
817 CpuFeatureScope use_sse2(this, SSE2); 725 bind(&have_double_value);
818 movsd(scratch2, FieldOperand(maybe_number, HeapNumber::kValueOffset)); 726 movsd(FieldOperand(elements, key, times_4,
819 bind(&have_double_value); 727 FixedDoubleArray::kHeaderSize - elements_offset),
820 movsd(FieldOperand(elements, key, times_4, 728 scratch2);
821 FixedDoubleArray::kHeaderSize - elements_offset),
822 scratch2);
823 } else {
824 fld_d(FieldOperand(maybe_number, HeapNumber::kValueOffset));
825 bind(&have_double_value);
826 fstp_d(FieldOperand(elements, key, times_4,
827 FixedDoubleArray::kHeaderSize - elements_offset));
828 }
829 jmp(&done); 729 jmp(&done);
830 730
831 bind(&maybe_nan); 731 bind(&maybe_nan);
832 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise 732 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise
833 // it's an Infinity, and the non-NaN code path applies. 733 // it's an Infinity, and the non-NaN code path applies.
834 j(greater, &is_nan, Label::kNear); 734 j(greater, &is_nan, Label::kNear);
835 cmp(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0)); 735 cmp(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0));
836 j(zero, &not_nan); 736 j(zero, &not_nan);
837 bind(&is_nan); 737 bind(&is_nan);
838 if (CpuFeatures::IsSupported(SSE2) && specialize_for_processor) { 738 movsd(scratch2, Operand::StaticVariable(canonical_nan_reference));
839 CpuFeatureScope use_sse2(this, SSE2);
840 movsd(scratch2, Operand::StaticVariable(canonical_nan_reference));
841 } else {
842 fld_d(Operand::StaticVariable(canonical_nan_reference));
843 }
844 jmp(&have_double_value, Label::kNear); 739 jmp(&have_double_value, Label::kNear);
845 740
846 bind(&smi_value); 741 bind(&smi_value);
847 // Value is a smi. Convert to a double and store. 742 // Value is a smi. Convert to a double and store.
848 // Preserve original value. 743 // Preserve original value.
849 mov(scratch1, maybe_number); 744 mov(scratch1, maybe_number);
850 SmiUntag(scratch1); 745 SmiUntag(scratch1);
851 if (CpuFeatures::IsSupported(SSE2) && specialize_for_processor) { 746 Cvtsi2sd(scratch2, scratch1);
852 CpuFeatureScope fscope(this, SSE2); 747 movsd(FieldOperand(elements, key, times_4,
853 Cvtsi2sd(scratch2, scratch1); 748 FixedDoubleArray::kHeaderSize - elements_offset),
854 movsd(FieldOperand(elements, key, times_4, 749 scratch2);
855 FixedDoubleArray::kHeaderSize - elements_offset),
856 scratch2);
857 } else {
858 push(scratch1);
859 fild_s(Operand(esp, 0));
860 pop(scratch1);
861 fstp_d(FieldOperand(elements, key, times_4,
862 FixedDoubleArray::kHeaderSize - elements_offset));
863 }
864 bind(&done); 750 bind(&done);
865 } 751 }
866 752
867 753
868 void MacroAssembler::CompareMap(Register obj, Handle<Map> map) { 754 void MacroAssembler::CompareMap(Register obj, Handle<Map> map) {
869 cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 755 cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
870 } 756 }
871 757
872 758
873 void MacroAssembler::CheckMap(Register obj, 759 void MacroAssembler::CheckMap(Register obj,
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); 972 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate());
1087 ExternalReference context_address(Isolate::kContextAddress, isolate()); 973 ExternalReference context_address(Isolate::kContextAddress, isolate());
1088 mov(Operand::StaticVariable(c_entry_fp_address), ebp); 974 mov(Operand::StaticVariable(c_entry_fp_address), ebp);
1089 mov(Operand::StaticVariable(context_address), esi); 975 mov(Operand::StaticVariable(context_address), esi);
1090 } 976 }
1091 977
1092 978
1093 void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { 979 void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) {
1094 // Optionally save all XMM registers. 980 // Optionally save all XMM registers.
1095 if (save_doubles) { 981 if (save_doubles) {
1096 CpuFeatureScope scope(this, SSE2);
1097 int space = XMMRegister::kNumRegisters * kDoubleSize + argc * kPointerSize; 982 int space = XMMRegister::kNumRegisters * kDoubleSize + argc * kPointerSize;
1098 sub(esp, Immediate(space)); 983 sub(esp, Immediate(space));
1099 const int offset = -2 * kPointerSize; 984 const int offset = -2 * kPointerSize;
1100 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 985 for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
1101 XMMRegister reg = XMMRegister::from_code(i); 986 XMMRegister reg = XMMRegister::from_code(i);
1102 movsd(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg); 987 movsd(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg);
1103 } 988 }
1104 } else { 989 } else {
1105 sub(esp, Immediate(argc * kPointerSize)); 990 sub(esp, Immediate(argc * kPointerSize));
1106 } 991 }
(...skipping 25 matching lines...) Expand all
1132 1017
1133 void MacroAssembler::EnterApiExitFrame(int argc) { 1018 void MacroAssembler::EnterApiExitFrame(int argc) {
1134 EnterExitFramePrologue(); 1019 EnterExitFramePrologue();
1135 EnterExitFrameEpilogue(argc, false); 1020 EnterExitFrameEpilogue(argc, false);
1136 } 1021 }
1137 1022
1138 1023
1139 void MacroAssembler::LeaveExitFrame(bool save_doubles) { 1024 void MacroAssembler::LeaveExitFrame(bool save_doubles) {
1140 // Optionally restore all XMM registers. 1025 // Optionally restore all XMM registers.
1141 if (save_doubles) { 1026 if (save_doubles) {
1142 CpuFeatureScope scope(this, SSE2);
1143 const int offset = -2 * kPointerSize; 1027 const int offset = -2 * kPointerSize;
1144 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 1028 for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
1145 XMMRegister reg = XMMRegister::from_code(i); 1029 XMMRegister reg = XMMRegister::from_code(i);
1146 movsd(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize))); 1030 movsd(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize)));
1147 } 1031 }
1148 } 1032 }
1149 1033
1150 // Get the return address from the stack and restore the frame pointer. 1034 // Get the return address from the stack and restore the frame pointer.
1151 mov(ecx, Operand(ebp, 1 * kPointerSize)); 1035 mov(ecx, Operand(ebp, 1 * kPointerSize));
1152 mov(ebp, Operand(ebp, 0 * kPointerSize)); 1036 mov(ebp, Operand(ebp, 0 * kPointerSize));
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
2205 // constant, we check that the actual number of arguments match the 2089 // constant, we check that the actual number of arguments match the
2206 // expectation. 2090 // expectation.
2207 CHECK(f->nargs < 0 || f->nargs == num_arguments); 2091 CHECK(f->nargs < 0 || f->nargs == num_arguments);
2208 2092
2209 // TODO(1236192): Most runtime routines don't need the number of 2093 // TODO(1236192): Most runtime routines don't need the number of
2210 // arguments passed in because it is constant. At some point we 2094 // arguments passed in because it is constant. At some point we
2211 // should remove this need and make the runtime routine entry code 2095 // should remove this need and make the runtime routine entry code
2212 // smarter. 2096 // smarter.
2213 Move(eax, Immediate(num_arguments)); 2097 Move(eax, Immediate(num_arguments));
2214 mov(ebx, Immediate(ExternalReference(f, isolate()))); 2098 mov(ebx, Immediate(ExternalReference(f, isolate())));
2215 CEntryStub ces(isolate(), 2099 CEntryStub ces(isolate(), 1, save_doubles);
2216 1,
2217 CpuFeatures::IsSupported(SSE2) ? save_doubles
2218 : kDontSaveFPRegs);
2219 CallStub(&ces); 2100 CallStub(&ces);
2220 } 2101 }
2221 2102
2222 2103
2223 void MacroAssembler::CallExternalReference(ExternalReference ref, 2104 void MacroAssembler::CallExternalReference(ExternalReference ref,
2224 int num_arguments) { 2105 int num_arguments) {
2225 mov(eax, Immediate(num_arguments)); 2106 mov(eax, Immediate(num_arguments));
2226 mov(ebx, Immediate(ref)); 2107 mov(ebx, Immediate(ref));
2227 2108
2228 CEntryStub stub(isolate(), 1); 2109 CEntryStub stub(isolate(), 1);
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
2757 ret(bytes_dropped); 2638 ret(bytes_dropped);
2758 } else { 2639 } else {
2759 pop(scratch); 2640 pop(scratch);
2760 add(esp, Immediate(bytes_dropped)); 2641 add(esp, Immediate(bytes_dropped));
2761 push(scratch); 2642 push(scratch);
2762 ret(0); 2643 ret(0);
2763 } 2644 }
2764 } 2645 }
2765 2646
2766 2647
2767 void MacroAssembler::VerifyX87StackDepth(uint32_t depth) {
2768 // Make sure the floating point stack is either empty or has depth items.
2769 ASSERT(depth <= 7);
2770 // This is very expensive.
2771 ASSERT(FLAG_debug_code && FLAG_enable_slow_asserts);
2772
2773 // The top-of-stack (tos) is 7 if there is one item pushed.
2774 int tos = (8 - depth) % 8;
2775 const int kTopMask = 0x3800;
2776 push(eax);
2777 fwait();
2778 fnstsw_ax();
2779 and_(eax, kTopMask);
2780 shr(eax, 11);
2781 cmp(eax, Immediate(tos));
2782 Check(equal, kUnexpectedFPUStackDepthAfterInstruction);
2783 fnclex();
2784 pop(eax);
2785 }
2786
2787
2788 void MacroAssembler::Drop(int stack_elements) { 2648 void MacroAssembler::Drop(int stack_elements) {
2789 if (stack_elements > 0) { 2649 if (stack_elements > 0) {
2790 add(esp, Immediate(stack_elements * kPointerSize)); 2650 add(esp, Immediate(stack_elements * kPointerSize));
2791 } 2651 }
2792 } 2652 }
2793 2653
2794 2654
2795 void MacroAssembler::Move(Register dst, Register src) { 2655 void MacroAssembler::Move(Register dst, Register src) {
2796 if (!dst.is(src)) { 2656 if (!dst.is(src)) {
2797 mov(dst, src); 2657 mov(dst, src);
(...skipping 10 matching lines...) Expand all
2808 } 2668 }
2809 2669
2810 2670
2811 void MacroAssembler::Move(const Operand& dst, const Immediate& x) { 2671 void MacroAssembler::Move(const Operand& dst, const Immediate& x) {
2812 mov(dst, x); 2672 mov(dst, x);
2813 } 2673 }
2814 2674
2815 2675
2816 void MacroAssembler::Move(XMMRegister dst, double val) { 2676 void MacroAssembler::Move(XMMRegister dst, double val) {
2817 // TODO(titzer): recognize double constants with ExternalReferences. 2677 // TODO(titzer): recognize double constants with ExternalReferences.
2818 CpuFeatureScope scope(this, SSE2);
2819 uint64_t int_val = BitCast<uint64_t, double>(val); 2678 uint64_t int_val = BitCast<uint64_t, double>(val);
2820 if (int_val == 0) { 2679 if (int_val == 0) {
2821 xorps(dst, dst); 2680 xorps(dst, dst);
2822 } else { 2681 } else {
2823 int32_t lower = static_cast<int32_t>(int_val); 2682 int32_t lower = static_cast<int32_t>(int_val);
2824 int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt); 2683 int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt);
2825 push(Immediate(upper)); 2684 push(Immediate(upper));
2826 push(Immediate(lower)); 2685 push(Immediate(lower));
2827 movsd(dst, Operand(esp, 0)); 2686 movsd(dst, Operand(esp, 0));
2828 add(esp, Immediate(kDoubleSize)); 2687 add(esp, Immediate(kDoubleSize));
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
3068 // Object is heap number and hash is now in scratch. Calculate cache index. 2927 // Object is heap number and hash is now in scratch. Calculate cache index.
3069 and_(scratch, mask); 2928 and_(scratch, mask);
3070 Register index = scratch; 2929 Register index = scratch;
3071 Register probe = mask; 2930 Register probe = mask;
3072 mov(probe, 2931 mov(probe,
3073 FieldOperand(number_string_cache, 2932 FieldOperand(number_string_cache,
3074 index, 2933 index,
3075 times_twice_pointer_size, 2934 times_twice_pointer_size,
3076 FixedArray::kHeaderSize)); 2935 FixedArray::kHeaderSize));
3077 JumpIfSmi(probe, not_found); 2936 JumpIfSmi(probe, not_found);
3078 if (CpuFeatures::IsSupported(SSE2)) { 2937 movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
3079 CpuFeatureScope fscope(this, SSE2); 2938 ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset));
3080 movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
3081 ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset));
3082 } else {
3083 fld_d(FieldOperand(object, HeapNumber::kValueOffset));
3084 fld_d(FieldOperand(probe, HeapNumber::kValueOffset));
3085 FCmp();
3086 }
3087 j(parity_even, not_found); // Bail out if NaN is involved. 2939 j(parity_even, not_found); // Bail out if NaN is involved.
3088 j(not_equal, not_found); // The cache did not contain this value. 2940 j(not_equal, not_found); // The cache did not contain this value.
3089 jmp(&load_result_from_cache, Label::kNear); 2941 jmp(&load_result_from_cache, Label::kNear);
3090 2942
3091 bind(&smi_hash_calculated); 2943 bind(&smi_hash_calculated);
3092 // Object is smi and hash is now in scratch. Calculate cache index. 2944 // Object is smi and hash is now in scratch. Calculate cache index.
3093 and_(scratch, mask); 2945 and_(scratch, mask);
3094 // Check if the entry is the smi we are looking for. 2946 // Check if the entry is the smi we are looking for.
3095 cmp(object, 2947 cmp(object,
3096 FieldOperand(number_string_cache, 2948 FieldOperand(number_string_cache,
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
3612 if (ms.shift() > 0) sar(edx, ms.shift()); 3464 if (ms.shift() > 0) sar(edx, ms.shift());
3613 mov(eax, dividend); 3465 mov(eax, dividend);
3614 shr(eax, 31); 3466 shr(eax, 31);
3615 add(edx, eax); 3467 add(edx, eax);
3616 } 3468 }
3617 3469
3618 3470
3619 } } // namespace v8::internal 3471 } } // namespace v8::internal
3620 3472
3621 #endif // V8_TARGET_ARCH_IA32 3473 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698