| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 void CodeGenerator::ConvertInt32ResultToNumber(Result* value) { | 549 void CodeGenerator::ConvertInt32ResultToNumber(Result* value) { |
| 550 ASSERT(value->is_untagged_int32()); | 550 ASSERT(value->is_untagged_int32()); |
| 551 if (value->is_register()) { | 551 if (value->is_register()) { |
| 552 Register val = value->reg(); | 552 Register val = value->reg(); |
| 553 JumpTarget done; | 553 JumpTarget done; |
| 554 __ add(val, Operand(val)); | 554 __ add(val, Operand(val)); |
| 555 done.Branch(no_overflow, value); | 555 done.Branch(no_overflow, value); |
| 556 __ sar(val, 1); | 556 __ sar(val, 1); |
| 557 // If there was an overflow, bits 30 and 31 of the original number disagree. | 557 // If there was an overflow, bits 30 and 31 of the original number disagree. |
| 558 __ xor_(val, 0x80000000u); | 558 __ xor_(val, 0x80000000u); |
| 559 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 559 if (CpuFeatures::IsSupported(SSE2)) { |
| 560 CpuFeatures::Scope fscope(SSE2); | 560 CpuFeatures::Scope fscope(SSE2); |
| 561 __ cvtsi2sd(xmm0, Operand(val)); | 561 __ cvtsi2sd(xmm0, Operand(val)); |
| 562 } else { | 562 } else { |
| 563 // Move val to ST[0] in the FPU | 563 // Move val to ST[0] in the FPU |
| 564 // Push and pop are safe with respect to the virtual frame because | 564 // Push and pop are safe with respect to the virtual frame because |
| 565 // all synced elements are below the actual stack pointer. | 565 // all synced elements are below the actual stack pointer. |
| 566 __ push(val); | 566 __ push(val); |
| 567 __ fild_s(Operand(esp, 0)); | 567 __ fild_s(Operand(esp, 0)); |
| 568 __ pop(val); | 568 __ pop(val); |
| 569 } | 569 } |
| 570 Result scratch = allocator_->Allocate(); | 570 Result scratch = allocator_->Allocate(); |
| 571 ASSERT(scratch.is_register()); | 571 ASSERT(scratch.is_register()); |
| 572 Label allocation_failed; | 572 Label allocation_failed; |
| 573 __ AllocateHeapNumber(val, scratch.reg(), | 573 __ AllocateHeapNumber(val, scratch.reg(), |
| 574 no_reg, &allocation_failed); | 574 no_reg, &allocation_failed); |
| 575 VirtualFrame* clone = new VirtualFrame(frame_); | 575 VirtualFrame* clone = new VirtualFrame(frame_); |
| 576 scratch.Unuse(); | 576 scratch.Unuse(); |
| 577 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 577 if (CpuFeatures::IsSupported(SSE2)) { |
| 578 CpuFeatures::Scope fscope(SSE2); | 578 CpuFeatures::Scope fscope(SSE2); |
| 579 __ movdbl(FieldOperand(val, HeapNumber::kValueOffset), xmm0); | 579 __ movdbl(FieldOperand(val, HeapNumber::kValueOffset), xmm0); |
| 580 } else { | 580 } else { |
| 581 __ fstp_d(FieldOperand(val, HeapNumber::kValueOffset)); | 581 __ fstp_d(FieldOperand(val, HeapNumber::kValueOffset)); |
| 582 } | 582 } |
| 583 done.Jump(value); | 583 done.Jump(value); |
| 584 | 584 |
| 585 // Establish the virtual frame, cloned from where AllocateHeapNumber | 585 // Establish the virtual frame, cloned from where AllocateHeapNumber |
| 586 // jumped to allocation_failed. | 586 // jumped to allocation_failed. |
| 587 RegisterFile empty_regs; | 587 RegisterFile empty_regs; |
| 588 SetFrame(clone, &empty_regs); | 588 SetFrame(clone, &empty_regs); |
| 589 __ bind(&allocation_failed); | 589 __ bind(&allocation_failed); |
| 590 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 590 if (!CpuFeatures::IsSupported(SSE2)) { |
| 591 // Pop the value from the floating point stack. | 591 // Pop the value from the floating point stack. |
| 592 __ fstp(0); | 592 __ fstp(0); |
| 593 } | 593 } |
| 594 unsafe_bailout_->Jump(); | 594 unsafe_bailout_->Jump(); |
| 595 | 595 |
| 596 done.Bind(value); | 596 done.Bind(value); |
| 597 } else { | 597 } else { |
| 598 ASSERT(value->is_constant()); | 598 ASSERT(value->is_constant()); |
| 599 } | 599 } |
| 600 value->set_untagged_int32(false); | 600 value->set_untagged_int32(false); |
| 601 value->set_type_info(TypeInfo::Integer32()); | 601 value->set_type_info(TypeInfo::Integer32()); |
| 602 } | 602 } |
| 603 | 603 |
| 604 | 604 |
| 605 void CodeGenerator::Load(Expression* expr) { | 605 void CodeGenerator::Load(Expression* expr) { |
| 606 #ifdef DEBUG | 606 #ifdef DEBUG |
| 607 int original_height = frame_->height(); | 607 int original_height = frame_->height(); |
| 608 #endif | 608 #endif |
| 609 ASSERT(!in_spilled_code()); | 609 ASSERT(!in_spilled_code()); |
| 610 | 610 |
| 611 // If the expression should be a side-effect-free 32-bit int computation, | 611 // If the expression should be a side-effect-free 32-bit int computation, |
| 612 // compile that SafeInt32 path, and a bailout path. | 612 // compile that SafeInt32 path, and a bailout path. |
| 613 if (!in_safe_int32_mode() && | 613 if (!in_safe_int32_mode() && |
| 614 safe_int32_mode_enabled() && | 614 safe_int32_mode_enabled() && |
| 615 expr->side_effect_free() && | 615 expr->side_effect_free() && |
| 616 expr->num_bit_ops() > 2 && | 616 expr->num_bit_ops() > 2 && |
| 617 masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 617 CpuFeatures::IsSupported(SSE2)) { |
| 618 BreakTarget unsafe_bailout; | 618 BreakTarget unsafe_bailout; |
| 619 JumpTarget done; | 619 JumpTarget done; |
| 620 unsafe_bailout.set_expected_height(frame_->height()); | 620 unsafe_bailout.set_expected_height(frame_->height()); |
| 621 LoadInSafeInt32Mode(expr, &unsafe_bailout); | 621 LoadInSafeInt32Mode(expr, &unsafe_bailout); |
| 622 done.Jump(); | 622 done.Jump(); |
| 623 | 623 |
| 624 if (unsafe_bailout.is_linked()) { | 624 if (unsafe_bailout.is_linked()) { |
| 625 unsafe_bailout.Bind(); | 625 unsafe_bailout.Bind(); |
| 626 LoadWithSafeInt32ModeDisabled(expr); | 626 LoadWithSafeInt32ModeDisabled(expr); |
| 627 } | 627 } |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 OverwriteMode mode_; | 988 OverwriteMode mode_; |
| 989 Label answer_out_of_range_; | 989 Label answer_out_of_range_; |
| 990 Label non_smi_input_; | 990 Label non_smi_input_; |
| 991 Label constant_rhs_; | 991 Label constant_rhs_; |
| 992 Smi* smi_value_; | 992 Smi* smi_value_; |
| 993 }; | 993 }; |
| 994 | 994 |
| 995 | 995 |
| 996 Label* DeferredInlineBinaryOperation::NonSmiInputLabel() { | 996 Label* DeferredInlineBinaryOperation::NonSmiInputLabel() { |
| 997 if (Token::IsBitOp(op_) && | 997 if (Token::IsBitOp(op_) && |
| 998 masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 998 CpuFeatures::IsSupported(SSE2)) { |
| 999 return &non_smi_input_; | 999 return &non_smi_input_; |
| 1000 } else { | 1000 } else { |
| 1001 return entry_label(); | 1001 return entry_label(); |
| 1002 } | 1002 } |
| 1003 } | 1003 } |
| 1004 | 1004 |
| 1005 | 1005 |
| 1006 void DeferredInlineBinaryOperation::JumpToAnswerOutOfRange(Condition cond) { | 1006 void DeferredInlineBinaryOperation::JumpToAnswerOutOfRange(Condition cond) { |
| 1007 __ j(cond, &answer_out_of_range_); | 1007 __ j(cond, &answer_out_of_range_); |
| 1008 } | 1008 } |
| 1009 | 1009 |
| 1010 | 1010 |
| 1011 void DeferredInlineBinaryOperation::JumpToConstantRhs(Condition cond, | 1011 void DeferredInlineBinaryOperation::JumpToConstantRhs(Condition cond, |
| 1012 Smi* smi_value) { | 1012 Smi* smi_value) { |
| 1013 smi_value_ = smi_value; | 1013 smi_value_ = smi_value; |
| 1014 __ j(cond, &constant_rhs_); | 1014 __ j(cond, &constant_rhs_); |
| 1015 } | 1015 } |
| 1016 | 1016 |
| 1017 | 1017 |
| 1018 void DeferredInlineBinaryOperation::Generate() { | 1018 void DeferredInlineBinaryOperation::Generate() { |
| 1019 // Registers are not saved implicitly for this stub, so we should not | 1019 // Registers are not saved implicitly for this stub, so we should not |
| 1020 // tread on the registers that were not passed to us. | 1020 // tread on the registers that were not passed to us. |
| 1021 if (masm()->isolate()->cpu_features()->IsSupported(SSE2) && | 1021 if (CpuFeatures::IsSupported(SSE2) && |
| 1022 ((op_ == Token::ADD) || | 1022 ((op_ == Token::ADD) || |
| 1023 (op_ == Token::SUB) || | 1023 (op_ == Token::SUB) || |
| 1024 (op_ == Token::MUL) || | 1024 (op_ == Token::MUL) || |
| 1025 (op_ == Token::DIV))) { | 1025 (op_ == Token::DIV))) { |
| 1026 CpuFeatures::Scope use_sse2(SSE2); | 1026 CpuFeatures::Scope use_sse2(SSE2); |
| 1027 Label call_runtime, after_alloc_failure; | 1027 Label call_runtime, after_alloc_failure; |
| 1028 Label left_smi, right_smi, load_right, do_op; | 1028 Label left_smi, right_smi, load_right, do_op; |
| 1029 if (!left_info_.IsSmi()) { | 1029 if (!left_info_.IsSmi()) { |
| 1030 __ test(left_, Immediate(kSmiTagMask)); | 1030 __ test(left_, Immediate(kSmiTagMask)); |
| 1031 __ j(zero, &left_smi); | 1031 __ j(zero, &left_smi); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 } | 1147 } |
| 1148 | 1148 |
| 1149 __ bind(&non_smi_input_); | 1149 __ bind(&non_smi_input_); |
| 1150 | 1150 |
| 1151 if (rhs_is_constant) { | 1151 if (rhs_is_constant) { |
| 1152 __ bind(&constant_rhs_); | 1152 __ bind(&constant_rhs_); |
| 1153 // In this case the input is a heap object and it is in the dst_ register. | 1153 // In this case the input is a heap object and it is in the dst_ register. |
| 1154 // The left_ and right_ registers have not been initialized yet. | 1154 // The left_ and right_ registers have not been initialized yet. |
| 1155 __ mov(right_, Immediate(smi_value_)); | 1155 __ mov(right_, Immediate(smi_value_)); |
| 1156 __ mov(left_, Operand(dst_)); | 1156 __ mov(left_, Operand(dst_)); |
| 1157 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 1157 if (!CpuFeatures::IsSupported(SSE2)) { |
| 1158 __ jmp(entry_label()); | 1158 __ jmp(entry_label()); |
| 1159 return; | 1159 return; |
| 1160 } else { | 1160 } else { |
| 1161 CpuFeatures::Scope use_sse2(SSE2); | 1161 CpuFeatures::Scope use_sse2(SSE2); |
| 1162 __ JumpIfNotNumber(dst_, left_info_, entry_label()); | 1162 __ JumpIfNotNumber(dst_, left_info_, entry_label()); |
| 1163 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label()); | 1163 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label()); |
| 1164 __ SmiUntag(right_); | 1164 __ SmiUntag(right_); |
| 1165 } | 1165 } |
| 1166 } else { | 1166 } else { |
| 1167 // We know we have SSE2 here because otherwise the label is not linked (see | 1167 // We know we have SSE2 here because otherwise the label is not linked (see |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 // Put a heap number pointer in left_. | 1260 // Put a heap number pointer in left_. |
| 1261 __ bind(&answer_out_of_range_); | 1261 __ bind(&answer_out_of_range_); |
| 1262 SaveRegisters(); | 1262 SaveRegisters(); |
| 1263 if (mode_ == OVERWRITE_LEFT) { | 1263 if (mode_ == OVERWRITE_LEFT) { |
| 1264 __ test(left_, Immediate(kSmiTagMask)); | 1264 __ test(left_, Immediate(kSmiTagMask)); |
| 1265 __ j(not_zero, &allocation_ok); | 1265 __ j(not_zero, &allocation_ok); |
| 1266 } | 1266 } |
| 1267 // This trashes right_. | 1267 // This trashes right_. |
| 1268 __ AllocateHeapNumber(left_, right_, no_reg, &after_alloc_failure2); | 1268 __ AllocateHeapNumber(left_, right_, no_reg, &after_alloc_failure2); |
| 1269 __ bind(&allocation_ok); | 1269 __ bind(&allocation_ok); |
| 1270 if (masm()->isolate()->cpu_features()->IsSupported(SSE2) && | 1270 if (CpuFeatures::IsSupported(SSE2) && |
| 1271 op_ != Token::SHR) { | 1271 op_ != Token::SHR) { |
| 1272 CpuFeatures::Scope use_sse2(SSE2); | 1272 CpuFeatures::Scope use_sse2(SSE2); |
| 1273 ASSERT(Token::IsBitOp(op_)); | 1273 ASSERT(Token::IsBitOp(op_)); |
| 1274 // Signed conversion. | 1274 // Signed conversion. |
| 1275 __ cvtsi2sd(xmm0, Operand(dst_)); | 1275 __ cvtsi2sd(xmm0, Operand(dst_)); |
| 1276 __ movdbl(FieldOperand(left_, HeapNumber::kValueOffset), xmm0); | 1276 __ movdbl(FieldOperand(left_, HeapNumber::kValueOffset), xmm0); |
| 1277 } else { | 1277 } else { |
| 1278 if (op_ == Token::SHR) { | 1278 if (op_ == Token::SHR) { |
| 1279 __ push(Immediate(0)); // High word of unsigned value. | 1279 __ push(Immediate(0)); // High word of unsigned value. |
| 1280 __ push(dst_); | 1280 __ push(dst_); |
| (...skipping 1744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3025 } else { | 3025 } else { |
| 3026 // Do the smi check, then the comparison. | 3026 // Do the smi check, then the comparison. |
| 3027 __ test(left_reg, Immediate(kSmiTagMask)); | 3027 __ test(left_reg, Immediate(kSmiTagMask)); |
| 3028 is_smi.Branch(zero, left_side, right_side); | 3028 is_smi.Branch(zero, left_side, right_side); |
| 3029 } | 3029 } |
| 3030 | 3030 |
| 3031 // Jump or fall through to here if we are comparing a non-smi to a | 3031 // Jump or fall through to here if we are comparing a non-smi to a |
| 3032 // constant smi. If the non-smi is a heap number and this is not | 3032 // constant smi. If the non-smi is a heap number and this is not |
| 3033 // a loop condition, inline the floating point code. | 3033 // a loop condition, inline the floating point code. |
| 3034 if (!is_loop_condition && | 3034 if (!is_loop_condition && |
| 3035 masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 3035 CpuFeatures::IsSupported(SSE2)) { |
| 3036 // Right side is a constant smi and left side has been checked | 3036 // Right side is a constant smi and left side has been checked |
| 3037 // not to be a smi. | 3037 // not to be a smi. |
| 3038 CpuFeatures::Scope use_sse2(SSE2); | 3038 CpuFeatures::Scope use_sse2(SSE2); |
| 3039 JumpTarget not_number; | 3039 JumpTarget not_number; |
| 3040 __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset), | 3040 __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset), |
| 3041 Immediate(FACTORY->heap_number_map())); | 3041 Immediate(FACTORY->heap_number_map())); |
| 3042 not_number.Branch(not_equal, left_side); | 3042 not_number.Branch(not_equal, left_side); |
| 3043 __ movdbl(xmm1, | 3043 __ movdbl(xmm1, |
| 3044 FieldOperand(left_reg, HeapNumber::kValueOffset)); | 3044 FieldOperand(left_reg, HeapNumber::kValueOffset)); |
| 3045 int value = Smi::cast(*right_val)->value(); | 3045 int value = Smi::cast(*right_val)->value(); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3189 | 3189 |
| 3190 | 3190 |
| 3191 void CodeGenerator::GenerateInlineNumberComparison(Result* left_side, | 3191 void CodeGenerator::GenerateInlineNumberComparison(Result* left_side, |
| 3192 Result* right_side, | 3192 Result* right_side, |
| 3193 Condition cc, | 3193 Condition cc, |
| 3194 ControlDestination* dest) { | 3194 ControlDestination* dest) { |
| 3195 ASSERT(left_side->is_register()); | 3195 ASSERT(left_side->is_register()); |
| 3196 ASSERT(right_side->is_register()); | 3196 ASSERT(right_side->is_register()); |
| 3197 | 3197 |
| 3198 JumpTarget not_numbers; | 3198 JumpTarget not_numbers; |
| 3199 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 3199 if (CpuFeatures::IsSupported(SSE2)) { |
| 3200 CpuFeatures::Scope use_sse2(SSE2); | 3200 CpuFeatures::Scope use_sse2(SSE2); |
| 3201 | 3201 |
| 3202 // Load left and right operand into registers xmm0 and xmm1 and compare. | 3202 // Load left and right operand into registers xmm0 and xmm1 and compare. |
| 3203 LoadComparisonOperandSSE2(masm_, left_side, xmm0, left_side, right_side, | 3203 LoadComparisonOperandSSE2(masm_, left_side, xmm0, left_side, right_side, |
| 3204 ¬_numbers); | 3204 ¬_numbers); |
| 3205 LoadComparisonOperandSSE2(masm_, right_side, xmm1, left_side, right_side, | 3205 LoadComparisonOperandSSE2(masm_, right_side, xmm1, left_side, right_side, |
| 3206 ¬_numbers); | 3206 ¬_numbers); |
| 3207 __ ucomisd(xmm0, xmm1); | 3207 __ ucomisd(xmm0, xmm1); |
| 3208 } else { | 3208 } else { |
| 3209 Label check_right, compare; | 3209 Label check_right, compare; |
| (...skipping 4240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7450 | 7450 |
| 7451 __ PrepareCallCFunction(1, ebx); | 7451 __ PrepareCallCFunction(1, ebx); |
| 7452 __ mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); | 7452 __ mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); |
| 7453 __ CallCFunction(ExternalReference::random_uint32_function(masm()->isolate()), | 7453 __ CallCFunction(ExternalReference::random_uint32_function(masm()->isolate()), |
| 7454 1); | 7454 1); |
| 7455 | 7455 |
| 7456 // Convert 32 random bits in eax to 0.(32 random bits) in a double | 7456 // Convert 32 random bits in eax to 0.(32 random bits) in a double |
| 7457 // by computing: | 7457 // by computing: |
| 7458 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). | 7458 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). |
| 7459 // This is implemented on both SSE2 and FPU. | 7459 // This is implemented on both SSE2 and FPU. |
| 7460 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 7460 if (CpuFeatures::IsSupported(SSE2)) { |
| 7461 CpuFeatures::Scope fscope(SSE2); | 7461 CpuFeatures::Scope fscope(SSE2); |
| 7462 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. | 7462 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. |
| 7463 __ movd(xmm1, Operand(ebx)); | 7463 __ movd(xmm1, Operand(ebx)); |
| 7464 __ movd(xmm0, Operand(eax)); | 7464 __ movd(xmm0, Operand(eax)); |
| 7465 __ cvtss2sd(xmm1, xmm1); | 7465 __ cvtss2sd(xmm1, xmm1); |
| 7466 __ pxor(xmm0, xmm1); | 7466 __ pxor(xmm0, xmm1); |
| 7467 __ subsd(xmm0, xmm1); | 7467 __ subsd(xmm0, xmm1); |
| 7468 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0); | 7468 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0); |
| 7469 } else { | 7469 } else { |
| 7470 // 0x4130000000000000 is 1.0 x 2^20 as a double. | 7470 // 0x4130000000000000 is 1.0 x 2^20 as a double. |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7856 | 7856 |
| 7857 | 7857 |
| 7858 // Generates the Math.pow method. Only handles special cases and | 7858 // Generates the Math.pow method. Only handles special cases and |
| 7859 // branches to the runtime system for everything else. Please note | 7859 // branches to the runtime system for everything else. Please note |
| 7860 // that this function assumes that the callsite has executed ToNumber | 7860 // that this function assumes that the callsite has executed ToNumber |
| 7861 // on both arguments. | 7861 // on both arguments. |
| 7862 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { | 7862 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { |
| 7863 ASSERT(args->length() == 2); | 7863 ASSERT(args->length() == 2); |
| 7864 Load(args->at(0)); | 7864 Load(args->at(0)); |
| 7865 Load(args->at(1)); | 7865 Load(args->at(1)); |
| 7866 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 7866 if (!CpuFeatures::IsSupported(SSE2)) { |
| 7867 Result res = frame_->CallRuntime(Runtime::kMath_pow, 2); | 7867 Result res = frame_->CallRuntime(Runtime::kMath_pow, 2); |
| 7868 frame_->Push(&res); | 7868 frame_->Push(&res); |
| 7869 } else { | 7869 } else { |
| 7870 CpuFeatures::Scope use_sse2(SSE2); | 7870 CpuFeatures::Scope use_sse2(SSE2); |
| 7871 Label allocate_return; | 7871 Label allocate_return; |
| 7872 // Load the two operands while leaving the values on the frame. | 7872 // Load the two operands while leaving the values on the frame. |
| 7873 frame()->Dup(); | 7873 frame()->Dup(); |
| 7874 Result exponent = frame()->Pop(); | 7874 Result exponent = frame()->Pop(); |
| 7875 exponent.ToRegister(); | 7875 exponent.ToRegister(); |
| 7876 frame()->Spill(exponent.reg()); | 7876 frame()->Spill(exponent.reg()); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8073 frame_->Push(&result); | 8073 frame_->Push(&result); |
| 8074 } | 8074 } |
| 8075 | 8075 |
| 8076 | 8076 |
| 8077 // Generates the Math.sqrt method. Please note - this function assumes that | 8077 // Generates the Math.sqrt method. Please note - this function assumes that |
| 8078 // the callsite has executed ToNumber on the argument. | 8078 // the callsite has executed ToNumber on the argument. |
| 8079 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { | 8079 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { |
| 8080 ASSERT_EQ(args->length(), 1); | 8080 ASSERT_EQ(args->length(), 1); |
| 8081 Load(args->at(0)); | 8081 Load(args->at(0)); |
| 8082 | 8082 |
| 8083 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) { | 8083 if (!CpuFeatures::IsSupported(SSE2)) { |
| 8084 Result result = frame()->CallRuntime(Runtime::kMath_sqrt, 1); | 8084 Result result = frame()->CallRuntime(Runtime::kMath_sqrt, 1); |
| 8085 frame()->Push(&result); | 8085 frame()->Push(&result); |
| 8086 } else { | 8086 } else { |
| 8087 CpuFeatures::Scope use_sse2(SSE2); | 8087 CpuFeatures::Scope use_sse2(SSE2); |
| 8088 // Leave original value on the frame if we need to call runtime. | 8088 // Leave original value on the frame if we need to call runtime. |
| 8089 frame()->Dup(); | 8089 frame()->Dup(); |
| 8090 Result result = frame()->Pop(); | 8090 Result result = frame()->Pop(); |
| 8091 result.ToRegister(); | 8091 result.ToRegister(); |
| 8092 frame()->Spill(result.reg()); | 8092 frame()->Spill(result.reg()); |
| 8093 Label runtime; | 8093 Label runtime; |
| (...skipping 2104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10198 int stack_offset = 0; // Update if we change the stack height. | 10198 int stack_offset = 0; // Update if we change the stack height. |
| 10199 | 10199 |
| 10200 if (FLAG_debug_code) { | 10200 if (FLAG_debug_code) { |
| 10201 __ cmp(Operand(esp, kSizeOffset + stack_offset), | 10201 __ cmp(Operand(esp, kSizeOffset + stack_offset), |
| 10202 Immediate(OS::kMinComplexMemCopy)); | 10202 Immediate(OS::kMinComplexMemCopy)); |
| 10203 Label ok; | 10203 Label ok; |
| 10204 __ j(greater_equal, &ok); | 10204 __ j(greater_equal, &ok); |
| 10205 __ int3(); | 10205 __ int3(); |
| 10206 __ bind(&ok); | 10206 __ bind(&ok); |
| 10207 } | 10207 } |
| 10208 if (masm.isolate()->cpu_features()->IsSupported(SSE2)) { | 10208 if (CpuFeatures::IsSupported(SSE2)) { |
| 10209 CpuFeatures::Scope enable(SSE2); | 10209 CpuFeatures::Scope enable(SSE2); |
| 10210 __ push(edi); | 10210 __ push(edi); |
| 10211 __ push(esi); | 10211 __ push(esi); |
| 10212 stack_offset += 2 * kPointerSize; | 10212 stack_offset += 2 * kPointerSize; |
| 10213 Register dst = edi; | 10213 Register dst = edi; |
| 10214 Register src = esi; | 10214 Register src = esi; |
| 10215 Register count = ecx; | 10215 Register count = ecx; |
| 10216 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset)); | 10216 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset)); |
| 10217 __ mov(src, Operand(esp, stack_offset + kSourceOffset)); | 10217 __ mov(src, Operand(esp, stack_offset + kSourceOffset)); |
| 10218 __ mov(count, Operand(esp, stack_offset + kSizeOffset)); | 10218 __ mov(count, Operand(esp, stack_offset + kSizeOffset)); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10379 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); | 10379 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); |
| 10380 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); | 10380 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); |
| 10381 return FUNCTION_CAST<OS::MemCopyFunction>(chunk->GetStartAddress()); | 10381 return FUNCTION_CAST<OS::MemCopyFunction>(chunk->GetStartAddress()); |
| 10382 } | 10382 } |
| 10383 | 10383 |
| 10384 #undef __ | 10384 #undef __ |
| 10385 | 10385 |
| 10386 } } // namespace v8::internal | 10386 } } // namespace v8::internal |
| 10387 | 10387 |
| 10388 #endif // V8_TARGET_ARCH_IA32 | 10388 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |