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

Side by Side Diff: src/a64/lithium-codegen-a64.cc

Issue 200413002: A64: Introduce a DeoptimizeIfMinusZero() helper. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 1099
1100 1100
1101 void LCodeGen::DeoptimizeIfNotRoot(Register rt, 1101 void LCodeGen::DeoptimizeIfNotRoot(Register rt,
1102 Heap::RootListIndex index, 1102 Heap::RootListIndex index,
1103 LEnvironment* environment) { 1103 LEnvironment* environment) {
1104 __ CompareRoot(rt, index); 1104 __ CompareRoot(rt, index);
1105 DeoptimizeIf(ne, environment); 1105 DeoptimizeIf(ne, environment);
1106 } 1106 }
1107 1107
1108 1108
1109 void LCodeGen::DeoptimizeIfMinusZero(DoubleRegister input,
1110 LEnvironment* environment) {
1111 __ TestForMinusZero(input);
1112 DeoptimizeIf(vs, environment);
1113 }
1114
1115
1109 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { 1116 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
1110 if (!info()->IsStub()) { 1117 if (!info()->IsStub()) {
1111 // Ensure that we have enough space after the previous lazy-bailout 1118 // Ensure that we have enough space after the previous lazy-bailout
1112 // instruction for patching the code here. 1119 // instruction for patching the code here.
1113 intptr_t current_pc = masm()->pc_offset(); 1120 intptr_t current_pc = masm()->pc_offset();
1114 1121
1115 if (current_pc < (last_lazy_deopt_pc_ + space_needed)) { 1122 if (current_pc < (last_lazy_deopt_pc_ + space_needed)) {
1116 ptrdiff_t padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 1123 ptrdiff_t padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
1117 ASSERT((padding_size % kInstructionSize) == 0); 1124 ASSERT((padding_size % kInstructionSize) == 0);
1118 InstructionAccurateScope instruction_accurate( 1125 InstructionAccurateScope instruction_accurate(
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after
2737 __ B(&div_ok); 2744 __ B(&div_ok);
2738 __ Bind(&deopt); 2745 __ Bind(&deopt);
2739 Deoptimize(instr->environment()); 2746 Deoptimize(instr->environment());
2740 __ Bind(&div_ok); 2747 __ Bind(&div_ok);
2741 } 2748 }
2742 2749
2743 2750
2744 void LCodeGen::DoDoubleToIntOrSmi(LDoubleToIntOrSmi* instr) { 2751 void LCodeGen::DoDoubleToIntOrSmi(LDoubleToIntOrSmi* instr) {
2745 DoubleRegister input = ToDoubleRegister(instr->value()); 2752 DoubleRegister input = ToDoubleRegister(instr->value());
2746 Register result = ToRegister32(instr->result()); 2753 Register result = ToRegister32(instr->result());
2747 Label done, deopt;
2748 2754
2749 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2755 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2750 __ JumpIfMinusZero(input, &deopt); 2756 DeoptimizeIfMinusZero(input, instr->environment());
2751 } 2757 }
2752 2758
2753 __ TryConvertDoubleToInt32(result, input, double_scratch(), &done); 2759 __ TryConvertDoubleToInt32(result, input, double_scratch());
2754 __ Bind(&deopt); 2760 DeoptimizeIf(ne, instr->environment());
2755 Deoptimize(instr->environment());
2756 __ Bind(&done);
2757 2761
2758 if (instr->tag_result()) { 2762 if (instr->tag_result()) {
2759 __ SmiTag(result.X()); 2763 __ SmiTag(result.X());
2760 } 2764 }
2761 } 2765 }
2762 2766
2763 2767
2764 void LCodeGen::DoDrop(LDrop* instr) { 2768 void LCodeGen::DoDrop(LDrop* instr) {
2765 __ Drop(instr->count()); 2769 __ Drop(instr->count());
2766 } 2770 }
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after
3809 double_temp1, double_temp2, 3813 double_temp1, double_temp2,
3810 temp1, temp2, temp3); 3814 temp1, temp2, temp3);
3811 } 3815 }
3812 3816
3813 3817
3814 void LCodeGen::DoMathFloor(LMathFloor* instr) { 3818 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3815 // TODO(jbramley): If we could provide a double result, we could use frintm 3819 // TODO(jbramley): If we could provide a double result, we could use frintm
3816 // and produce a valid double result in a single instruction. 3820 // and produce a valid double result in a single instruction.
3817 DoubleRegister input = ToDoubleRegister(instr->value()); 3821 DoubleRegister input = ToDoubleRegister(instr->value());
3818 Register result = ToRegister(instr->result()); 3822 Register result = ToRegister(instr->result());
3819 Label deopt;
3820 Label done;
3821 3823
3822 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3824 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3823 __ JumpIfMinusZero(input, &deopt); 3825 DeoptimizeIfMinusZero(input, instr->environment());
3824 } 3826 }
3825 3827
3826 __ Fcvtms(result, input); 3828 __ Fcvtms(result, input);
3827 3829
3828 // Check that the result fits into a 32-bit integer. 3830 // Check that the result fits into a 32-bit integer.
3829 // - The result did not overflow. 3831 // - The result did not overflow.
3830 __ Cmp(result, Operand(result, SXTW)); 3832 __ Cmp(result, Operand(result, SXTW));
3831 // - The input was not NaN. 3833 // - The input was not NaN.
3832 __ Fccmp(input, input, NoFlag, eq); 3834 __ Fccmp(input, input, NoFlag, eq);
3833 __ B(&done, eq); 3835 DeoptimizeIf(ne, instr->environment());
3834
3835 __ Bind(&deopt);
3836 Deoptimize(instr->environment());
3837
3838 __ Bind(&done);
3839 } 3836 }
3840 3837
3841 3838
3842 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { 3839 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
3843 Register dividend = ToRegister32(instr->dividend()); 3840 Register dividend = ToRegister32(instr->dividend());
3844 Register result = ToRegister32(instr->result()); 3841 Register result = ToRegister32(instr->result());
3845 int32_t divisor = instr->divisor(); 3842 int32_t divisor = instr->divisor();
3846 3843
3847 // If the divisor is positive, things are easy: There can be no deopts and we 3844 // If the divisor is positive, things are easy: There can be no deopts and we
3848 // can simply do an arithmetic right shift. 3845 // can simply do an arithmetic right shift.
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
4519 Label done, load_smi; 4516 Label done, load_smi;
4520 4517
4521 // Work out what untag mode we're working with. 4518 // Work out what untag mode we're working with.
4522 HValue* value = instr->hydrogen()->value(); 4519 HValue* value = instr->hydrogen()->value();
4523 NumberUntagDMode mode = value->representation().IsSmi() 4520 NumberUntagDMode mode = value->representation().IsSmi()
4524 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; 4521 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
4525 4522
4526 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 4523 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4527 __ JumpIfSmi(input, &load_smi); 4524 __ JumpIfSmi(input, &load_smi);
4528 4525
4529 Label convert_undefined, deopt; 4526 Label convert_undefined;
4530 4527
4531 // Heap number map check. 4528 // Heap number map check.
4532 Label* not_heap_number = can_convert_undefined_to_nan ? &convert_undefined
4533 : &deopt;
4534 __ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 4529 __ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
4535 __ JumpIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex, not_heap_number); 4530 if (can_convert_undefined_to_nan) {
4531 __ JumpIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex,
4532 &convert_undefined);
4533 } else {
4534 DeoptimizeIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex,
4535 instr->environment());
4536 }
4536 4537
4537 // Load heap number. 4538 // Load heap number.
4538 __ Ldr(result, FieldMemOperand(input, HeapNumber::kValueOffset)); 4539 __ Ldr(result, FieldMemOperand(input, HeapNumber::kValueOffset));
4539 if (instr->hydrogen()->deoptimize_on_minus_zero()) { 4540 if (instr->hydrogen()->deoptimize_on_minus_zero()) {
4540 __ JumpIfMinusZero(result, &deopt); 4541 DeoptimizeIfMinusZero(result, instr->environment());
4541 } 4542 }
4542 __ B(&done); 4543 __ B(&done);
4543 4544
4544 if (can_convert_undefined_to_nan) { 4545 if (can_convert_undefined_to_nan) {
4545 __ Bind(&convert_undefined); 4546 __ Bind(&convert_undefined);
4546 __ JumpIfNotRoot(input, Heap::kUndefinedValueRootIndex, &deopt); 4547 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex,
4548 instr->environment());
4547 4549
4548 __ LoadRoot(scratch, Heap::kNanValueRootIndex); 4550 __ LoadRoot(scratch, Heap::kNanValueRootIndex);
4549 __ Ldr(result, FieldMemOperand(scratch, HeapNumber::kValueOffset)); 4551 __ Ldr(result, FieldMemOperand(scratch, HeapNumber::kValueOffset));
4550 __ B(&done); 4552 __ B(&done);
4551 } 4553 }
4552 4554
4553 __ Bind(&deopt);
4554 Deoptimize(instr->environment());
4555 } else { 4555 } else {
4556 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 4556 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
4557 // Fall through to load_smi. 4557 // Fall through to load_smi.
4558 } 4558 }
4559 4559
4560 // Smi to double register conversion. 4560 // Smi to double register conversion.
4561 __ Bind(&load_smi); 4561 __ Bind(&load_smi);
4562 __ SmiUntagToDouble(result, input); 4562 __ SmiUntagToDouble(result, input);
4563 4563
4564 __ Bind(&done); 4564 __ Bind(&done);
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after
5487 __ B(eq, &done); 5487 __ B(eq, &done);
5488 5488
5489 // Output contains zero, undefined is converted to zero for truncating 5489 // Output contains zero, undefined is converted to zero for truncating
5490 // conversions. 5490 // conversions.
5491 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, 5491 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex,
5492 instr->environment()); 5492 instr->environment());
5493 } else { 5493 } else {
5494 Register output = ToRegister32(instr->result()); 5494 Register output = ToRegister32(instr->result());
5495 5495
5496 DoubleRegister dbl_scratch2 = ToDoubleRegister(temp2); 5496 DoubleRegister dbl_scratch2 = ToDoubleRegister(temp2);
5497 Label converted;
5498 5497
5499 // Deoptimized if it's not a heap number. 5498 // Deoptimized if it's not a heap number.
5500 DeoptimizeIfNotRoot(scratch1, Heap::kHeapNumberMapRootIndex, 5499 DeoptimizeIfNotRoot(scratch1, Heap::kHeapNumberMapRootIndex,
5501 instr->environment()); 5500 instr->environment());
5502 5501
5503 // A heap number: load value and convert to int32 using non-truncating 5502 // A heap number: load value and convert to int32 using non-truncating
5504 // function. If the result is out of range, branch to deoptimize. 5503 // function. If the result is out of range, branch to deoptimize.
5505 __ Ldr(dbl_scratch1, FieldMemOperand(input, HeapNumber::kValueOffset)); 5504 __ Ldr(dbl_scratch1, FieldMemOperand(input, HeapNumber::kValueOffset));
5506 __ TryConvertDoubleToInt32(output, dbl_scratch1, dbl_scratch2, &converted); 5505 __ TryConvertDoubleToInt32(output, dbl_scratch1, dbl_scratch2);
5507 Deoptimize(instr->environment()); 5506 DeoptimizeIf(ne, instr->environment());
5508
5509 __ Bind(&converted);
5510 5507
5511 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5508 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5512 __ Cmp(output, 0); 5509 __ Cmp(output, 0);
5513 __ B(ne, &done); 5510 __ B(ne, &done);
5514 __ Fmov(scratch1, dbl_scratch1); 5511 __ Fmov(scratch1, dbl_scratch1);
5515 DeoptimizeIfNegative(scratch1, instr->environment()); 5512 DeoptimizeIfNegative(scratch1, instr->environment());
5516 } 5513 }
5517 } 5514 }
5518 __ Bind(&done); 5515 __ Bind(&done);
5519 } 5516 }
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
5839 __ Bind(&out_of_object); 5836 __ Bind(&out_of_object);
5840 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 5837 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
5841 // Index is equal to negated out of object property index plus 1. 5838 // Index is equal to negated out of object property index plus 1.
5842 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 5839 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2));
5843 __ Ldr(result, FieldMemOperand(result, 5840 __ Ldr(result, FieldMemOperand(result,
5844 FixedArray::kHeaderSize - kPointerSize)); 5841 FixedArray::kHeaderSize - kPointerSize));
5845 __ Bind(&done); 5842 __ Bind(&done);
5846 } 5843 }
5847 5844
5848 } } // namespace v8::internal 5845 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698