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 3248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3259 Register scratch2, | 3259 Register scratch2, |
3260 Register heap_number_map, | 3260 Register heap_number_map, |
3261 Label* need_gc, | 3261 Label* need_gc, |
3262 TaggingMode tagging_mode) { | 3262 TaggingMode tagging_mode) { |
3263 // Allocate an object in the heap for the heap number and tag it as a heap | 3263 // Allocate an object in the heap for the heap number and tag it as a heap |
3264 // object. | 3264 // object. |
3265 Allocate(HeapNumber::kSize, result, scratch1, scratch2, need_gc, | 3265 Allocate(HeapNumber::kSize, result, scratch1, scratch2, need_gc, |
3266 tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS); | 3266 tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS); |
3267 | 3267 |
3268 // Store heap number map in the allocated object. | 3268 // Store heap number map in the allocated object. |
3269 AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); | 3269 AssertIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
3270 if (tagging_mode == TAG_RESULT) { | 3270 if (tagging_mode == TAG_RESULT) { |
3271 sw(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); | 3271 sw(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); |
3272 } else { | 3272 } else { |
3273 sw(heap_number_map, MemOperand(result, HeapObject::kMapOffset)); | 3273 sw(heap_number_map, MemOperand(result, HeapObject::kMapOffset)); |
3274 } | 3274 } |
3275 } | 3275 } |
3276 | 3276 |
3277 | 3277 |
3278 void MacroAssembler::AllocateHeapNumberWithValue(Register result, | 3278 void MacroAssembler::AllocateHeapNumberWithValue(Register result, |
3279 FPURegister value, | 3279 FPURegister value, |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3421 Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); | 3421 Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); |
3422 } | 3422 } |
3423 | 3423 |
3424 | 3424 |
3425 void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, | 3425 void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, |
3426 Register key_reg, | 3426 Register key_reg, |
3427 Register elements_reg, | 3427 Register elements_reg, |
3428 Register scratch1, | 3428 Register scratch1, |
3429 Register scratch2, | 3429 Register scratch2, |
3430 Register scratch3, | 3430 Register scratch3, |
3431 Register scratch4, | |
3432 Label* fail, | 3431 Label* fail, |
3433 int elements_offset) { | 3432 int elements_offset) { |
3434 Label smi_value, maybe_nan, have_double_value, is_nan, done; | 3433 Label smi_value, maybe_nan, have_double_value, is_nan, done; |
3435 Register mantissa_reg = scratch2; | 3434 Register mantissa_reg = scratch2; |
3436 Register exponent_reg = scratch3; | 3435 Register exponent_reg = scratch3; |
3437 | 3436 |
3438 // Handle smi values specially. | 3437 // Handle smi values specially. |
3439 JumpIfSmi(value_reg, &smi_value); | 3438 JumpIfSmi(value_reg, &smi_value); |
3440 | 3439 |
3441 // Ensure that the object is a heap number | 3440 // Ensure that the object is a heap number |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3478 jmp(&have_double_value); | 3477 jmp(&have_double_value); |
3479 | 3478 |
3480 bind(&smi_value); | 3479 bind(&smi_value); |
3481 Addu(scratch1, elements_reg, | 3480 Addu(scratch1, elements_reg, |
3482 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - | 3481 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - |
3483 elements_offset)); | 3482 elements_offset)); |
3484 sll(scratch2, key_reg, kDoubleSizeLog2 - kSmiTagSize); | 3483 sll(scratch2, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
3485 Addu(scratch1, scratch1, scratch2); | 3484 Addu(scratch1, scratch1, scratch2); |
3486 // scratch1 is now effective address of the double element | 3485 // scratch1 is now effective address of the double element |
3487 | 3486 |
3488 FloatingPointHelper::Destination destination; | |
3489 destination = FloatingPointHelper::kFPURegisters; | |
3490 | |
3491 Register untagged_value = elements_reg; | 3487 Register untagged_value = elements_reg; |
3492 SmiUntag(untagged_value, value_reg); | 3488 SmiUntag(untagged_value, value_reg); |
3493 FloatingPointHelper::ConvertIntToDouble(this, | 3489 mtc1(untagged_value, f2); |
3494 untagged_value, | 3490 cvt_d_w(f0, f2); |
3495 destination, | 3491 sdc1(f0, MemOperand(scratch1, 0)); |
3496 f0, | |
3497 mantissa_reg, | |
3498 exponent_reg, | |
3499 scratch4, | |
3500 f2); | |
3501 if (destination == FloatingPointHelper::kFPURegisters) { | |
3502 sdc1(f0, MemOperand(scratch1, 0)); | |
3503 } else { | |
3504 sw(mantissa_reg, MemOperand(scratch1, 0)); | |
3505 sw(exponent_reg, MemOperand(scratch1, Register::kSizeInBytes)); | |
3506 } | |
3507 bind(&done); | 3492 bind(&done); |
3508 } | 3493 } |
3509 | 3494 |
3510 | 3495 |
3511 void MacroAssembler::CompareMapAndBranch(Register obj, | 3496 void MacroAssembler::CompareMapAndBranch(Register obj, |
3512 Register scratch, | 3497 Register scratch, |
3513 Handle<Map> map, | 3498 Handle<Map> map, |
3514 Label* early_success, | 3499 Label* early_success, |
3515 Condition cond, | 3500 Condition cond, |
3516 Label* branch_to) { | 3501 Label* branch_to) { |
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4393 // ----------------------------------------------------------------------------- | 4378 // ----------------------------------------------------------------------------- |
4394 // Debugging. | 4379 // Debugging. |
4395 | 4380 |
4396 void MacroAssembler::Assert(Condition cc, BailoutReason reason, | 4381 void MacroAssembler::Assert(Condition cc, BailoutReason reason, |
4397 Register rs, Operand rt) { | 4382 Register rs, Operand rt) { |
4398 if (emit_debug_code()) | 4383 if (emit_debug_code()) |
4399 Check(cc, reason, rs, rt); | 4384 Check(cc, reason, rs, rt); |
4400 } | 4385 } |
4401 | 4386 |
4402 | 4387 |
4403 void MacroAssembler::AssertRegisterIsRoot(Register reg, | |
4404 Heap::RootListIndex index) { | |
4405 if (emit_debug_code()) { | |
4406 LoadRoot(at, index); | |
4407 Check(eq, kRegisterDidNotMatchExpectedRoot, reg, Operand(at)); | |
4408 } | |
4409 } | |
4410 | |
4411 | |
4412 void MacroAssembler::AssertFastElements(Register elements) { | 4388 void MacroAssembler::AssertFastElements(Register elements) { |
4413 if (emit_debug_code()) { | 4389 if (emit_debug_code()) { |
4414 ASSERT(!elements.is(at)); | 4390 ASSERT(!elements.is(at)); |
4415 Label ok; | 4391 Label ok; |
4416 push(elements); | 4392 push(elements); |
4417 lw(elements, FieldMemOperand(elements, HeapObject::kMapOffset)); | 4393 lw(elements, FieldMemOperand(elements, HeapObject::kMapOffset)); |
4418 LoadRoot(at, Heap::kFixedArrayMapRootIndex); | 4394 LoadRoot(at, Heap::kFixedArrayMapRootIndex); |
4419 Branch(&ok, eq, elements, Operand(at)); | 4395 Branch(&ok, eq, elements, Operand(at)); |
4420 LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex); | 4396 LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex); |
4421 Branch(&ok, eq, elements, Operand(at)); | 4397 Branch(&ok, eq, elements, Operand(at)); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4594 Label ok, fail; | 4570 Label ok, fail; |
4595 CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, DO_SMI_CHECK); | 4571 CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, DO_SMI_CHECK); |
4596 Branch(&ok); | 4572 Branch(&ok); |
4597 bind(&fail); | 4573 bind(&fail); |
4598 Abort(kGlobalFunctionsMustHaveInitialMap); | 4574 Abort(kGlobalFunctionsMustHaveInitialMap); |
4599 bind(&ok); | 4575 bind(&ok); |
4600 } | 4576 } |
4601 } | 4577 } |
4602 | 4578 |
4603 | 4579 |
| 4580 void MacroAssembler::ConvertNumberToInt32(Register object, |
| 4581 Register dst, |
| 4582 Register heap_number_map, |
| 4583 Register scratch1, |
| 4584 Register scratch2, |
| 4585 Register scratch3, |
| 4586 FPURegister double_scratch, |
| 4587 Label* not_number) { |
| 4588 Label done; |
| 4589 Label not_in_int32_range; |
| 4590 |
| 4591 UntagAndJumpIfSmi(dst, object, &done); |
| 4592 JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); |
| 4593 ConvertToInt32(object, |
| 4594 dst, |
| 4595 scratch1, |
| 4596 scratch2, |
| 4597 double_scratch, |
| 4598 ¬_in_int32_range); |
| 4599 jmp(&done); |
| 4600 |
| 4601 bind(¬_in_int32_range); |
| 4602 lw(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset)); |
| 4603 lw(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset)); |
| 4604 |
| 4605 EmitOutOfInt32RangeTruncate(dst, |
| 4606 scratch1, |
| 4607 scratch2, |
| 4608 scratch3); |
| 4609 |
| 4610 bind(&done); |
| 4611 } |
| 4612 |
| 4613 |
| 4614 void MacroAssembler::LoadNumber(Register object, |
| 4615 FPURegister dst, |
| 4616 Register heap_number_map, |
| 4617 Register scratch, |
| 4618 Label* not_number) { |
| 4619 Label is_smi, done; |
| 4620 |
| 4621 UntagAndJumpIfSmi(scratch, object, &is_smi); |
| 4622 JumpIfNotHeapNumber(object, heap_number_map, scratch, not_number); |
| 4623 |
| 4624 ldc1(dst, FieldMemOperand(object, HeapNumber::kValueOffset)); |
| 4625 Branch(&done); |
| 4626 |
| 4627 bind(&is_smi); |
| 4628 mtc1(scratch, dst); |
| 4629 cvt_d_w(dst, dst); |
| 4630 |
| 4631 bind(&done); |
| 4632 } |
| 4633 |
| 4634 |
| 4635 void MacroAssembler::LoadNumberAsInt32Double(Register object, |
| 4636 DoubleRegister double_dst, |
| 4637 Register heap_number_map, |
| 4638 Register scratch1, |
| 4639 Register scratch2, |
| 4640 FPURegister double_scratch, |
| 4641 Label* not_int32) { |
| 4642 ASSERT(!scratch1.is(object) && !scratch2.is(object)); |
| 4643 ASSERT(!scratch1.is(scratch2)); |
| 4644 ASSERT(!heap_number_map.is(object) && |
| 4645 !heap_number_map.is(scratch1) && |
| 4646 !heap_number_map.is(scratch2)); |
| 4647 |
| 4648 Label done, obj_is_not_smi; |
| 4649 |
| 4650 UntagAndJumpIfNotSmi(scratch1, object, &obj_is_not_smi); |
| 4651 mtc1(scratch1, double_scratch); |
| 4652 cvt_d_w(double_dst, double_scratch); |
| 4653 Branch(&done); |
| 4654 |
| 4655 bind(&obj_is_not_smi); |
| 4656 JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); |
| 4657 |
| 4658 // Load the number. |
| 4659 // Load the double value. |
| 4660 ldc1(double_dst, FieldMemOperand(object, HeapNumber::kValueOffset)); |
| 4661 |
| 4662 Register except_flag = scratch2; |
| 4663 EmitFPUTruncate(kRoundToZero, |
| 4664 scratch1, |
| 4665 double_dst, |
| 4666 at, |
| 4667 double_scratch, |
| 4668 except_flag, |
| 4669 kCheckForInexactConversion); |
| 4670 |
| 4671 // Jump to not_int32 if the operation did not succeed. |
| 4672 Branch(not_int32, ne, except_flag, Operand(zero_reg)); |
| 4673 bind(&done); |
| 4674 } |
| 4675 |
| 4676 |
| 4677 void MacroAssembler::LoadNumberAsInt32(Register object, |
| 4678 Register dst, |
| 4679 Register heap_number_map, |
| 4680 Register scratch1, |
| 4681 Register scratch2, |
| 4682 FPURegister double_scratch0, |
| 4683 FPURegister double_scratch1, |
| 4684 Label* not_int32) { |
| 4685 ASSERT(!dst.is(object)); |
| 4686 ASSERT(!scratch1.is(object) && !scratch2.is(object)); |
| 4687 ASSERT(!scratch1.is(scratch2)); |
| 4688 |
| 4689 Label done, maybe_undefined; |
| 4690 |
| 4691 UntagAndJumpIfSmi(dst, object, &done); |
| 4692 |
| 4693 JumpIfNotHeapNumber(object, heap_number_map, scratch1, &maybe_undefined); |
| 4694 |
| 4695 // Object is a heap number. |
| 4696 // Convert the floating point value to a 32-bit integer. |
| 4697 // Load the double value. |
| 4698 ldc1(double_scratch0, FieldMemOperand(object, HeapNumber::kValueOffset)); |
| 4699 |
| 4700 Register except_flag = scratch2; |
| 4701 EmitFPUTruncate(kRoundToZero, |
| 4702 dst, |
| 4703 double_scratch0, |
| 4704 scratch1, |
| 4705 double_scratch1, |
| 4706 except_flag, |
| 4707 kCheckForInexactConversion); |
| 4708 |
| 4709 // Jump to not_int32 if the operation did not succeed. |
| 4710 Branch(not_int32, ne, except_flag, Operand(zero_reg)); |
| 4711 Branch(&done); |
| 4712 |
| 4713 bind(&maybe_undefined); |
| 4714 LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 4715 Branch(not_int32, ne, object, Operand(at)); |
| 4716 // |undefined| is truncated to 0. |
| 4717 li(dst, Operand(Smi::FromInt(0))); |
| 4718 // Fall through. |
| 4719 |
| 4720 bind(&done); |
| 4721 } |
| 4722 |
| 4723 |
4604 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 4724 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
4605 addiu(sp, sp, -5 * kPointerSize); | 4725 addiu(sp, sp, -5 * kPointerSize); |
4606 li(t8, Operand(Smi::FromInt(type))); | 4726 li(t8, Operand(Smi::FromInt(type))); |
4607 li(t9, Operand(CodeObject()), CONSTANT_SIZE); | 4727 li(t9, Operand(CodeObject()), CONSTANT_SIZE); |
4608 sw(ra, MemOperand(sp, 4 * kPointerSize)); | 4728 sw(ra, MemOperand(sp, 4 * kPointerSize)); |
4609 sw(fp, MemOperand(sp, 3 * kPointerSize)); | 4729 sw(fp, MemOperand(sp, 3 * kPointerSize)); |
4610 sw(cp, MemOperand(sp, 2 * kPointerSize)); | 4730 sw(cp, MemOperand(sp, 2 * kPointerSize)); |
4611 sw(t8, MemOperand(sp, 1 * kPointerSize)); | 4731 sw(t8, MemOperand(sp, 1 * kPointerSize)); |
4612 sw(t9, MemOperand(sp, 0 * kPointerSize)); | 4732 sw(t9, MemOperand(sp, 0 * kPointerSize)); |
4613 addiu(fp, sp, 3 * kPointerSize); | 4733 addiu(fp, sp, 3 * kPointerSize); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4913 Check(ne, kOperandIsASmiAndNotAName, t0, Operand(zero_reg)); | 5033 Check(ne, kOperandIsASmiAndNotAName, t0, Operand(zero_reg)); |
4914 push(object); | 5034 push(object); |
4915 lw(object, FieldMemOperand(object, HeapObject::kMapOffset)); | 5035 lw(object, FieldMemOperand(object, HeapObject::kMapOffset)); |
4916 lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset)); | 5036 lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset)); |
4917 Check(le, kOperandIsNotAName, object, Operand(LAST_NAME_TYPE)); | 5037 Check(le, kOperandIsNotAName, object, Operand(LAST_NAME_TYPE)); |
4918 pop(object); | 5038 pop(object); |
4919 } | 5039 } |
4920 } | 5040 } |
4921 | 5041 |
4922 | 5042 |
4923 void MacroAssembler::AssertRootValue(Register src, | 5043 void MacroAssembler::AssertIsRoot(Register reg, Heap::RootListIndex index) { |
4924 Heap::RootListIndex root_value_index, | |
4925 BailoutReason reason) { | |
4926 if (emit_debug_code()) { | 5044 if (emit_debug_code()) { |
4927 ASSERT(!src.is(at)); | 5045 ASSERT(!reg.is(at)); |
4928 LoadRoot(at, root_value_index); | 5046 LoadRoot(at, index); |
4929 Check(eq, reason, src, Operand(at)); | 5047 Check(eq, kHeapNumberMapRegisterClobbered, reg, Operand(at)); |
4930 } | 5048 } |
4931 } | 5049 } |
4932 | 5050 |
4933 | 5051 |
4934 void MacroAssembler::JumpIfNotHeapNumber(Register object, | 5052 void MacroAssembler::JumpIfNotHeapNumber(Register object, |
4935 Register heap_number_map, | 5053 Register heap_number_map, |
4936 Register scratch, | 5054 Register scratch, |
4937 Label* on_not_heap_number) { | 5055 Label* on_not_heap_number) { |
4938 lw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); | 5056 lw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
4939 AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); | 5057 AssertIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
4940 Branch(on_not_heap_number, ne, scratch, Operand(heap_number_map)); | 5058 Branch(on_not_heap_number, ne, scratch, Operand(heap_number_map)); |
4941 } | 5059 } |
4942 | 5060 |
4943 | 5061 |
4944 void MacroAssembler::JumpIfNonSmisNotBothSequentialAsciiStrings( | 5062 void MacroAssembler::JumpIfNonSmisNotBothSequentialAsciiStrings( |
4945 Register first, | 5063 Register first, |
4946 Register second, | 5064 Register second, |
4947 Register scratch1, | 5065 Register scratch1, |
4948 Register scratch2, | 5066 Register scratch2, |
4949 Label* failure) { | 5067 Label* failure) { |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5584 opcode == BGTZL); | 5702 opcode == BGTZL); |
5585 opcode = (cond == eq) ? BEQ : BNE; | 5703 opcode = (cond == eq) ? BEQ : BNE; |
5586 instr = (instr & ~kOpcodeMask) | opcode; | 5704 instr = (instr & ~kOpcodeMask) | opcode; |
5587 masm_.emit(instr); | 5705 masm_.emit(instr); |
5588 } | 5706 } |
5589 | 5707 |
5590 | 5708 |
5591 } } // namespace v8::internal | 5709 } } // namespace v8::internal |
5592 | 5710 |
5593 #endif // V8_TARGET_ARCH_MIPS | 5711 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |