| 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 2325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3232 | 3274 |
| 3233 // Heap number map check. | 3275 // Heap number map check. |
| 3234 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3276 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 3235 factory()->heap_number_map()); | 3277 factory()->heap_number_map()); |
| 3236 __ j(equal, &heap_number); | 3278 __ j(equal, &heap_number); |
| 3237 | 3279 |
| 3238 __ cmp(input_reg, factory()->undefined_value()); | 3280 __ cmp(input_reg, factory()->undefined_value()); |
| 3239 DeoptimizeIf(not_equal, env); | 3281 DeoptimizeIf(not_equal, env); |
| 3240 | 3282 |
| 3241 // Convert undefined to NaN. | 3283 // Convert undefined to NaN. |
| 3242 __ push(input_reg); | 3284 ExternalReference nan = ExternalReference::address_of_nan(); |
| 3243 __ mov(input_reg, factory()->nan_value()); | 3285 __ movdbl(result_reg, Operand::StaticVariable(nan)); |
| 3244 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | |
| 3245 __ pop(input_reg); | |
| 3246 __ jmp(&done); | 3286 __ jmp(&done); |
| 3247 | 3287 |
| 3248 // Heap number to XMM conversion. | 3288 // Heap number to XMM conversion. |
| 3249 __ bind(&heap_number); | 3289 __ bind(&heap_number); |
| 3250 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3290 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3251 __ jmp(&done); | 3291 __ jmp(&done); |
| 3252 | 3292 |
| 3253 // Smi to XMM conversion | 3293 // Smi to XMM conversion |
| 3254 __ bind(&load_smi); | 3294 __ bind(&load_smi); |
| 3255 __ SmiUntag(input_reg); // Untag smi before converting to float. | 3295 __ SmiUntag(input_reg); // Untag smi before converting to float. |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3495 __ and_(result_reg, 1); | 3535 __ and_(result_reg, 1); |
| 3496 DeoptimizeIf(not_zero, instr->environment()); | 3536 DeoptimizeIf(not_zero, instr->environment()); |
| 3497 } | 3537 } |
| 3498 __ bind(&done); | 3538 __ bind(&done); |
| 3499 } | 3539 } |
| 3500 } | 3540 } |
| 3501 | 3541 |
| 3502 | 3542 |
| 3503 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 3543 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
| 3504 LOperand* input = instr->InputAt(0); | 3544 LOperand* input = instr->InputAt(0); |
| 3505 ASSERT(input->IsRegister()); | |
| 3506 __ test(ToRegister(input), Immediate(kSmiTagMask)); | 3545 __ test(ToRegister(input), Immediate(kSmiTagMask)); |
| 3507 DeoptimizeIf(instr->condition(), instr->environment()); | 3546 DeoptimizeIf(not_zero, instr->environment()); |
| 3547 } |
| 3548 |
| 3549 |
| 3550 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { |
| 3551 LOperand* input = instr->InputAt(0); |
| 3552 __ test(ToRegister(input), Immediate(kSmiTagMask)); |
| 3553 DeoptimizeIf(zero, instr->environment()); |
| 3508 } | 3554 } |
| 3509 | 3555 |
| 3510 | 3556 |
| 3511 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 3557 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
| 3512 Register input = ToRegister(instr->InputAt(0)); | 3558 Register input = ToRegister(instr->InputAt(0)); |
| 3513 Register temp = ToRegister(instr->TempAt(0)); | 3559 Register temp = ToRegister(instr->TempAt(0)); |
| 3514 InstanceType first = instr->hydrogen()->first(); | 3560 InstanceType first = instr->hydrogen()->first(); |
| 3515 InstanceType last = instr->hydrogen()->last(); | 3561 InstanceType last = instr->hydrogen()->last(); |
| 3516 | 3562 |
| 3517 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); | 3563 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3691 __ mov(FieldOperand(eax, size - kPointerSize), edx); | 3737 __ mov(FieldOperand(eax, size - kPointerSize), edx); |
| 3692 } | 3738 } |
| 3693 } | 3739 } |
| 3694 | 3740 |
| 3695 | 3741 |
| 3696 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 3742 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
| 3697 // Use the fast case closure allocation code that allocates in new | 3743 // Use the fast case closure allocation code that allocates in new |
| 3698 // space for nested functions that don't need literals cloning. | 3744 // space for nested functions that don't need literals cloning. |
| 3699 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); | 3745 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); |
| 3700 bool pretenure = instr->hydrogen()->pretenure(); | 3746 bool pretenure = instr->hydrogen()->pretenure(); |
| 3701 if (shared_info->num_literals() == 0 && !pretenure) { | 3747 if (!pretenure && shared_info->num_literals() == 0) { |
| 3702 FastNewClosureStub stub; | 3748 FastNewClosureStub stub( |
| 3749 shared_info->strict_mode() ? kStrictMode : kNonStrictMode); |
| 3703 __ push(Immediate(shared_info)); | 3750 __ push(Immediate(shared_info)); |
| 3704 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 3751 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); |
| 3705 } else { | 3752 } else { |
| 3706 __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); | 3753 __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 3707 __ push(Immediate(shared_info)); | 3754 __ push(Immediate(shared_info)); |
| 3708 __ push(Immediate(pretenure | 3755 __ push(Immediate(pretenure |
| 3709 ? factory()->true_value() | 3756 ? factory()->true_value() |
| 3710 : factory()->false_value())); | 3757 : factory()->false_value())); |
| 3711 CallRuntime(Runtime::kNewClosure, 3, instr, false); | 3758 CallRuntime(Runtime::kNewClosure, 3, instr, false); |
| 3712 } | 3759 } |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3943 ASSERT(osr_pc_offset_ == -1); | 3990 ASSERT(osr_pc_offset_ == -1); |
| 3944 osr_pc_offset_ = masm()->pc_offset(); | 3991 osr_pc_offset_ = masm()->pc_offset(); |
| 3945 } | 3992 } |
| 3946 | 3993 |
| 3947 | 3994 |
| 3948 #undef __ | 3995 #undef __ |
| 3949 | 3996 |
| 3950 } } // namespace v8::internal | 3997 } } // namespace v8::internal |
| 3951 | 3998 |
| 3952 #endif // V8_TARGET_ARCH_IA32 | 3999 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |