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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 1391963005: [x64] Use vmovapd and vmovsd when AVX is enabled. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Win compile. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/x64/assembler-x64.cc ('k') | src/x64/codegen-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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/handler-compiler.h" 10 #include "src/ic/handler-compiler.h"
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 Register result_reg = final_result_reg.is(rcx) ? rax : final_result_reg; 173 Register result_reg = final_result_reg.is(rcx) ? rax : final_result_reg;
174 // Save ecx if it isn't the return register and therefore volatile, or if it 174 // Save ecx if it isn't the return register and therefore volatile, or if it
175 // is the return register, then save the temp register we use in its stead 175 // is the return register, then save the temp register we use in its stead
176 // for the result. 176 // for the result.
177 Register save_reg = final_result_reg.is(rcx) ? rax : rcx; 177 Register save_reg = final_result_reg.is(rcx) ? rax : rcx;
178 __ pushq(scratch1); 178 __ pushq(scratch1);
179 __ pushq(save_reg); 179 __ pushq(save_reg);
180 180
181 bool stash_exponent_copy = !input_reg.is(rsp); 181 bool stash_exponent_copy = !input_reg.is(rsp);
182 __ movl(scratch1, mantissa_operand); 182 __ movl(scratch1, mantissa_operand);
183 __ movsd(xmm0, mantissa_operand); 183 __ Movsd(xmm0, mantissa_operand);
184 __ movl(rcx, exponent_operand); 184 __ movl(rcx, exponent_operand);
185 if (stash_exponent_copy) __ pushq(rcx); 185 if (stash_exponent_copy) __ pushq(rcx);
186 186
187 __ andl(rcx, Immediate(HeapNumber::kExponentMask)); 187 __ andl(rcx, Immediate(HeapNumber::kExponentMask));
188 __ shrl(rcx, Immediate(HeapNumber::kExponentShift)); 188 __ shrl(rcx, Immediate(HeapNumber::kExponentShift));
189 __ leal(result_reg, MemOperand(rcx, -HeapNumber::kExponentBias)); 189 __ leal(result_reg, MemOperand(rcx, -HeapNumber::kExponentBias));
190 __ cmpl(result_reg, Immediate(HeapNumber::kMantissaBits)); 190 __ cmpl(result_reg, Immediate(HeapNumber::kMantissaBits));
191 __ j(below, &process_64_bits); 191 __ j(below, &process_64_bits);
192 192
193 // Result is entirely in lower 32-bits of mantissa 193 // Result is entirely in lower 32-bits of mantissa
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 230
231 231
232 void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm, 232 void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm,
233 Label* not_numbers) { 233 Label* not_numbers) {
234 Label load_smi_rdx, load_nonsmi_rax, load_smi_rax, load_float_rax, done; 234 Label load_smi_rdx, load_nonsmi_rax, load_smi_rax, load_float_rax, done;
235 // Load operand in rdx into xmm0, or branch to not_numbers. 235 // Load operand in rdx into xmm0, or branch to not_numbers.
236 __ LoadRoot(rcx, Heap::kHeapNumberMapRootIndex); 236 __ LoadRoot(rcx, Heap::kHeapNumberMapRootIndex);
237 __ JumpIfSmi(rdx, &load_smi_rdx); 237 __ JumpIfSmi(rdx, &load_smi_rdx);
238 __ cmpp(FieldOperand(rdx, HeapObject::kMapOffset), rcx); 238 __ cmpp(FieldOperand(rdx, HeapObject::kMapOffset), rcx);
239 __ j(not_equal, not_numbers); // Argument in rdx is not a number. 239 __ j(not_equal, not_numbers); // Argument in rdx is not a number.
240 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); 240 __ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
241 // Load operand in rax into xmm1, or branch to not_numbers. 241 // Load operand in rax into xmm1, or branch to not_numbers.
242 __ JumpIfSmi(rax, &load_smi_rax); 242 __ JumpIfSmi(rax, &load_smi_rax);
243 243
244 __ bind(&load_nonsmi_rax); 244 __ bind(&load_nonsmi_rax);
245 __ cmpp(FieldOperand(rax, HeapObject::kMapOffset), rcx); 245 __ cmpp(FieldOperand(rax, HeapObject::kMapOffset), rcx);
246 __ j(not_equal, not_numbers); 246 __ j(not_equal, not_numbers);
247 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); 247 __ Movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
248 __ jmp(&done); 248 __ jmp(&done);
249 249
250 __ bind(&load_smi_rdx); 250 __ bind(&load_smi_rdx);
251 __ SmiToInteger32(kScratchRegister, rdx); 251 __ SmiToInteger32(kScratchRegister, rdx);
252 __ Cvtlsi2sd(xmm0, kScratchRegister); 252 __ Cvtlsi2sd(xmm0, kScratchRegister);
253 __ JumpIfNotSmi(rax, &load_nonsmi_rax); 253 __ JumpIfNotSmi(rax, &load_nonsmi_rax);
254 254
255 __ bind(&load_smi_rax); 255 __ bind(&load_smi_rax);
256 __ SmiToInteger32(kScratchRegister, rax); 256 __ SmiToInteger32(kScratchRegister, rax);
257 __ Cvtlsi2sd(xmm1, kScratchRegister); 257 __ Cvtlsi2sd(xmm1, kScratchRegister);
(...skipping 23 matching lines...) Expand all
281 // This can only happen if the stub is called from non-optimized code. 281 // This can only happen if the stub is called from non-optimized code.
282 // Load input parameters from stack. 282 // Load input parameters from stack.
283 StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER); 283 StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
284 __ movp(base, args.GetArgumentOperand(0)); 284 __ movp(base, args.GetArgumentOperand(0));
285 __ movp(exponent, args.GetArgumentOperand(1)); 285 __ movp(exponent, args.GetArgumentOperand(1));
286 __ JumpIfSmi(base, &base_is_smi, Label::kNear); 286 __ JumpIfSmi(base, &base_is_smi, Label::kNear);
287 __ CompareRoot(FieldOperand(base, HeapObject::kMapOffset), 287 __ CompareRoot(FieldOperand(base, HeapObject::kMapOffset),
288 Heap::kHeapNumberMapRootIndex); 288 Heap::kHeapNumberMapRootIndex);
289 __ j(not_equal, &call_runtime); 289 __ j(not_equal, &call_runtime);
290 290
291 __ movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset)); 291 __ Movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset));
292 __ jmp(&unpack_exponent, Label::kNear); 292 __ jmp(&unpack_exponent, Label::kNear);
293 293
294 __ bind(&base_is_smi); 294 __ bind(&base_is_smi);
295 __ SmiToInteger32(base, base); 295 __ SmiToInteger32(base, base);
296 __ Cvtlsi2sd(double_base, base); 296 __ Cvtlsi2sd(double_base, base);
297 __ bind(&unpack_exponent); 297 __ bind(&unpack_exponent);
298 298
299 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); 299 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
300 __ SmiToInteger32(exponent, exponent); 300 __ SmiToInteger32(exponent, exponent);
301 __ jmp(&int_exponent); 301 __ jmp(&int_exponent);
302 302
303 __ bind(&exponent_not_smi); 303 __ bind(&exponent_not_smi);
304 __ CompareRoot(FieldOperand(exponent, HeapObject::kMapOffset), 304 __ CompareRoot(FieldOperand(exponent, HeapObject::kMapOffset),
305 Heap::kHeapNumberMapRootIndex); 305 Heap::kHeapNumberMapRootIndex);
306 __ j(not_equal, &call_runtime); 306 __ j(not_equal, &call_runtime);
307 __ movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset)); 307 __ Movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
308 } else if (exponent_type() == TAGGED) { 308 } else if (exponent_type() == TAGGED) {
309 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); 309 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
310 __ SmiToInteger32(exponent, exponent); 310 __ SmiToInteger32(exponent, exponent);
311 __ jmp(&int_exponent); 311 __ jmp(&int_exponent);
312 312
313 __ bind(&exponent_not_smi); 313 __ bind(&exponent_not_smi);
314 __ movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset)); 314 __ Movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
315 } 315 }
316 316
317 if (exponent_type() != INTEGER) { 317 if (exponent_type() != INTEGER) {
318 Label fast_power, try_arithmetic_simplification; 318 Label fast_power, try_arithmetic_simplification;
319 // Detect integer exponents stored as double. 319 // Detect integer exponents stored as double.
320 __ DoubleToI(exponent, double_exponent, double_scratch, 320 __ DoubleToI(exponent, double_exponent, double_scratch,
321 TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification, 321 TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification,
322 &try_arithmetic_simplification, 322 &try_arithmetic_simplification,
323 &try_arithmetic_simplification); 323 &try_arithmetic_simplification);
324 __ jmp(&int_exponent); 324 __ jmp(&int_exponent);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 __ divsd(double_result, double_exponent); 398 __ divsd(double_result, double_exponent);
399 __ jmp(&done); 399 __ jmp(&done);
400 } 400 }
401 401
402 // Using FPU instructions to calculate power. 402 // Using FPU instructions to calculate power.
403 Label fast_power_failed; 403 Label fast_power_failed;
404 __ bind(&fast_power); 404 __ bind(&fast_power);
405 __ fnclex(); // Clear flags to catch exceptions later. 405 __ fnclex(); // Clear flags to catch exceptions later.
406 // Transfer (B)ase and (E)xponent onto the FPU register stack. 406 // Transfer (B)ase and (E)xponent onto the FPU register stack.
407 __ subp(rsp, Immediate(kDoubleSize)); 407 __ subp(rsp, Immediate(kDoubleSize));
408 __ movsd(Operand(rsp, 0), double_exponent); 408 __ Movsd(Operand(rsp, 0), double_exponent);
409 __ fld_d(Operand(rsp, 0)); // E 409 __ fld_d(Operand(rsp, 0)); // E
410 __ movsd(Operand(rsp, 0), double_base); 410 __ Movsd(Operand(rsp, 0), double_base);
411 __ fld_d(Operand(rsp, 0)); // B, E 411 __ fld_d(Operand(rsp, 0)); // B, E
412 412
413 // Exponent is in st(1) and base is in st(0) 413 // Exponent is in st(1) and base is in st(0)
414 // B ^ E = (2^(E * log2(B)) - 1) + 1 = (2^X - 1) + 1 for X = E * log2(B) 414 // B ^ E = (2^(E * log2(B)) - 1) + 1 = (2^X - 1) + 1 for X = E * log2(B)
415 // FYL2X calculates st(1) * log2(st(0)) 415 // FYL2X calculates st(1) * log2(st(0))
416 __ fyl2x(); // X 416 __ fyl2x(); // X
417 __ fld(0); // X, X 417 __ fld(0); // X, X
418 __ frndint(); // rnd(X), X 418 __ frndint(); // rnd(X), X
419 __ fsub(1); // rnd(X), X-rnd(X) 419 __ fsub(1); // rnd(X), X-rnd(X)
420 __ fxch(1); // X - rnd(X), rnd(X) 420 __ fxch(1); // X - rnd(X), rnd(X)
421 // F2XM1 calculates 2^st(0) - 1 for -1 < st(0) < 1 421 // F2XM1 calculates 2^st(0) - 1 for -1 < st(0) < 1
422 __ f2xm1(); // 2^(X-rnd(X)) - 1, rnd(X) 422 __ f2xm1(); // 2^(X-rnd(X)) - 1, rnd(X)
423 __ fld1(); // 1, 2^(X-rnd(X)) - 1, rnd(X) 423 __ fld1(); // 1, 2^(X-rnd(X)) - 1, rnd(X)
424 __ faddp(1); // 2^(X-rnd(X)), rnd(X) 424 __ faddp(1); // 2^(X-rnd(X)), rnd(X)
425 // FSCALE calculates st(0) * 2^st(1) 425 // FSCALE calculates st(0) * 2^st(1)
426 __ fscale(); // 2^X, rnd(X) 426 __ fscale(); // 2^X, rnd(X)
427 __ fstp(1); 427 __ fstp(1);
428 // Bail out to runtime in case of exceptions in the status word. 428 // Bail out to runtime in case of exceptions in the status word.
429 __ fnstsw_ax(); 429 __ fnstsw_ax();
430 __ testb(rax, Immediate(0x5F)); // Check for all but precision exception. 430 __ testb(rax, Immediate(0x5F)); // Check for all but precision exception.
431 __ j(not_zero, &fast_power_failed, Label::kNear); 431 __ j(not_zero, &fast_power_failed, Label::kNear);
432 __ fstp_d(Operand(rsp, 0)); 432 __ fstp_d(Operand(rsp, 0));
433 __ movsd(double_result, Operand(rsp, 0)); 433 __ Movsd(double_result, Operand(rsp, 0));
434 __ addp(rsp, Immediate(kDoubleSize)); 434 __ addp(rsp, Immediate(kDoubleSize));
435 __ jmp(&done); 435 __ jmp(&done);
436 436
437 __ bind(&fast_power_failed); 437 __ bind(&fast_power_failed);
438 __ fninit(); 438 __ fninit();
439 __ addp(rsp, Immediate(kDoubleSize)); 439 __ addp(rsp, Immediate(kDoubleSize));
440 __ jmp(&call_runtime); 440 __ jmp(&call_runtime);
441 } 441 }
442 442
443 // Calculate power with integer exponent. 443 // Calculate power with integer exponent.
444 __ bind(&int_exponent); 444 __ bind(&int_exponent);
445 const XMMRegister double_scratch2 = double_exponent; 445 const XMMRegister double_scratch2 = double_exponent;
446 // Back up exponent as we need to check if exponent is negative later. 446 // Back up exponent as we need to check if exponent is negative later.
447 __ movp(scratch, exponent); // Back up exponent. 447 __ movp(scratch, exponent); // Back up exponent.
448 __ movsd(double_scratch, double_base); // Back up base. 448 __ Movsd(double_scratch, double_base); // Back up base.
449 __ movsd(double_scratch2, double_result); // Load double_exponent with 1. 449 __ Movsd(double_scratch2, double_result); // Load double_exponent with 1.
450 450
451 // Get absolute value of exponent. 451 // Get absolute value of exponent.
452 Label no_neg, while_true, while_false; 452 Label no_neg, while_true, while_false;
453 __ testl(scratch, scratch); 453 __ testl(scratch, scratch);
454 __ j(positive, &no_neg, Label::kNear); 454 __ j(positive, &no_neg, Label::kNear);
455 __ negl(scratch); 455 __ negl(scratch);
456 __ bind(&no_neg); 456 __ bind(&no_neg);
457 457
458 __ j(zero, &while_false, Label::kNear); 458 __ j(zero, &while_false, Label::kNear);
459 __ shrl(scratch, Immediate(1)); 459 __ shrl(scratch, Immediate(1));
460 // Above condition means CF==0 && ZF==0. This means that the 460 // Above condition means CF==0 && ZF==0. This means that the
461 // bit that has been shifted out is 0 and the result is not 0. 461 // bit that has been shifted out is 0 and the result is not 0.
462 __ j(above, &while_true, Label::kNear); 462 __ j(above, &while_true, Label::kNear);
463 __ movsd(double_result, double_scratch); 463 __ Movsd(double_result, double_scratch);
464 __ j(zero, &while_false, Label::kNear); 464 __ j(zero, &while_false, Label::kNear);
465 465
466 __ bind(&while_true); 466 __ bind(&while_true);
467 __ shrl(scratch, Immediate(1)); 467 __ shrl(scratch, Immediate(1));
468 __ mulsd(double_scratch, double_scratch); 468 __ mulsd(double_scratch, double_scratch);
469 __ j(above, &while_true, Label::kNear); 469 __ j(above, &while_true, Label::kNear);
470 __ mulsd(double_result, double_scratch); 470 __ mulsd(double_result, double_scratch);
471 __ j(not_zero, &while_true); 471 __ j(not_zero, &while_true);
472 472
473 __ bind(&while_false); 473 __ bind(&while_false);
474 // If the exponent is negative, return 1/result. 474 // If the exponent is negative, return 1/result.
475 __ testl(exponent, exponent); 475 __ testl(exponent, exponent);
476 __ j(greater, &done); 476 __ j(greater, &done);
477 __ divsd(double_scratch2, double_result); 477 __ divsd(double_scratch2, double_result);
478 __ movsd(double_result, double_scratch2); 478 __ Movsd(double_result, double_scratch2);
479 // Test whether result is zero. Bail out to check for subnormal result. 479 // Test whether result is zero. Bail out to check for subnormal result.
480 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. 480 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
481 __ xorps(double_scratch2, double_scratch2); 481 __ xorps(double_scratch2, double_scratch2);
482 __ ucomisd(double_scratch2, double_result); 482 __ ucomisd(double_scratch2, double_result);
483 // double_exponent aliased as double_scratch2 has already been overwritten 483 // double_exponent aliased as double_scratch2 has already been overwritten
484 // and may not have contained the exponent value in the first place when the 484 // and may not have contained the exponent value in the first place when the
485 // input was a smi. We reset it with exponent value before bailing out. 485 // input was a smi. We reset it with exponent value before bailing out.
486 __ j(not_equal, &done); 486 __ j(not_equal, &done);
487 __ Cvtlsi2sd(double_exponent, exponent); 487 __ Cvtlsi2sd(double_exponent, exponent);
488 488
489 // Returning or bailing out. 489 // Returning or bailing out.
490 Counters* counters = isolate()->counters(); 490 Counters* counters = isolate()->counters();
491 if (exponent_type() == ON_STACK) { 491 if (exponent_type() == ON_STACK) {
492 // The arguments are still on the stack. 492 // The arguments are still on the stack.
493 __ bind(&call_runtime); 493 __ bind(&call_runtime);
494 __ TailCallRuntime(Runtime::kMathPowRT, 2, 1); 494 __ TailCallRuntime(Runtime::kMathPowRT, 2, 1);
495 495
496 // The stub is called from non-optimized code, which expects the result 496 // The stub is called from non-optimized code, which expects the result
497 // as heap number in rax. 497 // as heap number in rax.
498 __ bind(&done); 498 __ bind(&done);
499 __ AllocateHeapNumber(rax, rcx, &call_runtime); 499 __ AllocateHeapNumber(rax, rcx, &call_runtime);
500 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), double_result); 500 __ Movsd(FieldOperand(rax, HeapNumber::kValueOffset), double_result);
501 __ IncrementCounter(counters->math_pow(), 1); 501 __ IncrementCounter(counters->math_pow(), 1);
502 __ ret(2 * kPointerSize); 502 __ ret(2 * kPointerSize);
503 } else { 503 } else {
504 __ bind(&call_runtime); 504 __ bind(&call_runtime);
505 // Move base to the correct argument register. Exponent is already in xmm1. 505 // Move base to the correct argument register. Exponent is already in xmm1.
506 __ movsd(xmm0, double_base); 506 __ Movsd(xmm0, double_base);
507 DCHECK(double_exponent.is(xmm1)); 507 DCHECK(double_exponent.is(xmm1));
508 { 508 {
509 AllowExternalCallThatCantCauseGC scope(masm); 509 AllowExternalCallThatCantCauseGC scope(masm);
510 __ PrepareCallCFunction(2); 510 __ PrepareCallCFunction(2);
511 __ CallCFunction( 511 __ CallCFunction(
512 ExternalReference::power_double_double_function(isolate()), 2); 512 ExternalReference::power_double_double_function(isolate()), 2);
513 } 513 }
514 // Return value is in xmm0. 514 // Return value is in xmm0.
515 __ movsd(double_result, xmm0); 515 __ Movsd(double_result, xmm0);
516 516
517 __ bind(&done); 517 __ bind(&done);
518 __ IncrementCounter(counters->math_pow(), 1); 518 __ IncrementCounter(counters->math_pow(), 1);
519 __ ret(0); 519 __ ret(0);
520 } 520 }
521 } 521 }
522 522
523 523
524 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { 524 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
525 Label miss; 525 Label miss;
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 } 1558 }
1559 __ Set(rax, EQUAL); 1559 __ Set(rax, EQUAL);
1560 __ ret(0); 1560 __ ret(0);
1561 1561
1562 __ bind(&heap_number); 1562 __ bind(&heap_number);
1563 // It is a heap number, so return equal if it's not NaN. 1563 // It is a heap number, so return equal if it's not NaN.
1564 // For NaN, return 1 for every condition except greater and 1564 // For NaN, return 1 for every condition except greater and
1565 // greater-equal. Return -1 for them, so the comparison yields 1565 // greater-equal. Return -1 for them, so the comparison yields
1566 // false for all conditions except not-equal. 1566 // false for all conditions except not-equal.
1567 __ Set(rax, EQUAL); 1567 __ Set(rax, EQUAL);
1568 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); 1568 __ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
1569 __ ucomisd(xmm0, xmm0); 1569 __ ucomisd(xmm0, xmm0);
1570 __ setcc(parity_even, rax); 1570 __ setcc(parity_even, rax);
1571 // rax is 0 for equal non-NaN heapnumbers, 1 for NaNs. 1571 // rax is 0 for equal non-NaN heapnumbers, 1 for NaNs.
1572 if (cc == greater_equal || cc == greater) { 1572 if (cc == greater_equal || cc == greater) {
1573 __ negp(rax); 1573 __ negp(rax);
1574 } 1574 }
1575 __ ret(0); 1575 __ ret(0);
1576 1576
1577 __ bind(&not_identical); 1577 __ bind(&not_identical);
1578 } 1578 }
(...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after
3427 } 3427 }
3428 if (right() == CompareICState::SMI) { 3428 if (right() == CompareICState::SMI) {
3429 __ JumpIfNotSmi(rax, &miss); 3429 __ JumpIfNotSmi(rax, &miss);
3430 } 3430 }
3431 3431
3432 // Load left and right operand. 3432 // Load left and right operand.
3433 Label done, left, left_smi, right_smi; 3433 Label done, left, left_smi, right_smi;
3434 __ JumpIfSmi(rax, &right_smi, Label::kNear); 3434 __ JumpIfSmi(rax, &right_smi, Label::kNear);
3435 __ CompareMap(rax, isolate()->factory()->heap_number_map()); 3435 __ CompareMap(rax, isolate()->factory()->heap_number_map());
3436 __ j(not_equal, &maybe_undefined1, Label::kNear); 3436 __ j(not_equal, &maybe_undefined1, Label::kNear);
3437 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); 3437 __ Movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
3438 __ jmp(&left, Label::kNear); 3438 __ jmp(&left, Label::kNear);
3439 __ bind(&right_smi); 3439 __ bind(&right_smi);
3440 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet. 3440 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet.
3441 __ Cvtlsi2sd(xmm1, rcx); 3441 __ Cvtlsi2sd(xmm1, rcx);
3442 3442
3443 __ bind(&left); 3443 __ bind(&left);
3444 __ JumpIfSmi(rdx, &left_smi, Label::kNear); 3444 __ JumpIfSmi(rdx, &left_smi, Label::kNear);
3445 __ CompareMap(rdx, isolate()->factory()->heap_number_map()); 3445 __ CompareMap(rdx, isolate()->factory()->heap_number_map());
3446 __ j(not_equal, &maybe_undefined2, Label::kNear); 3446 __ j(not_equal, &maybe_undefined2, Label::kNear);
3447 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); 3447 __ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
3448 __ jmp(&done); 3448 __ jmp(&done);
3449 __ bind(&left_smi); 3449 __ bind(&left_smi);
3450 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet. 3450 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet.
3451 __ Cvtlsi2sd(xmm0, rcx); 3451 __ Cvtlsi2sd(xmm0, rcx);
3452 3452
3453 __ bind(&done); 3453 __ bind(&done);
3454 // Compare operands 3454 // Compare operands
3455 __ ucomisd(xmm0, xmm1); 3455 __ ucomisd(xmm0, xmm1);
3456 3456
3457 // Don't base result on EFLAGS when a NaN is involved. 3457 // Don't base result on EFLAGS when a NaN is involved.
(...skipping 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after
5576 kStackSpace, nullptr, return_value_operand, NULL); 5576 kStackSpace, nullptr, return_value_operand, NULL);
5577 } 5577 }
5578 5578
5579 5579
5580 #undef __ 5580 #undef __
5581 5581
5582 } // namespace internal 5582 } // namespace internal
5583 } // namespace v8 5583 } // namespace v8
5584 5584
5585 #endif // V8_TARGET_ARCH_X64 5585 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.cc ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698