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

Side by Side Diff: src/ppc/code-stubs-ppc.cc

Issue 1250733005: SIMD.js Add the other SIMD Phase 1 types. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Make _IsSimdObject an assembly intrinsic in fullcodegen. Created 5 years, 4 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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_PPC 7 #if V8_TARGET_ARCH_PPC
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 Label not_identical; 253 Label not_identical;
254 Label heap_number, return_equal; 254 Label heap_number, return_equal;
255 __ cmp(r3, r4); 255 __ cmp(r3, r4);
256 __ bne(&not_identical); 256 __ bne(&not_identical);
257 257
258 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), 258 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
259 // so we do the second best thing - test it ourselves. 259 // so we do the second best thing - test it ourselves.
260 // They are both equal and they are not both Smis so both of them are not 260 // They are both equal and they are not both Smis so both of them are not
261 // Smis. If it's not a heap number, then return equal. 261 // Smis. If it's not a heap number, then return equal.
262 if (cond == lt || cond == gt) { 262 if (cond == lt || cond == gt) {
263 Label not_simd;
263 // Call runtime on identical JSObjects. 264 // Call runtime on identical JSObjects.
264 __ CompareObjectType(r3, r7, r7, FIRST_SPEC_OBJECT_TYPE); 265 __ CompareObjectType(r3, r7, r7, FIRST_SPEC_OBJECT_TYPE);
265 __ bge(slow); 266 __ bge(slow);
266 // Call runtime on identical symbols since we need to throw a TypeError. 267 // Call runtime on identical symbols since we need to throw a TypeError.
267 __ cmpi(r7, Operand(SYMBOL_TYPE)); 268 __ cmpi(r7, Operand(SYMBOL_TYPE));
268 __ beq(slow); 269 __ beq(slow);
269 // Call runtime on identical SIMD values since we must throw a TypeError. 270 // Call runtime on identical SIMD values since we must throw a TypeError.
270 __ cmpi(r7, Operand(FLOAT32X4_TYPE)); 271 __ cmpi(r7, Operand(FIRST_SIMD_VALUE_TYPE));
271 __ beq(slow); 272 __ blt(&not_simd);
273 __ cmpi(r7, Operand(LAST_SIMD_VALUE_TYPE));
274 __ ble(slow);
275 __ bind(&not_simd);
272 if (is_strong(strength)) { 276 if (is_strong(strength)) {
273 // Call the runtime on anything that is converted in the semantics, since 277 // Call the runtime on anything that is converted in the semantics, since
274 // we need to throw a TypeError. Smis have already been ruled out. 278 // we need to throw a TypeError. Smis have already been ruled out.
275 __ cmpi(r7, Operand(HEAP_NUMBER_TYPE)); 279 __ cmpi(r7, Operand(HEAP_NUMBER_TYPE));
276 __ beq(&return_equal); 280 __ beq(&return_equal);
277 __ andi(r0, r7, Operand(kIsNotStringMask)); 281 __ andi(r0, r7, Operand(kIsNotStringMask));
278 __ bne(slow, cr0); 282 __ bne(slow, cr0);
279 } 283 }
280 } else { 284 } else {
281 __ CompareObjectType(r3, r7, r7, HEAP_NUMBER_TYPE); 285 __ CompareObjectType(r3, r7, r7, HEAP_NUMBER_TYPE);
282 __ beq(&heap_number); 286 __ beq(&heap_number);
283 // Comparing JS objects with <=, >= is complicated. 287 // Comparing JS objects with <=, >= is complicated.
284 if (cond != eq) { 288 if (cond != eq) {
289 Label not_simd;
285 __ cmpi(r7, Operand(FIRST_SPEC_OBJECT_TYPE)); 290 __ cmpi(r7, Operand(FIRST_SPEC_OBJECT_TYPE));
286 __ bge(slow); 291 __ bge(slow);
287 // Call runtime on identical symbols since we need to throw a TypeError. 292 // Call runtime on identical symbols since we need to throw a TypeError.
288 __ cmpi(r7, Operand(SYMBOL_TYPE)); 293 __ cmpi(r7, Operand(SYMBOL_TYPE));
289 __ beq(slow); 294 __ beq(slow);
290 // Call runtime on identical SIMD values since we must throw a TypeError. 295 // Call runtime on identical SIMD values since we must throw a TypeError.
291 __ cmpi(r7, Operand(FLOAT32X4_TYPE)); 296 __ cmpi(r7, Operand(FIRST_SIMD_VALUE_TYPE));
292 __ beq(slow); 297 __ blt(&not_simd);
298 __ cmpi(r7, Operand(LAST_SIMD_VALUE_TYPE));
299 __ ble(slow);
300 __ bind(&not_simd);
293 if (is_strong(strength)) { 301 if (is_strong(strength)) {
294 // Call the runtime on anything that is converted in the semantics, 302 // Call the runtime on anything that is converted in the semantics,
295 // since we need to throw a TypeError. Smis and heap numbers have 303 // since we need to throw a TypeError. Smis and heap numbers have
296 // already been ruled out. 304 // already been ruled out.
297 __ andi(r0, r7, Operand(kIsNotStringMask)); 305 __ andi(r0, r7, Operand(kIsNotStringMask));
298 __ bne(slow, cr0); 306 __ bne(slow, cr0);
299 } 307 }
300 // Normally here we fall through to return_equal, but undefined is 308 // Normally here we fall through to return_equal, but undefined is
301 // special: (undefined == undefined) == true, but 309 // special: (undefined == undefined) == true, but
302 // (undefined <= undefined) == false! See ECMAScript 11.8.5. 310 // (undefined <= undefined) == false! See ECMAScript 11.8.5.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 __ cmpi(r3, Operand::Zero()); 362 __ cmpi(r3, Operand::Zero());
355 // For equal we already have the right value in r3: Return zero (equal) 363 // For equal we already have the right value in r3: Return zero (equal)
356 // if all bits in mantissa are zero (it's an Infinity) and non-zero if 364 // if all bits in mantissa are zero (it's an Infinity) and non-zero if
357 // not (it's a NaN). For <= and >= we need to load r0 with the failing 365 // not (it's a NaN). For <= and >= we need to load r0 with the failing
358 // value if it's a NaN. 366 // value if it's a NaN.
359 if (cond != eq) { 367 if (cond != eq) {
360 if (CpuFeatures::IsSupported(ISELECT)) { 368 if (CpuFeatures::IsSupported(ISELECT)) {
361 __ li(r4, Operand((cond == le) ? GREATER : LESS)); 369 __ li(r4, Operand((cond == le) ? GREATER : LESS));
362 __ isel(eq, r3, r3, r4); 370 __ isel(eq, r3, r3, r4);
363 } else { 371 } else {
372 Label not_equal;
373 __ bne(&not_equal);
364 // All-zero means Infinity means equal. 374 // All-zero means Infinity means equal.
365 __ Ret(eq); 375 __ Ret();
376 __ bind(&not_equal);
366 if (cond == le) { 377 if (cond == le) {
367 __ li(r3, Operand(GREATER)); // NaN <= NaN should fail. 378 __ li(r3, Operand(GREATER)); // NaN <= NaN should fail.
368 } else { 379 } else {
369 __ li(r3, Operand(LESS)); // NaN >= NaN should fail. 380 __ li(r3, Operand(LESS)); // NaN >= NaN should fail.
370 } 381 }
371 } 382 }
372 } 383 }
373 __ Ret(); 384 __ Ret();
374 } 385 }
375 // No fall through here. 386 // No fall through here.
(...skipping 10 matching lines...) Expand all
386 397
387 Label rhs_is_smi; 398 Label rhs_is_smi;
388 __ JumpIfSmi(rhs, &rhs_is_smi); 399 __ JumpIfSmi(rhs, &rhs_is_smi);
389 400
390 // Lhs is a Smi. Check whether the rhs is a heap number. 401 // Lhs is a Smi. Check whether the rhs is a heap number.
391 __ CompareObjectType(rhs, r6, r7, HEAP_NUMBER_TYPE); 402 __ CompareObjectType(rhs, r6, r7, HEAP_NUMBER_TYPE);
392 if (strict) { 403 if (strict) {
393 // If rhs is not a number and lhs is a Smi then strict equality cannot 404 // If rhs is not a number and lhs is a Smi then strict equality cannot
394 // succeed. Return non-equal 405 // succeed. Return non-equal
395 // If rhs is r3 then there is already a non zero value in it. 406 // If rhs is r3 then there is already a non zero value in it.
407 Label skip;
408 __ beq(&skip);
396 if (!rhs.is(r3)) { 409 if (!rhs.is(r3)) {
397 Label skip;
398 __ beq(&skip);
399 __ mov(r3, Operand(NOT_EQUAL)); 410 __ mov(r3, Operand(NOT_EQUAL));
400 __ Ret();
401 __ bind(&skip);
402 } else {
403 __ Ret(ne);
404 } 411 }
412 __ Ret();
413 __ bind(&skip);
405 } else { 414 } else {
406 // Smi compared non-strictly with a non-Smi non-heap-number. Call 415 // Smi compared non-strictly with a non-Smi non-heap-number. Call
407 // the runtime. 416 // the runtime.
408 __ bne(slow); 417 __ bne(slow);
409 } 418 }
410 419
411 // Lhs is a smi, rhs is a number. 420 // Lhs is a smi, rhs is a number.
412 // Convert lhs to a double in d7. 421 // Convert lhs to a double in d7.
413 __ SmiToDouble(d7, lhs); 422 __ SmiToDouble(d7, lhs);
414 // Load the double from rhs, tagged HeapNumber r3, to d6. 423 // Load the double from rhs, tagged HeapNumber r3, to d6.
415 __ lfd(d6, FieldMemOperand(rhs, HeapNumber::kValueOffset)); 424 __ lfd(d6, FieldMemOperand(rhs, HeapNumber::kValueOffset));
416 425
417 // We now have both loaded as doubles but we can skip the lhs nan check 426 // We now have both loaded as doubles but we can skip the lhs nan check
418 // since it's a smi. 427 // since it's a smi.
419 __ b(lhs_not_nan); 428 __ b(lhs_not_nan);
420 429
421 __ bind(&rhs_is_smi); 430 __ bind(&rhs_is_smi);
422 // Rhs is a smi. Check whether the non-smi lhs is a heap number. 431 // Rhs is a smi. Check whether the non-smi lhs is a heap number.
423 __ CompareObjectType(lhs, r7, r7, HEAP_NUMBER_TYPE); 432 __ CompareObjectType(lhs, r7, r7, HEAP_NUMBER_TYPE);
424 if (strict) { 433 if (strict) {
425 // If lhs is not a number and rhs is a smi then strict equality cannot 434 // If lhs is not a number and rhs is a smi then strict equality cannot
426 // succeed. Return non-equal. 435 // succeed. Return non-equal.
427 // If lhs is r3 then there is already a non zero value in it. 436 // If lhs is r3 then there is already a non zero value in it.
437 Label skip;
438 __ beq(&skip);
428 if (!lhs.is(r3)) { 439 if (!lhs.is(r3)) {
429 Label skip;
430 __ beq(&skip);
431 __ mov(r3, Operand(NOT_EQUAL)); 440 __ mov(r3, Operand(NOT_EQUAL));
432 __ Ret();
433 __ bind(&skip);
434 } else {
435 __ Ret(ne);
436 } 441 }
442 __ Ret();
443 __ bind(&skip);
437 } else { 444 } else {
438 // Smi compared non-strictly with a non-smi non-heap-number. Call 445 // Smi compared non-strictly with a non-smi non-heap-number. Call
439 // the runtime. 446 // the runtime.
440 __ bne(slow); 447 __ bne(slow);
441 } 448 }
442 449
443 // Rhs is a smi, lhs is a heap number. 450 // Rhs is a smi, lhs is a heap number.
444 // Load the double from lhs, tagged HeapNumber r4, to d7. 451 // Load the double from lhs, tagged HeapNumber r4, to d7.
445 __ lfd(d7, FieldMemOperand(lhs, HeapNumber::kValueOffset)); 452 __ lfd(d7, FieldMemOperand(lhs, HeapNumber::kValueOffset));
446 // Convert rhs to a double in d6. 453 // Convert rhs to a double in d6.
(...skipping 3513 matching lines...) Expand 10 before | Expand all | Expand 10 after
3960 // Handle not identical strings. 3967 // Handle not identical strings.
3961 3968
3962 // Check that both strings are internalized strings. If they are, we're done 3969 // Check that both strings are internalized strings. If they are, we're done
3963 // because we already know they are not identical. We know they are both 3970 // because we already know they are not identical. We know they are both
3964 // strings. 3971 // strings.
3965 if (equality) { 3972 if (equality) {
3966 DCHECK(GetCondition() == eq); 3973 DCHECK(GetCondition() == eq);
3967 STATIC_ASSERT(kInternalizedTag == 0); 3974 STATIC_ASSERT(kInternalizedTag == 0);
3968 __ orx(tmp3, tmp1, tmp2); 3975 __ orx(tmp3, tmp1, tmp2);
3969 __ andi(r0, tmp3, Operand(kIsNotInternalizedMask)); 3976 __ andi(r0, tmp3, Operand(kIsNotInternalizedMask));
3977 __ bne(&is_symbol, cr0);
3970 // Make sure r3 is non-zero. At this point input operands are 3978 // Make sure r3 is non-zero. At this point input operands are
3971 // guaranteed to be non-zero. 3979 // guaranteed to be non-zero.
3972 DCHECK(right.is(r3)); 3980 DCHECK(right.is(r3));
3973 __ Ret(eq, cr0); 3981 __ Ret();
3982 __ bind(&is_symbol);
3974 } 3983 }
3975 3984
3976 // Check that both strings are sequential one-byte. 3985 // Check that both strings are sequential one-byte.
3977 Label runtime; 3986 Label runtime;
3978 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(tmp1, tmp2, tmp3, tmp4, 3987 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(tmp1, tmp2, tmp3, tmp4,
3979 &runtime); 3988 &runtime);
3980 3989
3981 // Compare flat one-byte strings. Returns when done. 3990 // Compare flat one-byte strings. Returns when done.
3982 if (equality) { 3991 if (equality) {
3983 StringHelper::GenerateFlatOneByteStringEquals(masm, left, right, tmp1, 3992 StringHelper::GenerateFlatOneByteStringEquals(masm, left, right, tmp1,
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
4200 // the hash in a separate instruction. The value hash + i + i * i is right 4209 // the hash in a separate instruction. The value hash + i + i * i is right
4201 // shifted in the following and instruction. 4210 // shifted in the following and instruction.
4202 DCHECK(NameDictionary::GetProbeOffset(i) < 4211 DCHECK(NameDictionary::GetProbeOffset(i) <
4203 1 << (32 - Name::kHashFieldOffset)); 4212 1 << (32 - Name::kHashFieldOffset));
4204 __ addi(scratch2, scratch2, 4213 __ addi(scratch2, scratch2,
4205 Operand(NameDictionary::GetProbeOffset(i) << Name::kHashShift)); 4214 Operand(NameDictionary::GetProbeOffset(i) << Name::kHashShift));
4206 } 4215 }
4207 __ srwi(scratch2, scratch2, Operand(Name::kHashShift)); 4216 __ srwi(scratch2, scratch2, Operand(Name::kHashShift));
4208 __ and_(scratch2, scratch1, scratch2); 4217 __ and_(scratch2, scratch1, scratch2);
4209 4218
4210 // Scale the index by multiplying by the entry size. 4219 // Scale the index by multiplying by the element size.
4211 STATIC_ASSERT(NameDictionary::kEntrySize == 3); 4220 STATIC_ASSERT(NameDictionary::kEntrySize == 3);
4212 // scratch2 = scratch2 * 3. 4221 // scratch2 = scratch2 * 3.
4213 __ ShiftLeftImm(ip, scratch2, Operand(1)); 4222 __ ShiftLeftImm(ip, scratch2, Operand(1));
4214 __ add(scratch2, scratch2, ip); 4223 __ add(scratch2, scratch2, ip);
4215 4224
4216 // Check if the key is identical to the name. 4225 // Check if the key is identical to the name.
4217 __ ShiftLeftImm(ip, scratch2, Operand(kPointerSizeLog2)); 4226 __ ShiftLeftImm(ip, scratch2, Operand(kPointerSizeLog2));
4218 __ add(scratch2, elements, ip); 4227 __ add(scratch2, elements, ip);
4219 __ LoadP(ip, FieldMemOperand(scratch2, kElementsStartOffset)); 4228 __ LoadP(ip, FieldMemOperand(scratch2, kElementsStartOffset));
4220 __ cmp(name, ip); 4229 __ cmp(name, ip);
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after
5305 Label fast_elements_case; 5314 Label fast_elements_case;
5306 __ cmpi(r6, Operand(FAST_ELEMENTS)); 5315 __ cmpi(r6, Operand(FAST_ELEMENTS));
5307 __ beq(&fast_elements_case); 5316 __ beq(&fast_elements_case);
5308 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 5317 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
5309 5318
5310 __ bind(&fast_elements_case); 5319 __ bind(&fast_elements_case);
5311 GenerateCase(masm, FAST_ELEMENTS); 5320 GenerateCase(masm, FAST_ELEMENTS);
5312 } 5321 }
5313 5322
5314 5323
5315 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) {
5316 Register context = cp;
5317 Register result = r3;
5318 Register slot = r5;
5319
5320 // Go up the context chain to the script context.
5321 for (int i = 0; i < depth(); ++i) {
5322 __ LoadP(result, ContextOperand(context, Context::PREVIOUS_INDEX));
5323 context = result;
5324 }
5325
5326 // Load the PropertyCell value at the specified slot.
5327 __ ShiftLeftImm(r0, slot, Operand(kPointerSizeLog2));
5328 __ add(result, context, r0);
5329 __ LoadP(result, ContextOperand(result));
5330 __ LoadP(result, FieldMemOperand(result, PropertyCell::kValueOffset));
5331
5332 // If the result is not the_hole, return. Otherwise, handle in the runtime.
5333 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
5334 __ Ret(ne);
5335
5336 // Fallback to runtime.
5337 __ SmiTag(slot);
5338 __ Push(slot);
5339 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 1, 1);
5340 }
5341
5342
5343 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) {
5344 Register value = r3;
5345 Register slot = r5;
5346
5347 Register cell = r4;
5348 Register cell_details = r6;
5349 Register cell_value = r7;
5350 Register cell_value_map = r8;
5351 Register scratch = r9;
5352
5353 Register context = cp;
5354 Register context_temp = cell;
5355
5356 Label fast_heapobject_case, fast_smi_case, slow_case;
5357
5358 if (FLAG_debug_code) {
5359 __ CompareRoot(value, Heap::kTheHoleValueRootIndex);
5360 __ Check(ne, kUnexpectedValue);
5361 }
5362
5363 // Go up the context chain to the script context.
5364 for (int i = 0; i < depth(); i++) {
5365 __ LoadP(context_temp, ContextOperand(context, Context::PREVIOUS_INDEX));
5366 context = context_temp;
5367 }
5368
5369 // Load the PropertyCell at the specified slot.
5370 __ ShiftLeftImm(r0, slot, Operand(kPointerSizeLog2));
5371 __ add(cell, context, r0);
5372 __ LoadP(cell, ContextOperand(cell));
5373
5374 // Load PropertyDetails for the cell (actually only the cell_type and kind).
5375 __ LoadP(cell_details, FieldMemOperand(cell, PropertyCell::kDetailsOffset));
5376 __ SmiUntag(cell_details);
5377 __ andi(cell_details, cell_details,
5378 Operand(PropertyDetails::PropertyCellTypeField::kMask |
5379 PropertyDetails::KindField::kMask |
5380 PropertyDetails::kAttributesReadOnlyMask));
5381
5382 // Check if PropertyCell holds mutable data.
5383 Label not_mutable_data;
5384 __ cmpi(cell_details, Operand(PropertyDetails::PropertyCellTypeField::encode(
5385 PropertyCellType::kMutable) |
5386 PropertyDetails::KindField::encode(kData)));
5387 __ bne(&not_mutable_data);
5388 __ JumpIfSmi(value, &fast_smi_case);
5389
5390 __ bind(&fast_heapobject_case);
5391 __ StoreP(value, FieldMemOperand(cell, PropertyCell::kValueOffset), r0);
5392 // RecordWriteField clobbers the value register, so we copy it before the
5393 // call.
5394 __ mr(r6, value);
5395 __ RecordWriteField(cell, PropertyCell::kValueOffset, r6, scratch,
5396 kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
5397 OMIT_SMI_CHECK);
5398 __ Ret();
5399
5400 __ bind(&not_mutable_data);
5401 // Check if PropertyCell value matches the new value (relevant for Constant,
5402 // ConstantType and Undefined cells).
5403 Label not_same_value;
5404 __ LoadP(cell_value, FieldMemOperand(cell, PropertyCell::kValueOffset));
5405 __ cmp(cell_value, value);
5406 __ bne(&not_same_value);
5407
5408 // Make sure the PropertyCell is not marked READ_ONLY.
5409 __ andi(r0, cell_details, Operand(PropertyDetails::kAttributesReadOnlyMask));
5410 __ bne(&slow_case, cr0);
5411
5412 if (FLAG_debug_code) {
5413 Label done;
5414 // This can only be true for Constant, ConstantType and Undefined cells,
5415 // because we never store the_hole via this stub.
5416 __ cmpi(cell_details,
5417 Operand(PropertyDetails::PropertyCellTypeField::encode(
5418 PropertyCellType::kConstant) |
5419 PropertyDetails::KindField::encode(kData)));
5420 __ beq(&done);
5421 __ cmpi(cell_details,
5422 Operand(PropertyDetails::PropertyCellTypeField::encode(
5423 PropertyCellType::kConstantType) |
5424 PropertyDetails::KindField::encode(kData)));
5425 __ beq(&done);
5426 __ cmpi(cell_details,
5427 Operand(PropertyDetails::PropertyCellTypeField::encode(
5428 PropertyCellType::kUndefined) |
5429 PropertyDetails::KindField::encode(kData)));
5430 __ Check(eq, kUnexpectedValue);
5431 __ bind(&done);
5432 }
5433 __ Ret();
5434 __ bind(&not_same_value);
5435
5436 // Check if PropertyCell contains data with constant type (and is not
5437 // READ_ONLY).
5438 __ cmpi(cell_details, Operand(PropertyDetails::PropertyCellTypeField::encode(
5439 PropertyCellType::kConstantType) |
5440 PropertyDetails::KindField::encode(kData)));
5441 __ bne(&slow_case);
5442
5443 // Now either both old and new values must be smis or both must be heap
5444 // objects with same map.
5445 Label value_is_heap_object;
5446 __ JumpIfNotSmi(value, &value_is_heap_object);
5447 __ JumpIfNotSmi(cell_value, &slow_case);
5448 // Old and new values are smis, no need for a write barrier here.
5449 __ bind(&fast_smi_case);
5450 __ StoreP(value, FieldMemOperand(cell, PropertyCell::kValueOffset), r0);
5451 __ Ret();
5452
5453 __ bind(&value_is_heap_object);
5454 __ JumpIfSmi(cell_value, &slow_case);
5455
5456 __ LoadP(cell_value_map, FieldMemOperand(cell_value, HeapObject::kMapOffset));
5457 __ LoadP(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
5458 __ cmp(cell_value_map, scratch);
5459 __ beq(&fast_heapobject_case);
5460
5461 // Fallback to runtime.
5462 __ bind(&slow_case);
5463 __ SmiTag(slot);
5464 __ Push(slot, value);
5465 __ TailCallRuntime(is_strict(language_mode())
5466 ? Runtime::kStoreGlobalViaContext_Strict
5467 : Runtime::kStoreGlobalViaContext_Sloppy,
5468 2, 1);
5469 }
5470
5471
5472 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { 5324 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
5473 return ref0.address() - ref1.address(); 5325 return ref0.address() - ref1.address();
5474 } 5326 }
5475 5327
5476 5328
5477 // Calls an API function. Allocates HandleScope, extracts returned value 5329 // Calls an API function. Allocates HandleScope, extracts returned value
5478 // from handle and propagates exceptions. Restores context. stack_space 5330 // from handle and propagates exceptions. Restores context. stack_space
5479 // - space to be unwound on exit (includes the call JS arguments space and 5331 // - space to be unwound on exit (includes the call JS arguments space and
5480 // the additional space allocated for the fast call). 5332 // the additional space allocated for the fast call).
5481 static void CallApiFunctionAndReturn(MacroAssembler* masm, 5333 static void CallApiFunctionAndReturn(MacroAssembler* masm,
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
5826 kStackUnwindSpace, NULL, 5678 kStackUnwindSpace, NULL,
5827 MemOperand(fp, 6 * kPointerSize), NULL); 5679 MemOperand(fp, 6 * kPointerSize), NULL);
5828 } 5680 }
5829 5681
5830 5682
5831 #undef __ 5683 #undef __
5832 } // namespace internal 5684 } // namespace internal
5833 } // namespace v8 5685 } // namespace v8
5834 5686
5835 #endif // V8_TARGET_ARCH_PPC 5687 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« src/macros.py ('K') | « src/objects-printer.cc ('k') | src/ppc/lithium-codegen-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698