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

Side by Side Diff: src/x64/lithium-x64.cc

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 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/x64/lithium-x64.h ('k') | src/x64/macro-assembler-x64.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 InputAt(0)->PrintTo(stream); 289 InputAt(0)->PrintTo(stream);
290 } 290 }
291 291
292 292
293 void LLoadContextSlot::PrintDataTo(StringStream* stream) { 293 void LLoadContextSlot::PrintDataTo(StringStream* stream) {
294 InputAt(0)->PrintTo(stream); 294 InputAt(0)->PrintTo(stream);
295 stream->Add("[%d]", slot_index()); 295 stream->Add("[%d]", slot_index());
296 } 296 }
297 297
298 298
299 void LStoreContextSlot::PrintDataTo(StringStream* stream) {
300 InputAt(0)->PrintTo(stream);
301 stream->Add("[%d] <- ", slot_index());
302 InputAt(1)->PrintTo(stream);
303 }
304
305
299 void LCallKeyed::PrintDataTo(StringStream* stream) { 306 void LCallKeyed::PrintDataTo(StringStream* stream) {
300 stream->Add("[ecx] #%d / ", arity()); 307 stream->Add("[rcx] #%d / ", arity());
301 } 308 }
302 309
303 310
304 void LCallNamed::PrintDataTo(StringStream* stream) { 311 void LCallNamed::PrintDataTo(StringStream* stream) {
305 SmartPointer<char> name_string = name()->ToCString(); 312 SmartPointer<char> name_string = name()->ToCString();
306 stream->Add("%s #%d / ", *name_string, arity()); 313 stream->Add("%s #%d / ", *name_string, arity());
307 } 314 }
308 315
309 316
310 void LCallGlobal::PrintDataTo(StringStream* stream) { 317 void LCallGlobal::PrintDataTo(StringStream* stream) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 398
392 if (can_eliminate) { 399 if (can_eliminate) {
393 label->set_replacement(GetLabel(goto_instr->block_id())); 400 label->set_replacement(GetLabel(goto_instr->block_id()));
394 } 401 }
395 } 402 }
396 } 403 }
397 } 404 }
398 } 405 }
399 406
400 407
401 void LStoreNamed::PrintDataTo(StringStream* stream) { 408 void LStoreNamedField::PrintDataTo(StringStream* stream) {
402 object()->PrintTo(stream); 409 object()->PrintTo(stream);
403 stream->Add("."); 410 stream->Add(".");
404 stream->Add(*String::cast(*name())->ToCString()); 411 stream->Add(*String::cast(*name())->ToCString());
405 stream->Add(" <- "); 412 stream->Add(" <- ");
406 value()->PrintTo(stream); 413 value()->PrintTo(stream);
407 } 414 }
408 415
409 416
410 void LStoreKeyed::PrintDataTo(StringStream* stream) { 417 void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
418 object()->PrintTo(stream);
419 stream->Add(".");
420 stream->Add(*String::cast(*name())->ToCString());
421 stream->Add(" <- ");
422 value()->PrintTo(stream);
423 }
424
425
426 void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) {
411 object()->PrintTo(stream); 427 object()->PrintTo(stream);
412 stream->Add("["); 428 stream->Add("[");
413 key()->PrintTo(stream); 429 key()->PrintTo(stream);
414 stream->Add("] <- "); 430 stream->Add("] <- ");
415 value()->PrintTo(stream); 431 value()->PrintTo(stream);
416 } 432 }
417 433
418 434
435 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
436 object()->PrintTo(stream);
437 stream->Add("[");
438 key()->PrintTo(stream);
439 stream->Add("] <- ");
440 value()->PrintTo(stream);
441 }
442
443
419 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { 444 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
420 LGap* gap = new LGap(block); 445 LGap* gap = new LGap(block);
421 int index = -1; 446 int index = -1;
422 if (instr->IsControl()) { 447 if (instr->IsControl()) {
423 instructions_.Add(gap); 448 instructions_.Add(gap);
424 index = instructions_.length(); 449 index = instructions_.length();
425 instructions_.Add(instr); 450 instructions_.Add(instr);
426 } else { 451 } else {
427 index = instructions_.length(); 452 index = instructions_.length();
428 instructions_.Add(instr); 453 instructions_.Add(instr);
429 instructions_.Add(gap); 454 instructions_.Add(gap);
430 } 455 }
431 if (instr->HasPointerMap()) { 456 if (instr->HasPointerMap()) {
432 pointer_maps_.Add(instr->pointer_map()); 457 pointer_maps_.Add(instr->pointer_map());
433 instr->pointer_map()->set_lithium_position(index); 458 instr->pointer_map()->set_lithium_position(index);
434 } 459 }
435 } 460 }
436 461
437 462
438 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { 463 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
439 return LConstantOperand::Create(constant->id()); 464 return LConstantOperand::Create(constant->id());
440 } 465 }
441 466
442 467
443 int LChunk::GetParameterStackSlot(int index) const { 468 int LChunk::GetParameterStackSlot(int index) const {
444 // The receiver is at index 0, the first parameter at index 1, so we 469 // The receiver is at index 0, the first parameter at index 1, so we
445 // shift all parameter indexes down by the number of parameters, and 470 // shift all parameter indexes down by the number of parameters, and
446 // make sure they end up negative so they are distinguishable from 471 // make sure they end up negative so they are distinguishable from
447 // spill slots. 472 // spill slots.
448 int result = index - graph()->info()->scope()->num_parameters() - 1; 473 int result = index - info()->scope()->num_parameters() - 1;
449 ASSERT(result < 0); 474 ASSERT(result < 0);
450 return result; 475 return result;
451 } 476 }
452 477
453 // A parameter relative to ebp in the arguments stub. 478 // A parameter relative to ebp in the arguments stub.
454 int LChunk::ParameterAt(int index) { 479 int LChunk::ParameterAt(int index) {
455 ASSERT(-1 <= index); // -1 is the receiver. 480 ASSERT(-1 <= index); // -1 is the receiver.
456 return (1 + graph()->info()->scope()->num_parameters() - index) * 481 return (1 + info()->scope()->num_parameters() - index) *
457 kPointerSize; 482 kPointerSize;
458 } 483 }
459 484
460 485
461 LGap* LChunk::GetGapAt(int index) const { 486 LGap* LChunk::GetGapAt(int index) const {
462 return LGap::cast(instructions_[index]); 487 return LGap::cast(instructions_[index]);
463 } 488 }
464 489
465 490
466 bool LChunk::IsGapAt(int index) const { 491 bool LChunk::IsGapAt(int index) const {
(...skipping 18 matching lines...) Expand all
485 510
486 511
487 Representation LChunk::LookupLiteralRepresentation( 512 Representation LChunk::LookupLiteralRepresentation(
488 LConstantOperand* operand) const { 513 LConstantOperand* operand) const {
489 return graph_->LookupValue(operand->index())->representation(); 514 return graph_->LookupValue(operand->index())->representation();
490 } 515 }
491 516
492 517
493 LChunk* LChunkBuilder::Build() { 518 LChunk* LChunkBuilder::Build() {
494 ASSERT(is_unused()); 519 ASSERT(is_unused());
495 chunk_ = new LChunk(graph()); 520 chunk_ = new LChunk(info(), graph());
496 HPhase phase("Building chunk", chunk_); 521 HPhase phase("Building chunk", chunk_);
497 status_ = BUILDING; 522 status_ = BUILDING;
498 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 523 const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
499 for (int i = 0; i < blocks->length(); i++) { 524 for (int i = 0; i < blocks->length(); i++) {
500 HBasicBlock* next = NULL; 525 HBasicBlock* next = NULL;
501 if (i < blocks->length() - 1) next = blocks->at(i + 1); 526 if (i < blocks->length() - 1) next = blocks->at(i + 1);
502 DoBasicBlock(blocks->at(i), next); 527 DoBasicBlock(blocks->at(i), next);
503 if (is_aborted()) return NULL; 528 if (is_aborted()) return NULL;
504 } 529 }
505 status_ = DONE; 530 status_ = DONE;
506 return chunk_; 531 return chunk_;
507 } 532 }
508 533
509 534
510 void LChunkBuilder::Abort(const char* format, ...) { 535 void LChunkBuilder::Abort(const char* format, ...) {
511 if (FLAG_trace_bailout) { 536 if (FLAG_trace_bailout) {
512 SmartPointer<char> debug_name = graph()->debug_name()->ToCString(); 537 SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString());
513 PrintF("Aborting LChunk building in @\"%s\": ", *debug_name); 538 PrintF("Aborting LChunk building in @\"%s\": ", *name);
514 va_list arguments; 539 va_list arguments;
515 va_start(arguments, format); 540 va_start(arguments, format);
516 OS::VPrint(format, arguments); 541 OS::VPrint(format, arguments);
517 va_end(arguments); 542 va_end(arguments);
518 PrintF("\n"); 543 PrintF("\n");
519 } 544 }
520 status_ = ABORTED; 545 status_ = ABORTED;
521 } 546 }
522 547
523 548
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 ? AssignEnvironment(DefineSameAsFirst(result)) 864 ? AssignEnvironment(DefineSameAsFirst(result))
840 : DefineSameAsFirst(result); 865 : DefineSameAsFirst(result);
841 } 866 }
842 867
843 868
844 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, 869 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
845 HArithmeticBinaryOperation* instr) { 870 HArithmeticBinaryOperation* instr) {
846 ASSERT(instr->representation().IsDouble()); 871 ASSERT(instr->representation().IsDouble());
847 ASSERT(instr->left()->representation().IsDouble()); 872 ASSERT(instr->left()->representation().IsDouble());
848 ASSERT(instr->right()->representation().IsDouble()); 873 ASSERT(instr->right()->representation().IsDouble());
849 if (op == Token::MOD) { 874 ASSERT(op != Token::MOD);
850 Abort("Unimplemented: %s", "DoArithmeticD MOD");
851 }
852 LOperand* left = UseRegisterAtStart(instr->left()); 875 LOperand* left = UseRegisterAtStart(instr->left());
853 LOperand* right = UseRegisterAtStart(instr->right()); 876 LOperand* right = UseRegisterAtStart(instr->right());
854 LArithmeticD* result = new LArithmeticD(op, left, right); 877 LArithmeticD* result = new LArithmeticD(op, left, right);
855 return DefineSameAsFirst(result); 878 return DefineSameAsFirst(result);
856 } 879 }
857 880
858 881
859 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, 882 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
860 HArithmeticBinaryOperation* instr) { 883 HArithmeticBinaryOperation* instr) {
861 ASSERT(op == Token::ADD || 884 ASSERT(op == Token::ADD ||
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 HIsObject* compare = HIsObject::cast(v); 1097 HIsObject* compare = HIsObject::cast(v);
1075 ASSERT(compare->value()->representation().IsTagged()); 1098 ASSERT(compare->value()->representation().IsTagged());
1076 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value())); 1099 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()));
1077 } else if (v->IsCompareJSObjectEq()) { 1100 } else if (v->IsCompareJSObjectEq()) {
1078 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); 1101 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1079 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), 1102 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1080 UseRegisterAtStart(compare->right())); 1103 UseRegisterAtStart(compare->right()));
1081 } else if (v->IsInstanceOf()) { 1104 } else if (v->IsInstanceOf()) {
1082 HInstanceOf* instance_of = HInstanceOf::cast(v); 1105 HInstanceOf* instance_of = HInstanceOf::cast(v);
1083 LInstanceOfAndBranch* result = 1106 LInstanceOfAndBranch* result =
1084 new LInstanceOfAndBranch( 1107 new LInstanceOfAndBranch(UseFixed(instance_of->left(), rax),
1085 UseFixed(instance_of->left(), InstanceofStub::left()), 1108 UseFixed(instance_of->right(), rdx));
1086 UseFixed(instance_of->right(), InstanceofStub::right()));
1087 return MarkAsCall(result, instr); 1109 return MarkAsCall(result, instr);
1088 } else if (v->IsTypeofIs()) { 1110 } else if (v->IsTypeofIs()) {
1089 HTypeofIs* typeof_is = HTypeofIs::cast(v); 1111 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1090 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); 1112 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1091 } else if (v->IsIsConstructCall()) { 1113 } else if (v->IsIsConstructCall()) {
1092 return new LIsConstructCallAndBranch(TempRegister()); 1114 return new LIsConstructCallAndBranch(TempRegister());
1093 } else { 1115 } else {
1094 if (v->IsConstant()) { 1116 if (v->IsConstant()) {
1095 if (HConstant::cast(v)->handle()->IsTrue()) { 1117 if (HConstant::cast(v)->handle()->IsTrue()) {
1096 return new LGoto(instr->FirstSuccessor()->block_id()); 1118 return new LGoto(instr->FirstSuccessor()->block_id());
(...skipping 20 matching lines...) Expand all
1117 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); 1139 return DefineAsRegister(new LArgumentsLength(Use(length->value())));
1118 } 1140 }
1119 1141
1120 1142
1121 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { 1143 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
1122 return DefineAsRegister(new LArgumentsElements); 1144 return DefineAsRegister(new LArgumentsElements);
1123 } 1145 }
1124 1146
1125 1147
1126 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { 1148 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1127 Abort("Unimplemented: %s", "DoInstanceOf"); 1149 LOperand* left = UseFixed(instr->left(), rax);
1128 return NULL; 1150 LOperand* right = UseFixed(instr->right(), rdx);
1151 LInstanceOf* result = new LInstanceOf(left, right);
1152 return MarkAsCall(DefineFixed(result, rax), instr);
1129 } 1153 }
1130 1154
1131 1155
1132 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( 1156 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1133 HInstanceOfKnownGlobal* instr) { 1157 HInstanceOfKnownGlobal* instr) {
1134 Abort("Unimplemented: %s", "DoInstanceOfKnownGlobal"); 1158 LInstanceOfKnownGlobal* result =
1135 return NULL; 1159 new LInstanceOfKnownGlobal(UseFixed(instr->value(), rax),
1160 FixedTemp(rdi));
1161 return MarkAsCall(DefineFixed(result, rax), instr);
1136 } 1162 }
1137 1163
1138 1164
1139 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1165 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1140 Abort("Unimplemented: %s", "DoApplyArguments"); 1166 LOperand* function = UseFixed(instr->function(), rdi);
1141 return NULL; 1167 LOperand* receiver = UseFixed(instr->receiver(), rax);
1168 LOperand* length = UseFixed(instr->length(), rbx);
1169 LOperand* elements = UseFixed(instr->elements(), rcx);
1170 LApplyArguments* result = new LApplyArguments(function,
1171 receiver,
1172 length,
1173 elements);
1174 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY);
1142 } 1175 }
1143 1176
1144 1177
1145 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1178 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1146 ++argument_count_; 1179 ++argument_count_;
1147 LOperand* argument = UseOrConstant(instr->argument()); 1180 LOperand* argument = UseOrConstant(instr->argument());
1148 return new LPushArgument(argument); 1181 return new LPushArgument(argument);
1149 } 1182 }
1150 1183
1151 1184
1152 LInstruction* LChunkBuilder::DoContext(HContext* instr) { 1185 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1153 return DefineAsRegister(new LContext); 1186 return DefineAsRegister(new LContext);
1154 } 1187 }
1155 1188
1156 1189
1157 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { 1190 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1158 Abort("Unimplemented: DoOuterContext"); 1191 LOperand* context = UseRegisterAtStart(instr->value());
1159 return NULL; 1192 return DefineAsRegister(new LOuterContext(context));
1160 } 1193 }
1161 1194
1162 1195
1163 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { 1196 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
1164 return DefineAsRegister(new LGlobalObject); 1197 return DefineAsRegister(new LGlobalObject);
1165 } 1198 }
1166 1199
1167 1200
1168 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { 1201 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
1169 return DefineAsRegister(new LGlobalReceiver); 1202 return DefineAsRegister(new LGlobalReceiver);
1170 } 1203 }
1171 1204
1172 1205
1173 LInstruction* LChunkBuilder::DoCallConstantFunction( 1206 LInstruction* LChunkBuilder::DoCallConstantFunction(
1174 HCallConstantFunction* instr) { 1207 HCallConstantFunction* instr) {
1175 argument_count_ -= instr->argument_count(); 1208 argument_count_ -= instr->argument_count();
1176 return MarkAsCall(DefineFixed(new LCallConstantFunction, rax), instr); 1209 return MarkAsCall(DefineFixed(new LCallConstantFunction, rax), instr);
1177 } 1210 }
1178 1211
1179 1212
1180 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1213 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1181 Abort("Unimplemented: %s", "DoUnaryMathOperation"); 1214 BuiltinFunctionId op = instr->op();
1182 return NULL; 1215 if (op == kMathLog || op == kMathSin || op == kMathCos) {
1216 LOperand* input = UseFixedDouble(instr->value(), xmm1);
1217 LUnaryMathOperation* result = new LUnaryMathOperation(input);
1218 return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
1219 } else {
1220 LOperand* input = UseRegisterAtStart(instr->value());
1221 LUnaryMathOperation* result = new LUnaryMathOperation(input);
1222 switch (op) {
1223 case kMathAbs:
1224 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1225 case kMathFloor:
1226 return AssignEnvironment(DefineAsRegister(result));
1227 case kMathRound:
1228 return AssignEnvironment(DefineAsRegister(result));
1229 case kMathSqrt:
1230 return DefineSameAsFirst(result);
1231 case kMathPowHalf:
1232 return DefineSameAsFirst(result);
1233 default:
1234 UNREACHABLE();
1235 return NULL;
1236 }
1237 }
1183 } 1238 }
1184 1239
1185 1240
1186 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { 1241 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1187 Abort("Unimplemented: %s", "DoCallKeyed"); 1242 ASSERT(instr->key()->representation().IsTagged());
1188 return NULL; 1243 LOperand* key = UseFixed(instr->key(), rcx);
1244 argument_count_ -= instr->argument_count();
1245 LCallKeyed* result = new LCallKeyed(key);
1246 return MarkAsCall(DefineFixed(result, rax), instr);
1189 } 1247 }
1190 1248
1191 1249
1192 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { 1250 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
1193 argument_count_ -= instr->argument_count(); 1251 argument_count_ -= instr->argument_count();
1194 return MarkAsCall(DefineFixed(new LCallNamed, rax), instr); 1252 return MarkAsCall(DefineFixed(new LCallNamed, rax), instr);
1195 } 1253 }
1196 1254
1197 1255
1198 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { 1256 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
(...skipping 10 matching lines...) Expand all
1209 1267
1210 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { 1268 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1211 LOperand* constructor = UseFixed(instr->constructor(), rdi); 1269 LOperand* constructor = UseFixed(instr->constructor(), rdi);
1212 argument_count_ -= instr->argument_count(); 1270 argument_count_ -= instr->argument_count();
1213 LCallNew* result = new LCallNew(constructor); 1271 LCallNew* result = new LCallNew(constructor);
1214 return MarkAsCall(DefineFixed(result, rax), instr); 1272 return MarkAsCall(DefineFixed(result, rax), instr);
1215 } 1273 }
1216 1274
1217 1275
1218 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { 1276 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1219 Abort("Unimplemented: %s", "DoCallFunction"); 1277 argument_count_ -= instr->argument_count();
1220 return NULL; 1278 LCallFunction* result = new LCallFunction();
1279 return MarkAsCall(DefineFixed(result, rax), instr);
1221 } 1280 }
1222 1281
1223 1282
1224 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { 1283 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1225 argument_count_ -= instr->argument_count(); 1284 argument_count_ -= instr->argument_count();
1226 return MarkAsCall(DefineFixed(new LCallRuntime, rax), instr); 1285 return MarkAsCall(DefineFixed(new LCallRuntime, rax), instr);
1227 } 1286 }
1228 1287
1229 1288
1230 LInstruction* LChunkBuilder::DoShr(HShr* instr) { 1289 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 LDivI* result = new LDivI(dividend, divisor, temp); 1337 LDivI* result = new LDivI(dividend, divisor, temp);
1279 return AssignEnvironment(DefineFixed(result, rax)); 1338 return AssignEnvironment(DefineFixed(result, rax));
1280 } else { 1339 } else {
1281 ASSERT(instr->representation().IsTagged()); 1340 ASSERT(instr->representation().IsTagged());
1282 return DoArithmeticT(Token::DIV, instr); 1341 return DoArithmeticT(Token::DIV, instr);
1283 } 1342 }
1284 } 1343 }
1285 1344
1286 1345
1287 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1346 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1288 Abort("Unimplemented: %s", "DoMod"); 1347 if (instr->representation().IsInteger32()) {
1289 return NULL; 1348 ASSERT(instr->left()->representation().IsInteger32());
1349 ASSERT(instr->right()->representation().IsInteger32());
1350
1351 LInstruction* result;
1352 if (instr->HasPowerOf2Divisor()) {
1353 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
1354 LOperand* value = UseRegisterAtStart(instr->left());
1355 LModI* mod = new LModI(value, UseOrConstant(instr->right()), NULL);
1356 result = DefineSameAsFirst(mod);
1357 } else {
1358 // The temporary operand is necessary to ensure that right is not
1359 // allocated into edx.
1360 LOperand* temp = FixedTemp(rdx);
1361 LOperand* value = UseFixed(instr->left(), rax);
1362 LOperand* divisor = UseRegister(instr->right());
1363 LModI* mod = new LModI(value, divisor, temp);
1364 result = DefineFixed(mod, rdx);
1365 }
1366
1367 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1368 instr->CheckFlag(HValue::kCanBeDivByZero))
1369 ? AssignEnvironment(result)
1370 : result;
1371 } else if (instr->representation().IsTagged()) {
1372 return DoArithmeticT(Token::MOD, instr);
1373 } else {
1374 ASSERT(instr->representation().IsDouble());
1375 // We call a C function for double modulo. It can't trigger a GC.
1376 // We need to use fixed result register for the call.
1377 // TODO(fschneider): Allow any register as input registers.
1378 LOperand* left = UseFixedDouble(instr->left(), xmm2);
1379 LOperand* right = UseFixedDouble(instr->right(), xmm1);
1380 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right);
1381 return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
1382 }
1290 } 1383 }
1291 1384
1292 1385
1293 LInstruction* LChunkBuilder::DoMul(HMul* instr) { 1386 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1294 if (instr->representation().IsInteger32()) { 1387 if (instr->representation().IsInteger32()) {
1295 ASSERT(instr->left()->representation().IsInteger32()); 1388 ASSERT(instr->left()->representation().IsInteger32());
1296 ASSERT(instr->right()->representation().IsInteger32()); 1389 ASSERT(instr->right()->representation().IsInteger32());
1297 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 1390 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1298 LOperand* right = UseOrConstant(instr->MostConstantOperand()); 1391 LOperand* right = UseOrConstant(instr->MostConstantOperand());
1299 LMulI* mul = new LMulI(left, right); 1392 LMulI* mul = new LMulI(left, right);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 return DoArithmeticD(Token::ADD, instr); 1437 return DoArithmeticD(Token::ADD, instr);
1345 } else { 1438 } else {
1346 ASSERT(instr->representation().IsTagged()); 1439 ASSERT(instr->representation().IsTagged());
1347 return DoArithmeticT(Token::ADD, instr); 1440 return DoArithmeticT(Token::ADD, instr);
1348 } 1441 }
1349 return NULL; 1442 return NULL;
1350 } 1443 }
1351 1444
1352 1445
1353 LInstruction* LChunkBuilder::DoPower(HPower* instr) { 1446 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1354 Abort("Unimplemented: %s", "DoPower"); 1447 ASSERT(instr->representation().IsDouble());
1355 return NULL; 1448 // We call a C function for double power. It can't trigger a GC.
1449 // We need to use fixed result register for the call.
1450 Representation exponent_type = instr->right()->representation();
1451 ASSERT(instr->left()->representation().IsDouble());
1452 LOperand* left = UseFixedDouble(instr->left(), xmm2);
1453 LOperand* right = exponent_type.IsDouble() ?
1454 UseFixedDouble(instr->right(), xmm1) :
1455 #ifdef _WIN64
1456 UseFixed(instr->right(), rdx);
1457 #else
1458 UseFixed(instr->right(), rdi);
1459 #endif
1460 LPower* result = new LPower(left, right);
1461 return MarkAsCall(DefineFixedDouble(result, xmm1), instr,
1462 CAN_DEOPTIMIZE_EAGERLY);
1356 } 1463 }
1357 1464
1358 1465
1359 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { 1466 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
1360 Token::Value op = instr->token(); 1467 Token::Value op = instr->token();
1361 Representation r = instr->GetInputRepresentation(); 1468 Representation r = instr->GetInputRepresentation();
1362 if (r.IsInteger32()) { 1469 if (r.IsInteger32()) {
1363 ASSERT(instr->left()->representation().IsInteger32()); 1470 ASSERT(instr->left()->representation().IsInteger32());
1364 ASSERT(instr->right()->representation().IsInteger32()); 1471 ASSERT(instr->right()->representation().IsInteger32());
1365 LOperand* left = UseRegisterAtStart(instr->left()); 1472 LOperand* left = UseRegisterAtStart(instr->left());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 1517
1411 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { 1518 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) {
1412 ASSERT(instr->value()->representation().IsTagged()); 1519 ASSERT(instr->value()->representation().IsTagged());
1413 LOperand* value = UseAtStart(instr->value()); 1520 LOperand* value = UseAtStart(instr->value());
1414 1521
1415 return DefineAsRegister(new LIsSmi(value)); 1522 return DefineAsRegister(new LIsSmi(value));
1416 } 1523 }
1417 1524
1418 1525
1419 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { 1526 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) {
1420 Abort("Unimplemented: %s", "DoHasInstanceType"); 1527 ASSERT(instr->value()->representation().IsTagged());
1421 return NULL; 1528 LOperand* value = UseRegisterAtStart(instr->value());
1529
1530 return DefineAsRegister(new LHasInstanceType(value));
1531 }
1532
1533
1534 LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1535 HGetCachedArrayIndex* instr) {
1536 ASSERT(instr->value()->representation().IsTagged());
1537 LOperand* value = UseRegisterAtStart(instr->value());
1538
1539 return DefineAsRegister(new LGetCachedArrayIndex(value));
1422 } 1540 }
1423 1541
1424 1542
1425 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( 1543 LInstruction* LChunkBuilder::DoHasCachedArrayIndex(
1426 HHasCachedArrayIndex* instr) { 1544 HHasCachedArrayIndex* instr) {
1427 Abort("Unimplemented: %s", "DoHasCachedArrayIndex"); 1545 ASSERT(instr->value()->representation().IsTagged());
1428 return NULL; 1546 LOperand* value = UseRegister(instr->value());
1547 return DefineAsRegister(new LHasCachedArrayIndex(value));
1429 } 1548 }
1430 1549
1431 1550
1432 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { 1551 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
1433 Abort("Unimplemented: %s", "DoClassOfTest"); 1552 Abort("Unimplemented: %s", "DoClassOfTest");
1434 return NULL; 1553 return NULL;
1435 } 1554 }
1436 1555
1437 1556
1438 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { 1557 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1439 LOperand* array = UseRegisterAtStart(instr->value()); 1558 LOperand* array = UseRegisterAtStart(instr->value());
1440 return DefineAsRegister(new LJSArrayLength(array)); 1559 return DefineAsRegister(new LJSArrayLength(array));
1441 } 1560 }
1442 1561
1443 1562
1444 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { 1563 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1445 LOperand* array = UseRegisterAtStart(instr->value()); 1564 LOperand* array = UseRegisterAtStart(instr->value());
1446 return DefineAsRegister(new LFixedArrayLength(array)); 1565 return DefineAsRegister(new LFixedArrayLength(array));
1447 } 1566 }
1448 1567
1449 1568
1450 LInstruction* LChunkBuilder::DoPixelArrayLength(HPixelArrayLength* instr) { 1569 LInstruction* LChunkBuilder::DoExternalArrayLength(
1570 HExternalArrayLength* instr) {
1451 LOperand* array = UseRegisterAtStart(instr->value()); 1571 LOperand* array = UseRegisterAtStart(instr->value());
1452 return DefineAsRegister(new LPixelArrayLength(array)); 1572 return DefineAsRegister(new LExternalArrayLength(array));
1453 } 1573 }
1454 1574
1455 1575
1456 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1576 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1457 Abort("Unimplemented: %s", "DoValueOf"); 1577 LOperand* object = UseRegister(instr->value());
1458 return NULL; 1578 LValueOf* result = new LValueOf(object);
1579 return AssignEnvironment(DefineSameAsFirst(result));
1459 } 1580 }
1460 1581
1461 1582
1462 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1583 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1463 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1584 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1464 Use(instr->length()))); 1585 Use(instr->length())));
1465 } 1586 }
1466 1587
1467 1588
1468 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { 1589 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 if (to.IsTagged()) { 1626 if (to.IsTagged()) {
1506 LOperand* value = UseRegister(instr->value()); 1627 LOperand* value = UseRegister(instr->value());
1507 LOperand* temp = TempRegister(); 1628 LOperand* temp = TempRegister();
1508 1629
1509 // Make sure that temp and result_temp are different registers. 1630 // Make sure that temp and result_temp are different registers.
1510 LUnallocated* result_temp = TempRegister(); 1631 LUnallocated* result_temp = TempRegister();
1511 LNumberTagD* result = new LNumberTagD(value, temp); 1632 LNumberTagD* result = new LNumberTagD(value, temp);
1512 return AssignPointerMap(Define(result, result_temp)); 1633 return AssignPointerMap(Define(result, result_temp));
1513 } else { 1634 } else {
1514 ASSERT(to.IsInteger32()); 1635 ASSERT(to.IsInteger32());
1515 bool needs_temp = instr->CanTruncateToInt32() && 1636 LOperand* value = UseRegister(instr->value());
1516 !CpuFeatures::IsSupported(SSE3); 1637 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value)));
1517 LOperand* value = needs_temp ?
1518 UseTempRegister(instr->value()) : UseRegister(instr->value());
1519 LOperand* temp = needs_temp ? TempRegister() : NULL;
1520 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp)));
1521 } 1638 }
1522 } else if (from.IsInteger32()) { 1639 } else if (from.IsInteger32()) {
1523 if (to.IsTagged()) { 1640 if (to.IsTagged()) {
1524 HValue* val = instr->value(); 1641 HValue* val = instr->value();
1525 LOperand* value = UseRegister(val); 1642 LOperand* value = UseRegister(val);
1526 if (val->HasRange() && val->range()->IsInSmiRange()) { 1643 if (val->HasRange() && val->range()->IsInSmiRange()) {
1527 return DefineSameAsFirst(new LSmiTag(value)); 1644 return DefineSameAsFirst(new LSmiTag(value));
1528 } else { 1645 } else {
1529 LNumberTagI* result = new LNumberTagI(value); 1646 LNumberTagI* result = new LNumberTagI(value);
1530 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1647 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 1725
1609 1726
1610 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { 1727 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) {
1611 LStoreGlobal* result = new LStoreGlobal(UseRegister(instr->value()), 1728 LStoreGlobal* result = new LStoreGlobal(UseRegister(instr->value()),
1612 TempRegister()); 1729 TempRegister());
1613 return instr->check_hole_value() ? AssignEnvironment(result) : result; 1730 return instr->check_hole_value() ? AssignEnvironment(result) : result;
1614 } 1731 }
1615 1732
1616 1733
1617 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 1734 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1618 Abort("Unimplemented: %s", "DoLoadContextSlot"); 1735 LOperand* context = UseRegisterAtStart(instr->value());
1619 return NULL; 1736 return DefineAsRegister(new LLoadContextSlot(context));
1620 } 1737 }
1621 1738
1622 1739
1623 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { 1740 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
1624 Abort("Unimplemented: DoStoreContextSlot"); 1741 LOperand* context;
1625 return NULL; 1742 LOperand* value;
1743 LOperand* temp;
1744 if (instr->NeedsWriteBarrier()) {
1745 context = UseTempRegister(instr->context());
1746 value = UseTempRegister(instr->value());
1747 temp = TempRegister();
1748 } else {
1749 context = UseRegister(instr->context());
1750 value = UseRegister(instr->value());
1751 temp = NULL;
1752 }
1753 return new LStoreContextSlot(context, value, temp);
1626 } 1754 }
1627 1755
1628 1756
1629 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 1757 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1630 ASSERT(instr->representation().IsTagged()); 1758 ASSERT(instr->representation().IsTagged());
1631 LOperand* obj = UseRegisterAtStart(instr->object()); 1759 LOperand* obj = UseRegisterAtStart(instr->object());
1632 return DefineAsRegister(new LLoadNamedField(obj)); 1760 return DefineAsRegister(new LLoadNamedField(obj));
1633 } 1761 }
1634 1762
1635 1763
(...skipping 10 matching lines...) Expand all
1646 new LLoadFunctionPrototype(UseRegister(instr->function())))); 1774 new LLoadFunctionPrototype(UseRegister(instr->function()))));
1647 } 1775 }
1648 1776
1649 1777
1650 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { 1778 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
1651 LOperand* input = UseRegisterAtStart(instr->value()); 1779 LOperand* input = UseRegisterAtStart(instr->value());
1652 return DefineAsRegister(new LLoadElements(input)); 1780 return DefineAsRegister(new LLoadElements(input));
1653 } 1781 }
1654 1782
1655 1783
1656 LInstruction* LChunkBuilder::DoLoadPixelArrayExternalPointer( 1784 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
1657 HLoadPixelArrayExternalPointer* instr) { 1785 HLoadExternalArrayPointer* instr) {
1658 LOperand* input = UseRegisterAtStart(instr->value()); 1786 LOperand* input = UseRegisterAtStart(instr->value());
1659 return DefineAsRegister(new LLoadPixelArrayExternalPointer(input)); 1787 return DefineAsRegister(new LLoadExternalArrayPointer(input));
1660 } 1788 }
1661 1789
1662 1790
1663 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( 1791 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1664 HLoadKeyedFastElement* instr) { 1792 HLoadKeyedFastElement* instr) {
1665 ASSERT(instr->representation().IsTagged()); 1793 ASSERT(instr->representation().IsTagged());
1666 ASSERT(instr->key()->representation().IsInteger32()); 1794 ASSERT(instr->key()->representation().IsInteger32());
1667 LOperand* obj = UseRegisterAtStart(instr->object()); 1795 LOperand* obj = UseRegisterAtStart(instr->object());
1668 LOperand* key = UseRegisterAtStart(instr->key()); 1796 LOperand* key = UseRegisterAtStart(instr->key());
1669 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); 1797 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1670 return AssignEnvironment(DefineSameAsFirst(result)); 1798 return AssignEnvironment(DefineSameAsFirst(result));
1671 } 1799 }
1672 1800
1673 1801
1674 LInstruction* LChunkBuilder::DoLoadPixelArrayElement( 1802 LInstruction* LChunkBuilder::DoLoadPixelArrayElement(
1675 HLoadPixelArrayElement* instr) { 1803 HLoadPixelArrayElement* instr) {
1676 ASSERT(instr->representation().IsInteger32()); 1804 ASSERT(instr->representation().IsInteger32());
1677 ASSERT(instr->key()->representation().IsInteger32()); 1805 ASSERT(instr->key()->representation().IsInteger32());
1678 LOperand* external_pointer = 1806 LOperand* external_pointer =
1679 UseRegisterAtStart(instr->external_pointer()); 1807 UseRegisterAtStart(instr->external_pointer());
1680 LOperand* key = UseRegisterAtStart(instr->key()); 1808 LOperand* key = UseRegisterAtStart(instr->key());
1681 LLoadPixelArrayElement* result = 1809 LLoadPixelArrayElement* result =
1682 new LLoadPixelArrayElement(external_pointer, key); 1810 new LLoadPixelArrayElement(external_pointer, key);
1683 return DefineSameAsFirst(result); 1811 return DefineSameAsFirst(result);
1684 } 1812 }
1685 1813
1686 1814
1687 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1815 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1688 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); 1816 LOperand* object = UseFixed(instr->object(), rdx);
1689 return NULL; 1817 LOperand* key = UseFixed(instr->key(), rax);
1818
1819 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key);
1820 return MarkAsCall(DefineFixed(result, rax), instr);
1690 } 1821 }
1691 1822
1692 1823
1693 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( 1824 LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
1694 HStoreKeyedFastElement* instr) { 1825 HStoreKeyedFastElement* instr) {
1695 bool needs_write_barrier = instr->NeedsWriteBarrier(); 1826 bool needs_write_barrier = instr->NeedsWriteBarrier();
1696 ASSERT(instr->value()->representation().IsTagged()); 1827 ASSERT(instr->value()->representation().IsTagged());
1697 ASSERT(instr->object()->representation().IsTagged()); 1828 ASSERT(instr->object()->representation().IsTagged());
1698 ASSERT(instr->key()->representation().IsInteger32()); 1829 ASSERT(instr->key()->representation().IsInteger32());
1699 1830
1700 LOperand* obj = UseTempRegister(instr->object()); 1831 LOperand* obj = UseTempRegister(instr->object());
1701 LOperand* val = needs_write_barrier 1832 LOperand* val = needs_write_barrier
1702 ? UseTempRegister(instr->value()) 1833 ? UseTempRegister(instr->value())
1703 : UseRegisterAtStart(instr->value()); 1834 : UseRegisterAtStart(instr->value());
1704 LOperand* key = needs_write_barrier 1835 LOperand* key = needs_write_barrier
1705 ? UseTempRegister(instr->key()) 1836 ? UseTempRegister(instr->key())
1706 : UseRegisterOrConstantAtStart(instr->key()); 1837 : UseRegisterOrConstantAtStart(instr->key());
1707 1838
1708 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); 1839 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val));
1709 } 1840 }
1710 1841
1711 1842
1843 LInstruction* LChunkBuilder::DoStorePixelArrayElement(
1844 HStorePixelArrayElement* instr) {
1845 ASSERT(instr->value()->representation().IsInteger32());
1846 ASSERT(instr->external_pointer()->representation().IsExternal());
1847 ASSERT(instr->key()->representation().IsInteger32());
1848
1849 LOperand* external_pointer = UseRegister(instr->external_pointer());
1850 LOperand* val = UseTempRegister(instr->value());
1851 LOperand* key = UseRegister(instr->key());
1852
1853 return new LStorePixelArrayElement(external_pointer, key, val);
1854 }
1855
1856
1712 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { 1857 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
1713 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); 1858 LOperand* object = UseFixed(instr->object(), rdx);
1714 return NULL; 1859 LOperand* key = UseFixed(instr->key(), rcx);
1860 LOperand* value = UseFixed(instr->value(), rax);
1861
1862 ASSERT(instr->object()->representation().IsTagged());
1863 ASSERT(instr->key()->representation().IsTagged());
1864 ASSERT(instr->value()->representation().IsTagged());
1865
1866 LStoreKeyedGeneric* result = new LStoreKeyedGeneric(object, key, value);
1867 return MarkAsCall(result, instr);
1715 } 1868 }
1716 1869
1717 1870
1718 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { 1871 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
1719 bool needs_write_barrier = instr->NeedsWriteBarrier(); 1872 bool needs_write_barrier = instr->NeedsWriteBarrier();
1720 1873
1721 LOperand* obj = needs_write_barrier 1874 LOperand* obj = needs_write_barrier
1722 ? UseTempRegister(instr->object()) 1875 ? UseTempRegister(instr->object())
1723 : UseRegisterAtStart(instr->object()); 1876 : UseRegisterAtStart(instr->object());
1724 1877
1725 LOperand* val = needs_write_barrier 1878 LOperand* val = needs_write_barrier
1726 ? UseTempRegister(instr->value()) 1879 ? UseTempRegister(instr->value())
1727 : UseRegister(instr->value()); 1880 : UseRegister(instr->value());
1728 1881
1729 // We only need a scratch register if we have a write barrier or we 1882 // We only need a scratch register if we have a write barrier or we
1730 // have a store into the properties array (not in-object-property). 1883 // have a store into the properties array (not in-object-property).
1731 LOperand* temp = (!instr->is_in_object() || needs_write_barrier) 1884 LOperand* temp = (!instr->is_in_object() || needs_write_barrier)
1732 ? TempRegister() : NULL; 1885 ? TempRegister() : NULL;
1733 1886
1734 return new LStoreNamedField(obj, val, temp); 1887 return new LStoreNamedField(obj, val, temp);
1735 } 1888 }
1736 1889
1737 1890
1738 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 1891 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
1739 Abort("Unimplemented: %s", "DoStoreNamedGeneric"); 1892 LOperand* object = UseFixed(instr->object(), rdx);
1740 return NULL; 1893 LOperand* value = UseFixed(instr->value(), rax);
1894
1895 LStoreNamedGeneric* result = new LStoreNamedGeneric(object, value);
1896 return MarkAsCall(result, instr);
1741 } 1897 }
1742 1898
1743 1899
1744 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { 1900 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
1745 Abort("Unimplemented: %s", "DoStringCharCodeAt"); 1901 LOperand* string = UseRegister(instr->string());
1746 return NULL; 1902 LOperand* index = UseRegisterOrConstant(instr->index());
1903 LStringCharCodeAt* result = new LStringCharCodeAt(string, index);
1904 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1905 }
1906
1907
1908 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
1909 LOperand* char_code = UseRegister(instr->value());
1910 LStringCharFromCode* result = new LStringCharFromCode(char_code);
1911 return AssignPointerMap(DefineAsRegister(result));
1747 } 1912 }
1748 1913
1749 1914
1750 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { 1915 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
1751 LOperand* string = UseRegisterAtStart(instr->value()); 1916 LOperand* string = UseRegisterAtStart(instr->value());
1752 return DefineAsRegister(new LStringLength(string)); 1917 return DefineAsRegister(new LStringLength(string));
1753 } 1918 }
1754 1919
1755 1920
1756 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { 1921 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
1757 return MarkAsCall(DefineFixed(new LArrayLiteral, rax), instr); 1922 return MarkAsCall(DefineFixed(new LArrayLiteral, rax), instr);
1758 } 1923 }
1759 1924
1760 1925
1761 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { 1926 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
1762 return MarkAsCall(DefineFixed(new LObjectLiteral, rax), instr); 1927 return MarkAsCall(DefineFixed(new LObjectLiteral, rax), instr);
1763 } 1928 }
1764 1929
1765 1930
1766 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { 1931 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
1767 Abort("Unimplemented: %s", "DoRegExpLiteral"); 1932 return MarkAsCall(DefineFixed(new LRegExpLiteral, rax), instr);
1768 return NULL;
1769 } 1933 }
1770 1934
1771 1935
1772 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { 1936 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
1773 return MarkAsCall(DefineFixed(new LFunctionLiteral, rax), instr); 1937 return MarkAsCall(DefineFixed(new LFunctionLiteral, rax), instr);
1774 } 1938 }
1775 1939
1776 1940
1777 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { 1941 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
1778 Abort("Unimplemented: %s", "DoDeleteProperty"); 1942 LDeleteProperty* result =
1779 return NULL; 1943 new LDeleteProperty(Use(instr->object()), UseOrConstant(instr->key()));
1944 return MarkAsCall(DefineFixed(result, rax), instr);
1780 } 1945 }
1781 1946
1782 1947
1783 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { 1948 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
1784 Abort("Unimplemented: %s", "DoOsrEntry"); 1949 allocator_->MarkAsOsrEntry();
1785 return NULL; 1950 current_block_->last_environment()->set_ast_id(instr->ast_id());
1951 return AssignEnvironment(new LOsrEntry);
1786 } 1952 }
1787 1953
1788 1954
1789 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { 1955 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
1790 int spill_index = chunk()->GetParameterStackSlot(instr->index()); 1956 int spill_index = chunk()->GetParameterStackSlot(instr->index());
1791 return DefineAsSpilled(new LParameter, spill_index); 1957 return DefineAsSpilled(new LParameter, spill_index);
1792 } 1958 }
1793 1959
1794 1960
1795 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { 1961 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
1796 Abort("Unimplemented: %s", "DoUnknownOSRValue"); 1962 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width.
1797 return NULL; 1963 return DefineAsSpilled(new LUnknownOSRValue, spill_index);
1798 } 1964 }
1799 1965
1800 1966
1801 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { 1967 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
1802 argument_count_ -= instr->argument_count(); 1968 argument_count_ -= instr->argument_count();
1803 return MarkAsCall(DefineFixed(new LCallStub, rax), instr); 1969 return MarkAsCall(DefineFixed(new LCallStub, rax), instr);
1804 } 1970 }
1805 1971
1806 1972
1807 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { 1973 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
1808 Abort("Unimplemented: %s", "DoArgumentsObject"); 1974 // There are no real uses of the arguments object.
1975 // arguments.length and element access are supported directly on
1976 // stack arguments, and any real arguments object use causes a bailout.
1977 // So this value is never used.
1809 return NULL; 1978 return NULL;
1810 } 1979 }
1811 1980
1812 1981
1813 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 1982 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
1814 LOperand* arguments = UseRegister(instr->arguments()); 1983 LOperand* arguments = UseRegister(instr->arguments());
1815 LOperand* length = UseTempRegister(instr->length()); 1984 LOperand* length = UseTempRegister(instr->length());
1816 LOperand* index = Use(instr->index()); 1985 LOperand* index = Use(instr->index());
1817 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); 1986 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index);
1818 return AssignEnvironment(DefineAsRegister(result)); 1987 return AssignEnvironment(DefineAsRegister(result));
1819 } 1988 }
1820 1989
1821 1990
1822 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 1991 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
1823 Abort("Unimplemented: %s", "DoTypeof"); 1992 LTypeof* result = new LTypeof(UseAtStart(instr->value()));
1824 return NULL; 1993 return MarkAsCall(DefineFixed(result, rax), instr);
1825 } 1994 }
1826 1995
1827 1996
1828 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 1997 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
1829 Abort("Unimplemented: %s", "DoTypeofIs"); 1998 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
1830 return NULL;
1831 } 1999 }
1832 2000
1833 2001
1834 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { 2002 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) {
1835 return DefineAsRegister(new LIsConstructCall); 2003 return DefineAsRegister(new LIsConstructCall);
1836 } 2004 }
1837 2005
1838 2006
1839 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 2007 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
1840 HEnvironment* env = current_block_->last_environment(); 2008 HEnvironment* env = current_block_->last_environment();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 2056
1889 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2057 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
1890 HEnvironment* outer = current_block_->last_environment()->outer(); 2058 HEnvironment* outer = current_block_->last_environment()->outer();
1891 current_block_->UpdateEnvironment(outer); 2059 current_block_->UpdateEnvironment(outer);
1892 return NULL; 2060 return NULL;
1893 } 2061 }
1894 2062
1895 } } // namespace v8::internal 2063 } } // namespace v8::internal
1896 2064
1897 #endif // V8_TARGET_ARCH_X64 2065 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-x64.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698