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 4945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4956 bool deoptimize_on_undefined, | 4956 bool deoptimize_on_undefined, |
4957 bool deoptimize_on_minus_zero, | 4957 bool deoptimize_on_minus_zero, |
4958 LEnvironment* env, | 4958 LEnvironment* env, |
4959 NumberUntagDMode mode) { | 4959 NumberUntagDMode mode) { |
4960 Register scratch = scratch0(); | 4960 Register scratch = scratch0(); |
4961 SwVfpRegister flt_scratch = double_scratch0().low(); | 4961 SwVfpRegister flt_scratch = double_scratch0().low(); |
4962 ASSERT(!result_reg.is(double_scratch0())); | 4962 ASSERT(!result_reg.is(double_scratch0())); |
4963 | 4963 |
4964 Label load_smi, heap_number, done; | 4964 Label load_smi, heap_number, done; |
4965 | 4965 |
4966 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 4966 STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE > |
| 4967 NUMBER_CANDIDATE_IS_ANY_TAGGED); |
| 4968 if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
4967 // Smi check. | 4969 // Smi check. |
4968 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | 4970 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); |
4969 | 4971 |
4970 // Heap number map check. | 4972 // Heap number map check. |
4971 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4973 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
4972 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 4974 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
4973 __ cmp(scratch, Operand(ip)); | 4975 __ cmp(scratch, Operand(ip)); |
4974 if (deoptimize_on_undefined) { | 4976 if (deoptimize_on_undefined) { |
4975 DeoptimizeIf(ne, env); | 4977 DeoptimizeIf(ne, env); |
4976 } else { | 4978 } else { |
4977 Label heap_number; | 4979 Label heap_number, convert; |
4978 __ b(eq, &heap_number); | 4980 __ b(eq, &heap_number); |
4979 | 4981 |
| 4982 // Convert undefined (and hole) to NaN. |
4980 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 4983 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
4981 __ cmp(input_reg, Operand(ip)); | 4984 __ cmp(input_reg, Operand(ip)); |
| 4985 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) { |
| 4986 __ b(eq, &convert); |
| 4987 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 4988 __ cmp(input_reg, Operand(ip)); |
| 4989 } |
4982 DeoptimizeIf(ne, env); | 4990 DeoptimizeIf(ne, env); |
4983 | 4991 |
4984 // Convert undefined to NaN. | 4992 __ bind(&convert); |
4985 __ LoadRoot(ip, Heap::kNanValueRootIndex); | 4993 __ LoadRoot(ip, Heap::kNanValueRootIndex); |
4986 __ sub(ip, ip, Operand(kHeapObjectTag)); | 4994 __ sub(ip, ip, Operand(kHeapObjectTag)); |
4987 __ vldr(result_reg, ip, HeapNumber::kValueOffset); | 4995 __ vldr(result_reg, ip, HeapNumber::kValueOffset); |
4988 __ jmp(&done); | 4996 __ jmp(&done); |
4989 | 4997 |
4990 __ bind(&heap_number); | 4998 __ bind(&heap_number); |
4991 } | 4999 } |
4992 // Heap number to double register conversion. | 5000 // Heap number to double register conversion. |
4993 __ sub(ip, input_reg, Operand(kHeapObjectTag)); | 5001 __ sub(ip, input_reg, Operand(kHeapObjectTag)); |
4994 __ vldr(result_reg, ip, HeapNumber::kValueOffset); | 5002 __ vldr(result_reg, ip, HeapNumber::kValueOffset); |
4995 if (deoptimize_on_minus_zero) { | 5003 if (deoptimize_on_minus_zero) { |
4996 __ vmov(ip, result_reg.low()); | 5004 __ vmov(ip, result_reg.low()); |
4997 __ cmp(ip, Operand::Zero()); | 5005 __ cmp(ip, Operand::Zero()); |
4998 __ b(ne, &done); | 5006 __ b(ne, &done); |
4999 __ vmov(ip, result_reg.high()); | 5007 __ vmov(ip, result_reg.high()); |
5000 __ cmp(ip, Operand(HeapNumber::kSignMask)); | 5008 __ cmp(ip, Operand(HeapNumber::kSignMask)); |
5001 DeoptimizeIf(eq, env); | 5009 DeoptimizeIf(eq, env); |
5002 } | 5010 } |
5003 __ jmp(&done); | 5011 __ jmp(&done); |
5004 } else if (mode == NUMBER_CANDIDATE_IS_SMI_OR_HOLE) { | |
5005 __ SmiUntag(scratch, input_reg, SetCC); | |
5006 DeoptimizeIf(cs, env); | |
5007 } else if (mode == NUMBER_CANDIDATE_IS_SMI_CONVERT_HOLE) { | |
5008 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | |
5009 __ Vmov(result_reg, | |
5010 FixedDoubleArray::hole_nan_as_double(), | |
5011 no_reg); | |
5012 __ b(&done); | |
5013 } else { | 5012 } else { |
5014 __ SmiUntag(scratch, input_reg); | 5013 __ SmiUntag(scratch, input_reg); |
5015 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); | 5014 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); |
5016 } | 5015 } |
5017 | 5016 |
5018 // Smi to double register conversion | 5017 // Smi to double register conversion |
5019 __ bind(&load_smi); | 5018 __ bind(&load_smi); |
5020 // scratch: untagged value of input_reg | 5019 // scratch: untagged value of input_reg |
5021 __ vmov(flt_scratch, scratch); | 5020 __ vmov(flt_scratch, scratch); |
5022 __ vcvt_f64_s32(result_reg, flt_scratch); | 5021 __ vcvt_f64_s32(result_reg, flt_scratch); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5126 ASSERT(input->IsRegister()); | 5125 ASSERT(input->IsRegister()); |
5127 LOperand* result = instr->result(); | 5126 LOperand* result = instr->result(); |
5128 ASSERT(result->IsDoubleRegister()); | 5127 ASSERT(result->IsDoubleRegister()); |
5129 | 5128 |
5130 Register input_reg = ToRegister(input); | 5129 Register input_reg = ToRegister(input); |
5131 DwVfpRegister result_reg = ToDoubleRegister(result); | 5130 DwVfpRegister result_reg = ToDoubleRegister(result); |
5132 | 5131 |
5133 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED; | 5132 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED; |
5134 HValue* value = instr->hydrogen()->value(); | 5133 HValue* value = instr->hydrogen()->value(); |
5135 if (value->type().IsSmi()) { | 5134 if (value->type().IsSmi()) { |
5136 if (value->IsLoadKeyed()) { | 5135 mode = NUMBER_CANDIDATE_IS_SMI; |
5137 HLoadKeyed* load = HLoadKeyed::cast(value); | 5136 } else if (value->IsLoadKeyed()) { |
5138 if (load->UsesMustHandleHole()) { | 5137 HLoadKeyed* load = HLoadKeyed::cast(value); |
5139 if (load->hole_mode() == ALLOW_RETURN_HOLE) { | 5138 if (load->UsesMustHandleHole()) { |
5140 mode = NUMBER_CANDIDATE_IS_SMI_CONVERT_HOLE; | 5139 if (load->hole_mode() == ALLOW_RETURN_HOLE) { |
5141 } else { | 5140 mode = NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE; |
5142 mode = NUMBER_CANDIDATE_IS_SMI_OR_HOLE; | |
5143 } | |
5144 } else { | |
5145 mode = NUMBER_CANDIDATE_IS_SMI; | |
5146 } | 5141 } |
5147 } else { | |
5148 mode = NUMBER_CANDIDATE_IS_SMI; | |
5149 } | 5142 } |
5150 } | 5143 } |
5151 | 5144 |
5152 EmitNumberUntagD(input_reg, result_reg, | 5145 EmitNumberUntagD(input_reg, result_reg, |
5153 instr->hydrogen()->deoptimize_on_undefined(), | 5146 instr->hydrogen()->deoptimize_on_undefined(), |
5154 instr->hydrogen()->deoptimize_on_minus_zero(), | 5147 instr->hydrogen()->deoptimize_on_minus_zero(), |
5155 instr->environment(), | 5148 instr->environment(), |
5156 mode); | 5149 mode); |
5157 } | 5150 } |
5158 | 5151 |
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5979 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5972 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
5980 __ ldr(result, FieldMemOperand(scratch, | 5973 __ ldr(result, FieldMemOperand(scratch, |
5981 FixedArray::kHeaderSize - kPointerSize)); | 5974 FixedArray::kHeaderSize - kPointerSize)); |
5982 __ bind(&done); | 5975 __ bind(&done); |
5983 } | 5976 } |
5984 | 5977 |
5985 | 5978 |
5986 #undef __ | 5979 #undef __ |
5987 | 5980 |
5988 } } // namespace v8::internal | 5981 } } // namespace v8::internal |
OLD | NEW |