| 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 2049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2060 __ BranchF(chunk_->GetAssemblyLabel(false_block), NULL, | 2060 __ BranchF(chunk_->GetAssemblyLabel(false_block), NULL, |
| 2061 condition, src1, src2); | 2061 condition, src1, src2); |
| 2062 } | 2062 } |
| 2063 | 2063 |
| 2064 | 2064 |
| 2065 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { | 2065 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { |
| 2066 __ stop("LDebugBreak"); | 2066 __ stop("LDebugBreak"); |
| 2067 } | 2067 } |
| 2068 | 2068 |
| 2069 | 2069 |
| 2070 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { | |
| 2071 Representation r = instr->hydrogen()->value()->representation(); | |
| 2072 if (r.IsSmiOrInteger32() || r.IsDouble()) { | |
| 2073 EmitBranch(instr, al, zero_reg, Operand(zero_reg)); | |
| 2074 } else { | |
| 2075 ASSERT(r.IsTagged()); | |
| 2076 Register reg = ToRegister(instr->value()); | |
| 2077 HType type = instr->hydrogen()->value()->type(); | |
| 2078 if (type.IsTaggedNumber()) { | |
| 2079 EmitBranch(instr, al, zero_reg, Operand(zero_reg)); | |
| 2080 } | |
| 2081 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | |
| 2082 __ lw(scratch0(), FieldMemOperand(reg, HeapObject::kMapOffset)); | |
| 2083 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | |
| 2084 EmitBranch(instr, eq, scratch0(), Operand(at)); | |
| 2085 } | |
| 2086 } | |
| 2087 | |
| 2088 | |
| 2089 void LCodeGen::DoBranch(LBranch* instr) { | 2070 void LCodeGen::DoBranch(LBranch* instr) { |
| 2090 Representation r = instr->hydrogen()->value()->representation(); | 2071 Representation r = instr->hydrogen()->value()->representation(); |
| 2091 if (r.IsInteger32() || r.IsSmi()) { | 2072 if (r.IsInteger32() || r.IsSmi()) { |
| 2092 ASSERT(!info()->IsStub()); | 2073 ASSERT(!info()->IsStub()); |
| 2093 Register reg = ToRegister(instr->value()); | 2074 Register reg = ToRegister(instr->value()); |
| 2094 EmitBranch(instr, ne, reg, Operand(zero_reg)); | 2075 EmitBranch(instr, ne, reg, Operand(zero_reg)); |
| 2095 } else if (r.IsDouble()) { | 2076 } else if (r.IsDouble()) { |
| 2096 ASSERT(!info()->IsStub()); | 2077 ASSERT(!info()->IsStub()); |
| 2097 DoubleRegister reg = ToDoubleRegister(instr->value()); | 2078 DoubleRegister reg = ToDoubleRegister(instr->value()); |
| 2098 // Test the double value. Zero and NaN are false. | 2079 // Test the double value. Zero and NaN are false. |
| (...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3014 // Non-instance prototype: Fetch prototype from constructor field | 2995 // Non-instance prototype: Fetch prototype from constructor field |
| 3015 // in initial map. | 2996 // in initial map. |
| 3016 __ bind(&non_instance); | 2997 __ bind(&non_instance); |
| 3017 __ lw(result, FieldMemOperand(result, Map::kConstructorOffset)); | 2998 __ lw(result, FieldMemOperand(result, Map::kConstructorOffset)); |
| 3018 | 2999 |
| 3019 // All done. | 3000 // All done. |
| 3020 __ bind(&done); | 3001 __ bind(&done); |
| 3021 } | 3002 } |
| 3022 | 3003 |
| 3023 | 3004 |
| 3005 void LCodeGen::DoLoadRoot(LLoadRoot* instr) { |
| 3006 Register result = ToRegister(instr->result()); |
| 3007 __ LoadRoot(result, instr->index()); |
| 3008 } |
| 3009 |
| 3010 |
| 3024 void LCodeGen::DoLoadExternalArrayPointer( | 3011 void LCodeGen::DoLoadExternalArrayPointer( |
| 3025 LLoadExternalArrayPointer* instr) { | 3012 LLoadExternalArrayPointer* instr) { |
| 3026 Register to_reg = ToRegister(instr->result()); | 3013 Register to_reg = ToRegister(instr->result()); |
| 3027 Register from_reg = ToRegister(instr->object()); | 3014 Register from_reg = ToRegister(instr->object()); |
| 3028 __ lw(to_reg, FieldMemOperand(from_reg, | 3015 __ lw(to_reg, FieldMemOperand(from_reg, |
| 3029 ExternalArray::kExternalPointerOffset)); | 3016 ExternalArray::kExternalPointerOffset)); |
| 3030 } | 3017 } |
| 3031 | 3018 |
| 3032 | 3019 |
| 3033 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { | 3020 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
| (...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4244 } else { | 4231 } else { |
| 4245 key = ToRegister(instr->key()); | 4232 key = ToRegister(instr->key()); |
| 4246 } | 4233 } |
| 4247 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4234 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4248 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4235 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4249 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4236 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4250 int additional_offset = instr->additional_index() << element_size_shift; | 4237 int additional_offset = instr->additional_index() << element_size_shift; |
| 4251 | 4238 |
| 4252 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4239 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 4253 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4240 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 4241 Register address = scratch0(); |
| 4254 FPURegister value(ToDoubleRegister(instr->value())); | 4242 FPURegister value(ToDoubleRegister(instr->value())); |
| 4255 if (key_is_constant) { | 4243 if (key_is_constant) { |
| 4256 __ Addu(scratch0(), external_pointer, constant_key << | 4244 if (constant_key != 0) { |
| 4257 element_size_shift); | 4245 __ Addu(address, external_pointer, |
| 4246 Operand(constant_key << element_size_shift)); |
| 4247 } else { |
| 4248 address = external_pointer; |
| 4249 } |
| 4258 } else { | 4250 } else { |
| 4259 __ sll(scratch0(), key, shift_size); | 4251 __ sll(address, key, shift_size); |
| 4260 __ Addu(scratch0(), scratch0(), external_pointer); | 4252 __ Addu(address, external_pointer, address); |
| 4261 } | 4253 } |
| 4262 | 4254 |
| 4263 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4255 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 4264 __ cvt_s_d(double_scratch0(), value); | 4256 __ cvt_s_d(double_scratch0(), value); |
| 4265 __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset)); | 4257 __ swc1(double_scratch0(), MemOperand(address, additional_offset)); |
| 4266 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 4258 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 4267 __ sdc1(value, MemOperand(scratch0(), additional_offset)); | 4259 __ sdc1(value, MemOperand(address, additional_offset)); |
| 4268 } | 4260 } |
| 4269 } else { | 4261 } else { |
| 4270 Register value(ToRegister(instr->value())); | 4262 Register value(ToRegister(instr->value())); |
| 4271 MemOperand mem_operand = PrepareKeyedOperand( | 4263 MemOperand mem_operand = PrepareKeyedOperand( |
| 4272 key, external_pointer, key_is_constant, constant_key, | 4264 key, external_pointer, key_is_constant, constant_key, |
| 4273 element_size_shift, shift_size, | 4265 element_size_shift, shift_size, |
| 4274 instr->additional_index(), additional_offset); | 4266 instr->additional_index(), additional_offset); |
| 4275 switch (elements_kind) { | 4267 switch (elements_kind) { |
| 4276 case EXTERNAL_PIXEL_ELEMENTS: | 4268 case EXTERNAL_PIXEL_ELEMENTS: |
| 4277 case EXTERNAL_BYTE_ELEMENTS: | 4269 case EXTERNAL_BYTE_ELEMENTS: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4299 UNREACHABLE(); | 4291 UNREACHABLE(); |
| 4300 break; | 4292 break; |
| 4301 } | 4293 } |
| 4302 } | 4294 } |
| 4303 } | 4295 } |
| 4304 | 4296 |
| 4305 | 4297 |
| 4306 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4298 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 4307 DoubleRegister value = ToDoubleRegister(instr->value()); | 4299 DoubleRegister value = ToDoubleRegister(instr->value()); |
| 4308 Register elements = ToRegister(instr->elements()); | 4300 Register elements = ToRegister(instr->elements()); |
| 4309 Register key = no_reg; | |
| 4310 Register scratch = scratch0(); | 4301 Register scratch = scratch0(); |
| 4302 DoubleRegister double_scratch = double_scratch0(); |
| 4311 bool key_is_constant = instr->key()->IsConstantOperand(); | 4303 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4312 int constant_key = 0; | 4304 Label not_nan, done; |
| 4313 Label not_nan; | |
| 4314 | 4305 |
| 4315 // Calculate the effective address of the slot in the array to store the | 4306 // Calculate the effective address of the slot in the array to store the |
| 4316 // double value. | 4307 // double value. |
| 4308 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
| 4317 if (key_is_constant) { | 4309 if (key_is_constant) { |
| 4318 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4310 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4319 if (constant_key & 0xF0000000) { | 4311 if (constant_key & 0xF0000000) { |
| 4320 Abort(kArrayIndexConstantValueTooBig); | 4312 Abort(kArrayIndexConstantValueTooBig); |
| 4321 } | 4313 } |
| 4314 __ Addu(scratch, elements, |
| 4315 Operand((constant_key << element_size_shift) + |
| 4316 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
| 4322 } else { | 4317 } else { |
| 4323 key = ToRegister(instr->key()); | 4318 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4324 } | 4319 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4325 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 4320 __ Addu(scratch, elements, |
| 4326 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | |
| 4327 ? (element_size_shift - kSmiTagSize) : element_size_shift; | |
| 4328 if (key_is_constant) { | |
| 4329 __ Addu(scratch, elements, Operand((constant_key << element_size_shift) + | |
| 4330 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
| 4331 } else { | |
| 4332 __ sll(scratch, key, shift_size); | |
| 4333 __ Addu(scratch, elements, Operand(scratch)); | |
| 4334 __ Addu(scratch, scratch, | |
| 4335 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 4321 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
| 4322 __ sll(at, ToRegister(instr->key()), shift_size); |
| 4323 __ Addu(scratch, scratch, at); |
| 4336 } | 4324 } |
| 4337 | 4325 |
| 4338 if (instr->NeedsCanonicalization()) { | 4326 if (instr->NeedsCanonicalization()) { |
| 4339 Label is_nan; | 4327 Label is_nan; |
| 4340 // Check for NaN. All NaNs must be canonicalized. | 4328 // Check for NaN. All NaNs must be canonicalized. |
| 4341 __ BranchF(NULL, &is_nan, eq, value, value); | 4329 __ BranchF(NULL, &is_nan, eq, value, value); |
| 4342 __ Branch(¬_nan); | 4330 __ Branch(¬_nan); |
| 4343 | 4331 |
| 4344 // Only load canonical NaN if the comparison above set the overflow. | 4332 // Only load canonical NaN if the comparison above set the overflow. |
| 4345 __ bind(&is_nan); | 4333 __ bind(&is_nan); |
| 4346 __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); | 4334 __ Move(double_scratch, |
| 4335 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); |
| 4336 __ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() << |
| 4337 element_size_shift)); |
| 4338 __ Branch(&done); |
| 4347 } | 4339 } |
| 4348 | 4340 |
| 4349 __ bind(¬_nan); | 4341 __ bind(¬_nan); |
| 4350 __ sdc1(value, MemOperand(scratch, instr->additional_index() << | 4342 __ sdc1(value, MemOperand(scratch, instr->additional_index() << |
| 4351 element_size_shift)); | 4343 element_size_shift)); |
| 4344 __ bind(&done); |
| 4352 } | 4345 } |
| 4353 | 4346 |
| 4354 | 4347 |
| 4355 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4348 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4356 Register value = ToRegister(instr->value()); | 4349 Register value = ToRegister(instr->value()); |
| 4357 Register elements = ToRegister(instr->elements()); | 4350 Register elements = ToRegister(instr->elements()); |
| 4358 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) | 4351 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) |
| 4359 : no_reg; | 4352 : no_reg; |
| 4360 Register scratch = scratch0(); | 4353 Register scratch = scratch0(); |
| 4361 Register store_base = scratch; | 4354 Register store_base = scratch; |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5098 } else { | 5091 } else { |
| 5099 __ And(scratch, scratch, Operand(mask)); | 5092 __ And(scratch, scratch, Operand(mask)); |
| 5100 DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag)); | 5093 DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag)); |
| 5101 } | 5094 } |
| 5102 } | 5095 } |
| 5103 } | 5096 } |
| 5104 | 5097 |
| 5105 | 5098 |
| 5106 void LCodeGen::DoCheckValue(LCheckValue* instr) { | 5099 void LCodeGen::DoCheckValue(LCheckValue* instr) { |
| 5107 Register reg = ToRegister(instr->value()); | 5100 Register reg = ToRegister(instr->value()); |
| 5108 Handle<HeapObject> object = instr->hydrogen()->object(); | 5101 Handle<HeapObject> object = instr->hydrogen()->object().handle(); |
| 5109 AllowDeferredHandleDereference smi_check; | 5102 AllowDeferredHandleDereference smi_check; |
| 5110 if (isolate()->heap()->InNewSpace(*object)) { | 5103 if (isolate()->heap()->InNewSpace(*object)) { |
| 5111 Register reg = ToRegister(instr->value()); | 5104 Register reg = ToRegister(instr->value()); |
| 5112 Handle<Cell> cell = isolate()->factory()->NewCell(object); | 5105 Handle<Cell> cell = isolate()->factory()->NewCell(object); |
| 5113 __ li(at, Operand(Handle<Object>(cell))); | 5106 __ li(at, Operand(Handle<Object>(cell))); |
| 5114 __ lw(at, FieldMemOperand(at, Cell::kValueOffset)); | 5107 __ lw(at, FieldMemOperand(at, Cell::kValueOffset)); |
| 5115 DeoptimizeIf(ne, instr->environment(), reg, | 5108 DeoptimizeIf(ne, instr->environment(), reg, |
| 5116 Operand(at)); | 5109 Operand(at)); |
| 5117 } else { | 5110 } else { |
| 5118 DeoptimizeIf(ne, instr->environment(), reg, | 5111 DeoptimizeIf(ne, instr->environment(), reg, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 5149 LCheckMaps* instr_; | 5142 LCheckMaps* instr_; |
| 5150 Label check_maps_; | 5143 Label check_maps_; |
| 5151 Register object_; | 5144 Register object_; |
| 5152 }; | 5145 }; |
| 5153 | 5146 |
| 5154 if (instr->hydrogen()->CanOmitMapChecks()) return; | 5147 if (instr->hydrogen()->CanOmitMapChecks()) return; |
| 5155 Register map_reg = scratch0(); | 5148 Register map_reg = scratch0(); |
| 5156 LOperand* input = instr->value(); | 5149 LOperand* input = instr->value(); |
| 5157 ASSERT(input->IsRegister()); | 5150 ASSERT(input->IsRegister()); |
| 5158 Register reg = ToRegister(input); | 5151 Register reg = ToRegister(input); |
| 5159 SmallMapList* map_set = instr->hydrogen()->map_set(); | |
| 5160 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); | 5152 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 5161 | 5153 |
| 5162 DeferredCheckMaps* deferred = NULL; | 5154 DeferredCheckMaps* deferred = NULL; |
| 5163 if (instr->hydrogen()->has_migration_target()) { | 5155 if (instr->hydrogen()->has_migration_target()) { |
| 5164 deferred = new(zone()) DeferredCheckMaps(this, instr, reg); | 5156 deferred = new(zone()) DeferredCheckMaps(this, instr, reg); |
| 5165 __ bind(deferred->check_maps()); | 5157 __ bind(deferred->check_maps()); |
| 5166 } | 5158 } |
| 5167 | 5159 |
| 5160 UniqueSet<Map> map_set = instr->hydrogen()->map_set(); |
| 5168 Label success; | 5161 Label success; |
| 5169 for (int i = 0; i < map_set->length() - 1; i++) { | 5162 for (int i = 0; i < map_set.size() - 1; i++) { |
| 5170 Handle<Map> map = map_set->at(i); | 5163 Handle<Map> map = map_set.at(i).handle(); |
| 5171 __ CompareMapAndBranch(map_reg, map, &success, eq, &success); | 5164 __ CompareMapAndBranch(map_reg, map, &success, eq, &success); |
| 5172 } | 5165 } |
| 5173 Handle<Map> map = map_set->last(); | 5166 Handle<Map> map = map_set.at(map_set.size() - 1).handle(); |
| 5174 // Do the CompareMap() directly within the Branch() and DeoptimizeIf(). | 5167 // Do the CompareMap() directly within the Branch() and DeoptimizeIf(). |
| 5175 if (instr->hydrogen()->has_migration_target()) { | 5168 if (instr->hydrogen()->has_migration_target()) { |
| 5176 __ Branch(deferred->entry(), ne, map_reg, Operand(map)); | 5169 __ Branch(deferred->entry(), ne, map_reg, Operand(map)); |
| 5177 } else { | 5170 } else { |
| 5178 DeoptimizeIf(ne, instr->environment(), map_reg, Operand(map)); | 5171 DeoptimizeIf(ne, instr->environment(), map_reg, Operand(map)); |
| 5179 } | 5172 } |
| 5180 | 5173 |
| 5181 __ bind(&success); | 5174 __ bind(&success); |
| 5182 } | 5175 } |
| 5183 | 5176 |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5787 __ Subu(scratch, result, scratch); | 5780 __ Subu(scratch, result, scratch); |
| 5788 __ lw(result, FieldMemOperand(scratch, | 5781 __ lw(result, FieldMemOperand(scratch, |
| 5789 FixedArray::kHeaderSize - kPointerSize)); | 5782 FixedArray::kHeaderSize - kPointerSize)); |
| 5790 __ bind(&done); | 5783 __ bind(&done); |
| 5791 } | 5784 } |
| 5792 | 5785 |
| 5793 | 5786 |
| 5794 #undef __ | 5787 #undef __ |
| 5795 | 5788 |
| 5796 } } // namespace v8::internal | 5789 } } // namespace v8::internal |
| OLD | NEW |