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

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

Issue 141363005: A64: Synchronize with r15204. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 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/mips/lithium-mips.h ('k') | src/mips/macro-assembler-mips.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 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 915 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 LEnvironment* LChunkBuilder::CreateEnvironment( 926 LEnvironment* LChunkBuilder::CreateEnvironment(
927 HEnvironment* hydrogen_env, 927 HEnvironment* hydrogen_env,
928 int* argument_index_accumulator) { 928 int* argument_index_accumulator) {
929 if (hydrogen_env == NULL) return NULL; 929 if (hydrogen_env == NULL) return NULL;
930 930
931 LEnvironment* outer = 931 LEnvironment* outer =
932 CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator); 932 CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
933 BailoutId ast_id = hydrogen_env->ast_id(); 933 BailoutId ast_id = hydrogen_env->ast_id();
934 ASSERT(!ast_id.IsNone() || 934 ASSERT(!ast_id.IsNone() ||
935 hydrogen_env->frame_type() != JS_FUNCTION); 935 hydrogen_env->frame_type() != JS_FUNCTION);
936 int value_count = hydrogen_env->length(); 936 int value_count = hydrogen_env->length() - hydrogen_env->specials_count();
937 LEnvironment* result = new(zone()) LEnvironment( 937 LEnvironment* result = new(zone()) LEnvironment(
938 hydrogen_env->closure(), 938 hydrogen_env->closure(),
939 hydrogen_env->frame_type(), 939 hydrogen_env->frame_type(),
940 ast_id, 940 ast_id,
941 hydrogen_env->parameter_count(), 941 hydrogen_env->parameter_count(),
942 argument_count_, 942 argument_count_,
943 value_count, 943 value_count,
944 outer, 944 outer,
945 hydrogen_env->entry(), 945 hydrogen_env->entry(),
946 zone()); 946 zone());
947 bool needs_arguments_object_materialization = false;
947 int argument_index = *argument_index_accumulator; 948 int argument_index = *argument_index_accumulator;
948 for (int i = 0; i < value_count; ++i) { 949 for (int i = 0; i < hydrogen_env->length(); ++i) {
949 if (hydrogen_env->is_special_index(i)) continue; 950 if (hydrogen_env->is_special_index(i)) continue;
950 951
951 HValue* value = hydrogen_env->values()->at(i); 952 HValue* value = hydrogen_env->values()->at(i);
952 LOperand* op = NULL; 953 LOperand* op = NULL;
953 if (value->IsArgumentsObject()) { 954 if (value->IsArgumentsObject()) {
955 needs_arguments_object_materialization = true;
954 op = NULL; 956 op = NULL;
955 } else if (value->IsPushArgument()) { 957 } else if (value->IsPushArgument()) {
956 op = new(zone()) LArgument(argument_index++); 958 op = new(zone()) LArgument(argument_index++);
957 } else { 959 } else {
958 op = UseAny(value); 960 op = UseAny(value);
959 } 961 }
960 result->AddValue(op, 962 result->AddValue(op,
961 value->representation(), 963 value->representation(),
962 value->CheckFlag(HInstruction::kUint32)); 964 value->CheckFlag(HInstruction::kUint32));
963 } 965 }
964 966
967 if (needs_arguments_object_materialization) {
968 HArgumentsObject* arguments = hydrogen_env->entry() == NULL
969 ? graph()->GetArgumentsObject()
970 : hydrogen_env->entry()->arguments_object();
971 ASSERT(arguments->IsLinked());
972 for (int i = 1; i < arguments->arguments_count(); ++i) {
973 HValue* value = arguments->arguments_values()->at(i);
974 ASSERT(!value->IsArgumentsObject() && !value->IsPushArgument());
975 LOperand* op = UseAny(value);
976 result->AddValue(op,
977 value->representation(),
978 value->CheckFlag(HInstruction::kUint32));
979 }
980 }
981
965 if (hydrogen_env->frame_type() == JS_FUNCTION) { 982 if (hydrogen_env->frame_type() == JS_FUNCTION) {
966 *argument_index_accumulator = argument_index; 983 *argument_index_accumulator = argument_index;
967 } 984 }
968 985
969 return result; 986 return result;
970 } 987 }
971 988
972 989
973 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 990 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
974 return new(zone()) LGoto(instr->FirstSuccessor()->block_id()); 991 return new(zone()) LGoto(instr->FirstSuccessor()->block_id());
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 if (instr->HasNoUses()) return NULL; 1352 if (instr->HasNoUses()) return NULL;
1336 LOperand* value = UseRegisterAtStart(instr->value()); 1353 LOperand* value = UseRegisterAtStart(instr->value());
1337 return DefineAsRegister(new(zone()) LBitNotI(value)); 1354 return DefineAsRegister(new(zone()) LBitNotI(value));
1338 } 1355 }
1339 1356
1340 1357
1341 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1358 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1342 if (instr->representation().IsDouble()) { 1359 if (instr->representation().IsDouble()) {
1343 return DoArithmeticD(Token::DIV, instr); 1360 return DoArithmeticD(Token::DIV, instr);
1344 } else if (instr->representation().IsInteger32()) { 1361 } else if (instr->representation().IsInteger32()) {
1345 // TODO(1042) The fixed register allocation 1362 LOperand* dividend = UseRegister(instr->left());
1346 // is needed because we call TypeRecordingBinaryOpStub from 1363 LOperand* divisor = UseRegister(instr->right());
1347 // the generated code, which requires registers a0 1364 LDivI* div = new(zone()) LDivI(dividend, divisor);
1348 // and a1 to be used. We should remove that 1365 return AssignEnvironment(DefineAsRegister(div));
1349 // when we provide a native implementation.
1350 LOperand* dividend = UseFixed(instr->left(), a0);
1351 LOperand* divisor = UseFixed(instr->right(), a1);
1352 return AssignEnvironment(AssignPointerMap(
1353 DefineFixed(new(zone()) LDivI(dividend, divisor), v0)));
1354 } else { 1366 } else {
1355 return DoArithmeticT(Token::DIV, instr); 1367 return DoArithmeticT(Token::DIV, instr);
1356 } 1368 }
1357 } 1369 }
1358 1370
1359 1371
1372 bool LChunkBuilder::HasMagicNumberForDivisor(int32_t divisor) {
1373 uint32_t divisor_abs = abs(divisor);
1374 // Dividing by 0, 1, and powers of 2 is easy.
1375 // Note that IsPowerOf2(0) returns true;
1376 ASSERT(IsPowerOf2(0) == true);
1377 if (IsPowerOf2(divisor_abs)) return true;
1378
1379 // We have magic numbers for a few specific divisors.
1380 // Details and proofs can be found in:
1381 // - Hacker's Delight, Henry S. Warren, Jr.
1382 // - The PowerPC Compiler Writer's Guide
1383 // and probably many others.
1384 //
1385 // We handle
1386 // <divisor with magic numbers> * <power of 2>
1387 // but not
1388 // <divisor with magic numbers> * <other divisor with magic numbers>
1389 int32_t power_of_2_factor =
1390 CompilerIntrinsics::CountTrailingZeros(divisor_abs);
1391 DivMagicNumbers magic_numbers =
1392 DivMagicNumberFor(divisor_abs >> power_of_2_factor);
1393 if (magic_numbers.M != InvalidDivMagicNumber.M) return true;
1394
1395 return false;
1396 }
1397
1398
1399 HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
1400 // Only optimize when we have magic numbers for the divisor.
1401 // The standard integer division routine is usually slower than transitionning
1402 // to FPU.
1403 if (divisor->IsConstant() &&
1404 HConstant::cast(divisor)->HasInteger32Value()) {
1405 HConstant* constant_val = HConstant::cast(divisor);
1406 return constant_val->CopyToRepresentation(Representation::Integer32(),
1407 divisor->block()->zone());
1408 }
1409 return NULL;
1410 }
1411
1412
1360 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { 1413 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1361 UNIMPLEMENTED(); 1414 HValue* right = instr->right();
1362 return NULL; 1415 LOperand* dividend = UseRegister(instr->left());
1416 LOperand* divisor = UseRegisterOrConstant(right);
1417 LOperand* remainder = TempRegister();
1418 ASSERT(right->IsConstant() &&
1419 HConstant::cast(right)->HasInteger32Value());
1420 return AssignEnvironment(DefineAsRegister(
1421 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder)));
1363 } 1422 }
1364 1423
1365 1424
1366 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1425 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1367 HValue* left = instr->left(); 1426 HValue* left = instr->left();
1368 HValue* right = instr->right(); 1427 HValue* right = instr->right();
1369 if (instr->representation().IsInteger32()) { 1428 if (instr->representation().IsInteger32()) {
1370 ASSERT(left->representation().IsInteger32()); 1429 ASSERT(left->representation().IsInteger32());
1371 ASSERT(right->representation().IsInteger32()); 1430 ASSERT(right->representation().IsInteger32());
1372 if (instr->HasPowerOf2Divisor()) { 1431 if (instr->HasPowerOf2Divisor()) {
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after
2444 2503
2445 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { 2504 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2446 HEnvironment* outer = current_block_->last_environment(); 2505 HEnvironment* outer = current_block_->last_environment();
2447 HConstant* undefined = graph()->GetConstantUndefined(); 2506 HConstant* undefined = graph()->GetConstantUndefined();
2448 HEnvironment* inner = outer->CopyForInlining(instr->closure(), 2507 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2449 instr->arguments_count(), 2508 instr->arguments_count(),
2450 instr->function(), 2509 instr->function(),
2451 undefined, 2510 undefined,
2452 instr->inlining_kind(), 2511 instr->inlining_kind(),
2453 instr->undefined_receiver()); 2512 instr->undefined_receiver());
2454 if (instr->arguments_var() != NULL) { 2513 // Only replay binding of arguments object if it wasn't removed from graph.
2455 inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject()); 2514 if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
2515 inner->Bind(instr->arguments_var(), instr->arguments_object());
2456 } 2516 }
2457 inner->set_entry(instr); 2517 inner->set_entry(instr);
2458 current_block_->UpdateEnvironment(inner); 2518 current_block_->UpdateEnvironment(inner);
2459 chunk_->AddInlinedClosure(instr->closure()); 2519 chunk_->AddInlinedClosure(instr->closure());
2460 return NULL; 2520 return NULL;
2461 } 2521 }
2462 2522
2463 2523
2464 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2524 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2465 LInstruction* pop = NULL; 2525 LInstruction* pop = NULL;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2509 2569
2510 2570
2511 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2571 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2512 LOperand* object = UseRegister(instr->object()); 2572 LOperand* object = UseRegister(instr->object());
2513 LOperand* index = UseRegister(instr->index()); 2573 LOperand* index = UseRegister(instr->index());
2514 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); 2574 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index));
2515 } 2575 }
2516 2576
2517 2577
2518 } } // namespace v8::internal 2578 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips/lithium-mips.h ('k') | src/mips/macro-assembler-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698