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

Side by Side Diff: src/crankshaft/mips/lithium-codegen-mips.cc

Issue 2751973002: MIPS: Move ldc1/sdc1 to macro-assembler. (Closed)
Patch Set: Created 3 years, 9 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved.7 1 // Copyright 2012 the V8 project authors. All rights reserved.7
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 108
109 109
110 void LCodeGen::SaveCallerDoubles() { 110 void LCodeGen::SaveCallerDoubles() {
111 DCHECK(info()->saves_caller_doubles()); 111 DCHECK(info()->saves_caller_doubles());
112 DCHECK(NeedsEagerFrame()); 112 DCHECK(NeedsEagerFrame());
113 Comment(";;; Save clobbered callee double registers"); 113 Comment(";;; Save clobbered callee double registers");
114 int count = 0; 114 int count = 0;
115 BitVector* doubles = chunk()->allocated_double_registers(); 115 BitVector* doubles = chunk()->allocated_double_registers();
116 BitVector::Iterator save_iterator(doubles); 116 BitVector::Iterator save_iterator(doubles);
117 while (!save_iterator.Done()) { 117 while (!save_iterator.Done()) {
118 __ sdc1(DoubleRegister::from_code(save_iterator.Current()), 118 __ Sdc1(DoubleRegister::from_code(save_iterator.Current()),
119 MemOperand(sp, count * kDoubleSize)); 119 MemOperand(sp, count * kDoubleSize));
120 save_iterator.Advance(); 120 save_iterator.Advance();
121 count++; 121 count++;
122 } 122 }
123 } 123 }
124 124
125 125
126 void LCodeGen::RestoreCallerDoubles() { 126 void LCodeGen::RestoreCallerDoubles() {
127 DCHECK(info()->saves_caller_doubles()); 127 DCHECK(info()->saves_caller_doubles());
128 DCHECK(NeedsEagerFrame()); 128 DCHECK(NeedsEagerFrame());
129 Comment(";;; Restore clobbered callee double registers"); 129 Comment(";;; Restore clobbered callee double registers");
130 BitVector* doubles = chunk()->allocated_double_registers(); 130 BitVector* doubles = chunk()->allocated_double_registers();
131 BitVector::Iterator save_iterator(doubles); 131 BitVector::Iterator save_iterator(doubles);
132 int count = 0; 132 int count = 0;
133 while (!save_iterator.Done()) { 133 while (!save_iterator.Done()) {
134 __ ldc1(DoubleRegister::from_code(save_iterator.Current()), 134 __ Ldc1(DoubleRegister::from_code(save_iterator.Current()),
135 MemOperand(sp, count * kDoubleSize)); 135 MemOperand(sp, count * kDoubleSize));
136 save_iterator.Advance(); 136 save_iterator.Advance();
137 count++; 137 count++;
138 } 138 }
139 } 139 }
140 140
141 141
142 bool LCodeGen::GeneratePrologue() { 142 bool LCodeGen::GeneratePrologue() {
143 DCHECK(is_generating()); 143 DCHECK(is_generating());
144 144
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 __ mtc1(at, flt_scratch); 465 __ mtc1(at, flt_scratch);
466 __ cvt_d_w(dbl_scratch, flt_scratch); 466 __ cvt_d_w(dbl_scratch, flt_scratch);
467 return dbl_scratch; 467 return dbl_scratch;
468 } else if (r.IsDouble()) { 468 } else if (r.IsDouble()) {
469 Abort(kUnsupportedDoubleImmediate); 469 Abort(kUnsupportedDoubleImmediate);
470 } else if (r.IsTagged()) { 470 } else if (r.IsTagged()) {
471 Abort(kUnsupportedTaggedImmediate); 471 Abort(kUnsupportedTaggedImmediate);
472 } 472 }
473 } else if (op->IsStackSlot()) { 473 } else if (op->IsStackSlot()) {
474 MemOperand mem_op = ToMemOperand(op); 474 MemOperand mem_op = ToMemOperand(op);
475 __ ldc1(dbl_scratch, mem_op); 475 __ Ldc1(dbl_scratch, mem_op);
476 return dbl_scratch; 476 return dbl_scratch;
477 } 477 }
478 UNREACHABLE(); 478 UNREACHABLE();
479 return dbl_scratch; 479 return dbl_scratch;
480 } 480 }
481 481
482 482
483 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 483 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
484 HConstant* constant = chunk_->LookupConstant(op); 484 HConstant* constant = chunk_->LookupConstant(op);
485 DCHECK(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); 485 DCHECK(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
(...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1942 EmitBranch(instr, eq, reg, Operand(at)); 1942 EmitBranch(instr, eq, reg, Operand(at));
1943 } else if (type.IsSmi()) { 1943 } else if (type.IsSmi()) {
1944 DCHECK(!info()->IsStub()); 1944 DCHECK(!info()->IsStub());
1945 EmitBranch(instr, ne, reg, Operand(zero_reg)); 1945 EmitBranch(instr, ne, reg, Operand(zero_reg));
1946 } else if (type.IsJSArray()) { 1946 } else if (type.IsJSArray()) {
1947 DCHECK(!info()->IsStub()); 1947 DCHECK(!info()->IsStub());
1948 EmitBranch(instr, al, zero_reg, Operand(zero_reg)); 1948 EmitBranch(instr, al, zero_reg, Operand(zero_reg));
1949 } else if (type.IsHeapNumber()) { 1949 } else if (type.IsHeapNumber()) {
1950 DCHECK(!info()->IsStub()); 1950 DCHECK(!info()->IsStub());
1951 DoubleRegister dbl_scratch = double_scratch0(); 1951 DoubleRegister dbl_scratch = double_scratch0();
1952 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 1952 __ Ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
1953 // Test the double value. Zero and NaN are false. 1953 // Test the double value. Zero and NaN are false.
1954 EmitBranchF(instr, ogl, dbl_scratch, kDoubleRegZero); 1954 EmitBranchF(instr, ogl, dbl_scratch, kDoubleRegZero);
1955 } else if (type.IsString()) { 1955 } else if (type.IsString()) {
1956 DCHECK(!info()->IsStub()); 1956 DCHECK(!info()->IsStub());
1957 __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); 1957 __ lw(at, FieldMemOperand(reg, String::kLengthOffset));
1958 EmitBranch(instr, ne, at, Operand(zero_reg)); 1958 EmitBranch(instr, ne, at, Operand(zero_reg));
1959 } else { 1959 } else {
1960 ToBooleanHints expected = instr->hydrogen()->expected_input_types(); 1960 ToBooleanHints expected = instr->hydrogen()->expected_input_types();
1961 // Avoid deopts in the case where we've never executed this path before. 1961 // Avoid deopts in the case where we've never executed this path before.
1962 if (expected == ToBooleanHint::kNone) expected = ToBooleanHint::kAny; 1962 if (expected == ToBooleanHint::kNone) expected = ToBooleanHint::kAny;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2024 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); 2024 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
2025 __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE)); 2025 __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE));
2026 } 2026 }
2027 2027
2028 if (expected & ToBooleanHint::kHeapNumber) { 2028 if (expected & ToBooleanHint::kHeapNumber) {
2029 // heap number -> false iff +0, -0, or NaN. 2029 // heap number -> false iff +0, -0, or NaN.
2030 DoubleRegister dbl_scratch = double_scratch0(); 2030 DoubleRegister dbl_scratch = double_scratch0();
2031 Label not_heap_number; 2031 Label not_heap_number;
2032 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 2032 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
2033 __ Branch(&not_heap_number, ne, map, Operand(at)); 2033 __ Branch(&not_heap_number, ne, map, Operand(at));
2034 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 2034 __ Ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
2035 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 2035 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2036 ne, dbl_scratch, kDoubleRegZero); 2036 ne, dbl_scratch, kDoubleRegZero);
2037 // Falls through if dbl_scratch == 0. 2037 // Falls through if dbl_scratch == 0.
2038 __ Branch(instr->FalseLabel(chunk_)); 2038 __ Branch(instr->FalseLabel(chunk_));
2039 __ bind(&not_heap_number); 2039 __ bind(&not_heap_number);
2040 } 2040 }
2041 2041
2042 if (expected != ToBooleanHint::kAny) { 2042 if (expected != ToBooleanHint::kAny) {
2043 // We've seen something for the first time -> deopt. 2043 // We've seen something for the first time -> deopt.
2044 // This can only happen if we are not generic already. 2044 // This can only happen if we are not generic already.
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
2474 2474
2475 if (access.IsExternalMemory()) { 2475 if (access.IsExternalMemory()) {
2476 Register result = ToRegister(instr->result()); 2476 Register result = ToRegister(instr->result());
2477 MemOperand operand = MemOperand(object, offset); 2477 MemOperand operand = MemOperand(object, offset);
2478 __ Load(result, operand, access.representation()); 2478 __ Load(result, operand, access.representation());
2479 return; 2479 return;
2480 } 2480 }
2481 2481
2482 if (instr->hydrogen()->representation().IsDouble()) { 2482 if (instr->hydrogen()->representation().IsDouble()) {
2483 DoubleRegister result = ToDoubleRegister(instr->result()); 2483 DoubleRegister result = ToDoubleRegister(instr->result());
2484 __ ldc1(result, FieldMemOperand(object, offset)); 2484 __ Ldc1(result, FieldMemOperand(object, offset));
2485 return; 2485 return;
2486 } 2486 }
2487 2487
2488 Register result = ToRegister(instr->result()); 2488 Register result = ToRegister(instr->result());
2489 if (!access.IsInobject()) { 2489 if (!access.IsInobject()) {
2490 __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 2490 __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
2491 object = result; 2491 object = result;
2492 } 2492 }
2493 MemOperand operand = FieldMemOperand(object, offset); 2493 MemOperand operand = FieldMemOperand(object, offset);
2494 __ Load(result, operand, access.representation()); 2494 __ Load(result, operand, access.representation());
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 if (key_is_constant) { 2592 if (key_is_constant) {
2593 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); 2593 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
2594 } else { 2594 } else {
2595 __ sll(scratch0(), key, shift_size); 2595 __ sll(scratch0(), key, shift_size);
2596 __ Addu(scratch0(), scratch0(), external_pointer); 2596 __ Addu(scratch0(), scratch0(), external_pointer);
2597 } 2597 }
2598 if (elements_kind == FLOAT32_ELEMENTS) { 2598 if (elements_kind == FLOAT32_ELEMENTS) {
2599 __ lwc1(result, MemOperand(scratch0(), base_offset)); 2599 __ lwc1(result, MemOperand(scratch0(), base_offset));
2600 __ cvt_d_s(result, result); 2600 __ cvt_d_s(result, result);
2601 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 2601 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
2602 __ ldc1(result, MemOperand(scratch0(), base_offset)); 2602 __ Ldc1(result, MemOperand(scratch0(), base_offset));
2603 } 2603 }
2604 } else { 2604 } else {
2605 Register result = ToRegister(instr->result()); 2605 Register result = ToRegister(instr->result());
2606 MemOperand mem_operand = PrepareKeyedOperand( 2606 MemOperand mem_operand = PrepareKeyedOperand(
2607 key, external_pointer, key_is_constant, constant_key, 2607 key, external_pointer, key_is_constant, constant_key,
2608 element_size_shift, shift_size, base_offset); 2608 element_size_shift, shift_size, base_offset);
2609 switch (elements_kind) { 2609 switch (elements_kind) {
2610 case INT8_ELEMENTS: 2610 case INT8_ELEMENTS:
2611 __ lb(result, mem_operand); 2611 __ lb(result, mem_operand);
2612 break; 2612 break;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2670 } 2670 }
2671 __ Addu(scratch, elements, Operand(base_offset)); 2671 __ Addu(scratch, elements, Operand(base_offset));
2672 2672
2673 if (!key_is_constant) { 2673 if (!key_is_constant) {
2674 key = ToRegister(instr->key()); 2674 key = ToRegister(instr->key());
2675 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 2675 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
2676 ? (element_size_shift - kSmiTagSize) : element_size_shift; 2676 ? (element_size_shift - kSmiTagSize) : element_size_shift;
2677 __ Lsa(scratch, scratch, key, shift_size); 2677 __ Lsa(scratch, scratch, key, shift_size);
2678 } 2678 }
2679 2679
2680 __ ldc1(result, MemOperand(scratch)); 2680 __ Ldc1(result, MemOperand(scratch));
2681 2681
2682 if (instr->hydrogen()->RequiresHoleCheck()) { 2682 if (instr->hydrogen()->RequiresHoleCheck()) {
2683 __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset)); 2683 __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset));
2684 DeoptimizeIf(eq, instr, DeoptimizeReason::kHole, scratch, 2684 DeoptimizeIf(eq, instr, DeoptimizeReason::kHole, scratch,
2685 Operand(kHoleNanUpper32)); 2685 Operand(kHoleNanUpper32));
2686 } 2686 }
2687 } 2687 }
2688 2688
2689 2689
2690 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 2690 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after
3597 __ AssertNotSmi(object); 3597 __ AssertNotSmi(object);
3598 3598
3599 DCHECK(!representation.IsSmi() || 3599 DCHECK(!representation.IsSmi() ||
3600 !instr->value()->IsConstantOperand() || 3600 !instr->value()->IsConstantOperand() ||
3601 IsSmi(LConstantOperand::cast(instr->value()))); 3601 IsSmi(LConstantOperand::cast(instr->value())));
3602 if (representation.IsDouble()) { 3602 if (representation.IsDouble()) {
3603 DCHECK(access.IsInobject()); 3603 DCHECK(access.IsInobject());
3604 DCHECK(!instr->hydrogen()->has_transition()); 3604 DCHECK(!instr->hydrogen()->has_transition());
3605 DCHECK(!instr->hydrogen()->NeedsWriteBarrier()); 3605 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
3606 DoubleRegister value = ToDoubleRegister(instr->value()); 3606 DoubleRegister value = ToDoubleRegister(instr->value());
3607 __ sdc1(value, FieldMemOperand(object, offset)); 3607 __ Sdc1(value, FieldMemOperand(object, offset));
3608 return; 3608 return;
3609 } 3609 }
3610 3610
3611 if (instr->hydrogen()->has_transition()) { 3611 if (instr->hydrogen()->has_transition()) {
3612 Handle<Map> transition = instr->hydrogen()->transition_map(); 3612 Handle<Map> transition = instr->hydrogen()->transition_map();
3613 AddDeprecationDependency(transition); 3613 AddDeprecationDependency(transition);
3614 __ li(scratch, Operand(transition)); 3614 __ li(scratch, Operand(transition));
3615 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 3615 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
3616 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { 3616 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
3617 Register temp = ToRegister(instr->temp()); 3617 Register temp = ToRegister(instr->temp());
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
3715 address = external_pointer; 3715 address = external_pointer;
3716 } 3716 }
3717 } else { 3717 } else {
3718 __ Lsa(address, external_pointer, key, shift_size); 3718 __ Lsa(address, external_pointer, key, shift_size);
3719 } 3719 }
3720 3720
3721 if (elements_kind == FLOAT32_ELEMENTS) { 3721 if (elements_kind == FLOAT32_ELEMENTS) {
3722 __ cvt_s_d(double_scratch0(), value); 3722 __ cvt_s_d(double_scratch0(), value);
3723 __ swc1(double_scratch0(), MemOperand(address, base_offset)); 3723 __ swc1(double_scratch0(), MemOperand(address, base_offset));
3724 } else { // Storing doubles, not floats. 3724 } else { // Storing doubles, not floats.
3725 __ sdc1(value, MemOperand(address, base_offset)); 3725 __ Sdc1(value, MemOperand(address, base_offset));
3726 } 3726 }
3727 } else { 3727 } else {
3728 Register value(ToRegister(instr->value())); 3728 Register value(ToRegister(instr->value()));
3729 MemOperand mem_operand = PrepareKeyedOperand( 3729 MemOperand mem_operand = PrepareKeyedOperand(
3730 key, external_pointer, key_is_constant, constant_key, 3730 key, external_pointer, key_is_constant, constant_key,
3731 element_size_shift, shift_size, 3731 element_size_shift, shift_size,
3732 base_offset); 3732 base_offset);
3733 switch (elements_kind) { 3733 switch (elements_kind) {
3734 case UINT8_ELEMENTS: 3734 case UINT8_ELEMENTS:
3735 case UINT8_CLAMPED_ELEMENTS: 3735 case UINT8_CLAMPED_ELEMENTS:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3795 3795
3796 if (instr->NeedsCanonicalization()) { 3796 if (instr->NeedsCanonicalization()) {
3797 Label is_nan; 3797 Label is_nan;
3798 // Check for NaN. All NaNs must be canonicalized. 3798 // Check for NaN. All NaNs must be canonicalized.
3799 __ BranchF(NULL, &is_nan, eq, value, value); 3799 __ BranchF(NULL, &is_nan, eq, value, value);
3800 __ Branch(&not_nan); 3800 __ Branch(&not_nan);
3801 3801
3802 // Only load canonical NaN if the comparison above set the overflow. 3802 // Only load canonical NaN if the comparison above set the overflow.
3803 __ bind(&is_nan); 3803 __ bind(&is_nan);
3804 __ LoadRoot(scratch_1, Heap::kNanValueRootIndex); 3804 __ LoadRoot(scratch_1, Heap::kNanValueRootIndex);
3805 __ ldc1(double_scratch, 3805 __ Ldc1(double_scratch,
3806 FieldMemOperand(scratch_1, HeapNumber::kValueOffset)); 3806 FieldMemOperand(scratch_1, HeapNumber::kValueOffset));
3807 __ sdc1(double_scratch, MemOperand(scratch, 0)); 3807 __ Sdc1(double_scratch, MemOperand(scratch, 0));
3808 __ Branch(&done); 3808 __ Branch(&done);
3809 } 3809 }
3810 3810
3811 __ bind(&not_nan); 3811 __ bind(&not_nan);
3812 __ sdc1(value, MemOperand(scratch, 0)); 3812 __ Sdc1(value, MemOperand(scratch, 0));
3813 __ bind(&done); 3813 __ bind(&done);
3814 } 3814 }
3815 3815
3816 3816
3817 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 3817 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
3818 Register value = ToRegister(instr->value()); 3818 Register value = ToRegister(instr->value());
3819 Register elements = ToRegister(instr->elements()); 3819 Register elements = ToRegister(instr->elements());
3820 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) 3820 Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
3821 : no_reg; 3821 : no_reg;
3822 Register scratch = scratch0(); 3822 Register scratch = scratch0();
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
4275 } 4275 }
4276 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 4276 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
4277 RecordSafepointWithRegisters( 4277 RecordSafepointWithRegisters(
4278 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4278 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4279 __ StoreToSafepointRegisterSlot(v0, dst); 4279 __ StoreToSafepointRegisterSlot(v0, dst);
4280 } 4280 }
4281 4281
4282 // Done. Put the value in dbl_scratch into the value of the allocated heap 4282 // Done. Put the value in dbl_scratch into the value of the allocated heap
4283 // number. 4283 // number.
4284 __ bind(&done); 4284 __ bind(&done);
4285 __ sdc1(dbl_scratch, FieldMemOperand(dst, HeapNumber::kValueOffset)); 4285 __ Sdc1(dbl_scratch, FieldMemOperand(dst, HeapNumber::kValueOffset));
4286 } 4286 }
4287 4287
4288 4288
4289 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4289 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4290 class DeferredNumberTagD final : public LDeferredCode { 4290 class DeferredNumberTagD final : public LDeferredCode {
4291 public: 4291 public:
4292 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4292 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4293 : LDeferredCode(codegen), instr_(instr) { } 4293 : LDeferredCode(codegen), instr_(instr) { }
4294 void Generate() override { codegen()->DoDeferredNumberTagD(instr_); } 4294 void Generate() override { codegen()->DoDeferredNumberTagD(instr_); }
4295 LInstruction* instr() override { return instr_; } 4295 LInstruction* instr() override { return instr_; }
4296 4296
4297 private: 4297 private:
4298 LNumberTagD* instr_; 4298 LNumberTagD* instr_;
4299 }; 4299 };
4300 4300
4301 DoubleRegister input_reg = ToDoubleRegister(instr->value()); 4301 DoubleRegister input_reg = ToDoubleRegister(instr->value());
4302 Register scratch = scratch0(); 4302 Register scratch = scratch0();
4303 Register reg = ToRegister(instr->result()); 4303 Register reg = ToRegister(instr->result());
4304 Register temp1 = ToRegister(instr->temp()); 4304 Register temp1 = ToRegister(instr->temp());
4305 Register temp2 = ToRegister(instr->temp2()); 4305 Register temp2 = ToRegister(instr->temp2());
4306 4306
4307 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4307 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4308 if (FLAG_inline_new) { 4308 if (FLAG_inline_new) {
4309 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4309 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
4310 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry()); 4310 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry());
4311 } else { 4311 } else {
4312 __ Branch(deferred->entry()); 4312 __ Branch(deferred->entry());
4313 } 4313 }
4314 __ bind(deferred->exit()); 4314 __ bind(deferred->exit());
4315 __ sdc1(input_reg, FieldMemOperand(reg, HeapNumber::kValueOffset)); 4315 __ Sdc1(input_reg, FieldMemOperand(reg, HeapNumber::kValueOffset));
4316 // Now that we have finished with the object's real address tag it 4316 // Now that we have finished with the object's real address tag it
4317 } 4317 }
4318 4318
4319 4319
4320 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4320 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4321 // TODO(3095996): Get rid of this. For now, we need to make the 4321 // TODO(3095996): Get rid of this. For now, we need to make the
4322 // result register contain a valid pointer because it is already 4322 // result register contain a valid pointer because it is already
4323 // contained in the register pointer map. 4323 // contained in the register pointer map.
4324 Register reg = ToRegister(instr->result()); 4324 Register reg = ToRegister(instr->result());
4325 __ mov(reg, zero_reg); 4325 __ mov(reg, zero_reg);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
4386 // Heap number map check. 4386 // Heap number map check.
4387 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4387 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4388 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4388 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4389 if (can_convert_undefined_to_nan) { 4389 if (can_convert_undefined_to_nan) {
4390 __ Branch(&convert, ne, scratch, Operand(at)); 4390 __ Branch(&convert, ne, scratch, Operand(at));
4391 } else { 4391 } else {
4392 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber, scratch, 4392 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber, scratch,
4393 Operand(at)); 4393 Operand(at));
4394 } 4394 }
4395 // Load heap number. 4395 // Load heap number.
4396 __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4396 __ Ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4397 if (deoptimize_on_minus_zero) { 4397 if (deoptimize_on_minus_zero) {
4398 __ mfc1(at, result_reg.low()); 4398 __ mfc1(at, result_reg.low());
4399 __ Branch(&done, ne, at, Operand(zero_reg)); 4399 __ Branch(&done, ne, at, Operand(zero_reg));
4400 __ Mfhc1(scratch, result_reg); 4400 __ Mfhc1(scratch, result_reg);
4401 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, scratch, 4401 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, scratch,
4402 Operand(HeapNumber::kSignMask)); 4402 Operand(HeapNumber::kSignMask));
4403 } 4403 }
4404 __ Branch(&done); 4404 __ Branch(&done);
4405 if (can_convert_undefined_to_nan) { 4405 if (can_convert_undefined_to_nan) {
4406 __ bind(&convert); 4406 __ bind(&convert);
4407 // Convert undefined (and hole) to NaN. 4407 // Convert undefined (and hole) to NaN.
4408 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 4408 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
4409 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefined, 4409 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefined,
4410 input_reg, Operand(at)); 4410 input_reg, Operand(at));
4411 __ LoadRoot(scratch, Heap::kNanValueRootIndex); 4411 __ LoadRoot(scratch, Heap::kNanValueRootIndex);
4412 __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset)); 4412 __ Ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset));
4413 __ Branch(&done); 4413 __ Branch(&done);
4414 } 4414 }
4415 } else { 4415 } else {
4416 __ SmiUntag(scratch, input_reg); 4416 __ SmiUntag(scratch, input_reg);
4417 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); 4417 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI);
4418 } 4418 }
4419 // Smi to double register conversion 4419 // Smi to double register conversion
4420 __ bind(&load_smi); 4420 __ bind(&load_smi);
4421 // scratch: untagged value of input_reg 4421 // scratch: untagged value of input_reg
4422 __ mtc1(scratch, result_reg); 4422 __ mtc1(scratch, result_reg);
(...skipping 28 matching lines...) Expand all
4451 __ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); 4451 __ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
4452 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotANumberOrOddball, scratch1, 4452 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotANumberOrOddball, scratch1,
4453 Operand(ODDBALL_TYPE)); 4453 Operand(ODDBALL_TYPE));
4454 __ bind(&truncate); 4454 __ bind(&truncate);
4455 __ TruncateHeapNumberToI(input_reg, scratch2); 4455 __ TruncateHeapNumberToI(input_reg, scratch2);
4456 } else { 4456 } else {
4457 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber, scratch1, 4457 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber, scratch1,
4458 Operand(at)); 4458 Operand(at));
4459 4459
4460 // Load the double value. 4460 // Load the double value.
4461 __ ldc1(double_scratch, 4461 __ Ldc1(double_scratch,
4462 FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4462 FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4463 4463
4464 Register except_flag = scratch2; 4464 Register except_flag = scratch2;
4465 __ EmitFPUTruncate(kRoundToZero, 4465 __ EmitFPUTruncate(kRoundToZero,
4466 input_reg, 4466 input_reg,
4467 double_scratch, 4467 double_scratch,
4468 scratch1, 4468 scratch1,
4469 double_scratch2, 4469 double_scratch2,
4470 except_flag, 4470 except_flag,
4471 kCheckForInexactConversion); 4471 kCheckForInexactConversion);
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
4816 4816
4817 // Check for undefined. Undefined is converted to zero for clamping 4817 // Check for undefined. Undefined is converted to zero for clamping
4818 // conversions. 4818 // conversions.
4819 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefined, input_reg, 4819 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefined, input_reg,
4820 Operand(factory()->undefined_value())); 4820 Operand(factory()->undefined_value()));
4821 __ mov(result_reg, zero_reg); 4821 __ mov(result_reg, zero_reg);
4822 __ jmp(&done); 4822 __ jmp(&done);
4823 4823
4824 // Heap number 4824 // Heap number
4825 __ bind(&heap_number); 4825 __ bind(&heap_number);
4826 __ ldc1(double_scratch0(), FieldMemOperand(input_reg, 4826 __ Ldc1(double_scratch0(),
4827 HeapNumber::kValueOffset)); 4827 FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4828 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg); 4828 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg);
4829 __ jmp(&done); 4829 __ jmp(&done);
4830 4830
4831 __ bind(&is_smi); 4831 __ bind(&is_smi);
4832 __ ClampUint8(result_reg, scratch); 4832 __ ClampUint8(result_reg, scratch);
4833 4833
4834 __ bind(&done); 4834 __ bind(&done);
4835 } 4835 }
4836 4836
4837 4837
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
5356 __ lw(result, FieldMemOperand(scratch, 5356 __ lw(result, FieldMemOperand(scratch,
5357 FixedArray::kHeaderSize - kPointerSize)); 5357 FixedArray::kHeaderSize - kPointerSize));
5358 __ bind(deferred->exit()); 5358 __ bind(deferred->exit());
5359 __ bind(&done); 5359 __ bind(&done);
5360 } 5360 }
5361 5361
5362 #undef __ 5362 #undef __
5363 5363
5364 } // namespace internal 5364 } // namespace internal
5365 } // namespace v8 5365 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/mips/code-generator-mips.cc ('k') | src/crankshaft/mips/lithium-gap-resolver-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698