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

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

Issue 133443009: A64: Synchronize with r17441. (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-codegen-a64.h ('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 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 409
410 410
411 void LCodeGen::CallCodeGeneric(Handle<Code> code, 411 void LCodeGen::CallCodeGeneric(Handle<Code> code,
412 RelocInfo::Mode mode, 412 RelocInfo::Mode mode,
413 LInstruction* instr, 413 LInstruction* instr,
414 SafepointMode safepoint_mode) { 414 SafepointMode safepoint_mode) {
415 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 415 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
416 ASSERT(instr != NULL); 416 ASSERT(instr != NULL);
417 417
418 Assembler::BlockConstPoolScope scope(masm_); 418 Assembler::BlockConstPoolScope scope(masm_);
419 LPointerMap* pointers = instr->pointer_map();
420 RecordPosition(pointers->position());
421 __ Call(code, mode); 419 __ Call(code, mode);
422 RecordSafepointWithLazyDeopt(instr, safepoint_mode); 420 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
423 421
424 if ((code->kind() == Code::BINARY_OP_IC) || 422 if ((code->kind() == Code::BINARY_OP_IC) ||
425 (code->kind() == Code::COMPARE_IC)) { 423 (code->kind() == Code::COMPARE_IC)) {
426 // Signal that we don't inline smi code before these stubs in the 424 // Signal that we don't inline smi code before these stubs in the
427 // optimizing code generator. 425 // optimizing code generator.
428 InlineSmiCheckInfo::EmitNotInlined(masm()); 426 InlineSmiCheckInfo::EmitNotInlined(masm());
429 } 427 }
430 } 428 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 499
502 ASSERT(ToRegister(instr->result()).is(x0)); 500 ASSERT(ToRegister(instr->result()).is(x0));
503 } 501 }
504 502
505 503
506 void LCodeGen::CallRuntime(const Runtime::Function* function, 504 void LCodeGen::CallRuntime(const Runtime::Function* function,
507 int num_arguments, 505 int num_arguments,
508 LInstruction* instr, 506 LInstruction* instr,
509 SaveFPRegsMode save_doubles) { 507 SaveFPRegsMode save_doubles) {
510 ASSERT(instr != NULL); 508 ASSERT(instr != NULL);
511 LPointerMap* pointers = instr->pointer_map();
512 ASSERT(pointers != NULL);
513 RecordPosition(pointers->position());
514 509
515 __ CallRuntime(function, num_arguments, save_doubles); 510 __ CallRuntime(function, num_arguments, save_doubles);
516 511
517 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 512 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
518 } 513 }
519 514
520 515
521 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 516 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
522 int argc, 517 int argc,
523 LInstruction* instr) { 518 LInstruction* instr) {
524 __ CallRuntimeSaveDoubles(id); 519 __ CallRuntimeSaveDoubles(id);
525 RecordSafepointWithRegisters( 520 RecordSafepointWithRegisters(
526 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); 521 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
527 } 522 }
528 523
529 524
530 void LCodeGen::RecordPosition(int position) { 525 void LCodeGen::RecordAndWritePosition(int position) {
531 if (position == RelocInfo::kNoPosition) return; 526 if (position == RelocInfo::kNoPosition) return;
532 masm()->positions_recorder()->RecordPosition(position); 527 masm()->positions_recorder()->RecordPosition(position);
528 masm()->positions_recorder()->WriteRecordedPositions();
533 } 529 }
534 530
535 531
536 void LCodeGen::RecordAndUpdatePosition(int position) {
537 if (position >= 0 && position != old_position_) {
538 masm()->positions_recorder()->RecordPosition(position);
539 old_position_ = position;
540 }
541 }
542
543
544 void LCodeGen::RecordSafepointWithLazyDeopt(LInstruction* instr, 532 void LCodeGen::RecordSafepointWithLazyDeopt(LInstruction* instr,
545 SafepointMode safepoint_mode) { 533 SafepointMode safepoint_mode) {
546 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { 534 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
547 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); 535 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
548 } else { 536 } else {
549 ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 537 ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
550 RecordSafepointWithRegisters( 538 RecordSafepointWithRegisters(
551 instr->pointer_map(), 0, Safepoint::kLazyDeopt); 539 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
552 } 540 }
553 } 541 }
(...skipping 24 matching lines...) Expand all
578 } 566 }
579 } 567 }
580 568
581 void LCodeGen::RecordSafepoint(LPointerMap* pointers, 569 void LCodeGen::RecordSafepoint(LPointerMap* pointers,
582 Safepoint::DeoptMode deopt_mode) { 570 Safepoint::DeoptMode deopt_mode) {
583 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); 571 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode);
584 } 572 }
585 573
586 574
587 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { 575 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) {
588 LPointerMap empty_pointers(RelocInfo::kNoPosition, zone()); 576 LPointerMap empty_pointers(zone());
589 RecordSafepoint(&empty_pointers, deopt_mode); 577 RecordSafepoint(&empty_pointers, deopt_mode);
590 } 578 }
591 579
592 580
593 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 581 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
594 int arguments, 582 int arguments,
595 Safepoint::DeoptMode deopt_mode) { 583 Safepoint::DeoptMode deopt_mode) {
596 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, deopt_mode); 584 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, deopt_mode);
597 } 585 }
598 586
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 int receiver_offset = scope()->num_parameters() * kPointerSize; 629 int receiver_offset = scope()->num_parameters() * kPointerSize;
642 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); 630 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
643 __ Poke(x10, receiver_offset); 631 __ Poke(x10, receiver_offset);
644 __ Bind(&ok); 632 __ Bind(&ok);
645 } 633 }
646 } 634 }
647 635
648 ASSERT(__ StackPointer().Is(jssp)); 636 ASSERT(__ StackPointer().Is(jssp));
649 info()->set_prologue_offset(masm_->pc_offset()); 637 info()->set_prologue_offset(masm_->pc_offset());
650 if (NeedsEagerFrame()) { 638 if (NeedsEagerFrame()) {
651 if (info()->IsStub()) { 639 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
652 // TODO(jbramley): Does x1 contain a JSFunction here, or does it already
653 // have the special STUB smi?
654 __ Mov(x10, Operand(Smi::FromInt(StackFrame::STUB)));
655 // Compiled stubs don't age, and so they don't need the predictable code
656 // ageing sequence.
657 __ Push(lr, fp, cp, x10);
658 __ Add(fp, jssp, 2 * kPointerSize);
659 } else {
660 // This call emits the following sequence in a way that can be patched for
661 // code ageing support:
662 // Push(lr, fp, cp, x1);
663 // Add(fp, jssp, 2 * kPointerSize);
664 __ EmitFrameSetupForCodeAgePatching();
665 }
666 frame_is_built_ = true; 640 frame_is_built_ = true;
667 info_->AddNoFrameRange(0, masm_->pc_offset()); 641 info_->AddNoFrameRange(0, masm_->pc_offset());
668 } 642 }
669 643
670 // Reserve space for the stack slots needed by the code. 644 // Reserve space for the stack slots needed by the code.
671 int slots = GetStackSlotCount(); 645 int slots = GetStackSlotCount();
672 if (slots > 0) { 646 if (slots > 0) {
673 __ Claim(slots, kPointerSize); 647 __ Claim(slots, kPointerSize);
674 } 648 }
675 649
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 __ Claim(slots); 723 __ Claim(slots);
750 } 724 }
751 725
752 726
753 bool LCodeGen::GenerateDeferredCode() { 727 bool LCodeGen::GenerateDeferredCode() {
754 ASSERT(is_generating()); 728 ASSERT(is_generating());
755 if (deferred_.length() > 0) { 729 if (deferred_.length() > 0) {
756 for (int i = 0; !is_aborted() && (i < deferred_.length()); i++) { 730 for (int i = 0; !is_aborted() && (i < deferred_.length()); i++) {
757 LDeferredCode* code = deferred_[i]; 731 LDeferredCode* code = deferred_[i];
758 732
759 int pos = instructions_->at(code->instruction_index())->position(); 733 HValue* value =
760 RecordAndUpdatePosition(pos); 734 instructions_->at(code->instruction_index())->hydrogen_value();
735 RecordAndWritePosition(value->position());
761 736
762 Comment(";;; <@%d,#%d> " 737 Comment(";;; <@%d,#%d> "
763 "-------------------- Deferred %s --------------------", 738 "-------------------- Deferred %s --------------------",
764 code->instruction_index(), 739 code->instruction_index(),
765 code->instr()->hydrogen_value()->id(), 740 code->instr()->hydrogen_value()->id(),
766 code->instr()->Mnemonic()); 741 code->instr()->Mnemonic());
767 742
768 __ Bind(code->entry()); 743 __ Bind(code->entry());
769 744
770 if (NeedsDeferredFrame()) { 745 if (NeedsDeferredFrame()) {
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 } 1169 }
1195 1170
1196 1171
1197 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 1172 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
1198 Condition cond = nv; 1173 Condition cond = nv;
1199 switch (op) { 1174 switch (op) {
1200 case Token::EQ: 1175 case Token::EQ:
1201 case Token::EQ_STRICT: 1176 case Token::EQ_STRICT:
1202 cond = eq; 1177 cond = eq;
1203 break; 1178 break;
1179 case Token::NE:
1180 case Token::NE_STRICT:
1181 cond = ne;
1182 break;
1204 case Token::LT: 1183 case Token::LT:
1205 cond = is_unsigned ? lo : lt; 1184 cond = is_unsigned ? lo : lt;
1206 break; 1185 break;
1207 case Token::GT: 1186 case Token::GT:
1208 cond = is_unsigned ? hi : gt; 1187 cond = is_unsigned ? hi : gt;
1209 break; 1188 break;
1210 case Token::LTE: 1189 case Token::LTE:
1211 cond = is_unsigned ? ls : le; 1190 cond = is_unsigned ? ls : le;
1212 break; 1191 break;
1213 case Token::GTE: 1192 case Token::GTE:
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 __ Cbz(length, &invoke); 1474 __ Cbz(length, &invoke);
1496 __ Bind(&loop); 1475 __ Bind(&loop);
1497 __ Ldr(scratch, MemOperand(elements, length, LSL, kPointerSizeLog2)); 1476 __ Ldr(scratch, MemOperand(elements, length, LSL, kPointerSizeLog2));
1498 __ Push(scratch); 1477 __ Push(scratch);
1499 __ Subs(length, length, 1); 1478 __ Subs(length, length, 1);
1500 __ B(ne, &loop); 1479 __ B(ne, &loop);
1501 1480
1502 __ Bind(&invoke); 1481 __ Bind(&invoke);
1503 ASSERT(instr->HasPointerMap()); 1482 ASSERT(instr->HasPointerMap());
1504 LPointerMap* pointers = instr->pointer_map(); 1483 LPointerMap* pointers = instr->pointer_map();
1505 RecordPosition(pointers->position());
1506 SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt); 1484 SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt);
1507 // The number of arguments is stored in argc (receiver) which is x0, as 1485 // The number of arguments is stored in argc (receiver) which is x0, as
1508 // expected by InvokeFunction. 1486 // expected by InvokeFunction.
1509 ParameterCount actual(argc); 1487 ParameterCount actual(argc);
1510 __ InvokeFunction(function, actual, CALL_FUNCTION, 1488 __ InvokeFunction(function, actual, CALL_FUNCTION,
1511 safepoint_generator, CALL_AS_METHOD); 1489 safepoint_generator, CALL_AS_METHOD);
1512 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1490 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1513 } 1491 }
1514 1492
1515 1493
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1822 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 1800 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
1823 bool can_invoke_directly = 1801 bool can_invoke_directly =
1824 dont_adapt_arguments || formal_parameter_count == arity; 1802 dont_adapt_arguments || formal_parameter_count == arity;
1825 1803
1826 // The function interface relies on the following register assignments. 1804 // The function interface relies on the following register assignments.
1827 ASSERT(function_reg.Is(x1) || function_reg.IsNone()); 1805 ASSERT(function_reg.Is(x1) || function_reg.IsNone());
1828 Register arity_reg = x0; 1806 Register arity_reg = x0;
1829 Register call_kind_reg = x5; 1807 Register call_kind_reg = x5;
1830 1808
1831 LPointerMap* pointers = instr->pointer_map(); 1809 LPointerMap* pointers = instr->pointer_map();
1832 RecordPosition(pointers->position());
1833 1810
1834 // If necessary, load the function object. 1811 // If necessary, load the function object.
1835 if (function_reg.IsNone()) { 1812 if (function_reg.IsNone()) {
1836 function_reg = x1; 1813 function_reg = x1;
1837 __ LoadHeapObject(function_reg, function); 1814 __ LoadObject(function_reg, function);
1838 } 1815 }
1839 1816
1840 if (FLAG_debug_code) { 1817 if (FLAG_debug_code) {
1841 Label is_not_smi; 1818 Label is_not_smi;
1842 // Try to confirm that function_reg (x1) is a tagged pointer. 1819 // Try to confirm that function_reg (x1) is a tagged pointer.
1843 __ JumpIfNotSmi(function_reg, &is_not_smi); 1820 __ JumpIfNotSmi(function_reg, &is_not_smi);
1844 __ Abort(kExpectedFunctionObject); 1821 __ Abort(kExpectedFunctionObject);
1845 __ Bind(&is_not_smi); 1822 __ Bind(&is_not_smi);
1846 } 1823 }
1847 1824
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
2942 2919
2943 __ Bind(&return_false); 2920 __ Bind(&return_false);
2944 __ LoadRoot(result, Heap::kFalseValueRootIndex); 2921 __ LoadRoot(result, Heap::kFalseValueRootIndex);
2945 2922
2946 // Here result is either true or false. 2923 // Here result is either true or false.
2947 __ Bind(deferred->exit()); 2924 __ Bind(deferred->exit());
2948 __ Bind(&done); 2925 __ Bind(&done);
2949 } 2926 }
2950 2927
2951 2928
2952 void LCodeGen::DoInstanceSize(LInstanceSize* instr) {
2953 Register object = ToRegister(instr->object());
2954 Register result = ToRegister(instr->result());
2955 __ Ldr(result, FieldMemOperand(object, HeapObject::kMapOffset));
2956 __ Ldrb(result, FieldMemOperand(result, Map::kInstanceSizeOffset));
2957 }
2958
2959
2960 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 2929 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2961 Register result = ToRegister(instr->result()); 2930 Register result = ToRegister(instr->result());
2962 ASSERT(result.Is(x0)); // InstanceofStub returns its result in x0. 2931 ASSERT(result.Is(x0)); // InstanceofStub returns its result in x0.
2963 InstanceofStub::Flags flags = InstanceofStub::kNoFlags; 2932 InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
2964 flags = static_cast<InstanceofStub::Flags>( 2933 flags = static_cast<InstanceofStub::Flags>(
2965 flags | InstanceofStub::kArgsInRegisters); 2934 flags | InstanceofStub::kArgsInRegisters);
2966 flags = static_cast<InstanceofStub::Flags>( 2935 flags = static_cast<InstanceofStub::Flags>(
2967 flags | InstanceofStub::kReturnTrueFalseObject); 2936 flags | InstanceofStub::kReturnTrueFalseObject);
2968 flags = static_cast<InstanceofStub::Flags>( 2937 flags = static_cast<InstanceofStub::Flags>(
2969 flags | InstanceofStub::kCallSiteInlineCheck); 2938 flags | InstanceofStub::kCallSiteInlineCheck);
2970 2939
2971 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2940 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2972 2941
2973 // Prepare InstanceofStub arguments. 2942 // Prepare InstanceofStub arguments.
2974 ASSERT(ToRegister(instr->value()).Is(InstanceofStub::left())); 2943 ASSERT(ToRegister(instr->value()).Is(InstanceofStub::left()));
2975 __ LoadHeapObject(InstanceofStub::right(), instr->function()); 2944 __ LoadObject(InstanceofStub::right(), instr->function());
2976 2945
2977 InstanceofStub stub(flags); 2946 InstanceofStub stub(flags);
2978 CallCodeGeneric(stub.GetCode(isolate()), 2947 CallCodeGeneric(stub.GetCode(isolate()),
2979 RelocInfo::CODE_TARGET, 2948 RelocInfo::CODE_TARGET,
2980 instr, 2949 instr,
2981 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 2950 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
2982 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); 2951 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
2983 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 2952 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
2984 2953
2985 // Put the result value into the result register slot. 2954 // Put the result value into the result register slot.
(...skipping 25 matching lines...) Expand all
3011 2980
3012 2981
3013 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 2982 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3014 // The function is required to be in x1. 2983 // The function is required to be in x1.
3015 ASSERT(ToRegister(instr->function()).is(x1)); 2984 ASSERT(ToRegister(instr->function()).is(x1));
3016 ASSERT(instr->HasPointerMap()); 2985 ASSERT(instr->HasPointerMap());
3017 2986
3018 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 2987 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3019 if (known_function.is_null()) { 2988 if (known_function.is_null()) {
3020 LPointerMap* pointers = instr->pointer_map(); 2989 LPointerMap* pointers = instr->pointer_map();
3021 RecordPosition(pointers->position());
3022 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 2990 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3023 ParameterCount count(instr->arity()); 2991 ParameterCount count(instr->arity());
3024 __ InvokeFunction(x1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 2992 __ InvokeFunction(x1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
3025 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2993 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3026 } else { 2994 } else {
3027 CallKnownFunction(known_function, 2995 CallKnownFunction(known_function,
3028 instr->hydrogen()->formal_parameter_count(), 2996 instr->hydrogen()->formal_parameter_count(),
3029 instr->arity(), 2997 instr->arity(),
3030 instr, 2998 instr,
3031 CALL_AS_METHOD, 2999 CALL_AS_METHOD,
(...skipping 2117 matching lines...) Expand 10 before | Expand all | Expand 10 after
5149 DoubleRegister dbl_scratch1 = double_scratch(); 5117 DoubleRegister dbl_scratch1 = double_scratch();
5150 5118
5151 Label done; 5119 Label done;
5152 5120
5153 // Load heap object map. 5121 // Load heap object map.
5154 __ Ldr(scratch1, FieldMemOperand(input, HeapObject::kMapOffset)); 5122 __ Ldr(scratch1, FieldMemOperand(input, HeapObject::kMapOffset));
5155 5123
5156 if (instr->truncating()) { 5124 if (instr->truncating()) {
5157 Register output = ToRegister(instr->result()); 5125 Register output = ToRegister(instr->result());
5158 Register scratch2 = ToRegister(temp2); 5126 Register scratch2 = ToRegister(temp2);
5159 Label undefined; 5127 Label check_bools, undefined;
5160 5128
5161 // If it's not a heap number, jump to undefined check. 5129 // If it's not a heap number, jump to undefined check.
5162 __ JumpIfNotRoot(scratch1, Heap::kHeapNumberMapRootIndex, &undefined); 5130 __ JumpIfNotRoot(scratch1, Heap::kHeapNumberMapRootIndex, &check_bools);
5163 5131
5164 // A heap number: load value and convert to int32 using truncating function. 5132 // A heap number: load value and convert to int32 using truncating function.
5165 __ Ldr(dbl_scratch1, FieldMemOperand(input, HeapNumber::kValueOffset)); 5133 __ Ldr(dbl_scratch1, FieldMemOperand(input, HeapNumber::kValueOffset));
5166 __ ECMA262ToInt32(output, dbl_scratch1, scratch1, scratch2); 5134 __ ECMA262ToInt32(output, dbl_scratch1, scratch1, scratch2);
5167 __ B(&done); 5135 __ B(&done);
5168 5136
5137 __ Bind(&check_bools);
5138
5139 TODO_UNIMPLEMENTED("LTaggedToI: Truncate booleans to 0 or 1.");
5140
5169 // Check for undefined. Undefined is converted to zero for truncating 5141 // Check for undefined. Undefined is converted to zero for truncating
5170 // conversions. 5142 // conversions.
5171 __ Bind(&undefined); 5143 __ Bind(&undefined);
5172 5144
5173 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, 5145 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex,
5174 instr->environment()); 5146 instr->environment());
5175 __ Mov(output, 0); 5147 __ Mov(output, 0);
5176 } else { 5148 } else {
5177 Register output = ToRegister32(instr->result()); 5149 Register output = ToRegister32(instr->result());
5178 5150
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
5254 5226
5255 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5227 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5256 Label materialized; 5228 Label materialized;
5257 // Registers will be used as follows: 5229 // Registers will be used as follows:
5258 // x7 = literals array. 5230 // x7 = literals array.
5259 // x1 = regexp literal. 5231 // x1 = regexp literal.
5260 // x0 = regexp literal clone. 5232 // x0 = regexp literal clone.
5261 // x10-x12 are used as temporaries. 5233 // x10-x12 are used as temporaries.
5262 int literal_offset = 5234 int literal_offset =
5263 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); 5235 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5264 __ LoadHeapObject(x7, instr->hydrogen()->literals()); 5236 __ LoadObject(x7, instr->hydrogen()->literals());
5265 __ Ldr(x1, FieldMemOperand(x7, literal_offset)); 5237 __ Ldr(x1, FieldMemOperand(x7, literal_offset));
5266 __ JumpIfNotRoot(x1, Heap::kUndefinedValueRootIndex, &materialized); 5238 __ JumpIfNotRoot(x1, Heap::kUndefinedValueRootIndex, &materialized);
5267 5239
5268 // Create regexp literal using runtime function 5240 // Create regexp literal using runtime function
5269 // Result will be in x0. 5241 // Result will be in x0.
5270 __ Mov(x12, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); 5242 __ Mov(x12, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
5271 __ Mov(x11, Operand(instr->hydrogen()->pattern())); 5243 __ Mov(x11, Operand(instr->hydrogen()->pattern()));
5272 __ Mov(x10, Operand(instr->hydrogen()->flags())); 5244 __ Mov(x10, Operand(instr->hydrogen()->flags()));
5273 __ Push(x7, x12, x11, x10); 5245 __ Push(x7, x12, x11, x10);
5274 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); 5246 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
5334 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 5306 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5335 } 5307 }
5336 __ Bind(&not_applicable); 5308 __ Bind(&not_applicable);
5337 } 5309 }
5338 5310
5339 5311
5340 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 5312 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
5341 Register object = ToRegister(instr->object()); 5313 Register object = ToRegister(instr->object());
5342 Register temp1 = ToRegister(instr->temp1()); 5314 Register temp1 = ToRegister(instr->temp1());
5343 Register temp2 = ToRegister(instr->temp2()); 5315 Register temp2 = ToRegister(instr->temp2());
5344 __ TestJSArrayForAllocationMemento(object, temp1, temp2); 5316
5345 DeoptimizeIf(eq, instr->environment()); 5317 Label no_memento_found;
5318 __ JumpIfJSArrayHasAllocationMemento(object, temp1, temp2, &no_memento_found);
5319 Deoptimize(instr->environment());
5320 __ Bind(&no_memento_found);
5346 } 5321 }
5347 5322
5348 5323
5349 void LCodeGen::DoTruncateDoubleToIntOrSmi(LTruncateDoubleToIntOrSmi* instr) { 5324 void LCodeGen::DoTruncateDoubleToIntOrSmi(LTruncateDoubleToIntOrSmi* instr) {
5350 DoubleRegister input = ToDoubleRegister(instr->value()); 5325 DoubleRegister input = ToDoubleRegister(instr->value());
5351 Register result = ToRegister(instr->result()); 5326 Register result = ToRegister(instr->result());
5352 __ ECMA262ToInt32(result, input, 5327 __ ECMA262ToInt32(result, input,
5353 ToRegister(instr->temp1()), 5328 ToRegister(instr->temp1()),
5354 ToRegister(instr->temp2()), 5329 ToRegister(instr->temp2()),
5355 instr->tag_result() 5330 instr->tag_result()
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
5451 __ B(false_label); 5426 __ B(false_label);
5452 } 5427 }
5453 } 5428 }
5454 5429
5455 5430
5456 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 5431 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
5457 __ Ucvtf(ToDoubleRegister(instr->result()), ToRegister32(instr->value())); 5432 __ Ucvtf(ToDoubleRegister(instr->result()), ToRegister32(instr->value()));
5458 } 5433 }
5459 5434
5460 5435
5436 void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) {
5437 Register value = ToRegister(instr->value());
5438 Register result = ToRegister(instr->result());
5439
5440 if (!instr->hydrogen()->value()->HasRange() ||
5441 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
5442 DeoptimizeIfNegative(value.W(), instr->environment());
5443 }
5444 __ SmiTag(result, value);
5445 }
5446
5447
5461 void LCodeGen::DoValueOf(LValueOf* instr) { 5448 void LCodeGen::DoValueOf(LValueOf* instr) {
5462 Register input = ToRegister(instr->value()); 5449 Register input = ToRegister(instr->value());
5463 Register result = ToRegister(instr->result()); 5450 Register result = ToRegister(instr->result());
5464 Register scratch = ToRegister(instr->temp()); 5451 Register scratch = ToRegister(instr->temp());
5465 Label done; 5452 Label done;
5466 5453
5467 ASSERT(input.Is(result)); 5454 ASSERT(input.Is(result));
5468 5455
5469 if (!instr->hydrogen()->value()->IsHeapObject()) { 5456 if (!instr->hydrogen()->value()->IsHeapObject()) {
5470 // If the object is a smi return it. 5457 // If the object is a smi return it.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
5560 __ Bind(&out_of_object); 5547 __ Bind(&out_of_object);
5561 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 5548 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
5562 // Index is equal to negated out of object property index plus 1. 5549 // Index is equal to negated out of object property index plus 1.
5563 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 5550 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2));
5564 __ Ldr(result, FieldMemOperand(result, 5551 __ Ldr(result, FieldMemOperand(result,
5565 FixedArray::kHeaderSize - kPointerSize)); 5552 FixedArray::kHeaderSize - kPointerSize));
5566 __ Bind(&done); 5553 __ Bind(&done);
5567 } 5554 }
5568 5555
5569 } } // namespace v8::internal 5556 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698