| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 | 886 |
| 887 void LCodeGen::DoMulI(LMulI* instr) { | 887 void LCodeGen::DoMulI(LMulI* instr) { |
| 888 Register left = ToRegister(instr->InputAt(0)); | 888 Register left = ToRegister(instr->InputAt(0)); |
| 889 LOperand* right = instr->InputAt(1); | 889 LOperand* right = instr->InputAt(1); |
| 890 | 890 |
| 891 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 891 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 892 __ mov(ToRegister(instr->TempAt(0)), left); | 892 __ mov(ToRegister(instr->TempAt(0)), left); |
| 893 } | 893 } |
| 894 | 894 |
| 895 if (right->IsConstantOperand()) { | 895 if (right->IsConstantOperand()) { |
| 896 __ imul(left, left, ToInteger32(LConstantOperand::cast(right))); | 896 // Try strength reductions on the multiplication. |
| 897 // All replacement instructions are at most as long as the imul |
| 898 // and have better latency. |
| 899 int constant = ToInteger32(LConstantOperand::cast(right)); |
| 900 if (constant == -1) { |
| 901 __ neg(left); |
| 902 } else if (constant == 0) { |
| 903 __ xor_(left, Operand(left)); |
| 904 } else if (constant == 2) { |
| 905 __ add(left, Operand(left)); |
| 906 } else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 907 // If we know that the multiplication can't overflow, it's safe to |
| 908 // use instructions that don't set the overflow flag for the |
| 909 // multiplication. |
| 910 switch (constant) { |
| 911 case 1: |
| 912 // Do nothing. |
| 913 break; |
| 914 case 3: |
| 915 __ lea(left, Operand(left, left, times_2, 0)); |
| 916 break; |
| 917 case 4: |
| 918 __ shl(left, 2); |
| 919 break; |
| 920 case 5: |
| 921 __ lea(left, Operand(left, left, times_4, 0)); |
| 922 break; |
| 923 case 8: |
| 924 __ shl(left, 3); |
| 925 break; |
| 926 case 9: |
| 927 __ lea(left, Operand(left, left, times_8, 0)); |
| 928 break; |
| 929 case 16: |
| 930 __ shl(left, 4); |
| 931 break; |
| 932 default: |
| 933 __ imul(left, left, constant); |
| 934 break; |
| 935 } |
| 936 } else { |
| 937 __ imul(left, left, constant); |
| 938 } |
| 897 } else { | 939 } else { |
| 898 __ imul(left, ToOperand(right)); | 940 __ imul(left, ToOperand(right)); |
| 899 } | 941 } |
| 900 | 942 |
| 901 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 943 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 902 DeoptimizeIf(overflow, instr->environment()); | 944 DeoptimizeIf(overflow, instr->environment()); |
| 903 } | 945 } |
| 904 | 946 |
| 905 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 947 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 906 // Bail out if the result is supposed to be negative zero. | 948 // Bail out if the result is supposed to be negative zero. |
| (...skipping 2328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3235 | 3277 |
| 3236 // Heap number map check. | 3278 // Heap number map check. |
| 3237 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3279 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 3238 Factory::heap_number_map()); | 3280 Factory::heap_number_map()); |
| 3239 __ j(equal, &heap_number); | 3281 __ j(equal, &heap_number); |
| 3240 | 3282 |
| 3241 __ cmp(input_reg, Factory::undefined_value()); | 3283 __ cmp(input_reg, Factory::undefined_value()); |
| 3242 DeoptimizeIf(not_equal, env); | 3284 DeoptimizeIf(not_equal, env); |
| 3243 | 3285 |
| 3244 // Convert undefined to NaN. | 3286 // Convert undefined to NaN. |
| 3245 __ push(input_reg); | 3287 ExternalReference nan = ExternalReference::address_of_nan(); |
| 3246 __ mov(input_reg, Factory::nan_value()); | 3288 __ movdbl(result_reg, Operand::StaticVariable(nan)); |
| 3247 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | |
| 3248 __ pop(input_reg); | |
| 3249 __ jmp(&done); | 3289 __ jmp(&done); |
| 3250 | 3290 |
| 3251 // Heap number to XMM conversion. | 3291 // Heap number to XMM conversion. |
| 3252 __ bind(&heap_number); | 3292 __ bind(&heap_number); |
| 3253 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3293 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3254 __ jmp(&done); | 3294 __ jmp(&done); |
| 3255 | 3295 |
| 3256 // Smi to XMM conversion | 3296 // Smi to XMM conversion |
| 3257 __ bind(&load_smi); | 3297 __ bind(&load_smi); |
| 3258 __ SmiUntag(input_reg); // Untag smi before converting to float. | 3298 __ SmiUntag(input_reg); // Untag smi before converting to float. |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3498 __ and_(result_reg, 1); | 3538 __ and_(result_reg, 1); |
| 3499 DeoptimizeIf(not_zero, instr->environment()); | 3539 DeoptimizeIf(not_zero, instr->environment()); |
| 3500 } | 3540 } |
| 3501 __ bind(&done); | 3541 __ bind(&done); |
| 3502 } | 3542 } |
| 3503 } | 3543 } |
| 3504 | 3544 |
| 3505 | 3545 |
| 3506 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 3546 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
| 3507 LOperand* input = instr->InputAt(0); | 3547 LOperand* input = instr->InputAt(0); |
| 3508 ASSERT(input->IsRegister()); | |
| 3509 __ test(ToRegister(input), Immediate(kSmiTagMask)); | 3548 __ test(ToRegister(input), Immediate(kSmiTagMask)); |
| 3510 DeoptimizeIf(instr->condition(), instr->environment()); | 3549 DeoptimizeIf(not_zero, instr->environment()); |
| 3550 } |
| 3551 |
| 3552 |
| 3553 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { |
| 3554 LOperand* input = instr->InputAt(0); |
| 3555 __ test(ToRegister(input), Immediate(kSmiTagMask)); |
| 3556 DeoptimizeIf(zero, instr->environment()); |
| 3511 } | 3557 } |
| 3512 | 3558 |
| 3513 | 3559 |
| 3514 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 3560 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
| 3515 Register input = ToRegister(instr->InputAt(0)); | 3561 Register input = ToRegister(instr->InputAt(0)); |
| 3516 Register temp = ToRegister(instr->TempAt(0)); | 3562 Register temp = ToRegister(instr->TempAt(0)); |
| 3517 InstanceType first = instr->hydrogen()->first(); | 3563 InstanceType first = instr->hydrogen()->first(); |
| 3518 InstanceType last = instr->hydrogen()->last(); | 3564 InstanceType last = instr->hydrogen()->last(); |
| 3519 | 3565 |
| 3520 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); | 3566 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3694 __ mov(FieldOperand(eax, size - kPointerSize), edx); | 3740 __ mov(FieldOperand(eax, size - kPointerSize), edx); |
| 3695 } | 3741 } |
| 3696 } | 3742 } |
| 3697 | 3743 |
| 3698 | 3744 |
| 3699 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 3745 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
| 3700 // Use the fast case closure allocation code that allocates in new | 3746 // Use the fast case closure allocation code that allocates in new |
| 3701 // space for nested functions that don't need literals cloning. | 3747 // space for nested functions that don't need literals cloning. |
| 3702 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); | 3748 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); |
| 3703 bool pretenure = instr->hydrogen()->pretenure(); | 3749 bool pretenure = instr->hydrogen()->pretenure(); |
| 3704 if (shared_info->num_literals() == 0 && !pretenure) { | 3750 if (!pretenure && shared_info->num_literals() == 0) { |
| 3705 FastNewClosureStub stub; | 3751 FastNewClosureStub stub( |
| 3752 shared_info->strict_mode() ? kStrictMode : kNonStrictMode); |
| 3706 __ push(Immediate(shared_info)); | 3753 __ push(Immediate(shared_info)); |
| 3707 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 3754 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); |
| 3708 } else { | 3755 } else { |
| 3709 __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); | 3756 __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 3710 __ push(Immediate(shared_info)); | 3757 __ push(Immediate(shared_info)); |
| 3711 __ push(Immediate(pretenure | 3758 __ push(Immediate(pretenure |
| 3712 ? Factory::true_value() | 3759 ? Factory::true_value() |
| 3713 : Factory::false_value())); | 3760 : Factory::false_value())); |
| 3714 CallRuntime(Runtime::kNewClosure, 3, instr, false); | 3761 CallRuntime(Runtime::kNewClosure, 3, instr, false); |
| 3715 } | 3762 } |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3946 ASSERT(osr_pc_offset_ == -1); | 3993 ASSERT(osr_pc_offset_ == -1); |
| 3947 osr_pc_offset_ = masm()->pc_offset(); | 3994 osr_pc_offset_ = masm()->pc_offset(); |
| 3948 } | 3995 } |
| 3949 | 3996 |
| 3950 | 3997 |
| 3951 #undef __ | 3998 #undef __ |
| 3952 | 3999 |
| 3953 } } // namespace v8::internal | 4000 } } // namespace v8::internal |
| 3954 | 4001 |
| 3955 #endif // V8_TARGET_ARCH_IA32 | 4002 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |