| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 descriptor->deoptimization_handler_ = NULL; | 59 descriptor->deoptimization_handler_ = NULL; |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 void NumberToStringStub::InitializeInterfaceDescriptor( | 63 void NumberToStringStub::InitializeInterfaceDescriptor( |
| 64 Isolate* isolate, | 64 Isolate* isolate, |
| 65 CodeStubInterfaceDescriptor* descriptor) { | 65 CodeStubInterfaceDescriptor* descriptor) { |
| 66 static Register registers[] = { a0 }; | 66 static Register registers[] = { a0 }; |
| 67 descriptor->register_param_count_ = 1; | 67 descriptor->register_param_count_ = 1; |
| 68 descriptor->register_params_ = registers; | 68 descriptor->register_params_ = registers; |
| 69 descriptor->deoptimization_handler_ = NULL; | 69 descriptor->deoptimization_handler_ = |
| 70 Runtime::FunctionForId(Runtime::kNumberToString)->entry; |
| 70 } | 71 } |
| 71 | 72 |
| 72 | 73 |
| 73 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | 74 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( |
| 74 Isolate* isolate, | 75 Isolate* isolate, |
| 75 CodeStubInterfaceDescriptor* descriptor) { | 76 CodeStubInterfaceDescriptor* descriptor) { |
| 76 static Register registers[] = { a3, a2, a1 }; | 77 static Register registers[] = { a3, a2, a1 }; |
| 77 descriptor->register_param_count_ = 3; | 78 descriptor->register_param_count_ = 3; |
| 78 descriptor->register_params_ = registers; | 79 descriptor->register_params_ = registers; |
| 79 descriptor->deoptimization_handler_ = | 80 descriptor->deoptimization_handler_ = |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 CodeStubInterfaceDescriptor* descriptor, | 175 CodeStubInterfaceDescriptor* descriptor, |
| 175 int constant_stack_parameter_count) { | 176 int constant_stack_parameter_count) { |
| 176 // register state | 177 // register state |
| 177 // a0 -- number of arguments | 178 // a0 -- number of arguments |
| 178 // a1 -- function | 179 // a1 -- function |
| 179 // a2 -- type info cell with elements kind | 180 // a2 -- type info cell with elements kind |
| 180 static Register registers[] = { a1, a2 }; | 181 static Register registers[] = { a1, a2 }; |
| 181 descriptor->register_param_count_ = 2; | 182 descriptor->register_param_count_ = 2; |
| 182 if (constant_stack_parameter_count != 0) { | 183 if (constant_stack_parameter_count != 0) { |
| 183 // stack param count needs (constructor pointer, and single argument) | 184 // stack param count needs (constructor pointer, and single argument) |
| 184 descriptor->stack_parameter_count_ = &a0; | 185 descriptor->stack_parameter_count_ = a0; |
| 185 } | 186 } |
| 186 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 187 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
| 187 descriptor->register_params_ = registers; | 188 descriptor->register_params_ = registers; |
| 188 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 189 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
| 189 descriptor->deoptimization_handler_ = | 190 descriptor->deoptimization_handler_ = |
| 190 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; | 191 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; |
| 191 } | 192 } |
| 192 | 193 |
| 193 | 194 |
| 194 static void InitializeInternalArrayConstructorDescriptor( | 195 static void InitializeInternalArrayConstructorDescriptor( |
| 195 Isolate* isolate, | 196 Isolate* isolate, |
| 196 CodeStubInterfaceDescriptor* descriptor, | 197 CodeStubInterfaceDescriptor* descriptor, |
| 197 int constant_stack_parameter_count) { | 198 int constant_stack_parameter_count) { |
| 198 // register state | 199 // register state |
| 199 // a0 -- number of arguments | 200 // a0 -- number of arguments |
| 200 // a1 -- constructor function | 201 // a1 -- constructor function |
| 201 static Register registers[] = { a1 }; | 202 static Register registers[] = { a1 }; |
| 202 descriptor->register_param_count_ = 1; | 203 descriptor->register_param_count_ = 1; |
| 203 | 204 |
| 204 if (constant_stack_parameter_count != 0) { | 205 if (constant_stack_parameter_count != 0) { |
| 205 // Stack param count needs (constructor pointer, and single argument). | 206 // Stack param count needs (constructor pointer, and single argument). |
| 206 descriptor->stack_parameter_count_ = &a0; | 207 descriptor->stack_parameter_count_ = a0; |
| 207 } | 208 } |
| 208 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 209 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
| 209 descriptor->register_params_ = registers; | 210 descriptor->register_params_ = registers; |
| 210 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 211 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
| 211 descriptor->deoptimization_handler_ = | 212 descriptor->deoptimization_handler_ = |
| 212 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; | 213 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; |
| 213 } | 214 } |
| 214 | 215 |
| 215 | 216 |
| 216 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 217 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 int double_offset = offset(); | 540 int double_offset = offset(); |
| 540 // Account for saved regs if input is sp. | 541 // Account for saved regs if input is sp. |
| 541 if (input_reg.is(sp)) double_offset += 3 * kPointerSize; | 542 if (input_reg.is(sp)) double_offset += 3 * kPointerSize; |
| 542 | 543 |
| 543 Register scratch = | 544 Register scratch = |
| 544 GetRegisterThatIsNotOneOf(input_reg, result_reg); | 545 GetRegisterThatIsNotOneOf(input_reg, result_reg); |
| 545 Register scratch2 = | 546 Register scratch2 = |
| 546 GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch); | 547 GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch); |
| 547 Register scratch3 = | 548 Register scratch3 = |
| 548 GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch, scratch2); | 549 GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch, scratch2); |
| 549 DoubleRegister double_scratch = kLithiumScratchDouble.low(); | 550 DoubleRegister double_scratch = kLithiumScratchDouble; |
| 550 DoubleRegister double_input = f12; | |
| 551 | 551 |
| 552 __ Push(scratch, scratch2, scratch3); | 552 __ Push(scratch, scratch2, scratch3); |
| 553 | 553 |
| 554 __ ldc1(double_input, MemOperand(input_reg, double_offset)); | 554 if (!skip_fastpath()) { |
| 555 // Load double input. |
| 556 __ ldc1(double_scratch, MemOperand(input_reg, double_offset)); |
| 555 | 557 |
| 556 if (!skip_fastpath()) { | |
| 557 // Clear cumulative exception flags and save the FCSR. | 558 // Clear cumulative exception flags and save the FCSR. |
| 558 __ cfc1(scratch2, FCSR); | 559 __ cfc1(scratch2, FCSR); |
| 559 __ ctc1(zero_reg, FCSR); | 560 __ ctc1(zero_reg, FCSR); |
| 561 |
| 560 // Try a conversion to a signed integer. | 562 // Try a conversion to a signed integer. |
| 561 __ trunc_w_d(double_scratch, double_input); | 563 __ Trunc_w_d(double_scratch, double_scratch); |
| 564 // Move the converted value into the result register. |
| 562 __ mfc1(result_reg, double_scratch); | 565 __ mfc1(result_reg, double_scratch); |
| 566 |
| 563 // Retrieve and restore the FCSR. | 567 // Retrieve and restore the FCSR. |
| 564 __ cfc1(scratch, FCSR); | 568 __ cfc1(scratch, FCSR); |
| 565 __ ctc1(scratch2, FCSR); | 569 __ ctc1(scratch2, FCSR); |
| 570 |
| 566 // Check for overflow and NaNs. | 571 // Check for overflow and NaNs. |
| 567 __ And( | 572 __ And( |
| 568 scratch, scratch, | 573 scratch, scratch, |
| 569 kFCSROverflowFlagMask | kFCSRUnderflowFlagMask | 574 kFCSROverflowFlagMask | kFCSRUnderflowFlagMask |
| 570 | kFCSRInvalidOpFlagMask); | 575 | kFCSRInvalidOpFlagMask); |
| 571 // If we had no exceptions we are done. | 576 // If we had no exceptions we are done. |
| 572 __ Branch(&done, eq, scratch, Operand(zero_reg)); | 577 __ Branch(&done, eq, scratch, Operand(zero_reg)); |
| 573 } | 578 } |
| 574 | 579 |
| 575 // Load the double value and perform a manual truncation. | 580 // Load the double value and perform a manual truncation. |
| 576 Register input_high = scratch2; | 581 Register input_high = scratch2; |
| 577 Register input_low = scratch3; | 582 Register input_low = scratch3; |
| 578 __ Move(input_low, input_high, double_input); | 583 |
| 584 __ lw(input_low, MemOperand(input_reg, double_offset)); |
| 585 __ lw(input_high, MemOperand(input_reg, double_offset + kIntSize)); |
| 579 | 586 |
| 580 Label normal_exponent, restore_sign; | 587 Label normal_exponent, restore_sign; |
| 581 // Extract the biased exponent in result. | 588 // Extract the biased exponent in result. |
| 582 __ Ext(result_reg, | 589 __ Ext(result_reg, |
| 583 input_high, | 590 input_high, |
| 584 HeapNumber::kExponentShift, | 591 HeapNumber::kExponentShift, |
| 585 HeapNumber::kExponentBits); | 592 HeapNumber::kExponentBits); |
| 586 | 593 |
| 587 // Check for Infinity and NaNs, which should return 0. | 594 // Check for Infinity and NaNs, which should return 0. |
| 588 __ Subu(scratch, result_reg, HeapNumber::kExponentMask); | 595 __ Subu(scratch, result_reg, HeapNumber::kExponentMask); |
| (...skipping 4178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4767 // t2: first character of result. | 4774 // t2: first character of result. |
| 4768 StringHelper::GenerateCopyCharacters(masm, t2, t3, a2, t0, false); | 4775 StringHelper::GenerateCopyCharacters(masm, t2, t3, a2, t0, false); |
| 4769 // t2: next character of result. | 4776 // t2: next character of result. |
| 4770 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, false); | 4777 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, false); |
| 4771 | 4778 |
| 4772 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); | 4779 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); |
| 4773 __ DropAndRet(2); | 4780 __ DropAndRet(2); |
| 4774 | 4781 |
| 4775 // Just jump to runtime to add the two strings. | 4782 // Just jump to runtime to add the two strings. |
| 4776 __ bind(&call_runtime); | 4783 __ bind(&call_runtime); |
| 4777 if ((flags_ & STRING_ADD_ERECT_FRAME) != 0) { | 4784 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
| 4778 GenerateRegisterArgsPop(masm); | |
| 4779 // Build a frame. | |
| 4780 { | |
| 4781 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 4782 GenerateRegisterArgsPush(masm); | |
| 4783 __ CallRuntime(Runtime::kStringAdd, 2); | |
| 4784 } | |
| 4785 __ Ret(); | |
| 4786 } else { | |
| 4787 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | |
| 4788 } | |
| 4789 | 4785 |
| 4790 if (call_builtin.is_linked()) { | 4786 if (call_builtin.is_linked()) { |
| 4791 __ bind(&call_builtin); | 4787 __ bind(&call_builtin); |
| 4792 if ((flags_ & STRING_ADD_ERECT_FRAME) != 0) { | 4788 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); |
| 4793 GenerateRegisterArgsPop(masm); | |
| 4794 // Build a frame. | |
| 4795 { | |
| 4796 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 4797 GenerateRegisterArgsPush(masm); | |
| 4798 __ InvokeBuiltin(builtin_id, CALL_FUNCTION); | |
| 4799 } | |
| 4800 __ Ret(); | |
| 4801 } else { | |
| 4802 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); | |
| 4803 } | |
| 4804 } | 4789 } |
| 4805 } | 4790 } |
| 4806 | 4791 |
| 4807 | 4792 |
| 4808 void StringAddStub::GenerateRegisterArgsPush(MacroAssembler* masm) { | 4793 void StringAddStub::GenerateRegisterArgsPush(MacroAssembler* masm) { |
| 4809 __ push(a0); | 4794 __ push(a0); |
| 4810 __ push(a1); | 4795 __ push(a1); |
| 4811 } | 4796 } |
| 4812 | 4797 |
| 4813 | 4798 |
| (...skipping 1417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6231 __ bind(&fast_elements_case); | 6216 __ bind(&fast_elements_case); |
| 6232 GenerateCase(masm, FAST_ELEMENTS); | 6217 GenerateCase(masm, FAST_ELEMENTS); |
| 6233 } | 6218 } |
| 6234 | 6219 |
| 6235 | 6220 |
| 6236 #undef __ | 6221 #undef __ |
| 6237 | 6222 |
| 6238 } } // namespace v8::internal | 6223 } } // namespace v8::internal |
| 6239 | 6224 |
| 6240 #endif // V8_TARGET_ARCH_MIPS | 6225 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |