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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 6794050: Revert "[Arguments] Merge (7442,7496] from bleeding_edge." (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/arguments
Patch Set: Created 9 years, 8 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/code-stubs-ia32.cc ('k') | src/ia32/cpu-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 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
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 (CpuFeatures::IsSupported(SSE2)) { 559 if (masm()->isolate()->cpu_features()->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 (CpuFeatures::IsSupported(SSE2)) { 577 if (masm()->isolate()->cpu_features()->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 (!CpuFeatures::IsSupported(SSE2)) { 590 if (!masm()->isolate()->cpu_features()->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 CpuFeatures::IsSupported(SSE2)) { 617 masm()->isolate()->cpu_features()->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 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 OverwriteMode mode_; 978 OverwriteMode mode_;
979 Label answer_out_of_range_; 979 Label answer_out_of_range_;
980 Label non_smi_input_; 980 Label non_smi_input_;
981 Label constant_rhs_; 981 Label constant_rhs_;
982 Smi* smi_value_; 982 Smi* smi_value_;
983 }; 983 };
984 984
985 985
986 Label* DeferredInlineBinaryOperation::NonSmiInputLabel() { 986 Label* DeferredInlineBinaryOperation::NonSmiInputLabel() {
987 if (Token::IsBitOp(op_) && 987 if (Token::IsBitOp(op_) &&
988 CpuFeatures::IsSupported(SSE2)) { 988 masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
989 return &non_smi_input_; 989 return &non_smi_input_;
990 } else { 990 } else {
991 return entry_label(); 991 return entry_label();
992 } 992 }
993 } 993 }
994 994
995 995
996 void DeferredInlineBinaryOperation::JumpToAnswerOutOfRange(Condition cond) { 996 void DeferredInlineBinaryOperation::JumpToAnswerOutOfRange(Condition cond) {
997 __ j(cond, &answer_out_of_range_); 997 __ j(cond, &answer_out_of_range_);
998 } 998 }
999 999
1000 1000
1001 void DeferredInlineBinaryOperation::JumpToConstantRhs(Condition cond, 1001 void DeferredInlineBinaryOperation::JumpToConstantRhs(Condition cond,
1002 Smi* smi_value) { 1002 Smi* smi_value) {
1003 smi_value_ = smi_value; 1003 smi_value_ = smi_value;
1004 __ j(cond, &constant_rhs_); 1004 __ j(cond, &constant_rhs_);
1005 } 1005 }
1006 1006
1007 1007
1008 void DeferredInlineBinaryOperation::Generate() { 1008 void DeferredInlineBinaryOperation::Generate() {
1009 // Registers are not saved implicitly for this stub, so we should not 1009 // Registers are not saved implicitly for this stub, so we should not
1010 // tread on the registers that were not passed to us. 1010 // tread on the registers that were not passed to us.
1011 if (CpuFeatures::IsSupported(SSE2) && 1011 if (masm()->isolate()->cpu_features()->IsSupported(SSE2) &&
1012 ((op_ == Token::ADD) || 1012 ((op_ == Token::ADD) ||
1013 (op_ == Token::SUB) || 1013 (op_ == Token::SUB) ||
1014 (op_ == Token::MUL) || 1014 (op_ == Token::MUL) ||
1015 (op_ == Token::DIV))) { 1015 (op_ == Token::DIV))) {
1016 CpuFeatures::Scope use_sse2(SSE2); 1016 CpuFeatures::Scope use_sse2(SSE2);
1017 Label call_runtime, after_alloc_failure; 1017 Label call_runtime, after_alloc_failure;
1018 Label left_smi, right_smi, load_right, do_op; 1018 Label left_smi, right_smi, load_right, do_op;
1019 if (!left_info_.IsSmi()) { 1019 if (!left_info_.IsSmi()) {
1020 __ test(left_, Immediate(kSmiTagMask)); 1020 __ test(left_, Immediate(kSmiTagMask));
1021 __ j(zero, &left_smi); 1021 __ j(zero, &left_smi);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 } 1137 }
1138 1138
1139 __ bind(&non_smi_input_); 1139 __ bind(&non_smi_input_);
1140 1140
1141 if (rhs_is_constant) { 1141 if (rhs_is_constant) {
1142 __ bind(&constant_rhs_); 1142 __ bind(&constant_rhs_);
1143 // In this case the input is a heap object and it is in the dst_ register. 1143 // In this case the input is a heap object and it is in the dst_ register.
1144 // The left_ and right_ registers have not been initialized yet. 1144 // The left_ and right_ registers have not been initialized yet.
1145 __ mov(right_, Immediate(smi_value_)); 1145 __ mov(right_, Immediate(smi_value_));
1146 __ mov(left_, Operand(dst_)); 1146 __ mov(left_, Operand(dst_));
1147 if (!CpuFeatures::IsSupported(SSE2)) { 1147 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
1148 __ jmp(entry_label()); 1148 __ jmp(entry_label());
1149 return; 1149 return;
1150 } else { 1150 } else {
1151 CpuFeatures::Scope use_sse2(SSE2); 1151 CpuFeatures::Scope use_sse2(SSE2);
1152 __ JumpIfNotNumber(dst_, left_info_, entry_label()); 1152 __ JumpIfNotNumber(dst_, left_info_, entry_label());
1153 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label()); 1153 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label());
1154 __ SmiUntag(right_); 1154 __ SmiUntag(right_);
1155 } 1155 }
1156 } else { 1156 } else {
1157 // We know we have SSE2 here because otherwise the label is not linked (see 1157 // 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
1250 // Put a heap number pointer in left_. 1250 // Put a heap number pointer in left_.
1251 __ bind(&answer_out_of_range_); 1251 __ bind(&answer_out_of_range_);
1252 SaveRegisters(); 1252 SaveRegisters();
1253 if (mode_ == OVERWRITE_LEFT) { 1253 if (mode_ == OVERWRITE_LEFT) {
1254 __ test(left_, Immediate(kSmiTagMask)); 1254 __ test(left_, Immediate(kSmiTagMask));
1255 __ j(not_zero, &allocation_ok); 1255 __ j(not_zero, &allocation_ok);
1256 } 1256 }
1257 // This trashes right_. 1257 // This trashes right_.
1258 __ AllocateHeapNumber(left_, right_, no_reg, &after_alloc_failure2); 1258 __ AllocateHeapNumber(left_, right_, no_reg, &after_alloc_failure2);
1259 __ bind(&allocation_ok); 1259 __ bind(&allocation_ok);
1260 if (CpuFeatures::IsSupported(SSE2) && 1260 if (masm()->isolate()->cpu_features()->IsSupported(SSE2) &&
1261 op_ != Token::SHR) { 1261 op_ != Token::SHR) {
1262 CpuFeatures::Scope use_sse2(SSE2); 1262 CpuFeatures::Scope use_sse2(SSE2);
1263 ASSERT(Token::IsBitOp(op_)); 1263 ASSERT(Token::IsBitOp(op_));
1264 // Signed conversion. 1264 // Signed conversion.
1265 __ cvtsi2sd(xmm0, Operand(dst_)); 1265 __ cvtsi2sd(xmm0, Operand(dst_));
1266 __ movdbl(FieldOperand(left_, HeapNumber::kValueOffset), xmm0); 1266 __ movdbl(FieldOperand(left_, HeapNumber::kValueOffset), xmm0);
1267 } else { 1267 } else {
1268 if (op_ == Token::SHR) { 1268 if (op_ == Token::SHR) {
1269 __ push(Immediate(0)); // High word of unsigned value. 1269 __ push(Immediate(0)); // High word of unsigned value.
1270 __ push(dst_); 1270 __ push(dst_);
(...skipping 1744 matching lines...) Expand 10 before | Expand all | Expand 10 after
3015 } else { 3015 } else {
3016 // Do the smi check, then the comparison. 3016 // Do the smi check, then the comparison.
3017 __ test(left_reg, Immediate(kSmiTagMask)); 3017 __ test(left_reg, Immediate(kSmiTagMask));
3018 is_smi.Branch(zero, left_side, right_side); 3018 is_smi.Branch(zero, left_side, right_side);
3019 } 3019 }
3020 3020
3021 // Jump or fall through to here if we are comparing a non-smi to a 3021 // Jump or fall through to here if we are comparing a non-smi to a
3022 // constant smi. If the non-smi is a heap number and this is not 3022 // constant smi. If the non-smi is a heap number and this is not
3023 // a loop condition, inline the floating point code. 3023 // a loop condition, inline the floating point code.
3024 if (!is_loop_condition && 3024 if (!is_loop_condition &&
3025 CpuFeatures::IsSupported(SSE2)) { 3025 masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
3026 // Right side is a constant smi and left side has been checked 3026 // Right side is a constant smi and left side has been checked
3027 // not to be a smi. 3027 // not to be a smi.
3028 CpuFeatures::Scope use_sse2(SSE2); 3028 CpuFeatures::Scope use_sse2(SSE2);
3029 JumpTarget not_number; 3029 JumpTarget not_number;
3030 __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset), 3030 __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset),
3031 Immediate(FACTORY->heap_number_map())); 3031 Immediate(FACTORY->heap_number_map()));
3032 not_number.Branch(not_equal, left_side); 3032 not_number.Branch(not_equal, left_side);
3033 __ movdbl(xmm1, 3033 __ movdbl(xmm1,
3034 FieldOperand(left_reg, HeapNumber::kValueOffset)); 3034 FieldOperand(left_reg, HeapNumber::kValueOffset));
3035 int value = Smi::cast(*right_val)->value(); 3035 int value = Smi::cast(*right_val)->value();
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
3179 3179
3180 3180
3181 void CodeGenerator::GenerateInlineNumberComparison(Result* left_side, 3181 void CodeGenerator::GenerateInlineNumberComparison(Result* left_side,
3182 Result* right_side, 3182 Result* right_side,
3183 Condition cc, 3183 Condition cc,
3184 ControlDestination* dest) { 3184 ControlDestination* dest) {
3185 ASSERT(left_side->is_register()); 3185 ASSERT(left_side->is_register());
3186 ASSERT(right_side->is_register()); 3186 ASSERT(right_side->is_register());
3187 3187
3188 JumpTarget not_numbers; 3188 JumpTarget not_numbers;
3189 if (CpuFeatures::IsSupported(SSE2)) { 3189 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
3190 CpuFeatures::Scope use_sse2(SSE2); 3190 CpuFeatures::Scope use_sse2(SSE2);
3191 3191
3192 // Load left and right operand into registers xmm0 and xmm1 and compare. 3192 // Load left and right operand into registers xmm0 and xmm1 and compare.
3193 LoadComparisonOperandSSE2(masm_, left_side, xmm0, left_side, right_side, 3193 LoadComparisonOperandSSE2(masm_, left_side, xmm0, left_side, right_side,
3194 &not_numbers); 3194 &not_numbers);
3195 LoadComparisonOperandSSE2(masm_, right_side, xmm1, left_side, right_side, 3195 LoadComparisonOperandSSE2(masm_, right_side, xmm1, left_side, right_side,
3196 &not_numbers); 3196 &not_numbers);
3197 __ ucomisd(xmm0, xmm1); 3197 __ ucomisd(xmm0, xmm1);
3198 } else { 3198 } else {
3199 Label check_right, compare; 3199 Label check_right, compare;
(...skipping 4221 matching lines...) Expand 10 before | Expand all | Expand 10 after
7421 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber); 7421 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber);
7422 __ jmp(&heapnumber_allocated); 7422 __ jmp(&heapnumber_allocated);
7423 7423
7424 __ bind(&slow_allocate_heapnumber); 7424 __ bind(&slow_allocate_heapnumber);
7425 // Allocate a heap number. 7425 // Allocate a heap number.
7426 __ CallRuntime(Runtime::kNumberAlloc, 0); 7426 __ CallRuntime(Runtime::kNumberAlloc, 0);
7427 __ mov(edi, eax); 7427 __ mov(edi, eax);
7428 7428
7429 __ bind(&heapnumber_allocated); 7429 __ bind(&heapnumber_allocated);
7430 7430
7431 __ PrepareCallCFunction(1, ebx); 7431 __ PrepareCallCFunction(0, ebx);
7432 __ mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address()));
7433 __ CallCFunction(ExternalReference::random_uint32_function(masm()->isolate()), 7432 __ CallCFunction(ExternalReference::random_uint32_function(masm()->isolate()),
7434 1); 7433 0);
7435 7434
7436 // Convert 32 random bits in eax to 0.(32 random bits) in a double 7435 // Convert 32 random bits in eax to 0.(32 random bits) in a double
7437 // by computing: 7436 // by computing:
7438 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 7437 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
7439 // This is implemented on both SSE2 and FPU. 7438 // This is implemented on both SSE2 and FPU.
7440 if (CpuFeatures::IsSupported(SSE2)) { 7439 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
7441 CpuFeatures::Scope fscope(SSE2); 7440 CpuFeatures::Scope fscope(SSE2);
7442 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. 7441 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
7443 __ movd(xmm1, Operand(ebx)); 7442 __ movd(xmm1, Operand(ebx));
7444 __ movd(xmm0, Operand(eax)); 7443 __ movd(xmm0, Operand(eax));
7445 __ cvtss2sd(xmm1, xmm1); 7444 __ cvtss2sd(xmm1, xmm1);
7446 __ pxor(xmm0, xmm1); 7445 __ pxor(xmm0, xmm1);
7447 __ subsd(xmm0, xmm1); 7446 __ subsd(xmm0, xmm1);
7448 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0); 7447 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0);
7449 } else { 7448 } else {
7450 // 0x4130000000000000 is 1.0 x 2^20 as a double. 7449 // 0x4130000000000000 is 1.0 x 2^20 as a double.
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
7836 7835
7837 7836
7838 // Generates the Math.pow method. Only handles special cases and 7837 // Generates the Math.pow method. Only handles special cases and
7839 // branches to the runtime system for everything else. Please note 7838 // branches to the runtime system for everything else. Please note
7840 // that this function assumes that the callsite has executed ToNumber 7839 // that this function assumes that the callsite has executed ToNumber
7841 // on both arguments. 7840 // on both arguments.
7842 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { 7841 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
7843 ASSERT(args->length() == 2); 7842 ASSERT(args->length() == 2);
7844 Load(args->at(0)); 7843 Load(args->at(0));
7845 Load(args->at(1)); 7844 Load(args->at(1));
7846 if (!CpuFeatures::IsSupported(SSE2)) { 7845 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
7847 Result res = frame_->CallRuntime(Runtime::kMath_pow, 2); 7846 Result res = frame_->CallRuntime(Runtime::kMath_pow, 2);
7848 frame_->Push(&res); 7847 frame_->Push(&res);
7849 } else { 7848 } else {
7850 CpuFeatures::Scope use_sse2(SSE2); 7849 CpuFeatures::Scope use_sse2(SSE2);
7851 Label allocate_return; 7850 Label allocate_return;
7852 // Load the two operands while leaving the values on the frame. 7851 // Load the two operands while leaving the values on the frame.
7853 frame()->Dup(); 7852 frame()->Dup();
7854 Result exponent = frame()->Pop(); 7853 Result exponent = frame()->Pop();
7855 exponent.ToRegister(); 7854 exponent.ToRegister();
7856 frame()->Spill(exponent.reg()); 7855 frame()->Spill(exponent.reg());
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
8053 frame_->Push(&result); 8052 frame_->Push(&result);
8054 } 8053 }
8055 8054
8056 8055
8057 // Generates the Math.sqrt method. Please note - this function assumes that 8056 // Generates the Math.sqrt method. Please note - this function assumes that
8058 // the callsite has executed ToNumber on the argument. 8057 // the callsite has executed ToNumber on the argument.
8059 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { 8058 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
8060 ASSERT_EQ(args->length(), 1); 8059 ASSERT_EQ(args->length(), 1);
8061 Load(args->at(0)); 8060 Load(args->at(0));
8062 8061
8063 if (!CpuFeatures::IsSupported(SSE2)) { 8062 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
8064 Result result = frame()->CallRuntime(Runtime::kMath_sqrt, 1); 8063 Result result = frame()->CallRuntime(Runtime::kMath_sqrt, 1);
8065 frame()->Push(&result); 8064 frame()->Push(&result);
8066 } else { 8065 } else {
8067 CpuFeatures::Scope use_sse2(SSE2); 8066 CpuFeatures::Scope use_sse2(SSE2);
8068 // Leave original value on the frame if we need to call runtime. 8067 // Leave original value on the frame if we need to call runtime.
8069 frame()->Dup(); 8068 frame()->Dup();
8070 Result result = frame()->Pop(); 8069 Result result = frame()->Pop();
8071 result.ToRegister(); 8070 result.ToRegister();
8072 frame()->Spill(result.reg()); 8071 frame()->Spill(result.reg());
8073 Label runtime; 8072 Label runtime;
(...skipping 2075 matching lines...) Expand 10 before | Expand all | Expand 10 after
10149 10148
10150 #define __ masm. 10149 #define __ masm.
10151 10150
10152 10151
10153 static void MemCopyWrapper(void* dest, const void* src, size_t size) { 10152 static void MemCopyWrapper(void* dest, const void* src, size_t size) {
10154 memcpy(dest, src, size); 10153 memcpy(dest, src, size);
10155 } 10154 }
10156 10155
10157 10156
10158 OS::MemCopyFunction CreateMemCopyFunction() { 10157 OS::MemCopyFunction CreateMemCopyFunction() {
10159 size_t actual_size; 10158 HandleScope scope;
10160 // Allocate buffer in executable space. 10159 MacroAssembler masm(NULL, 1 * KB);
10161 byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB,
10162 &actual_size,
10163 true));
10164 if (buffer == NULL) return &MemCopyWrapper;
10165 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
10166 10160
10167 // Generated code is put into a fixed, unmovable, buffer, and not into 10161 // Generated code is put into a fixed, unmovable, buffer, and not into
10168 // the V8 heap. We can't, and don't, refer to any relocatable addresses 10162 // the V8 heap. We can't, and don't, refer to any relocatable addresses
10169 // (e.g. the JavaScript nan-object). 10163 // (e.g. the JavaScript nan-object).
10170 10164
10171 // 32-bit C declaration function calls pass arguments on stack. 10165 // 32-bit C declaration function calls pass arguments on stack.
10172 10166
10173 // Stack layout: 10167 // Stack layout:
10174 // esp[12]: Third argument, size. 10168 // esp[12]: Third argument, size.
10175 // esp[8]: Second argument, source pointer. 10169 // esp[8]: Second argument, source pointer.
10176 // esp[4]: First argument, destination pointer. 10170 // esp[4]: First argument, destination pointer.
10177 // esp[0]: return address 10171 // esp[0]: return address
10178 10172
10179 const int kDestinationOffset = 1 * kPointerSize; 10173 const int kDestinationOffset = 1 * kPointerSize;
10180 const int kSourceOffset = 2 * kPointerSize; 10174 const int kSourceOffset = 2 * kPointerSize;
10181 const int kSizeOffset = 3 * kPointerSize; 10175 const int kSizeOffset = 3 * kPointerSize;
10182 10176
10183 int stack_offset = 0; // Update if we change the stack height. 10177 int stack_offset = 0; // Update if we change the stack height.
10184 10178
10185 if (FLAG_debug_code) { 10179 if (FLAG_debug_code) {
10186 __ cmp(Operand(esp, kSizeOffset + stack_offset), 10180 __ cmp(Operand(esp, kSizeOffset + stack_offset),
10187 Immediate(OS::kMinComplexMemCopy)); 10181 Immediate(OS::kMinComplexMemCopy));
10188 Label ok; 10182 Label ok;
10189 __ j(greater_equal, &ok); 10183 __ j(greater_equal, &ok);
10190 __ int3(); 10184 __ int3();
10191 __ bind(&ok); 10185 __ bind(&ok);
10192 } 10186 }
10193 if (CpuFeatures::IsSupported(SSE2)) { 10187 if (masm.isolate()->cpu_features()->IsSupported(SSE2)) {
10194 CpuFeatures::Scope enable(SSE2); 10188 CpuFeatures::Scope enable(SSE2);
10195 __ push(edi); 10189 __ push(edi);
10196 __ push(esi); 10190 __ push(esi);
10197 stack_offset += 2 * kPointerSize; 10191 stack_offset += 2 * kPointerSize;
10198 Register dst = edi; 10192 Register dst = edi;
10199 Register src = esi; 10193 Register src = esi;
10200 Register count = ecx; 10194 Register count = ecx;
10201 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset)); 10195 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset));
10202 __ mov(src, Operand(esp, stack_offset + kSourceOffset)); 10196 __ mov(src, Operand(esp, stack_offset + kSourceOffset));
10203 __ mov(count, Operand(esp, stack_offset + kSizeOffset)); 10197 __ mov(count, Operand(esp, stack_offset + kSizeOffset));
10204 10198
10205 10199
10206 __ movdqu(xmm0, Operand(src, 0)); 10200 __ movdqu(xmm0, Operand(src, 0));
10207 __ movdqu(Operand(dst, 0), xmm0); 10201 __ movdqu(Operand(dst, 0), xmm0);
10208 __ mov(edx, dst); 10202 __ mov(edx, dst);
10209 __ and_(edx, 0xF); 10203 __ and_(edx, 0xF);
10210 __ neg(edx); 10204 __ neg(edx);
10211 __ add(Operand(edx), Immediate(16)); 10205 __ add(Operand(edx), Immediate(16));
10212 __ add(dst, Operand(edx)); 10206 __ add(dst, Operand(edx));
10213 __ add(src, Operand(edx)); 10207 __ add(src, Operand(edx));
10214 __ sub(Operand(count), edx); 10208 __ sub(Operand(count), edx);
10215 10209
10216 // edi is now aligned. Check if esi is also aligned. 10210 // edi is now aligned. Check if esi is also aligned.
10217 Label unaligned_source; 10211 Label unaligned_source;
10218 __ test(Operand(src), Immediate(0x0F)); 10212 __ test(Operand(src), Immediate(0x0F));
10219 __ j(not_zero, &unaligned_source); 10213 __ j(not_zero, &unaligned_source);
10220 { 10214 {
10215 __ IncrementCounter(masm.isolate()->counters()->memcopy_aligned(), 1);
10221 // Copy loop for aligned source and destination. 10216 // Copy loop for aligned source and destination.
10222 __ mov(edx, count); 10217 __ mov(edx, count);
10223 Register loop_count = ecx; 10218 Register loop_count = ecx;
10224 Register count = edx; 10219 Register count = edx;
10225 __ shr(loop_count, 5); 10220 __ shr(loop_count, 5);
10226 { 10221 {
10227 // Main copy loop. 10222 // Main copy loop.
10228 Label loop; 10223 Label loop;
10229 __ bind(&loop); 10224 __ bind(&loop);
10230 __ prefetch(Operand(src, 0x20), 1); 10225 __ prefetch(Operand(src, 0x20), 1);
(...skipping 27 matching lines...) Expand all
10258 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset)); 10253 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset));
10259 __ pop(esi); 10254 __ pop(esi);
10260 __ pop(edi); 10255 __ pop(edi);
10261 __ ret(0); 10256 __ ret(0);
10262 } 10257 }
10263 __ Align(16); 10258 __ Align(16);
10264 { 10259 {
10265 // Copy loop for unaligned source and aligned destination. 10260 // Copy loop for unaligned source and aligned destination.
10266 // If source is not aligned, we can't read it as efficiently. 10261 // If source is not aligned, we can't read it as efficiently.
10267 __ bind(&unaligned_source); 10262 __ bind(&unaligned_source);
10263 __ IncrementCounter(masm.isolate()->counters()->memcopy_unaligned(), 1);
10268 __ mov(edx, ecx); 10264 __ mov(edx, ecx);
10269 Register loop_count = ecx; 10265 Register loop_count = ecx;
10270 Register count = edx; 10266 Register count = edx;
10271 __ shr(loop_count, 5); 10267 __ shr(loop_count, 5);
10272 { 10268 {
10273 // Main copy loop 10269 // Main copy loop
10274 Label loop; 10270 Label loop;
10275 __ bind(&loop); 10271 __ bind(&loop);
10276 __ prefetch(Operand(src, 0x20), 1); 10272 __ prefetch(Operand(src, 0x20), 1);
10277 __ movdqu(xmm0, Operand(src, 0x00)); 10273 __ movdqu(xmm0, Operand(src, 0x00));
(...skipping 23 matching lines...) Expand all
10301 __ movdqu(xmm0, Operand(src, count, times_1, -0x10)); 10297 __ movdqu(xmm0, Operand(src, count, times_1, -0x10));
10302 __ movdqu(Operand(dst, count, times_1, -0x10), xmm0); 10298 __ movdqu(Operand(dst, count, times_1, -0x10), xmm0);
10303 10299
10304 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset)); 10300 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset));
10305 __ pop(esi); 10301 __ pop(esi);
10306 __ pop(edi); 10302 __ pop(edi);
10307 __ ret(0); 10303 __ ret(0);
10308 } 10304 }
10309 10305
10310 } else { 10306 } else {
10307 __ IncrementCounter(masm.isolate()->counters()->memcopy_noxmm(), 1);
10311 // SSE2 not supported. Unlikely to happen in practice. 10308 // SSE2 not supported. Unlikely to happen in practice.
10312 __ push(edi); 10309 __ push(edi);
10313 __ push(esi); 10310 __ push(esi);
10314 stack_offset += 2 * kPointerSize; 10311 stack_offset += 2 * kPointerSize;
10315 __ cld(); 10312 __ cld();
10316 Register dst = edi; 10313 Register dst = edi;
10317 Register src = esi; 10314 Register src = esi;
10318 Register count = ecx; 10315 Register count = ecx;
10319 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset)); 10316 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset));
10320 __ mov(src, Operand(esp, stack_offset + kSourceOffset)); 10317 __ mov(src, Operand(esp, stack_offset + kSourceOffset));
(...skipping 26 matching lines...) Expand all
10347 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset)); 10344 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset));
10348 __ pop(esi); 10345 __ pop(esi);
10349 __ pop(edi); 10346 __ pop(edi);
10350 __ ret(0); 10347 __ ret(0);
10351 } 10348 }
10352 10349
10353 CodeDesc desc; 10350 CodeDesc desc;
10354 masm.GetCode(&desc); 10351 masm.GetCode(&desc);
10355 ASSERT(desc.reloc_size == 0); 10352 ASSERT(desc.reloc_size == 0);
10356 10353
10357 CPU::FlushICache(buffer, actual_size); 10354 // Copy the generated code into an executable chunk and return a pointer
10358 return FUNCTION_CAST<OS::MemCopyFunction>(buffer); 10355 // to the first instruction in it as a C++ function pointer.
10356 LargeObjectChunk* chunk = LargeObjectChunk::New(desc.instr_size, EXECUTABLE);
10357 if (chunk == NULL) return &MemCopyWrapper;
10358 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size);
10359 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size);
10360 return FUNCTION_CAST<OS::MemCopyFunction>(chunk->GetStartAddress());
10359 } 10361 }
10360 10362
10361 #undef __ 10363 #undef __
10362 10364
10363 } } // namespace v8::internal 10365 } } // namespace v8::internal
10364 10366
10365 #endif // V8_TARGET_ARCH_IA32 10367 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/cpu-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698