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

Side by Side Diff: src/a64/lithium-codegen-a64.cc

Issue 155723005: A64: Synchronize with r19001. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/a64/lithium-a64.cc ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 } 426 }
427 } 427 }
428 428
429 429
430 void LCodeGen::DoCallFunction(LCallFunction* instr) { 430 void LCodeGen::DoCallFunction(LCallFunction* instr) {
431 ASSERT(ToRegister(instr->context()).is(cp)); 431 ASSERT(ToRegister(instr->context()).is(cp));
432 ASSERT(ToRegister(instr->function()).Is(x1)); 432 ASSERT(ToRegister(instr->function()).Is(x1));
433 ASSERT(ToRegister(instr->result()).Is(x0)); 433 ASSERT(ToRegister(instr->result()).Is(x0));
434 434
435 int arity = instr->arity(); 435 int arity = instr->arity();
436 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 436 CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
437 if (instr->hydrogen()->IsTailCall()) { 437 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
438 if (NeedsEagerFrame()) {
439 __ Mov(masm()->StackPointer(), fp);
440 }
441 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
442 } else {
443 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
444 }
445 } 438 }
446 439
447 440
448 void LCodeGen::DoCallNew(LCallNew* instr) { 441 void LCodeGen::DoCallNew(LCallNew* instr) {
449 ASSERT(ToRegister(instr->context()).is(cp)); 442 ASSERT(ToRegister(instr->context()).is(cp));
450 ASSERT(instr->IsMarkedAsCall()); 443 ASSERT(instr->IsMarkedAsCall());
451 ASSERT(ToRegister(instr->constructor()).is(x1)); 444 ASSERT(ToRegister(instr->constructor()).is(x1));
452 445
453 __ Mov(x0, instr->arity()); 446 __ Mov(x0, instr->arity());
454 // No cell in x2 for construct type feedback in optimized code. 447 // No cell in x2 for construct type feedback in optimized code.
(...skipping 2261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 void LCodeGen::DoDummy(LDummy* instr) { 2709 void LCodeGen::DoDummy(LDummy* instr) {
2717 // Nothing to see here, move on! 2710 // Nothing to see here, move on!
2718 } 2711 }
2719 2712
2720 2713
2721 void LCodeGen::DoDummyUse(LDummyUse* instr) { 2714 void LCodeGen::DoDummyUse(LDummyUse* instr) {
2722 // Nothing to see here, move on! 2715 // Nothing to see here, move on!
2723 } 2716 }
2724 2717
2725 2718
2726 void LCodeGen::DoElementsKind(LElementsKind* instr) {
2727 Register result = ToRegister(instr->result());
2728 Register input = ToRegister(instr->value());
2729
2730 // Load map into result.
2731 __ Ldr(result, FieldMemOperand(input, HeapObject::kMapOffset));
2732
2733 // Load the map's "bit field 2" into result.
2734 ASSERT((Map::kElementsKindBitCount + Map::kElementsKindShift) <= kByteSize);
2735 __ Ldrb(result.W(), FieldMemOperand(result, Map::kBitField2Offset));
2736
2737 // Retrieve elements_kind from bit field 2.
2738 __ Ubfx(result.W(), result.W(), Map::kElementsKindShift,
2739 Map::kElementsKindBitCount);
2740 }
2741
2742
2743 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 2719 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
2744 ASSERT(ToRegister(instr->context()).is(cp)); 2720 ASSERT(ToRegister(instr->context()).is(cp));
2745 // FunctionLiteral instruction is marked as call, we can trash any register. 2721 // FunctionLiteral instruction is marked as call, we can trash any register.
2746 ASSERT(instr->IsMarkedAsCall()); 2722 ASSERT(instr->IsMarkedAsCall());
2747 2723
2748 // Use the fast case closure allocation code that allocates in new 2724 // Use the fast case closure allocation code that allocates in new
2749 // space for nested functions that don't need literals cloning. 2725 // space for nested functions that don't need literals cloning.
2750 bool pretenure = instr->hydrogen()->pretenure(); 2726 bool pretenure = instr->hydrogen()->pretenure();
2751 if (!pretenure && instr->hydrogen()->has_no_literals()) { 2727 if (!pretenure && instr->hydrogen()->has_no_literals()) {
2752 FastNewClosureStub stub(instr->hydrogen()->language_mode(), 2728 FastNewClosureStub stub(instr->hydrogen()->language_mode(),
(...skipping 2300 matching lines...) Expand 10 before | Expand all | Expand 10 after
5053 return; 5029 return;
5054 } 5030 }
5055 5031
5056 Handle<Map> transition = instr->transition(); 5032 Handle<Map> transition = instr->transition();
5057 5033
5058 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 5034 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
5059 Register value = ToRegister(instr->value()); 5035 Register value = ToRegister(instr->value());
5060 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 5036 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
5061 DeoptimizeIfSmi(value, instr->environment()); 5037 DeoptimizeIfSmi(value, instr->environment());
5062 } 5038 }
5063 } else if (FLAG_track_double_fields && representation.IsDouble()) { 5039 } else if (representation.IsDouble()) {
5064 ASSERT(transition.is_null()); 5040 ASSERT(transition.is_null());
5065 ASSERT(access.IsInobject()); 5041 ASSERT(access.IsInobject());
5066 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 5042 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
5067 FPRegister value = ToDoubleRegister(instr->value()); 5043 FPRegister value = ToDoubleRegister(instr->value());
5068 __ Str(value, FieldMemOperand(object, offset)); 5044 __ Str(value, FieldMemOperand(object, offset));
5069 return; 5045 return;
5070 } 5046 }
5071 5047
5072 if (!transition.is_null()) { 5048 if (!transition.is_null()) {
5073 // Store the new map value. 5049 // Store the new map value.
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
5435 __ Push(x1, x0); 5411 __ Push(x1, x0);
5436 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); 5412 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5437 __ Pop(x1); 5413 __ Pop(x1);
5438 5414
5439 __ Bind(&allocated); 5415 __ Bind(&allocated);
5440 // Copy the content into the newly allocated memory. 5416 // Copy the content into the newly allocated memory.
5441 __ CopyFields(x0, x1, CPURegList(x10, x11, x12), size / kPointerSize); 5417 __ CopyFields(x0, x1, CPURegList(x10, x11, x12), size / kPointerSize);
5442 } 5418 }
5443 5419
5444 5420
5445 void LCodeGen::DoThrow(LThrow* instr) {
5446 ASSERT(ToRegister(instr->context()).is(cp));
5447 Register value = ToRegister(instr->value());
5448 __ Push(value);
5449 CallRuntime(Runtime::kThrow, 1, instr);
5450
5451 if (FLAG_debug_code) {
5452 __ Unreachable();
5453 }
5454 }
5455
5456
5457 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 5421 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
5458 Register object = ToRegister(instr->object()); 5422 Register object = ToRegister(instr->object());
5459 Register temp1 = ToRegister(instr->temp1()); 5423 Register temp1 = ToRegister(instr->temp1());
5460 5424
5461 Handle<Map> from_map = instr->original_map(); 5425 Handle<Map> from_map = instr->original_map();
5462 Handle<Map> to_map = instr->transitioned_map(); 5426 Handle<Map> to_map = instr->transitioned_map();
5463 ElementsKind from_kind = instr->from_kind(); 5427 ElementsKind from_kind = instr->from_kind();
5464 ElementsKind to_kind = instr->to_kind(); 5428 ElementsKind to_kind = instr->to_kind();
5465 5429
5466 Label not_applicable; 5430 Label not_applicable;
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
5620 !instr->hydrogen()->value()->range()->IsInSmiRange() || 5584 !instr->hydrogen()->value()->range()->IsInSmiRange() ||
5621 instr->hydrogen()->value()->range()->upper() == kMaxInt) { 5585 instr->hydrogen()->value()->range()->upper() == kMaxInt) {
5622 // The Range class can't express upper bounds in the (kMaxInt, kMaxUint32] 5586 // The Range class can't express upper bounds in the (kMaxInt, kMaxUint32]
5623 // interval, so we treat kMaxInt as a sentinel for this entire interval. 5587 // interval, so we treat kMaxInt as a sentinel for this entire interval.
5624 DeoptimizeIfNegative(value.W(), instr->environment()); 5588 DeoptimizeIfNegative(value.W(), instr->environment());
5625 } 5589 }
5626 __ SmiTag(result, value); 5590 __ SmiTag(result, value);
5627 } 5591 }
5628 5592
5629 5593
5630 void LCodeGen::DoValueOf(LValueOf* instr) {
5631 Register input = ToRegister(instr->value());
5632 Register result = ToRegister(instr->result());
5633 Register scratch = ToRegister(instr->temp());
5634 Label done;
5635
5636 ASSERT(input.Is(result));
5637
5638 if (!instr->hydrogen()->value()->IsHeapObject()) {
5639 // If the object is a smi return it.
5640 __ JumpIfSmi(input, &done);
5641 }
5642
5643 // If the object is not a value type, return the object, otherwise
5644 // return the value.
5645 __ JumpIfNotObjectType(input, scratch, scratch, JS_VALUE_TYPE, &done);
5646 __ Ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
5647
5648 __ Bind(&done);
5649 }
5650
5651
5652 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 5594 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5653 Register object = ToRegister(instr->value()); 5595 Register object = ToRegister(instr->value());
5654 Register map = ToRegister(instr->map()); 5596 Register map = ToRegister(instr->map());
5655 Register temp = ToRegister(instr->temp()); 5597 Register temp = ToRegister(instr->temp());
5656 __ Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset)); 5598 __ Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset));
5657 __ Cmp(map, temp); 5599 __ Cmp(map, temp);
5658 DeoptimizeIf(ne, instr->environment()); 5600 DeoptimizeIf(ne, instr->environment());
5659 } 5601 }
5660 5602
5661 5603
5662 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 5604 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
5663 Register receiver = ToRegister(instr->receiver()); 5605 Register receiver = ToRegister(instr->receiver());
5664 Register function = ToRegister(instr->function()); 5606 Register function = ToRegister(instr->function());
5665 Register result = ToRegister(instr->result()); 5607 Register result = ToRegister(instr->result());
5666 5608
5667 // If the receiver is null or undefined, we have to pass the global object as 5609 // If the receiver is null or undefined, we have to pass the global object as
5668 // a receiver to normal functions. Values have to be passed unchanged to 5610 // a receiver to normal functions. Values have to be passed unchanged to
5669 // builtins and strict-mode functions. 5611 // builtins and strict-mode functions.
5670 Label global_object, done, deopt; 5612 Label global_object, done, deopt;
5671 5613
5672 __ Ldr(result, FieldMemOperand(function, 5614 if (!instr->hydrogen()->known_function()) {
5673 JSFunction::kSharedFunctionInfoOffset)); 5615 __ Ldr(result, FieldMemOperand(function,
5616 JSFunction::kSharedFunctionInfoOffset));
5674 5617
5675 // CompilerHints is an int32 field. See objects.h. 5618 // CompilerHints is an int32 field. See objects.h.
5676 __ Ldr(result.W(), 5619 __ Ldr(result.W(),
5677 FieldMemOperand(result, SharedFunctionInfo::kCompilerHintsOffset)); 5620 FieldMemOperand(result, SharedFunctionInfo::kCompilerHintsOffset));
5678 5621
5679 // Do not transform the receiver to object for strict mode functions. 5622 // Do not transform the receiver to object for strict mode functions.
5680 __ Tbnz(result, SharedFunctionInfo::kStrictModeFunction, &done); 5623 __ Tbnz(result, SharedFunctionInfo::kStrictModeFunction, &done);
5681 5624
5682 // Do not transform the receiver to object for builtins. 5625 // Do not transform the receiver to object for builtins.
5683 __ Tbnz(result, SharedFunctionInfo::kNative, &done); 5626 __ Tbnz(result, SharedFunctionInfo::kNative, &done);
5627 }
5684 5628
5685 // Normal function. Replace undefined or null with global receiver. 5629 // Normal function. Replace undefined or null with global receiver.
5686 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &global_object); 5630 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &global_object);
5687 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, &global_object); 5631 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, &global_object);
5688 5632
5689 // Deoptimize if the receiver is not a JS object. 5633 // Deoptimize if the receiver is not a JS object.
5690 __ JumpIfSmi(receiver, &deopt); 5634 __ JumpIfSmi(receiver, &deopt);
5691 __ CompareObjectType(receiver, result, result, FIRST_SPEC_OBJECT_TYPE); 5635 __ CompareObjectType(receiver, result, result, FIRST_SPEC_OBJECT_TYPE);
5692 __ B(ge, &done); 5636 __ B(ge, &done);
5693 // Otherwise, fall through to deopt. 5637 // Otherwise, fall through to deopt.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5729 __ Bind(&out_of_object); 5673 __ Bind(&out_of_object);
5730 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 5674 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
5731 // Index is equal to negated out of object property index plus 1. 5675 // Index is equal to negated out of object property index plus 1.
5732 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 5676 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2));
5733 __ Ldr(result, FieldMemOperand(result, 5677 __ Ldr(result, FieldMemOperand(result,
5734 FixedArray::kHeaderSize - kPointerSize)); 5678 FixedArray::kHeaderSize - kPointerSize));
5735 __ Bind(&done); 5679 __ Bind(&done);
5736 } 5680 }
5737 5681
5738 } } // namespace v8::internal 5682 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/a64/lithium-a64.cc ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698