| 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 2199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2210 int false_block = instr->FalseDestination(chunk_); | 2210 int false_block = instr->FalseDestination(chunk_); |
| 2211 __ b(condition, chunk_->GetAssemblyLabel(false_block)); | 2211 __ b(condition, chunk_->GetAssemblyLabel(false_block)); |
| 2212 } | 2212 } |
| 2213 | 2213 |
| 2214 | 2214 |
| 2215 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { | 2215 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { |
| 2216 __ stop("LBreak"); | 2216 __ stop("LBreak"); |
| 2217 } | 2217 } |
| 2218 | 2218 |
| 2219 | 2219 |
| 2220 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { | |
| 2221 Representation r = instr->hydrogen()->value()->representation(); | |
| 2222 if (r.IsSmiOrInteger32() || r.IsDouble()) { | |
| 2223 EmitBranch(instr, al); | |
| 2224 } else { | |
| 2225 ASSERT(r.IsTagged()); | |
| 2226 Register reg = ToRegister(instr->value()); | |
| 2227 HType type = instr->hydrogen()->value()->type(); | |
| 2228 if (type.IsTaggedNumber()) { | |
| 2229 EmitBranch(instr, al); | |
| 2230 } | |
| 2231 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | |
| 2232 __ ldr(scratch0(), FieldMemOperand(reg, HeapObject::kMapOffset)); | |
| 2233 __ CompareRoot(scratch0(), Heap::kHeapNumberMapRootIndex); | |
| 2234 EmitBranch(instr, eq); | |
| 2235 } | |
| 2236 } | |
| 2237 | |
| 2238 | |
| 2239 void LCodeGen::DoBranch(LBranch* instr) { | 2220 void LCodeGen::DoBranch(LBranch* instr) { |
| 2240 Representation r = instr->hydrogen()->value()->representation(); | 2221 Representation r = instr->hydrogen()->value()->representation(); |
| 2241 if (r.IsInteger32() || r.IsSmi()) { | 2222 if (r.IsInteger32() || r.IsSmi()) { |
| 2242 ASSERT(!info()->IsStub()); | 2223 ASSERT(!info()->IsStub()); |
| 2243 Register reg = ToRegister(instr->value()); | 2224 Register reg = ToRegister(instr->value()); |
| 2244 __ cmp(reg, Operand::Zero()); | 2225 __ cmp(reg, Operand::Zero()); |
| 2245 EmitBranch(instr, ne); | 2226 EmitBranch(instr, ne); |
| 2246 } else if (r.IsDouble()) { | 2227 } else if (r.IsDouble()) { |
| 2247 ASSERT(!info()->IsStub()); | 2228 ASSERT(!info()->IsStub()); |
| 2248 DwVfpRegister reg = ToDoubleRegister(instr->value()); | 2229 DwVfpRegister reg = ToDoubleRegister(instr->value()); |
| (...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3161 // Non-instance prototype: Fetch prototype from constructor field | 3142 // Non-instance prototype: Fetch prototype from constructor field |
| 3162 // in initial map. | 3143 // in initial map. |
| 3163 __ bind(&non_instance); | 3144 __ bind(&non_instance); |
| 3164 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); | 3145 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); |
| 3165 | 3146 |
| 3166 // All done. | 3147 // All done. |
| 3167 __ bind(&done); | 3148 __ bind(&done); |
| 3168 } | 3149 } |
| 3169 | 3150 |
| 3170 | 3151 |
| 3152 void LCodeGen::DoLoadRoot(LLoadRoot* instr) { |
| 3153 Register result = ToRegister(instr->result()); |
| 3154 __ LoadRoot(result, instr->index()); |
| 3155 } |
| 3156 |
| 3157 |
| 3171 void LCodeGen::DoLoadExternalArrayPointer( | 3158 void LCodeGen::DoLoadExternalArrayPointer( |
| 3172 LLoadExternalArrayPointer* instr) { | 3159 LLoadExternalArrayPointer* instr) { |
| 3173 Register to_reg = ToRegister(instr->result()); | 3160 Register to_reg = ToRegister(instr->result()); |
| 3174 Register from_reg = ToRegister(instr->object()); | 3161 Register from_reg = ToRegister(instr->object()); |
| 3175 __ ldr(to_reg, FieldMemOperand(from_reg, | 3162 __ ldr(to_reg, FieldMemOperand(from_reg, |
| 3176 ExternalArray::kExternalPointerOffset)); | 3163 ExternalArray::kExternalPointerOffset)); |
| 3177 } | 3164 } |
| 3178 | 3165 |
| 3179 | 3166 |
| 3180 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { | 3167 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4324 } else { | 4311 } else { |
| 4325 key = ToRegister(instr->key()); | 4312 key = ToRegister(instr->key()); |
| 4326 } | 4313 } |
| 4327 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4314 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4328 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4315 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4329 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4316 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4330 int additional_offset = instr->additional_index() << element_size_shift; | 4317 int additional_offset = instr->additional_index() << element_size_shift; |
| 4331 | 4318 |
| 4332 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4319 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 4333 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4320 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 4321 Register address = scratch0(); |
| 4334 DwVfpRegister value(ToDoubleRegister(instr->value())); | 4322 DwVfpRegister value(ToDoubleRegister(instr->value())); |
| 4335 Operand operand(key_is_constant | 4323 if (key_is_constant) { |
| 4336 ? Operand(constant_key << element_size_shift) | 4324 if (constant_key != 0) { |
| 4337 : Operand(key, LSL, shift_size)); | 4325 __ add(address, external_pointer, |
| 4338 __ add(scratch0(), external_pointer, operand); | 4326 Operand(constant_key << element_size_shift)); |
| 4327 } else { |
| 4328 address = external_pointer; |
| 4329 } |
| 4330 } else { |
| 4331 __ add(address, external_pointer, Operand(key, LSL, shift_size)); |
| 4332 } |
| 4339 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4333 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 4340 __ vcvt_f32_f64(double_scratch0().low(), value); | 4334 __ vcvt_f32_f64(double_scratch0().low(), value); |
| 4341 __ vstr(double_scratch0().low(), scratch0(), additional_offset); | 4335 __ vstr(double_scratch0().low(), address, additional_offset); |
| 4342 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 4336 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 4343 __ vstr(value, scratch0(), additional_offset); | 4337 __ vstr(value, address, additional_offset); |
| 4344 } | 4338 } |
| 4345 } else { | 4339 } else { |
| 4346 Register value(ToRegister(instr->value())); | 4340 Register value(ToRegister(instr->value())); |
| 4347 MemOperand mem_operand = PrepareKeyedOperand( | 4341 MemOperand mem_operand = PrepareKeyedOperand( |
| 4348 key, external_pointer, key_is_constant, constant_key, | 4342 key, external_pointer, key_is_constant, constant_key, |
| 4349 element_size_shift, shift_size, | 4343 element_size_shift, shift_size, |
| 4350 instr->additional_index(), additional_offset); | 4344 instr->additional_index(), additional_offset); |
| 4351 switch (elements_kind) { | 4345 switch (elements_kind) { |
| 4352 case EXTERNAL_PIXEL_ELEMENTS: | 4346 case EXTERNAL_PIXEL_ELEMENTS: |
| 4353 case EXTERNAL_BYTE_ELEMENTS: | 4347 case EXTERNAL_BYTE_ELEMENTS: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4375 UNREACHABLE(); | 4369 UNREACHABLE(); |
| 4376 break; | 4370 break; |
| 4377 } | 4371 } |
| 4378 } | 4372 } |
| 4379 } | 4373 } |
| 4380 | 4374 |
| 4381 | 4375 |
| 4382 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4376 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 4383 DwVfpRegister value = ToDoubleRegister(instr->value()); | 4377 DwVfpRegister value = ToDoubleRegister(instr->value()); |
| 4384 Register elements = ToRegister(instr->elements()); | 4378 Register elements = ToRegister(instr->elements()); |
| 4385 Register key = no_reg; | |
| 4386 Register scratch = scratch0(); | 4379 Register scratch = scratch0(); |
| 4380 DwVfpRegister double_scratch = double_scratch0(); |
| 4387 bool key_is_constant = instr->key()->IsConstantOperand(); | 4381 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4388 int constant_key = 0; | |
| 4389 | 4382 |
| 4390 // Calculate the effective address of the slot in the array to store the | 4383 // Calculate the effective address of the slot in the array to store the |
| 4391 // double value. | 4384 // double value. |
| 4385 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
| 4392 if (key_is_constant) { | 4386 if (key_is_constant) { |
| 4393 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4387 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4394 if (constant_key & 0xF0000000) { | 4388 if (constant_key & 0xF0000000) { |
| 4395 Abort(kArrayIndexConstantValueTooBig); | 4389 Abort(kArrayIndexConstantValueTooBig); |
| 4396 } | 4390 } |
| 4391 __ add(scratch, elements, |
| 4392 Operand((constant_key << element_size_shift) + |
| 4393 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
| 4397 } else { | 4394 } else { |
| 4398 key = ToRegister(instr->key()); | 4395 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4399 } | 4396 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4400 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 4397 __ add(scratch, elements, |
| 4401 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4398 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
| 4402 ? (element_size_shift - kSmiTagSize) : element_size_shift; | |
| 4403 Operand operand = key_is_constant | |
| 4404 ? Operand((constant_key << element_size_shift) + | |
| 4405 FixedDoubleArray::kHeaderSize - kHeapObjectTag) | |
| 4406 : Operand(key, LSL, shift_size); | |
| 4407 __ add(scratch, elements, operand); | |
| 4408 if (!key_is_constant) { | |
| 4409 __ add(scratch, scratch, | 4399 __ add(scratch, scratch, |
| 4410 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 4400 Operand(ToRegister(instr->key()), LSL, shift_size)); |
| 4411 } | 4401 } |
| 4412 | 4402 |
| 4413 if (instr->NeedsCanonicalization()) { | 4403 if (instr->NeedsCanonicalization()) { |
| 4414 // Force a canonical NaN. | 4404 // Force a canonical NaN. |
| 4415 if (masm()->emit_debug_code()) { | 4405 if (masm()->emit_debug_code()) { |
| 4416 __ vmrs(ip); | 4406 __ vmrs(ip); |
| 4417 __ tst(ip, Operand(kVFPDefaultNaNModeControlBit)); | 4407 __ tst(ip, Operand(kVFPDefaultNaNModeControlBit)); |
| 4418 __ Assert(ne, kDefaultNaNModeNotSet); | 4408 __ Assert(ne, kDefaultNaNModeNotSet); |
| 4419 } | 4409 } |
| 4420 __ VFPCanonicalizeNaN(value); | 4410 __ VFPCanonicalizeNaN(double_scratch, value); |
| 4411 __ vstr(double_scratch, scratch, |
| 4412 instr->additional_index() << element_size_shift); |
| 4413 } else { |
| 4414 __ vstr(value, scratch, instr->additional_index() << element_size_shift); |
| 4421 } | 4415 } |
| 4422 __ vstr(value, scratch, instr->additional_index() << element_size_shift); | |
| 4423 } | 4416 } |
| 4424 | 4417 |
| 4425 | 4418 |
| 4426 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4419 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4427 Register value = ToRegister(instr->value()); | 4420 Register value = ToRegister(instr->value()); |
| 4428 Register elements = ToRegister(instr->elements()); | 4421 Register elements = ToRegister(instr->elements()); |
| 4429 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) | 4422 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) |
| 4430 : no_reg; | 4423 : no_reg; |
| 4431 Register scratch = scratch0(); | 4424 Register scratch = scratch0(); |
| 4432 Register store_base = scratch; | 4425 Register store_base = scratch; |
| (...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5150 __ and_(scratch, scratch, Operand(mask)); | 5143 __ and_(scratch, scratch, Operand(mask)); |
| 5151 __ cmp(scratch, Operand(tag)); | 5144 __ cmp(scratch, Operand(tag)); |
| 5152 DeoptimizeIf(ne, instr->environment()); | 5145 DeoptimizeIf(ne, instr->environment()); |
| 5153 } | 5146 } |
| 5154 } | 5147 } |
| 5155 } | 5148 } |
| 5156 | 5149 |
| 5157 | 5150 |
| 5158 void LCodeGen::DoCheckValue(LCheckValue* instr) { | 5151 void LCodeGen::DoCheckValue(LCheckValue* instr) { |
| 5159 Register reg = ToRegister(instr->value()); | 5152 Register reg = ToRegister(instr->value()); |
| 5160 Handle<HeapObject> object = instr->hydrogen()->object(); | 5153 Handle<HeapObject> object = instr->hydrogen()->object().handle(); |
| 5161 AllowDeferredHandleDereference smi_check; | 5154 AllowDeferredHandleDereference smi_check; |
| 5162 if (isolate()->heap()->InNewSpace(*object)) { | 5155 if (isolate()->heap()->InNewSpace(*object)) { |
| 5163 Register reg = ToRegister(instr->value()); | 5156 Register reg = ToRegister(instr->value()); |
| 5164 Handle<Cell> cell = isolate()->factory()->NewCell(object); | 5157 Handle<Cell> cell = isolate()->factory()->NewCell(object); |
| 5165 __ mov(ip, Operand(Handle<Object>(cell))); | 5158 __ mov(ip, Operand(Handle<Object>(cell))); |
| 5166 __ ldr(ip, FieldMemOperand(ip, Cell::kValueOffset)); | 5159 __ ldr(ip, FieldMemOperand(ip, Cell::kValueOffset)); |
| 5167 __ cmp(reg, ip); | 5160 __ cmp(reg, ip); |
| 5168 } else { | 5161 } else { |
| 5169 __ cmp(reg, Operand(object)); | 5162 __ cmp(reg, Operand(object)); |
| 5170 } | 5163 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5202 Register object_; | 5195 Register object_; |
| 5203 }; | 5196 }; |
| 5204 | 5197 |
| 5205 if (instr->hydrogen()->CanOmitMapChecks()) return; | 5198 if (instr->hydrogen()->CanOmitMapChecks()) return; |
| 5206 Register map_reg = scratch0(); | 5199 Register map_reg = scratch0(); |
| 5207 | 5200 |
| 5208 LOperand* input = instr->value(); | 5201 LOperand* input = instr->value(); |
| 5209 ASSERT(input->IsRegister()); | 5202 ASSERT(input->IsRegister()); |
| 5210 Register reg = ToRegister(input); | 5203 Register reg = ToRegister(input); |
| 5211 | 5204 |
| 5212 SmallMapList* map_set = instr->hydrogen()->map_set(); | |
| 5213 __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); | 5205 __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 5214 | 5206 |
| 5215 DeferredCheckMaps* deferred = NULL; | 5207 DeferredCheckMaps* deferred = NULL; |
| 5216 if (instr->hydrogen()->has_migration_target()) { | 5208 if (instr->hydrogen()->has_migration_target()) { |
| 5217 deferred = new(zone()) DeferredCheckMaps(this, instr, reg); | 5209 deferred = new(zone()) DeferredCheckMaps(this, instr, reg); |
| 5218 __ bind(deferred->check_maps()); | 5210 __ bind(deferred->check_maps()); |
| 5219 } | 5211 } |
| 5220 | 5212 |
| 5213 UniqueSet<Map> map_set = instr->hydrogen()->map_set(); |
| 5221 Label success; | 5214 Label success; |
| 5222 for (int i = 0; i < map_set->length() - 1; i++) { | 5215 for (int i = 0; i < map_set.size() - 1; i++) { |
| 5223 Handle<Map> map = map_set->at(i); | 5216 Handle<Map> map = map_set.at(i).handle(); |
| 5224 __ CompareMap(map_reg, map, &success); | 5217 __ CompareMap(map_reg, map, &success); |
| 5225 __ b(eq, &success); | 5218 __ b(eq, &success); |
| 5226 } | 5219 } |
| 5227 | 5220 |
| 5228 Handle<Map> map = map_set->last(); | 5221 Handle<Map> map = map_set.at(map_set.size() - 1).handle(); |
| 5229 __ CompareMap(map_reg, map, &success); | 5222 __ CompareMap(map_reg, map, &success); |
| 5230 if (instr->hydrogen()->has_migration_target()) { | 5223 if (instr->hydrogen()->has_migration_target()) { |
| 5231 __ b(ne, deferred->entry()); | 5224 __ b(ne, deferred->entry()); |
| 5232 } else { | 5225 } else { |
| 5233 DeoptimizeIf(ne, instr->environment()); | 5226 DeoptimizeIf(ne, instr->environment()); |
| 5234 } | 5227 } |
| 5235 | 5228 |
| 5236 __ bind(&success); | 5229 __ bind(&success); |
| 5237 } | 5230 } |
| 5238 | 5231 |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5801 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5794 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5802 __ ldr(result, FieldMemOperand(scratch, | 5795 __ ldr(result, FieldMemOperand(scratch, |
| 5803 FixedArray::kHeaderSize - kPointerSize)); | 5796 FixedArray::kHeaderSize - kPointerSize)); |
| 5804 __ bind(&done); | 5797 __ bind(&done); |
| 5805 } | 5798 } |
| 5806 | 5799 |
| 5807 | 5800 |
| 5808 #undef __ | 5801 #undef __ |
| 5809 | 5802 |
| 5810 } } // namespace v8::internal | 5803 } } // namespace v8::internal |
| OLD | NEW |