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

Side by Side Diff: src/arm/lithium-codegen-arm.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/arm/lithium-codegen-arm.h ('k') | src/arm/lithium-gap-resolver-arm.cc » ('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 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 // r1: Callee's JS function. 114 // r1: Callee's JS function.
115 // cp: Callee's context. 115 // cp: Callee's context.
116 // fp: Caller's frame pointer. 116 // fp: Caller's frame pointer.
117 // lr: Caller's pc. 117 // lr: Caller's pc.
118 118
119 // Strict mode functions and builtins need to replace the receiver 119 // Strict mode functions and builtins need to replace the receiver
120 // with undefined when called as functions (without an explicit 120 // with undefined when called as functions (without an explicit
121 // receiver object). r5 is zero for method calls and non-zero for 121 // receiver object). r5 is zero for method calls and non-zero for
122 // function calls. 122 // function calls.
123 if (!info_->is_classic_mode() || info_->is_native()) { 123 if (!info_->is_classic_mode() || info_->is_native()) {
124 Label ok;
125 __ cmp(r5, Operand::Zero()); 124 __ cmp(r5, Operand::Zero());
126 __ b(eq, &ok);
127 int receiver_offset = scope()->num_parameters() * kPointerSize; 125 int receiver_offset = scope()->num_parameters() * kPointerSize;
128 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); 126 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
129 __ str(r2, MemOperand(sp, receiver_offset)); 127 __ str(r2, MemOperand(sp, receiver_offset), ne);
130 __ bind(&ok);
131 } 128 }
132 } 129 }
133 130
134 info()->set_prologue_offset(masm_->pc_offset()); 131 info()->set_prologue_offset(masm_->pc_offset());
135 if (NeedsEagerFrame()) { 132 if (NeedsEagerFrame()) {
136 if (info()->IsStub()) { 133 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
137 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
138 __ Push(Smi::FromInt(StackFrame::STUB));
139 // Adjust FP to point to saved FP.
140 __ add(fp, sp, Operand(2 * kPointerSize));
141 } else {
142 PredictableCodeSizeScope predictible_code_size_scope(
143 masm_, kNoCodeAgeSequenceLength * Assembler::kInstrSize);
144 // The following three instructions must remain together and unmodified
145 // for code aging to work properly.
146 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
147 __ nop(ip.code());
148 // Adjust FP to point to saved FP.
149 __ add(fp, sp, Operand(2 * kPointerSize));
150 }
151 frame_is_built_ = true; 134 frame_is_built_ = true;
152 info_->AddNoFrameRange(0, masm_->pc_offset()); 135 info_->AddNoFrameRange(0, masm_->pc_offset());
153 } 136 }
154 137
155 // Reserve space for the stack slots needed by the code. 138 // Reserve space for the stack slots needed by the code.
156 int slots = GetStackSlotCount(); 139 int slots = GetStackSlotCount();
157 if (slots > 0) { 140 if (slots > 0) {
158 if (FLAG_debug_code) { 141 if (FLAG_debug_code) {
159 __ sub(sp, sp, Operand(slots * kPointerSize)); 142 __ sub(sp, sp, Operand(slots * kPointerSize));
160 __ push(r0); 143 __ push(r0);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 __ sub(sp, sp, Operand(slots * kPointerSize)); 235 __ sub(sp, sp, Operand(slots * kPointerSize));
253 } 236 }
254 237
255 238
256 bool LCodeGen::GenerateDeferredCode() { 239 bool LCodeGen::GenerateDeferredCode() {
257 ASSERT(is_generating()); 240 ASSERT(is_generating());
258 if (deferred_.length() > 0) { 241 if (deferred_.length() > 0) {
259 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 242 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
260 LDeferredCode* code = deferred_[i]; 243 LDeferredCode* code = deferred_[i];
261 244
262 int pos = instructions_->at(code->instruction_index())->position(); 245 HValue* value =
263 RecordAndUpdatePosition(pos); 246 instructions_->at(code->instruction_index())->hydrogen_value();
247 RecordAndWritePosition(value->position());
264 248
265 Comment(";;; <@%d,#%d> " 249 Comment(";;; <@%d,#%d> "
266 "-------------------- Deferred %s --------------------", 250 "-------------------- Deferred %s --------------------",
267 code->instruction_index(), 251 code->instruction_index(),
268 code->instr()->hydrogen_value()->id(), 252 code->instr()->hydrogen_value()->id(),
269 code->instr()->Mnemonic()); 253 code->instr()->Mnemonic());
270 __ bind(code->entry()); 254 __ bind(code->entry());
271 if (NeedsDeferredFrame()) { 255 if (NeedsDeferredFrame()) {
272 Comment(";;; Build frame"); 256 Comment(";;; Build frame");
273 ASSERT(!frame_is_built_); 257 ASSERT(!frame_is_built_);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 HConstant* constant = chunk_->LookupConstant(const_op); 378 HConstant* constant = chunk_->LookupConstant(const_op);
395 Handle<Object> literal = constant->handle(isolate()); 379 Handle<Object> literal = constant->handle(isolate());
396 Representation r = chunk_->LookupLiteralRepresentation(const_op); 380 Representation r = chunk_->LookupLiteralRepresentation(const_op);
397 if (r.IsInteger32()) { 381 if (r.IsInteger32()) {
398 ASSERT(literal->IsNumber()); 382 ASSERT(literal->IsNumber());
399 __ mov(scratch, Operand(static_cast<int32_t>(literal->Number()))); 383 __ mov(scratch, Operand(static_cast<int32_t>(literal->Number())));
400 } else if (r.IsDouble()) { 384 } else if (r.IsDouble()) {
401 Abort(kEmitLoadRegisterUnsupportedDoubleImmediate); 385 Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
402 } else { 386 } else {
403 ASSERT(r.IsSmiOrTagged()); 387 ASSERT(r.IsSmiOrTagged());
404 __ LoadObject(scratch, literal); 388 __ Move(scratch, literal);
405 } 389 }
406 return scratch; 390 return scratch;
407 } else if (op->IsStackSlot() || op->IsArgument()) { 391 } else if (op->IsStackSlot() || op->IsArgument()) {
408 __ ldr(scratch, ToMemOperand(op)); 392 __ ldr(scratch, ToMemOperand(op));
409 return scratch; 393 return scratch;
410 } 394 }
411 UNREACHABLE(); 395 UNREACHABLE();
412 return scratch; 396 return scratch;
413 } 397 }
414 398
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 void LCodeGen::CallCodeGeneric(Handle<Code> code, 662 void LCodeGen::CallCodeGeneric(Handle<Code> code,
679 RelocInfo::Mode mode, 663 RelocInfo::Mode mode,
680 LInstruction* instr, 664 LInstruction* instr,
681 SafepointMode safepoint_mode, 665 SafepointMode safepoint_mode,
682 TargetAddressStorageMode storage_mode) { 666 TargetAddressStorageMode storage_mode) {
683 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 667 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
684 ASSERT(instr != NULL); 668 ASSERT(instr != NULL);
685 // Block literal pool emission to ensure nop indicating no inlined smi code 669 // Block literal pool emission to ensure nop indicating no inlined smi code
686 // is in the correct position. 670 // is in the correct position.
687 Assembler::BlockConstPoolScope block_const_pool(masm()); 671 Assembler::BlockConstPoolScope block_const_pool(masm());
688 LPointerMap* pointers = instr->pointer_map();
689 RecordPosition(pointers->position());
690 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode); 672 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode);
691 RecordSafepointWithLazyDeopt(instr, safepoint_mode); 673 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
692 674
693 // Signal that we don't inline smi code before these stubs in the 675 // Signal that we don't inline smi code before these stubs in the
694 // optimizing code generator. 676 // optimizing code generator.
695 if (code->kind() == Code::BINARY_OP_IC || 677 if (code->kind() == Code::BINARY_OP_IC ||
696 code->kind() == Code::COMPARE_IC) { 678 code->kind() == Code::COMPARE_IC) {
697 __ nop(); 679 __ nop();
698 } 680 }
699 } 681 }
700 682
701 683
702 void LCodeGen::CallRuntime(const Runtime::Function* function, 684 void LCodeGen::CallRuntime(const Runtime::Function* function,
703 int num_arguments, 685 int num_arguments,
704 LInstruction* instr, 686 LInstruction* instr,
705 SaveFPRegsMode save_doubles) { 687 SaveFPRegsMode save_doubles) {
706 ASSERT(instr != NULL); 688 ASSERT(instr != NULL);
707 LPointerMap* pointers = instr->pointer_map();
708 ASSERT(pointers != NULL);
709 RecordPosition(pointers->position());
710 689
711 __ CallRuntime(function, num_arguments, save_doubles); 690 __ CallRuntime(function, num_arguments, save_doubles);
712 691
713 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 692 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
714 } 693 }
715 694
716 695
717 void LCodeGen::LoadContextFromDeferred(LOperand* context) { 696 void LCodeGen::LoadContextFromDeferred(LOperand* context) {
718 if (context->IsRegister()) { 697 if (context->IsRegister()) {
719 __ Move(cp, ToRegister(context)); 698 __ Move(cp, ToRegister(context));
720 } else if (context->IsStackSlot()) { 699 } else if (context->IsStackSlot()) {
721 __ ldr(cp, ToMemOperand(context)); 700 __ ldr(cp, ToMemOperand(context));
722 } else if (context->IsConstantOperand()) { 701 } else if (context->IsConstantOperand()) {
723 HConstant* constant = 702 HConstant* constant =
724 chunk_->LookupConstant(LConstantOperand::cast(context)); 703 chunk_->LookupConstant(LConstantOperand::cast(context));
725 __ LoadObject(cp, Handle<Object>::cast(constant->handle(isolate()))); 704 __ Move(cp, Handle<Object>::cast(constant->handle(isolate())));
726 } else { 705 } else {
727 UNREACHABLE(); 706 UNREACHABLE();
728 } 707 }
729 } 708 }
730 709
731 710
732 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 711 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
733 int argc, 712 int argc,
734 LInstruction* instr, 713 LInstruction* instr,
735 LOperand* context) { 714 LOperand* context) {
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 } 936 }
958 937
959 938
960 void LCodeGen::RecordSafepoint(LPointerMap* pointers, 939 void LCodeGen::RecordSafepoint(LPointerMap* pointers,
961 Safepoint::DeoptMode deopt_mode) { 940 Safepoint::DeoptMode deopt_mode) {
962 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); 941 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode);
963 } 942 }
964 943
965 944
966 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { 945 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) {
967 LPointerMap empty_pointers(RelocInfo::kNoPosition, zone()); 946 LPointerMap empty_pointers(zone());
968 RecordSafepoint(&empty_pointers, deopt_mode); 947 RecordSafepoint(&empty_pointers, deopt_mode);
969 } 948 }
970 949
971 950
972 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 951 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
973 int arguments, 952 int arguments,
974 Safepoint::DeoptMode deopt_mode) { 953 Safepoint::DeoptMode deopt_mode) {
975 RecordSafepoint( 954 RecordSafepoint(
976 pointers, Safepoint::kWithRegisters, arguments, deopt_mode); 955 pointers, Safepoint::kWithRegisters, arguments, deopt_mode);
977 } 956 }
978 957
979 958
980 void LCodeGen::RecordSafepointWithRegistersAndDoubles( 959 void LCodeGen::RecordSafepointWithRegistersAndDoubles(
981 LPointerMap* pointers, 960 LPointerMap* pointers,
982 int arguments, 961 int arguments,
983 Safepoint::DeoptMode deopt_mode) { 962 Safepoint::DeoptMode deopt_mode) {
984 RecordSafepoint( 963 RecordSafepoint(
985 pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode); 964 pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode);
986 } 965 }
987 966
988 967
989 void LCodeGen::RecordPosition(int position) { 968 void LCodeGen::RecordAndWritePosition(int position) {
990 if (position == RelocInfo::kNoPosition) return; 969 if (position == RelocInfo::kNoPosition) return;
991 masm()->positions_recorder()->RecordPosition(position); 970 masm()->positions_recorder()->RecordPosition(position);
971 masm()->positions_recorder()->WriteRecordedPositions();
992 } 972 }
993 973
994 974
995 void LCodeGen::RecordAndUpdatePosition(int position) {
996 if (position >= 0 && position != old_position_) {
997 masm()->positions_recorder()->RecordPosition(position);
998 old_position_ = position;
999 }
1000 }
1001
1002
1003 static const char* LabelType(LLabel* label) { 975 static const char* LabelType(LLabel* label) {
1004 if (label->is_loop_header()) return " (loop header)"; 976 if (label->is_loop_header()) return " (loop header)";
1005 if (label->is_osr_entry()) return " (OSR entry)"; 977 if (label->is_osr_entry()) return " (OSR entry)";
1006 return ""; 978 return "";
1007 } 979 }
1008 980
1009 981
1010 void LCodeGen::DoLabel(LLabel* label) { 982 void LCodeGen::DoLabel(LLabel* label) {
1011 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", 983 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------",
1012 current_instruction_, 984 current_instruction_,
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
1858 1830
1859 1831
1860 void LCodeGen::DoConstantE(LConstantE* instr) { 1832 void LCodeGen::DoConstantE(LConstantE* instr) {
1861 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1833 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1862 } 1834 }
1863 1835
1864 1836
1865 void LCodeGen::DoConstantT(LConstantT* instr) { 1837 void LCodeGen::DoConstantT(LConstantT* instr) {
1866 Handle<Object> value = instr->value(isolate()); 1838 Handle<Object> value = instr->value(isolate());
1867 AllowDeferredHandleDereference smi_check; 1839 AllowDeferredHandleDereference smi_check;
1868 __ LoadObject(ToRegister(instr->result()), value); 1840 __ Move(ToRegister(instr->result()), value);
1869 } 1841 }
1870 1842
1871 1843
1872 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1844 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1873 Register result = ToRegister(instr->result()); 1845 Register result = ToRegister(instr->result());
1874 Register map = ToRegister(instr->value()); 1846 Register map = ToRegister(instr->value());
1875 __ EnumLength(result, map); 1847 __ EnumLength(result, map);
1876 } 1848 }
1877 1849
1878 1850
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 } 2301 }
2330 2302
2331 2303
2332 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 2304 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
2333 Condition cond = kNoCondition; 2305 Condition cond = kNoCondition;
2334 switch (op) { 2306 switch (op) {
2335 case Token::EQ: 2307 case Token::EQ:
2336 case Token::EQ_STRICT: 2308 case Token::EQ_STRICT:
2337 cond = eq; 2309 cond = eq;
2338 break; 2310 break;
2311 case Token::NE:
2312 case Token::NE_STRICT:
2313 cond = ne;
2314 break;
2339 case Token::LT: 2315 case Token::LT:
2340 cond = is_unsigned ? lo : lt; 2316 cond = is_unsigned ? lo : lt;
2341 break; 2317 break;
2342 case Token::GT: 2318 case Token::GT:
2343 cond = is_unsigned ? hi : gt; 2319 cond = is_unsigned ? hi : gt;
2344 break; 2320 break;
2345 case Token::LTE: 2321 case Token::LTE:
2346 cond = is_unsigned ? ls : le; 2322 cond = is_unsigned ? ls : le;
2347 break; 2323 break;
2348 case Token::GTE: 2324 case Token::GTE:
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
2811 InstanceofStub stub(flags); 2787 InstanceofStub stub(flags);
2812 2788
2813 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2789 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2814 LoadContextFromDeferred(instr->context()); 2790 LoadContextFromDeferred(instr->context());
2815 2791
2816 // Get the temp register reserved by the instruction. This needs to be r4 as 2792 // Get the temp register reserved by the instruction. This needs to be r4 as
2817 // its slot of the pushing of safepoint registers is used to communicate the 2793 // its slot of the pushing of safepoint registers is used to communicate the
2818 // offset to the location of the map check. 2794 // offset to the location of the map check.
2819 Register temp = ToRegister(instr->temp()); 2795 Register temp = ToRegister(instr->temp());
2820 ASSERT(temp.is(r4)); 2796 ASSERT(temp.is(r4));
2821 __ LoadHeapObject(InstanceofStub::right(), instr->function()); 2797 __ Move(InstanceofStub::right(), instr->function());
2822 static const int kAdditionalDelta = 5; 2798 static const int kAdditionalDelta = 5;
2823 // Make sure that code size is predicable, since we use specific constants 2799 // Make sure that code size is predicable, since we use specific constants
2824 // offsets in the code to find embedded values.. 2800 // offsets in the code to find embedded values..
2825 PredictableCodeSizeScope predictable(masm_, 6 * Assembler::kInstrSize); 2801 PredictableCodeSizeScope predictable(masm_, 6 * Assembler::kInstrSize);
2826 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; 2802 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
2827 Label before_push_delta; 2803 Label before_push_delta;
2828 __ bind(&before_push_delta); 2804 __ bind(&before_push_delta);
2829 __ BlockConstPoolFor(kAdditionalDelta); 2805 __ BlockConstPoolFor(kAdditionalDelta);
2830 __ mov(temp, Operand(delta * kPointerSize)); 2806 __ mov(temp, Operand(delta * kPointerSize));
2831 // The mov above can generate one or two instructions. The delta was computed 2807 // The mov above can generate one or two instructions. The delta was computed
2832 // for two instructions, so we need to pad here in case of one instruction. 2808 // for two instructions, so we need to pad here in case of one instruction.
2833 if (masm_->InstructionsGeneratedSince(&before_push_delta) != 2) { 2809 if (masm_->InstructionsGeneratedSince(&before_push_delta) != 2) {
2834 ASSERT_EQ(1, masm_->InstructionsGeneratedSince(&before_push_delta)); 2810 ASSERT_EQ(1, masm_->InstructionsGeneratedSince(&before_push_delta));
2835 __ nop(); 2811 __ nop();
2836 } 2812 }
2837 __ StoreToSafepointRegisterSlot(temp, temp); 2813 __ StoreToSafepointRegisterSlot(temp, temp);
2838 CallCodeGeneric(stub.GetCode(isolate()), 2814 CallCodeGeneric(stub.GetCode(isolate()),
2839 RelocInfo::CODE_TARGET, 2815 RelocInfo::CODE_TARGET,
2840 instr, 2816 instr,
2841 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 2817 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
2842 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); 2818 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
2843 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 2819 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
2844 // Put the result value into the result register slot and 2820 // Put the result value into the result register slot and
2845 // restore all registers. 2821 // restore all registers.
2846 __ StoreToSafepointRegisterSlot(result, result); 2822 __ StoreToSafepointRegisterSlot(result, result);
2847 } 2823 }
2848 2824
2849 2825
2850 void LCodeGen::DoInstanceSize(LInstanceSize* instr) {
2851 Register object = ToRegister(instr->object());
2852 Register result = ToRegister(instr->result());
2853 __ ldr(result, FieldMemOperand(object, HeapObject::kMapOffset));
2854 __ ldrb(result, FieldMemOperand(result, Map::kInstanceSizeOffset));
2855 }
2856
2857
2858 void LCodeGen::DoCmpT(LCmpT* instr) { 2826 void LCodeGen::DoCmpT(LCmpT* instr) {
2859 ASSERT(ToRegister(instr->context()).is(cp)); 2827 ASSERT(ToRegister(instr->context()).is(cp));
2860 Token::Value op = instr->op(); 2828 Token::Value op = instr->op();
2861 2829
2862 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 2830 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
2863 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2831 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2864 // This instruction also signals no smi code inlined. 2832 // This instruction also signals no smi code inlined.
2865 __ cmp(r0, Operand::Zero()); 2833 __ cmp(r0, Operand::Zero());
2866 2834
2867 Condition condition = ComputeCompareCondition(op); 2835 Condition condition = ComputeCompareCondition(op);
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
3504 __ b(eq, &invoke); 3472 __ b(eq, &invoke);
3505 __ bind(&loop); 3473 __ bind(&loop);
3506 __ ldr(scratch, MemOperand(elements, length, LSL, 2)); 3474 __ ldr(scratch, MemOperand(elements, length, LSL, 2));
3507 __ push(scratch); 3475 __ push(scratch);
3508 __ sub(length, length, Operand(1), SetCC); 3476 __ sub(length, length, Operand(1), SetCC);
3509 __ b(ne, &loop); 3477 __ b(ne, &loop);
3510 3478
3511 __ bind(&invoke); 3479 __ bind(&invoke);
3512 ASSERT(instr->HasPointerMap()); 3480 ASSERT(instr->HasPointerMap());
3513 LPointerMap* pointers = instr->pointer_map(); 3481 LPointerMap* pointers = instr->pointer_map();
3514 RecordPosition(pointers->position());
3515 SafepointGenerator safepoint_generator( 3482 SafepointGenerator safepoint_generator(
3516 this, pointers, Safepoint::kLazyDeopt); 3483 this, pointers, Safepoint::kLazyDeopt);
3517 // The number of arguments is stored in receiver which is r0, as expected 3484 // The number of arguments is stored in receiver which is r0, as expected
3518 // by InvokeFunction. 3485 // by InvokeFunction.
3519 ParameterCount actual(receiver); 3486 ParameterCount actual(receiver);
3520 __ InvokeFunction(function, actual, CALL_FUNCTION, 3487 __ InvokeFunction(function, actual, CALL_FUNCTION,
3521 safepoint_generator, CALL_AS_METHOD); 3488 safepoint_generator, CALL_AS_METHOD);
3522 } 3489 }
3523 3490
3524 3491
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3560 Register context = ToRegister(instr->context()); 3527 Register context = ToRegister(instr->context());
3561 Register result = ToRegister(instr->result()); 3528 Register result = ToRegister(instr->result());
3562 __ ldr(result, 3529 __ ldr(result,
3563 MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); 3530 MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3564 } 3531 }
3565 3532
3566 3533
3567 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3534 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3568 ASSERT(ToRegister(instr->context()).is(cp)); 3535 ASSERT(ToRegister(instr->context()).is(cp));
3569 __ push(cp); // The context is the first argument. 3536 __ push(cp); // The context is the first argument.
3570 __ LoadHeapObject(scratch0(), instr->hydrogen()->pairs()); 3537 __ Move(scratch0(), instr->hydrogen()->pairs());
3571 __ push(scratch0()); 3538 __ push(scratch0());
3572 __ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); 3539 __ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags())));
3573 __ push(scratch0()); 3540 __ push(scratch0());
3574 CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3541 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3575 } 3542 }
3576 3543
3577 3544
3578 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 3545 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3579 Register context = ToRegister(instr->context()); 3546 Register context = ToRegister(instr->context());
3580 Register result = ToRegister(instr->result()); 3547 Register result = ToRegister(instr->result());
(...skipping 13 matching lines...) Expand all
3594 int arity, 3561 int arity,
3595 LInstruction* instr, 3562 LInstruction* instr,
3596 CallKind call_kind, 3563 CallKind call_kind,
3597 R1State r1_state) { 3564 R1State r1_state) {
3598 bool dont_adapt_arguments = 3565 bool dont_adapt_arguments =
3599 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 3566 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3600 bool can_invoke_directly = 3567 bool can_invoke_directly =
3601 dont_adapt_arguments || formal_parameter_count == arity; 3568 dont_adapt_arguments || formal_parameter_count == arity;
3602 3569
3603 LPointerMap* pointers = instr->pointer_map(); 3570 LPointerMap* pointers = instr->pointer_map();
3604 RecordPosition(pointers->position());
3605 3571
3606 if (can_invoke_directly) { 3572 if (can_invoke_directly) {
3607 if (r1_state == R1_UNINITIALIZED) { 3573 if (r1_state == R1_UNINITIALIZED) {
3608 __ LoadHeapObject(r1, function); 3574 __ Move(r1, function);
3609 } 3575 }
3610 3576
3611 // Change context. 3577 // Change context.
3612 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 3578 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
3613 3579
3614 // Set r0 to arguments count if adaption is not needed. Assumes that r0 3580 // Set r0 to arguments count if adaption is not needed. Assumes that r0
3615 // is available to write to at this point. 3581 // is available to write to at this point.
3616 if (dont_adapt_arguments) { 3582 if (dont_adapt_arguments) {
3617 __ mov(r0, Operand(arity)); 3583 __ mov(r0, Operand(arity));
3618 } 3584 }
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
4006 3972
4007 3973
4008 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3974 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
4009 ASSERT(ToRegister(instr->context()).is(cp)); 3975 ASSERT(ToRegister(instr->context()).is(cp));
4010 ASSERT(ToRegister(instr->function()).is(r1)); 3976 ASSERT(ToRegister(instr->function()).is(r1));
4011 ASSERT(instr->HasPointerMap()); 3977 ASSERT(instr->HasPointerMap());
4012 3978
4013 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 3979 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
4014 if (known_function.is_null()) { 3980 if (known_function.is_null()) {
4015 LPointerMap* pointers = instr->pointer_map(); 3981 LPointerMap* pointers = instr->pointer_map();
4016 RecordPosition(pointers->position());
4017 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3982 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
4018 ParameterCount count(instr->arity()); 3983 ParameterCount count(instr->arity());
4019 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 3984 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
4020 } else { 3985 } else {
4021 CallKnownFunction(known_function, 3986 CallKnownFunction(known_function,
4022 instr->hydrogen()->formal_parameter_count(), 3987 instr->hydrogen()->formal_parameter_count(),
4023 instr->arity(), 3988 instr->arity(),
4024 instr, 3989 instr,
4025 CALL_AS_METHOD, 3990 CALL_AS_METHOD,
4026 R1_CONTAINS_TARGET); 3991 R1_CONTAINS_TARGET);
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
4537 RecordSafepointWithRegistersAndDoubles( 4502 RecordSafepointWithRegistersAndDoubles(
4538 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4503 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4539 } 4504 }
4540 __ bind(&not_applicable); 4505 __ bind(&not_applicable);
4541 } 4506 }
4542 4507
4543 4508
4544 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4509 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4545 Register object = ToRegister(instr->object()); 4510 Register object = ToRegister(instr->object());
4546 Register temp = ToRegister(instr->temp()); 4511 Register temp = ToRegister(instr->temp());
4547 __ TestJSArrayForAllocationMemento(object, temp); 4512 Label no_memento_found;
4513 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
4548 DeoptimizeIf(eq, instr->environment()); 4514 DeoptimizeIf(eq, instr->environment());
4515 __ bind(&no_memento_found);
4549 } 4516 }
4550 4517
4551 4518
4552 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4519 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4553 ASSERT(ToRegister(instr->context()).is(cp)); 4520 ASSERT(ToRegister(instr->context()).is(cp));
4554 __ push(ToRegister(instr->left())); 4521 __ push(ToRegister(instr->left()));
4555 __ push(ToRegister(instr->right())); 4522 __ push(ToRegister(instr->right()));
4556 StringAddStub stub(instr->hydrogen()->flags()); 4523 StringAddStub stub(instr->hydrogen()->flags());
4557 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4524 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4558 } 4525 }
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
4676 __ vmov(single_scratch, scratch); 4643 __ vmov(single_scratch, scratch);
4677 } else { 4644 } else {
4678 __ vmov(single_scratch, ToRegister(input)); 4645 __ vmov(single_scratch, ToRegister(input));
4679 } 4646 }
4680 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); 4647 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
4681 } 4648 }
4682 4649
4683 4650
4684 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { 4651 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4685 LOperand* input = instr->value(); 4652 LOperand* input = instr->value();
4686 ASSERT(input->IsRegister());
4687 LOperand* output = instr->result(); 4653 LOperand* output = instr->result();
4688 ASSERT(output->IsRegister());
4689 __ SmiTag(ToRegister(output), ToRegister(input), SetCC); 4654 __ SmiTag(ToRegister(output), ToRegister(input), SetCC);
4690 if (!instr->hydrogen()->value()->HasRange() || 4655 if (!instr->hydrogen()->value()->HasRange() ||
4691 !instr->hydrogen()->value()->range()->IsInSmiRange()) { 4656 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4692 DeoptimizeIf(vs, instr->environment()); 4657 DeoptimizeIf(vs, instr->environment());
4693 } 4658 }
4694 } 4659 }
4695 4660
4696 4661
4697 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4662 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4698 LOperand* input = instr->value(); 4663 LOperand* input = instr->value();
4699 LOperand* output = instr->result(); 4664 LOperand* output = instr->result();
4700 4665
4701 SwVfpRegister flt_scratch = double_scratch0().low(); 4666 SwVfpRegister flt_scratch = double_scratch0().low();
4702 __ vmov(flt_scratch, ToRegister(input)); 4667 __ vmov(flt_scratch, ToRegister(input));
4703 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); 4668 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch);
4704 } 4669 }
4705 4670
4706 4671
4672 void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) {
4673 LOperand* input = instr->value();
4674 LOperand* output = instr->result();
4675 if (!instr->hydrogen()->value()->HasRange() ||
4676 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4677 __ tst(ToRegister(input), Operand(0xc0000000));
4678 DeoptimizeIf(ne, instr->environment());
4679 }
4680 __ SmiTag(ToRegister(output), ToRegister(input));
4681 }
4682
4683
4707 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4684 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4708 class DeferredNumberTagI V8_FINAL : public LDeferredCode { 4685 class DeferredNumberTagI V8_FINAL : public LDeferredCode {
4709 public: 4686 public:
4710 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4687 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4711 : LDeferredCode(codegen), instr_(instr) { } 4688 : LDeferredCode(codegen), instr_(instr) { }
4712 virtual void Generate() V8_OVERRIDE { 4689 virtual void Generate() V8_OVERRIDE {
4713 codegen()->DoDeferredNumberTagI(instr_, 4690 codegen()->DoDeferredNumberTagI(instr_,
4714 instr_->value(), 4691 instr_->value(),
4715 SIGNED_INT32); 4692 SIGNED_INT32);
4716 } 4693 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
4971 __ adc(scratch2, input_reg, Operand(input_reg)); 4948 __ adc(scratch2, input_reg, Operand(input_reg));
4972 4949
4973 // Heap number map check. 4950 // Heap number map check.
4974 __ ldr(scratch1, FieldMemOperand(scratch2, HeapObject::kMapOffset)); 4951 __ ldr(scratch1, FieldMemOperand(scratch2, HeapObject::kMapOffset));
4975 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4952 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
4976 __ cmp(scratch1, Operand(ip)); 4953 __ cmp(scratch1, Operand(ip));
4977 4954
4978 if (instr->truncating()) { 4955 if (instr->truncating()) {
4979 // Performs a truncating conversion of a floating point number as used by 4956 // Performs a truncating conversion of a floating point number as used by
4980 // the JS bitwise operations. 4957 // the JS bitwise operations.
4981 Label heap_number; 4958 Label no_heap_number, check_bools, check_false;
4982 __ b(eq, &heap_number); 4959 __ b(ne, &no_heap_number);
4983 // Check for undefined. Undefined is converted to zero for truncating 4960 __ TruncateHeapNumberToI(input_reg, scratch2);
4984 // conversions. 4961 __ b(&done);
4962
4963 // Check for Oddballs. Undefined/False is converted to zero and True to one
4964 // for truncating conversions.
4965 __ bind(&no_heap_number);
4985 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 4966 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
4986 __ cmp(scratch2, Operand(ip)); 4967 __ cmp(scratch2, Operand(ip));
4968 __ b(ne, &check_bools);
4969 __ mov(input_reg, Operand::Zero());
4970 __ b(&done);
4971
4972 __ bind(&check_bools);
4973 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
4974 __ cmp(scratch2, Operand(ip));
4975 __ b(ne, &check_false);
4976 __ mov(input_reg, Operand(1));
4977 __ b(&done);
4978
4979 __ bind(&check_false);
4980 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
4981 __ cmp(scratch2, Operand(ip));
4987 DeoptimizeIf(ne, instr->environment()); 4982 DeoptimizeIf(ne, instr->environment());
4988 __ mov(input_reg, Operand::Zero()); 4983 __ mov(input_reg, Operand::Zero());
4989 __ b(&done); 4984 __ b(&done);
4990
4991 __ bind(&heap_number);
4992 __ TruncateHeapNumberToI(input_reg, scratch2);
4993 } else { 4985 } else {
4994 // Deoptimize if we don't have a heap number. 4986 // Deoptimize if we don't have a heap number.
4995 DeoptimizeIf(ne, instr->environment()); 4987 DeoptimizeIf(ne, instr->environment());
4996 4988
4997 __ sub(ip, scratch2, Operand(kHeapObjectTag)); 4989 __ sub(ip, scratch2, Operand(kHeapObjectTag));
4998 __ vldr(double_scratch2, ip, HeapNumber::kValueOffset); 4990 __ vldr(double_scratch2, ip, HeapNumber::kValueOffset);
4999 __ TryDoubleToInt32Exact(input_reg, double_scratch2, double_scratch); 4991 __ TryDoubleToInt32Exact(input_reg, double_scratch2, double_scratch);
5000 DeoptimizeIf(ne, instr->environment()); 4992 DeoptimizeIf(ne, instr->environment());
5001 4993
5002 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4994 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
5429 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5421 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5430 ASSERT(ToRegister(instr->context()).is(cp)); 5422 ASSERT(ToRegister(instr->context()).is(cp));
5431 Label materialized; 5423 Label materialized;
5432 // Registers will be used as follows: 5424 // Registers will be used as follows:
5433 // r6 = literals array. 5425 // r6 = literals array.
5434 // r1 = regexp literal. 5426 // r1 = regexp literal.
5435 // r0 = regexp literal clone. 5427 // r0 = regexp literal clone.
5436 // r2-5 are used as temporaries. 5428 // r2-5 are used as temporaries.
5437 int literal_offset = 5429 int literal_offset =
5438 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); 5430 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5439 __ LoadHeapObject(r6, instr->hydrogen()->literals()); 5431 __ Move(r6, instr->hydrogen()->literals());
5440 __ ldr(r1, FieldMemOperand(r6, literal_offset)); 5432 __ ldr(r1, FieldMemOperand(r6, literal_offset));
5441 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 5433 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
5442 __ cmp(r1, ip); 5434 __ cmp(r1, ip);
5443 __ b(ne, &materialized); 5435 __ b(ne, &materialized);
5444 5436
5445 // Create regexp literal using runtime function 5437 // Create regexp literal using runtime function
5446 // Result will be in r0. 5438 // Result will be in r0.
5447 __ mov(r5, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); 5439 __ mov(r5, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
5448 __ mov(r4, Operand(instr->hydrogen()->pattern())); 5440 __ mov(r4, Operand(instr->hydrogen()->pattern()));
5449 __ mov(r3, Operand(instr->hydrogen()->flags())); 5441 __ mov(r3, Operand(instr->hydrogen()->flags()));
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
5834 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5826 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5835 __ ldr(result, FieldMemOperand(scratch, 5827 __ ldr(result, FieldMemOperand(scratch,
5836 FixedArray::kHeaderSize - kPointerSize)); 5828 FixedArray::kHeaderSize - kPointerSize));
5837 __ bind(&done); 5829 __ bind(&done);
5838 } 5830 }
5839 5831
5840 5832
5841 #undef __ 5833 #undef __
5842 5834
5843 } } // namespace v8::internal 5835 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/lithium-gap-resolver-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698