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

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

Issue 110573004: Merge bleeding_edge 17696:18016. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years 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
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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 info()->CommitDependencies(code); 91 info()->CommitDependencies(code);
92 } 92 }
93 93
94 94
95 void LChunkBuilder::Abort(BailoutReason reason) { 95 void LChunkBuilder::Abort(BailoutReason reason) {
96 info()->set_bailout_reason(reason); 96 info()->set_bailout_reason(reason);
97 status_ = ABORTED; 97 status_ = ABORTED;
98 } 98 }
99 99
100 100
101 void LCodeGen::SaveCallerDoubles() {
102 ASSERT(info()->saves_caller_doubles());
103 ASSERT(NeedsEagerFrame());
104 Comment(";;; Save clobbered callee double registers");
105 int count = 0;
106 BitVector* doubles = chunk()->allocated_double_registers();
107 BitVector::Iterator save_iterator(doubles);
108 while (!save_iterator.Done()) {
109 __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
110 MemOperand(sp, count * kDoubleSize));
111 save_iterator.Advance();
112 count++;
113 }
114 }
115
116
117 void LCodeGen::RestoreCallerDoubles() {
118 ASSERT(info()->saves_caller_doubles());
119 ASSERT(NeedsEagerFrame());
120 Comment(";;; Restore clobbered callee double registers");
121 BitVector* doubles = chunk()->allocated_double_registers();
122 BitVector::Iterator save_iterator(doubles);
123 int count = 0;
124 while (!save_iterator.Done()) {
125 __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
126 MemOperand(sp, count * kDoubleSize));
127 save_iterator.Advance();
128 count++;
129 }
130 }
131
132
101 bool LCodeGen::GeneratePrologue() { 133 bool LCodeGen::GeneratePrologue() {
102 ASSERT(is_generating()); 134 ASSERT(is_generating());
103 135
104 if (info()->IsOptimizing()) { 136 if (info()->IsOptimizing()) {
105 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 137 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
106 138
107 #ifdef DEBUG 139 #ifdef DEBUG
108 if (strlen(FLAG_stop_at) > 0 && 140 if (strlen(FLAG_stop_at) > 0 &&
109 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 141 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
110 __ stop("stop_at"); 142 __ stop("stop_at");
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 __ sw(a1, MemOperand(a0, 2 * kPointerSize)); 185 __ sw(a1, MemOperand(a0, 2 * kPointerSize));
154 __ Branch(&loop, ne, a0, Operand(sp)); 186 __ Branch(&loop, ne, a0, Operand(sp));
155 __ pop(a1); 187 __ pop(a1);
156 __ pop(a0); 188 __ pop(a0);
157 } else { 189 } else {
158 __ Subu(sp, sp, Operand(slots * kPointerSize)); 190 __ Subu(sp, sp, Operand(slots * kPointerSize));
159 } 191 }
160 } 192 }
161 193
162 if (info()->saves_caller_doubles()) { 194 if (info()->saves_caller_doubles()) {
163 Comment(";;; Save clobbered callee double registers"); 195 SaveCallerDoubles();
164 int count = 0;
165 BitVector* doubles = chunk()->allocated_double_registers();
166 BitVector::Iterator save_iterator(doubles);
167 while (!save_iterator.Done()) {
168 __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
169 MemOperand(sp, count * kDoubleSize));
170 save_iterator.Advance();
171 count++;
172 }
173 } 196 }
174 197
175 // Possibly allocate a local context. 198 // Possibly allocate a local context.
176 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 199 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
177 if (heap_slots > 0) { 200 if (heap_slots > 0) {
178 Comment(";;; Allocate local context"); 201 Comment(";;; Allocate local context");
179 // Argument to NewContext is the function, which is in a1. 202 // Argument to NewContext is the function, which is in a1.
180 __ push(a1); 203 __ push(a1);
181 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 204 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
182 FastNewContextStub stub(heap_slots); 205 FastNewContextStub stub(heap_slots);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 code->instr()->Mnemonic()); 273 code->instr()->Mnemonic());
251 __ bind(code->entry()); 274 __ bind(code->entry());
252 if (NeedsDeferredFrame()) { 275 if (NeedsDeferredFrame()) {
253 Comment(";;; Build frame"); 276 Comment(";;; Build frame");
254 ASSERT(!frame_is_built_); 277 ASSERT(!frame_is_built_);
255 ASSERT(info()->IsStub()); 278 ASSERT(info()->IsStub());
256 frame_is_built_ = true; 279 frame_is_built_ = true;
257 __ MultiPush(cp.bit() | fp.bit() | ra.bit()); 280 __ MultiPush(cp.bit() | fp.bit() | ra.bit());
258 __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); 281 __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
259 __ push(scratch0()); 282 __ push(scratch0());
260 __ Addu(fp, sp, Operand(2 * kPointerSize)); 283 __ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
261 Comment(";;; Deferred code"); 284 Comment(";;; Deferred code");
262 } 285 }
263 code->Generate(); 286 code->Generate();
264 if (NeedsDeferredFrame()) { 287 if (NeedsDeferredFrame()) {
265 Comment(";;; Destroy frame"); 288 Comment(";;; Destroy frame");
266 ASSERT(frame_is_built_); 289 ASSERT(frame_is_built_);
267 __ pop(at); 290 __ pop(at);
268 __ MultiPop(cp.bit() | fp.bit() | ra.bit()); 291 __ MultiPop(cp.bit() | fp.bit() | ra.bit());
269 frame_is_built_ = false; 292 frame_is_built_ = false;
270 } 293 }
(...skipping 20 matching lines...) Expand all
291 Address entry = deopt_jump_table_[i].address; 314 Address entry = deopt_jump_table_[i].address;
292 Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; 315 Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type;
293 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 316 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
294 if (id == Deoptimizer::kNotDeoptimizationEntry) { 317 if (id == Deoptimizer::kNotDeoptimizationEntry) {
295 Comment(";;; jump table entry %d.", i); 318 Comment(";;; jump table entry %d.", i);
296 } else { 319 } else {
297 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); 320 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id);
298 } 321 }
299 __ li(t9, Operand(ExternalReference::ForDeoptEntry(entry))); 322 __ li(t9, Operand(ExternalReference::ForDeoptEntry(entry)));
300 if (deopt_jump_table_[i].needs_frame) { 323 if (deopt_jump_table_[i].needs_frame) {
324 ASSERT(!info()->saves_caller_doubles());
301 if (needs_frame.is_bound()) { 325 if (needs_frame.is_bound()) {
302 __ Branch(&needs_frame); 326 __ Branch(&needs_frame);
303 } else { 327 } else {
304 __ bind(&needs_frame); 328 __ bind(&needs_frame);
305 __ MultiPush(cp.bit() | fp.bit() | ra.bit()); 329 __ MultiPush(cp.bit() | fp.bit() | ra.bit());
306 // This variant of deopt can only be used with stubs. Since we don't 330 // This variant of deopt can only be used with stubs. Since we don't
307 // have a function pointer to install in the stack frame that we're 331 // have a function pointer to install in the stack frame that we're
308 // building, install a special marker there instead. 332 // building, install a special marker there instead.
309 ASSERT(info()->IsStub()); 333 ASSERT(info()->IsStub());
310 __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); 334 __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
311 __ push(scratch0()); 335 __ push(scratch0());
312 __ Addu(fp, sp, Operand(2 * kPointerSize)); 336 __ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
313 __ Call(t9); 337 __ Call(t9);
314 } 338 }
315 } else { 339 } else {
340 if (info()->saves_caller_doubles()) {
341 ASSERT(info()->IsStub());
342 RestoreCallerDoubles();
343 }
316 __ Call(t9); 344 __ Call(t9);
317 } 345 }
318 } 346 }
319 __ RecordComment("]"); 347 __ RecordComment("]");
320 348
321 // The deoptimization jump table is the last part of the instruction 349 // The deoptimization jump table is the last part of the instruction
322 // sequence. Mark the generated code as done unless we bailed out. 350 // sequence. Mark the generated code as done unless we bailed out.
323 if (!is_aborted()) status_ = DONE; 351 if (!is_aborted()) status_ = DONE;
324 return !is_aborted(); 352 return !is_aborted();
325 } 353 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 } else if (op->IsDoubleRegister()) { 509 } else if (op->IsDoubleRegister()) {
482 Abort(kToOperandIsDoubleRegisterUnimplemented); 510 Abort(kToOperandIsDoubleRegisterUnimplemented);
483 return Operand(0); 511 return Operand(0);
484 } 512 }
485 // Stack slots not implemented, use ToMemOperand instead. 513 // Stack slots not implemented, use ToMemOperand instead.
486 UNREACHABLE(); 514 UNREACHABLE();
487 return Operand(0); 515 return Operand(0);
488 } 516 }
489 517
490 518
519 static int ArgumentsOffsetWithoutFrame(int index) {
520 ASSERT(index < 0);
521 return -(index + 1) * kPointerSize;
522 }
523
524
491 MemOperand LCodeGen::ToMemOperand(LOperand* op) const { 525 MemOperand LCodeGen::ToMemOperand(LOperand* op) const {
492 ASSERT(!op->IsRegister()); 526 ASSERT(!op->IsRegister());
493 ASSERT(!op->IsDoubleRegister()); 527 ASSERT(!op->IsDoubleRegister());
494 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); 528 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot());
495 return MemOperand(fp, StackSlotOffset(op->index())); 529 if (NeedsEagerFrame()) {
530 return MemOperand(fp, StackSlotOffset(op->index()));
531 } else {
532 // Retrieve parameter without eager stack-frame relative to the
533 // stack-pointer.
534 return MemOperand(sp, ArgumentsOffsetWithoutFrame(op->index()));
535 }
496 } 536 }
497 537
498 538
499 MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const { 539 MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const {
500 ASSERT(op->IsDoubleStackSlot()); 540 ASSERT(op->IsDoubleStackSlot());
501 return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize); 541 if (NeedsEagerFrame()) {
542 return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize);
543 } else {
544 // Retrieve parameter without eager stack-frame relative to the
545 // stack-pointer.
546 return MemOperand(
547 sp, ArgumentsOffsetWithoutFrame(op->index()) + kPointerSize);
548 }
502 } 549 }
503 550
504 551
505 void LCodeGen::WriteTranslation(LEnvironment* environment, 552 void LCodeGen::WriteTranslation(LEnvironment* environment,
506 Translation* translation) { 553 Translation* translation) {
507 if (environment == NULL) return; 554 if (environment == NULL) return;
508 555
509 // The translation includes one command per value in the environment. 556 // The translation includes one command per value in the environment.
510 int translation_size = environment->translation_size(); 557 int translation_size = environment->translation_size();
511 // The output frame height does not include the parameters. 558 // The output frame height does not include the parameters.
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 if (info()->ShouldTrapOnDeopt()) { 807 if (info()->ShouldTrapOnDeopt()) {
761 Label skip; 808 Label skip;
762 if (condition != al) { 809 if (condition != al) {
763 __ Branch(&skip, NegateCondition(condition), src1, src2); 810 __ Branch(&skip, NegateCondition(condition), src1, src2);
764 } 811 }
765 __ stop("trap_on_deopt"); 812 __ stop("trap_on_deopt");
766 __ bind(&skip); 813 __ bind(&skip);
767 } 814 }
768 815
769 ASSERT(info()->IsStub() || frame_is_built_); 816 ASSERT(info()->IsStub() || frame_is_built_);
770 if (condition == al && frame_is_built_) { 817 // Go through jump table if we need to handle condition, build frame, or
818 // restore caller doubles.
819 if (condition == al && frame_is_built_ &&
820 !info()->saves_caller_doubles()) {
771 __ Call(entry, RelocInfo::RUNTIME_ENTRY, condition, src1, src2); 821 __ Call(entry, RelocInfo::RUNTIME_ENTRY, condition, src1, src2);
772 } else { 822 } else {
773 // We often have several deopts to the same entry, reuse the last 823 // We often have several deopts to the same entry, reuse the last
774 // jump entry if this is the case. 824 // jump entry if this is the case.
775 if (deopt_jump_table_.is_empty() || 825 if (deopt_jump_table_.is_empty() ||
776 (deopt_jump_table_.last().address != entry) || 826 (deopt_jump_table_.last().address != entry) ||
777 (deopt_jump_table_.last().bailout_type != bailout_type) || 827 (deopt_jump_table_.last().bailout_type != bailout_type) ||
778 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) { 828 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) {
779 Deoptimizer::JumpTableEntry table_entry(entry, 829 Deoptimizer::JumpTableEntry table_entry(entry,
780 bailout_type, 830 bailout_type,
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1115 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1066 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); 1116 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
1067 } 1117 }
1068 __ Branch(USE_DELAY_SLOT, &done); 1118 __ Branch(USE_DELAY_SLOT, &done);
1069 __ subu(result_reg, zero_reg, result_reg); 1119 __ subu(result_reg, zero_reg, result_reg);
1070 } 1120 }
1071 1121
1072 __ bind(&left_is_not_negative); 1122 __ bind(&left_is_not_negative);
1073 __ And(result_reg, left_reg, divisor - 1); 1123 __ And(result_reg, left_reg, divisor - 1);
1074 __ bind(&done); 1124 __ bind(&done);
1075
1076 } else if (hmod->fixed_right_arg().has_value) {
1077 const Register left_reg = ToRegister(instr->left());
1078 const Register result_reg = ToRegister(instr->result());
1079 const Register right_reg = ToRegister(instr->right());
1080
1081 int32_t divisor = hmod->fixed_right_arg().value;
1082 ASSERT(IsPowerOf2(divisor));
1083
1084 // Check if our assumption of a fixed right operand still holds.
1085 DeoptimizeIf(ne, instr->environment(), right_reg, Operand(divisor));
1086
1087 Label left_is_not_negative, done;
1088 if (left->CanBeNegative()) {
1089 __ Branch(left_reg.is(result_reg) ? PROTECT : USE_DELAY_SLOT,
1090 &left_is_not_negative, ge, left_reg, Operand(zero_reg));
1091 __ subu(result_reg, zero_reg, left_reg);
1092 __ And(result_reg, result_reg, divisor - 1);
1093 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1094 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
1095 }
1096 __ Branch(USE_DELAY_SLOT, &done);
1097 __ subu(result_reg, zero_reg, result_reg);
1098 }
1099
1100 __ bind(&left_is_not_negative);
1101 __ And(result_reg, left_reg, divisor - 1);
1102 __ bind(&done);
1103
1104 } else { 1125 } else {
1105 const Register scratch = scratch0(); 1126 const Register scratch = scratch0();
1106 const Register left_reg = ToRegister(instr->left()); 1127 const Register left_reg = ToRegister(instr->left());
1107 const Register result_reg = ToRegister(instr->result()); 1128 const Register result_reg = ToRegister(instr->result());
1108 1129
1109 // div runs in the background while we check for special cases. 1130 // div runs in the background while we check for special cases.
1110 Register right_reg = EmitLoadRegister(instr->right(), scratch); 1131 Register right_reg = EmitLoadRegister(instr->right(), scratch);
1111 __ div(left_reg, right_reg); 1132 __ div(left_reg, right_reg);
1112 1133
1113 Label done; 1134 Label done;
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 Register object = ToRegister(instr->date()); 1728 Register object = ToRegister(instr->date());
1708 Register result = ToRegister(instr->result()); 1729 Register result = ToRegister(instr->result());
1709 Register scratch = ToRegister(instr->temp()); 1730 Register scratch = ToRegister(instr->temp());
1710 Smi* index = instr->index(); 1731 Smi* index = instr->index();
1711 Label runtime, done; 1732 Label runtime, done;
1712 ASSERT(object.is(a0)); 1733 ASSERT(object.is(a0));
1713 ASSERT(result.is(v0)); 1734 ASSERT(result.is(v0));
1714 ASSERT(!scratch.is(scratch0())); 1735 ASSERT(!scratch.is(scratch0()));
1715 ASSERT(!scratch.is(object)); 1736 ASSERT(!scratch.is(object));
1716 1737
1717 __ And(at, object, Operand(kSmiTagMask)); 1738 __ SmiTst(object, at);
1718 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 1739 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
1719 __ GetObjectType(object, scratch, scratch); 1740 __ GetObjectType(object, scratch, scratch);
1720 DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_DATE_TYPE)); 1741 DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_DATE_TYPE));
1721 1742
1722 if (index->value() == 0) { 1743 if (index->value() == 0) {
1723 __ lw(result, FieldMemOperand(object, JSDate::kValueOffset)); 1744 __ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
1724 } else { 1745 } else {
1725 if (index->value() < JSDate::kFirstUncachedField) { 1746 if (index->value() < JSDate::kFirstUncachedField) {
1726 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 1747 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
1727 __ li(scratch, Operand(stamp)); 1748 __ li(scratch, Operand(stamp));
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 } 1815 }
1795 1816
1796 1817
1797 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { 1818 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1798 String::Encoding encoding = instr->hydrogen()->encoding(); 1819 String::Encoding encoding = instr->hydrogen()->encoding();
1799 Register string = ToRegister(instr->string()); 1820 Register string = ToRegister(instr->string());
1800 Register value = ToRegister(instr->value()); 1821 Register value = ToRegister(instr->value());
1801 1822
1802 if (FLAG_debug_code) { 1823 if (FLAG_debug_code) {
1803 Register scratch = scratch0(); 1824 Register scratch = scratch0();
1804 __ lw(scratch, FieldMemOperand(string, HeapObject::kMapOffset)); 1825 Register index = ToRegister(instr->index());
1805 __ lbu(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
1806
1807 __ And(scratch, scratch,
1808 Operand(kStringRepresentationMask | kStringEncodingMask));
1809 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 1826 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
1810 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 1827 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
1811 __ Subu(at, scratch, Operand(encoding == String::ONE_BYTE_ENCODING 1828 int encoding_mask =
1812 ? one_byte_seq_type : two_byte_seq_type)); 1829 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
1813 __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg)); 1830 ? one_byte_seq_type : two_byte_seq_type;
1831 __ EmitSeqStringSetCharCheck(string, index, value, scratch, encoding_mask);
1814 } 1832 }
1815 1833
1816 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding); 1834 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1817 if (encoding == String::ONE_BYTE_ENCODING) { 1835 if (encoding == String::ONE_BYTE_ENCODING) {
1818 __ sb(value, operand); 1836 __ sb(value, operand);
1819 } else { 1837 } else {
1820 __ sh(value, operand); 1838 __ sh(value, operand);
1821 } 1839 }
1822 } 1840 }
1823 1841
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
2121 __ LoadRoot(at, Heap::kNullValueRootIndex); 2139 __ LoadRoot(at, Heap::kNullValueRootIndex);
2122 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); 2140 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2123 } 2141 }
2124 2142
2125 if (expected.Contains(ToBooleanStub::SMI)) { 2143 if (expected.Contains(ToBooleanStub::SMI)) {
2126 // Smis: 0 -> false, all other -> true. 2144 // Smis: 0 -> false, all other -> true.
2127 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg)); 2145 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
2128 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2146 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2129 } else if (expected.NeedsMap()) { 2147 } else if (expected.NeedsMap()) {
2130 // If we need a map later and have a Smi -> deopt. 2148 // If we need a map later and have a Smi -> deopt.
2131 __ And(at, reg, Operand(kSmiTagMask)); 2149 __ SmiTst(reg, at);
2132 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 2150 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
2133 } 2151 }
2134 2152
2135 const Register map = scratch0(); 2153 const Register map = scratch0();
2136 if (expected.NeedsMap()) { 2154 if (expected.NeedsMap()) {
2137 __ lw(map, FieldMemOperand(reg, HeapObject::kMapOffset)); 2155 __ lw(map, FieldMemOperand(reg, HeapObject::kMapOffset));
2138 if (expected.CanBeUndetectable()) { 2156 if (expected.CanBeUndetectable()) {
2139 // Undetectable -> false. 2157 // Undetectable -> false.
2140 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset)); 2158 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
2141 __ And(at, at, Operand(1 << Map::kIsUndetectable)); 2159 __ And(at, at, Operand(1 << Map::kIsUndetectable));
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
2783 if (FLAG_trace && info()->IsOptimizing()) { 2801 if (FLAG_trace && info()->IsOptimizing()) {
2784 // Push the return value on the stack as the parameter. 2802 // Push the return value on the stack as the parameter.
2785 // Runtime::TraceExit returns its parameter in v0. We're leaving the code 2803 // Runtime::TraceExit returns its parameter in v0. We're leaving the code
2786 // managed by the register allocator and tearing down the frame, it's 2804 // managed by the register allocator and tearing down the frame, it's
2787 // safe to write to the context register. 2805 // safe to write to the context register.
2788 __ push(v0); 2806 __ push(v0);
2789 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2807 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2790 __ CallRuntime(Runtime::kTraceExit, 1); 2808 __ CallRuntime(Runtime::kTraceExit, 1);
2791 } 2809 }
2792 if (info()->saves_caller_doubles()) { 2810 if (info()->saves_caller_doubles()) {
2793 ASSERT(NeedsEagerFrame()); 2811 RestoreCallerDoubles();
2794 BitVector* doubles = chunk()->allocated_double_registers();
2795 BitVector::Iterator save_iterator(doubles);
2796 int count = 0;
2797 while (!save_iterator.Done()) {
2798 __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
2799 MemOperand(sp, count * kDoubleSize));
2800 save_iterator.Advance();
2801 count++;
2802 }
2803 } 2812 }
2804 int no_frame_start = -1; 2813 int no_frame_start = -1;
2805 if (NeedsEagerFrame()) { 2814 if (NeedsEagerFrame()) {
2806 __ mov(sp, fp); 2815 __ mov(sp, fp);
2807 no_frame_start = masm_->pc_offset(); 2816 no_frame_start = masm_->pc_offset();
2808 __ Pop(ra, fp); 2817 __ Pop(ra, fp);
2809 } 2818 }
2810 if (instr->has_constant_parameter_count()) { 2819 if (instr->has_constant_parameter_count()) {
2811 int parameter_count = ToInteger32(instr->constant_parameter_count()); 2820 int parameter_count = ToInteger32(instr->constant_parameter_count());
2812 int32_t sp_delta = (parameter_count + 1) * kPointerSize; 2821 int32_t sp_delta = (parameter_count + 1) * kPointerSize;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
3043 Register to_reg = ToRegister(instr->result()); 3052 Register to_reg = ToRegister(instr->result());
3044 Register from_reg = ToRegister(instr->object()); 3053 Register from_reg = ToRegister(instr->object());
3045 __ lw(to_reg, FieldMemOperand(from_reg, 3054 __ lw(to_reg, FieldMemOperand(from_reg,
3046 ExternalArray::kExternalPointerOffset)); 3055 ExternalArray::kExternalPointerOffset));
3047 } 3056 }
3048 3057
3049 3058
3050 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 3059 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3051 Register arguments = ToRegister(instr->arguments()); 3060 Register arguments = ToRegister(instr->arguments());
3052 Register result = ToRegister(instr->result()); 3061 Register result = ToRegister(instr->result());
3053 if (instr->length()->IsConstantOperand() && 3062 // There are two words between the frame pointer and the last argument.
3054 instr->index()->IsConstantOperand()) { 3063 // Subtracting from length accounts for one of them add one more.
3064 if (instr->length()->IsConstantOperand()) {
3065 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3066 if (instr->index()->IsConstantOperand()) {
3067 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3068 int index = (const_length - const_index) + 1;
3069 __ lw(result, MemOperand(arguments, index * kPointerSize));
3070 } else {
3071 Register index = ToRegister(instr->index());
3072 __ li(at, Operand(const_length + 1));
3073 __ Subu(result, at, index);
3074 __ sll(at, result, kPointerSizeLog2);
3075 __ Addu(at, arguments, at);
3076 __ lw(result, MemOperand(at));
3077 }
3078 } else if (instr->index()->IsConstantOperand()) {
3079 Register length = ToRegister(instr->length());
3055 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3080 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3056 int const_length = ToInteger32(LConstantOperand::cast(instr->length())); 3081 int loc = const_index - 1;
3057 int index = (const_length - const_index) + 1; 3082 if (loc != 0) {
3058 __ lw(result, MemOperand(arguments, index * kPointerSize)); 3083 __ Subu(result, length, Operand(loc));
3084 __ sll(at, result, kPointerSizeLog2);
3085 __ Addu(at, arguments, at);
3086 __ lw(result, MemOperand(at));
3087 } else {
3088 __ sll(at, length, kPointerSizeLog2);
3089 __ Addu(at, arguments, at);
3090 __ lw(result, MemOperand(at));
3091 }
3059 } else { 3092 } else {
3060 Register length = ToRegister(instr->length()); 3093 Register length = ToRegister(instr->length());
3061 Register index = ToRegister(instr->index()); 3094 Register index = ToRegister(instr->index());
3062 // There are two words between the frame pointer and the last argument. 3095 __ Subu(result, length, index);
3063 // Subtracting from length accounts for one of them, add one more. 3096 __ Addu(result, result, 1);
3064 __ subu(length, length, index); 3097 __ sll(at, result, kPointerSizeLog2);
3065 __ Addu(length, length, Operand(1)); 3098 __ Addu(at, arguments, at);
3066 __ sll(length, length, kPointerSizeLog2); 3099 __ lw(result, MemOperand(at));
3067 __ Addu(at, arguments, Operand(length));
3068 __ lw(result, MemOperand(at, 0));
3069 } 3100 }
3070 } 3101 }
3071 3102
3072 3103
3073 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3104 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3074 Register external_pointer = ToRegister(instr->elements()); 3105 Register external_pointer = ToRegister(instr->elements());
3075 Register key = no_reg; 3106 Register key = no_reg;
3076 ElementsKind elements_kind = instr->elements_kind(); 3107 ElementsKind elements_kind = instr->elements_kind();
3077 bool key_is_constant = instr->key()->IsConstantOperand(); 3108 bool key_is_constant = instr->key()->IsConstantOperand();
3078 int constant_key = 0; 3109 int constant_key = 0;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
3214 __ sll(scratch, key, kPointerSizeLog2); 3245 __ sll(scratch, key, kPointerSizeLog2);
3215 __ addu(scratch, elements, scratch); 3246 __ addu(scratch, elements, scratch);
3216 } 3247 }
3217 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); 3248 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
3218 } 3249 }
3219 __ lw(result, FieldMemOperand(store_base, offset)); 3250 __ lw(result, FieldMemOperand(store_base, offset));
3220 3251
3221 // Check for the hole value. 3252 // Check for the hole value.
3222 if (instr->hydrogen()->RequiresHoleCheck()) { 3253 if (instr->hydrogen()->RequiresHoleCheck()) {
3223 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 3254 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3224 __ And(scratch, result, Operand(kSmiTagMask)); 3255 __ SmiTst(result, scratch);
3225 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 3256 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
3226 } else { 3257 } else {
3227 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 3258 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
3228 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); 3259 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch));
3229 } 3260 }
3230 } 3261 }
3231 } 3262 }
3232 3263
3233 3264
3234 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 3265 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
3363 __ And(scratch, scratch, Operand(strict_mode_function_mask | native_mask)); 3394 __ And(scratch, scratch, Operand(strict_mode_function_mask | native_mask));
3364 __ Branch(&receiver_ok, ne, scratch, Operand(zero_reg)); 3395 __ Branch(&receiver_ok, ne, scratch, Operand(zero_reg));
3365 3396
3366 // Normal function. Replace undefined or null with global receiver. 3397 // Normal function. Replace undefined or null with global receiver.
3367 __ LoadRoot(scratch, Heap::kNullValueRootIndex); 3398 __ LoadRoot(scratch, Heap::kNullValueRootIndex);
3368 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3399 __ Branch(&global_object, eq, receiver, Operand(scratch));
3369 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 3400 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
3370 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3401 __ Branch(&global_object, eq, receiver, Operand(scratch));
3371 3402
3372 // Deoptimize if the receiver is not a JS object. 3403 // Deoptimize if the receiver is not a JS object.
3373 __ And(scratch, receiver, Operand(kSmiTagMask)); 3404 __ SmiTst(receiver, scratch);
3374 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); 3405 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
3375 3406
3376 __ GetObjectType(receiver, scratch, scratch); 3407 __ GetObjectType(receiver, scratch, scratch);
3377 DeoptimizeIf(lt, instr->environment(), 3408 DeoptimizeIf(lt, instr->environment(),
3378 scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); 3409 scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
3379 __ Branch(&receiver_ok); 3410 __ Branch(&receiver_ok);
3380 3411
3381 __ bind(&global_object); 3412 __ bind(&global_object);
3382 __ lw(receiver, GlobalObjectOperand()); 3413 __ lw(receiver, GlobalObjectOperand());
3383 __ lw(receiver, 3414 __ lw(receiver,
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
3835 MathPowStub stub(MathPowStub::INTEGER); 3866 MathPowStub stub(MathPowStub::INTEGER);
3836 __ CallStub(&stub); 3867 __ CallStub(&stub);
3837 } else { 3868 } else {
3838 ASSERT(exponent_type.IsDouble()); 3869 ASSERT(exponent_type.IsDouble());
3839 MathPowStub stub(MathPowStub::DOUBLE); 3870 MathPowStub stub(MathPowStub::DOUBLE);
3840 __ CallStub(&stub); 3871 __ CallStub(&stub);
3841 } 3872 }
3842 } 3873 }
3843 3874
3844 3875
3845 void LCodeGen::DoRandom(LRandom* instr) {
3846 // Assert that the register size is indeed the size of each seed.
3847 static const int kSeedSize = sizeof(uint32_t);
3848 STATIC_ASSERT(kPointerSize == kSeedSize);
3849
3850 // Load native context.
3851 Register global_object = ToRegister(instr->global_object());
3852 Register native_context = global_object;
3853 __ lw(native_context, FieldMemOperand(
3854 global_object, GlobalObject::kNativeContextOffset));
3855
3856 // Load state (FixedArray of the native context's random seeds).
3857 static const int kRandomSeedOffset =
3858 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
3859 Register state = native_context;
3860 __ lw(state, FieldMemOperand(native_context, kRandomSeedOffset));
3861
3862 // Load state[0].
3863 Register state0 = ToRegister(instr->scratch());
3864 __ lw(state0, FieldMemOperand(state, ByteArray::kHeaderSize));
3865 // Load state[1].
3866 Register state1 = ToRegister(instr->scratch2());
3867 __ lw(state1, FieldMemOperand(state, ByteArray::kHeaderSize + kSeedSize));
3868
3869 // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
3870 Register scratch3 = ToRegister(instr->scratch3());
3871 Register scratch4 = scratch0();
3872 __ And(scratch3, state0, Operand(0xFFFF));
3873 __ li(scratch4, Operand(18273));
3874 __ Mul(scratch3, scratch3, scratch4);
3875 __ srl(state0, state0, 16);
3876 __ Addu(state0, scratch3, state0);
3877 // Save state[0].
3878 __ sw(state0, FieldMemOperand(state, ByteArray::kHeaderSize));
3879
3880 // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
3881 __ And(scratch3, state1, Operand(0xFFFF));
3882 __ li(scratch4, Operand(36969));
3883 __ Mul(scratch3, scratch3, scratch4);
3884 __ srl(state1, state1, 16),
3885 __ Addu(state1, scratch3, state1);
3886 // Save state[1].
3887 __ sw(state1, FieldMemOperand(state, ByteArray::kHeaderSize + kSeedSize));
3888
3889 // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
3890 Register random = scratch4;
3891 __ And(random, state1, Operand(0x3FFFF));
3892 __ sll(state0, state0, 14);
3893 __ Addu(random, random, state0);
3894
3895 // 0x41300000 is the top half of 1.0 x 2^20 as a double.
3896 __ li(scratch3, Operand(0x41300000));
3897 // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU.
3898 DoubleRegister result = ToDoubleRegister(instr->result());
3899 __ Move(result, random, scratch3);
3900 // Move 0x4130000000000000 to FPU.
3901 DoubleRegister scratch5 = double_scratch0();
3902 __ Move(scratch5, zero_reg, scratch3);
3903 __ sub_d(result, result, scratch5);
3904 }
3905
3906
3907 void LCodeGen::DoMathExp(LMathExp* instr) { 3876 void LCodeGen::DoMathExp(LMathExp* instr) {
3908 DoubleRegister input = ToDoubleRegister(instr->value()); 3877 DoubleRegister input = ToDoubleRegister(instr->value());
3909 DoubleRegister result = ToDoubleRegister(instr->result()); 3878 DoubleRegister result = ToDoubleRegister(instr->result());
3910 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); 3879 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
3911 DoubleRegister double_scratch2 = double_scratch0(); 3880 DoubleRegister double_scratch2 = double_scratch0();
3912 Register temp1 = ToRegister(instr->temp1()); 3881 Register temp1 = ToRegister(instr->temp1());
3913 Register temp2 = ToRegister(instr->temp2()); 3882 Register temp2 = ToRegister(instr->temp2());
3914 3883
3915 MathExpGenerator::EmitMathExp( 3884 MathExpGenerator::EmitMathExp(
3916 masm(), input, result, double_scratch1, double_scratch2, 3885 masm(), input, result, double_scratch1, double_scratch2,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
4008 } 3977 }
4009 3978
4010 3979
4011 void LCodeGen::DoCallFunction(LCallFunction* instr) { 3980 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4012 ASSERT(ToRegister(instr->context()).is(cp)); 3981 ASSERT(ToRegister(instr->context()).is(cp));
4013 ASSERT(ToRegister(instr->function()).is(a1)); 3982 ASSERT(ToRegister(instr->function()).is(a1));
4014 ASSERT(ToRegister(instr->result()).is(v0)); 3983 ASSERT(ToRegister(instr->result()).is(v0));
4015 3984
4016 int arity = instr->arity(); 3985 int arity = instr->arity();
4017 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 3986 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
4018 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3987 if (instr->hydrogen()->IsTailCall()) {
3988 if (NeedsEagerFrame()) __ mov(sp, fp);
3989 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
3990 } else {
3991 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3992 }
4019 } 3993 }
4020 3994
4021 3995
4022 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { 3996 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
4023 ASSERT(ToRegister(instr->context()).is(cp)); 3997 ASSERT(ToRegister(instr->context()).is(cp));
4024 ASSERT(ToRegister(instr->result()).is(v0)); 3998 ASSERT(ToRegister(instr->result()).is(v0));
4025 3999
4026 int arity = instr->arity(); 4000 int arity = instr->arity();
4027 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; 4001 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
4028 Handle<Code> ic = 4002 Handle<Code> ic =
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
4136 MemOperand operand = MemOperand(object, offset); 4110 MemOperand operand = MemOperand(object, offset);
4137 __ Store(value, operand, representation); 4111 __ Store(value, operand, representation);
4138 return; 4112 return;
4139 } 4113 }
4140 4114
4141 Handle<Map> transition = instr->transition(); 4115 Handle<Map> transition = instr->transition();
4142 4116
4143 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 4117 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
4144 Register value = ToRegister(instr->value()); 4118 Register value = ToRegister(instr->value());
4145 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 4119 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4146 __ And(scratch, value, Operand(kSmiTagMask)); 4120 __ SmiTst(value, scratch);
4147 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); 4121 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
4148 } 4122 }
4149 } else if (FLAG_track_double_fields && representation.IsDouble()) { 4123 } else if (FLAG_track_double_fields && representation.IsDouble()) {
4150 ASSERT(transition.is_null()); 4124 ASSERT(transition.is_null());
4151 ASSERT(access.IsInobject()); 4125 ASSERT(access.IsInobject());
4152 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 4126 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4153 DoubleRegister value = ToDoubleRegister(instr->value()); 4127 DoubleRegister value = ToDoubleRegister(instr->value());
4154 __ sdc1(value, FieldMemOperand(object, offset)); 4128 __ sdc1(value, FieldMemOperand(object, offset));
4155 return; 4129 return;
4156 } 4130 }
(...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after
5131 __ bind(&done); 5105 __ bind(&done);
5132 } 5106 }
5133 } 5107 }
5134 __ SmiTagCheckOverflow(result_reg, result_reg, scratch1); 5108 __ SmiTagCheckOverflow(result_reg, result_reg, scratch1);
5135 DeoptimizeIf(lt, instr->environment(), scratch1, Operand(zero_reg)); 5109 DeoptimizeIf(lt, instr->environment(), scratch1, Operand(zero_reg));
5136 } 5110 }
5137 5111
5138 5112
5139 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5113 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5140 LOperand* input = instr->value(); 5114 LOperand* input = instr->value();
5141 __ And(at, ToRegister(input), Operand(kSmiTagMask)); 5115 __ SmiTst(ToRegister(input), at);
5142 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 5116 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg));
5143 } 5117 }
5144 5118
5145 5119
5146 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 5120 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5147 if (!instr->hydrogen()->value()->IsHeapObject()) { 5121 if (!instr->hydrogen()->value()->IsHeapObject()) {
5148 LOperand* input = instr->value(); 5122 LOperand* input = instr->value();
5149 __ And(at, ToRegister(input), Operand(kSmiTagMask)); 5123 __ SmiTst(ToRegister(input), at);
5150 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5124 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
5151 } 5125 }
5152 } 5126 }
5153 5127
5154 5128
5155 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 5129 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5156 Register input = ToRegister(instr->value()); 5130 Register input = ToRegister(instr->value());
5157 Register scratch = scratch0(); 5131 Register scratch = scratch0();
5158 5132
5159 __ GetObjectType(input, scratch, scratch); 5133 __ GetObjectType(input, scratch, scratch);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
5212 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5186 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5213 { 5187 {
5214 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 5188 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
5215 __ push(object); 5189 __ push(object);
5216 __ mov(cp, zero_reg); 5190 __ mov(cp, zero_reg);
5217 __ CallRuntimeSaveDoubles(Runtime::kMigrateInstance); 5191 __ CallRuntimeSaveDoubles(Runtime::kMigrateInstance);
5218 RecordSafepointWithRegisters( 5192 RecordSafepointWithRegisters(
5219 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5193 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5220 __ StoreToSafepointRegisterSlot(v0, scratch0()); 5194 __ StoreToSafepointRegisterSlot(v0, scratch0());
5221 } 5195 }
5222 __ And(at, scratch0(), Operand(kSmiTagMask)); 5196 __ SmiTst(scratch0(), at);
5223 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5197 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
5224 } 5198 }
5225 5199
5226 5200
5227 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5201 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5228 class DeferredCheckMaps V8_FINAL : public LDeferredCode { 5202 class DeferredCheckMaps V8_FINAL : public LDeferredCode {
5229 public: 5203 public:
5230 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 5204 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5231 : LDeferredCode(codegen), instr_(instr), object_(object) { 5205 : LDeferredCode(codegen), instr_(instr), object_(object) {
5232 SetExit(check_maps()); 5206 SetExit(check_maps());
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
5404 if (instr->size()->IsRegister()) { 5378 if (instr->size()->IsRegister()) {
5405 Register size = ToRegister(instr->size()); 5379 Register size = ToRegister(instr->size());
5406 ASSERT(!size.is(result)); 5380 ASSERT(!size.is(result));
5407 __ SmiTag(size); 5381 __ SmiTag(size);
5408 __ push(size); 5382 __ push(size);
5409 } else { 5383 } else {
5410 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5384 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5411 __ Push(Smi::FromInt(size)); 5385 __ Push(Smi::FromInt(size));
5412 } 5386 }
5413 5387
5388 int flags = AllocateDoubleAlignFlag::encode(
5389 instr->hydrogen()->MustAllocateDoubleAligned());
5414 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5390 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5415 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5391 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5416 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5392 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5417 CallRuntimeFromDeferred(Runtime::kAllocateInOldPointerSpace, 1, instr, 5393 flags = AllocateTargetSpace::update(flags, OLD_POINTER_SPACE);
5418 instr->context());
5419 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5394 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5420 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5395 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5421 CallRuntimeFromDeferred(Runtime::kAllocateInOldDataSpace, 1, instr, 5396 flags = AllocateTargetSpace::update(flags, OLD_DATA_SPACE);
5422 instr->context());
5423 } else { 5397 } else {
5424 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr, 5398 flags = AllocateTargetSpace::update(flags, NEW_SPACE);
5425 instr->context());
5426 } 5399 }
5400 __ Push(Smi::FromInt(flags));
5401
5402 CallRuntimeFromDeferred(
5403 Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
5427 __ StoreToSafepointRegisterSlot(v0, result); 5404 __ StoreToSafepointRegisterSlot(v0, result);
5428 } 5405 }
5429 5406
5430 5407
5431 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 5408 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5432 ASSERT(ToRegister(instr->value()).is(a0)); 5409 ASSERT(ToRegister(instr->value()).is(a0));
5433 ASSERT(ToRegister(instr->result()).is(v0)); 5410 ASSERT(ToRegister(instr->result()).is(v0));
5434 __ push(a0); 5411 __ push(a0);
5435 CallRuntime(Runtime::kToFastProperties, 1, instr); 5412 CallRuntime(Runtime::kToFastProperties, 1, instr);
5436 } 5413 }
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
5890 __ Subu(scratch, result, scratch); 5867 __ Subu(scratch, result, scratch);
5891 __ lw(result, FieldMemOperand(scratch, 5868 __ lw(result, FieldMemOperand(scratch,
5892 FixedArray::kHeaderSize - kPointerSize)); 5869 FixedArray::kHeaderSize - kPointerSize));
5893 __ bind(&done); 5870 __ bind(&done);
5894 } 5871 }
5895 5872
5896 5873
5897 #undef __ 5874 #undef __
5898 5875
5899 } } // namespace v8::internal 5876 } } // namespace v8::internal
OLDNEW
« include/v8-platform.h ('K') | « src/mips/ic-mips.cc ('k') | src/mips/lithium-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698