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

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 8947017: MIPS: Porting r10252 to ARM. (Closed)
Patch Set: Created 9 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
« no previous file with comments | « no previous file | no next file » | 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 6399 matching lines...) Expand 10 before | Expand all | Expand 10 after
6410 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3); 6410 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3);
6411 __ Addu(sp, sp, Operand(2 * kPointerSize)); 6411 __ Addu(sp, sp, Operand(2 * kPointerSize));
6412 GenerateCompareFlatAsciiStrings(masm, a1, a0, a2, a3, t0, t1); 6412 GenerateCompareFlatAsciiStrings(masm, a1, a0, a2, a3, t0, t1);
6413 6413
6414 __ bind(&runtime); 6414 __ bind(&runtime);
6415 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 6415 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
6416 } 6416 }
6417 6417
6418 6418
6419 void StringAddStub::Generate(MacroAssembler* masm) { 6419 void StringAddStub::Generate(MacroAssembler* masm) {
6420 Label string_add_runtime, call_builtin; 6420 Label call_runtime, call_builtin;
6421 Builtins::JavaScript builtin_id = Builtins::ADD; 6421 Builtins::JavaScript builtin_id = Builtins::ADD;
6422 6422
6423 Counters* counters = masm->isolate()->counters(); 6423 Counters* counters = masm->isolate()->counters();
6424 6424
6425 // Stack on entry: 6425 // Stack on entry:
6426 // sp[0]: second argument (right). 6426 // sp[0]: second argument (right).
6427 // sp[4]: first argument (left). 6427 // sp[4]: first argument (left).
6428 6428
6429 // Load the two arguments. 6429 // Load the two arguments.
6430 __ lw(a0, MemOperand(sp, 1 * kPointerSize)); // First argument. 6430 __ lw(a0, MemOperand(sp, 1 * kPointerSize)); // First argument.
6431 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); // Second argument. 6431 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); // Second argument.
6432 6432
6433 // Make sure that both arguments are strings if not known in advance. 6433 // Make sure that both arguments are strings if not known in advance.
6434 if (flags_ == NO_STRING_ADD_FLAGS) { 6434 if (flags_ == NO_STRING_ADD_FLAGS) {
6435 __ JumpIfEitherSmi(a0, a1, &string_add_runtime); 6435 __ JumpIfEitherSmi(a0, a1, &call_runtime);
6436 // Load instance types. 6436 // Load instance types.
6437 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); 6437 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset));
6438 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); 6438 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
6439 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); 6439 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
6440 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); 6440 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset));
6441 STATIC_ASSERT(kStringTag == 0); 6441 STATIC_ASSERT(kStringTag == 0);
6442 // If either is not a string, go to runtime. 6442 // If either is not a string, go to runtime.
6443 __ Or(t4, t0, Operand(t1)); 6443 __ Or(t4, t0, Operand(t1));
6444 __ And(t4, t4, Operand(kIsNotStringMask)); 6444 __ And(t4, t4, Operand(kIsNotStringMask));
6445 __ Branch(&string_add_runtime, ne, t4, Operand(zero_reg)); 6445 __ Branch(&call_runtime, ne, t4, Operand(zero_reg));
6446 } else { 6446 } else {
6447 // Here at least one of the arguments is definitely a string. 6447 // Here at least one of the arguments is definitely a string.
6448 // We convert the one that is not known to be a string. 6448 // We convert the one that is not known to be a string.
6449 if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) { 6449 if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) {
6450 ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0); 6450 ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0);
6451 GenerateConvertArgument( 6451 GenerateConvertArgument(
6452 masm, 1 * kPointerSize, a0, a2, a3, t0, t1, &call_builtin); 6452 masm, 1 * kPointerSize, a0, a2, a3, t0, t1, &call_builtin);
6453 builtin_id = Builtins::STRING_ADD_RIGHT; 6453 builtin_id = Builtins::STRING_ADD_RIGHT;
6454 } else if ((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) == 0) { 6454 } else if ((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) == 0) {
6455 ASSERT((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) != 0); 6455 ASSERT((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) != 0);
(...skipping 18 matching lines...) Expand all
6474 __ lw(a2, FieldMemOperand(a0, String::kLengthOffset)); 6474 __ lw(a2, FieldMemOperand(a0, String::kLengthOffset));
6475 __ lw(a3, FieldMemOperand(a1, String::kLengthOffset)); 6475 __ lw(a3, FieldMemOperand(a1, String::kLengthOffset));
6476 __ mov(v0, a0); // Assume we'll return first string (from a0). 6476 __ mov(v0, a0); // Assume we'll return first string (from a0).
6477 __ movz(v0, a1, a2); // If first is empty, return second (from a1). 6477 __ movz(v0, a1, a2); // If first is empty, return second (from a1).
6478 __ slt(t4, zero_reg, a2); // if (a2 > 0) t4 = 1. 6478 __ slt(t4, zero_reg, a2); // if (a2 > 0) t4 = 1.
6479 __ slt(t5, zero_reg, a3); // if (a3 > 0) t5 = 1. 6479 __ slt(t5, zero_reg, a3); // if (a3 > 0) t5 = 1.
6480 __ and_(t4, t4, t5); // Branch if both strings were non-empty. 6480 __ and_(t4, t4, t5); // Branch if both strings were non-empty.
6481 __ Branch(&strings_not_empty, ne, t4, Operand(zero_reg)); 6481 __ Branch(&strings_not_empty, ne, t4, Operand(zero_reg));
6482 6482
6483 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); 6483 __ IncrementCounter(counters->string_add_native(), 1, a2, a3);
6484 __ Addu(sp, sp, Operand(2 * kPointerSize)); 6484 __ DropAndRet(2);
6485 __ Ret();
6486 6485
6487 __ bind(&strings_not_empty); 6486 __ bind(&strings_not_empty);
6488 } 6487 }
6489 6488
6490 // Untag both string-lengths. 6489 // Untag both string-lengths.
6491 __ sra(a2, a2, kSmiTagSize); 6490 __ sra(a2, a2, kSmiTagSize);
6492 __ sra(a3, a3, kSmiTagSize); 6491 __ sra(a3, a3, kSmiTagSize);
6493 6492
6494 // Both strings are non-empty. 6493 // Both strings are non-empty.
6495 // a0: first string 6494 // a0: first string
(...skipping 12 matching lines...) Expand all
6508 __ Branch(&longer_than_two, ne, t2, Operand(2)); 6507 __ Branch(&longer_than_two, ne, t2, Operand(2));
6509 6508
6510 // Check that both strings are non-external ASCII strings. 6509 // Check that both strings are non-external ASCII strings.
6511 if (flags_ != NO_STRING_ADD_FLAGS) { 6510 if (flags_ != NO_STRING_ADD_FLAGS) {
6512 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); 6511 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset));
6513 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); 6512 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
6514 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); 6513 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
6515 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); 6514 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset));
6516 } 6515 }
6517 __ JumpIfBothInstanceTypesAreNotSequentialAscii(t0, t1, t2, t3, 6516 __ JumpIfBothInstanceTypesAreNotSequentialAscii(t0, t1, t2, t3,
6518 &string_add_runtime); 6517 &call_runtime);
6519 6518
6520 // Get the two characters forming the sub string. 6519 // Get the two characters forming the sub string.
6521 __ lbu(a2, FieldMemOperand(a0, SeqAsciiString::kHeaderSize)); 6520 __ lbu(a2, FieldMemOperand(a0, SeqAsciiString::kHeaderSize));
6522 __ lbu(a3, FieldMemOperand(a1, SeqAsciiString::kHeaderSize)); 6521 __ lbu(a3, FieldMemOperand(a1, SeqAsciiString::kHeaderSize));
6523 6522
6524 // Try to lookup two character string in symbol table. If it is not found 6523 // Try to lookup two character string in symbol table. If it is not found
6525 // just allocate a new one. 6524 // just allocate a new one.
6526 Label make_two_character_string; 6525 Label make_two_character_string;
6527 StringHelper::GenerateTwoCharacterSymbolTableProbe( 6526 StringHelper::GenerateTwoCharacterSymbolTableProbe(
6528 masm, a2, a3, t2, t3, t0, t1, t4, &make_two_character_string); 6527 masm, a2, a3, t2, t3, t0, t1, t5, &make_two_character_string);
6529 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); 6528 __ IncrementCounter(counters->string_add_native(), 1, a2, a3);
6530 __ Addu(sp, sp, Operand(2 * kPointerSize)); 6529 __ DropAndRet(2);
6531 __ Ret();
6532 6530
6533 __ bind(&make_two_character_string); 6531 __ bind(&make_two_character_string);
6534 // Resulting string has length 2 and first chars of two strings 6532 // Resulting string has length 2 and first chars of two strings
6535 // are combined into single halfword in a2 register. 6533 // are combined into single halfword in a2 register.
6536 // So we can fill resulting string without two loops by a single 6534 // So we can fill resulting string without two loops by a single
6537 // halfword store instruction (which assumes that processor is 6535 // halfword store instruction (which assumes that processor is
6538 // in a little endian mode). 6536 // in a little endian mode).
6539 __ li(t2, Operand(2)); 6537 __ li(t2, Operand(2));
6540 __ AllocateAsciiString(v0, t2, t0, t1, t4, &string_add_runtime); 6538 __ AllocateAsciiString(v0, t2, t0, t1, t5, &call_runtime);
6541 __ sh(a2, FieldMemOperand(v0, SeqAsciiString::kHeaderSize)); 6539 __ sh(a2, FieldMemOperand(v0, SeqAsciiString::kHeaderSize));
6542 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); 6540 __ IncrementCounter(counters->string_add_native(), 1, a2, a3);
6543 __ Addu(sp, sp, Operand(2 * kPointerSize)); 6541 __ DropAndRet(2);
6544 __ Ret();
6545 6542
6546 __ bind(&longer_than_two); 6543 __ bind(&longer_than_two);
6547 // Check if resulting string will be flat. 6544 // Check if resulting string will be flat.
6548 __ Branch(&string_add_flat_result, lt, t2, 6545 __ Branch(&string_add_flat_result, lt, t2,
6549 Operand(String::kMinNonFlatLength)); 6546 Operand(String::kMinNonFlatLength));
6550 // Handle exceptionally long strings in the runtime system. 6547 // Handle exceptionally long strings in the runtime system.
6551 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); 6548 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0);
6552 ASSERT(IsPowerOf2(String::kMaxLength + 1)); 6549 ASSERT(IsPowerOf2(String::kMaxLength + 1));
6553 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not. 6550 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not.
6554 __ Branch(&string_add_runtime, hs, t2, Operand(String::kMaxLength + 1)); 6551 __ Branch(&call_runtime, hs, t2, Operand(String::kMaxLength + 1));
6555 6552
6556 // If result is not supposed to be flat, allocate a cons string object. 6553 // If result is not supposed to be flat, allocate a cons string object.
6557 // If both strings are ASCII the result is an ASCII cons string. 6554 // If both strings are ASCII the result is an ASCII cons string.
6558 if (flags_ != NO_STRING_ADD_FLAGS) { 6555 if (flags_ != NO_STRING_ADD_FLAGS) {
6559 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); 6556 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset));
6560 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); 6557 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
6561 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); 6558 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
6562 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); 6559 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset));
6563 } 6560 }
6564 Label non_ascii, allocated, ascii_data; 6561 Label non_ascii, allocated, ascii_data;
6565 STATIC_ASSERT(kTwoByteStringTag == 0); 6562 STATIC_ASSERT(kTwoByteStringTag == 0);
6566 // Branch to non_ascii if either string-encoding field is zero (non-ascii). 6563 // Branch to non_ascii if either string-encoding field is zero (non-ascii).
6567 __ And(t4, t0, Operand(t1)); 6564 __ And(t4, t0, Operand(t1));
6568 __ And(t4, t4, Operand(kStringEncodingMask)); 6565 __ And(t4, t4, Operand(kStringEncodingMask));
6569 __ Branch(&non_ascii, eq, t4, Operand(zero_reg)); 6566 __ Branch(&non_ascii, eq, t4, Operand(zero_reg));
6570 6567
6571 // Allocate an ASCII cons string. 6568 // Allocate an ASCII cons string.
6572 __ bind(&ascii_data); 6569 __ bind(&ascii_data);
6573 __ AllocateAsciiConsString(t3, t2, t0, t1, &string_add_runtime); 6570 __ AllocateAsciiConsString(v0, t2, t0, t1, &call_runtime);
6574 __ bind(&allocated); 6571 __ bind(&allocated);
6575 // Fill the fields of the cons string. 6572 // Fill the fields of the cons string.
6576 __ sw(a0, FieldMemOperand(t3, ConsString::kFirstOffset)); 6573 __ sw(a0, FieldMemOperand(v0, ConsString::kFirstOffset));
6577 __ sw(a1, FieldMemOperand(t3, ConsString::kSecondOffset)); 6574 __ sw(a1, FieldMemOperand(v0, ConsString::kSecondOffset));
6578 __ mov(v0, t3);
6579 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); 6575 __ IncrementCounter(counters->string_add_native(), 1, a2, a3);
6580 __ Addu(sp, sp, Operand(2 * kPointerSize)); 6576 __ DropAndRet(2);
6581 __ Ret();
6582 6577
6583 __ bind(&non_ascii); 6578 __ bind(&non_ascii);
6584 // At least one of the strings is two-byte. Check whether it happens 6579 // At least one of the strings is two-byte. Check whether it happens
6585 // to contain only ASCII characters. 6580 // to contain only ASCII characters.
6586 // t0: first instance type. 6581 // t0: first instance type.
6587 // t1: second instance type. 6582 // t1: second instance type.
6588 // Branch to if _both_ instances have kAsciiDataHintMask set. 6583 // Branch to if _both_ instances have kAsciiDataHintMask set.
6589 __ And(at, t0, Operand(kAsciiDataHintMask)); 6584 __ And(at, t0, Operand(kAsciiDataHintMask));
6590 __ and_(at, at, t1); 6585 __ and_(at, at, t1);
6591 __ Branch(&ascii_data, ne, at, Operand(zero_reg)); 6586 __ Branch(&ascii_data, ne, at, Operand(zero_reg));
6592 6587
6593 __ xor_(t0, t0, t1); 6588 __ xor_(t0, t0, t1);
6594 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0); 6589 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0);
6595 __ And(t0, t0, Operand(kAsciiStringTag | kAsciiDataHintTag)); 6590 __ And(t0, t0, Operand(kAsciiStringTag | kAsciiDataHintTag));
6596 __ Branch(&ascii_data, eq, t0, Operand(kAsciiStringTag | kAsciiDataHintTag)); 6591 __ Branch(&ascii_data, eq, t0, Operand(kAsciiStringTag | kAsciiDataHintTag));
6597 6592
6598 // Allocate a two byte cons string. 6593 // Allocate a two byte cons string.
6599 __ AllocateTwoByteConsString(t3, t2, t0, t1, &string_add_runtime); 6594 __ AllocateTwoByteConsString(v0, t2, t0, t1, &call_runtime);
6600 __ Branch(&allocated); 6595 __ Branch(&allocated);
6601 6596
6602 // Handle creating a flat result. First check that both strings are 6597 // We cannot encounter sliced strings or cons strings here since:
6603 // sequential and that they have the same encoding. 6598 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength);
6599 // Handle creating a flat result from either external or sequential strings.
6600 // Locate the first characters' locations.
6604 // a0: first string 6601 // a0: first string
6605 // a1: second string 6602 // a1: second string
6606 // a2: length of first string 6603 // a2: length of first string
6607 // a3: length of second string 6604 // a3: length of second string
6608 // t0: first string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6605 // t0: first string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6609 // t1: second string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6606 // t1: second string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6610 // t2: sum of lengths. 6607 // t2: sum of lengths.
6608 Label first_prepared, second_prepared;
6611 __ bind(&string_add_flat_result); 6609 __ bind(&string_add_flat_result);
6612 if (flags_ != NO_STRING_ADD_FLAGS) { 6610 if (flags_ != NO_STRING_ADD_FLAGS) {
6613 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); 6611 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset));
6614 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); 6612 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
6615 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); 6613 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
6616 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); 6614 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset));
6617 } 6615 }
6618 // Check that both strings are sequential, meaning that we 6616 // Check whether both strings have same encoding
6619 // branch to runtime if either string tag is non-zero. 6617 __ Xor(t3, t0, Operand(t1));
6618 __ And(t3, t3, Operand(kStringEncodingMask));
6619 __ Branch(&call_runtime, ne, t3, Operand(zero_reg));
6620
6620 STATIC_ASSERT(kSeqStringTag == 0); 6621 STATIC_ASSERT(kSeqStringTag == 0);
6621 __ Or(t4, t0, Operand(t1)); 6622 __ And(t4, t0, Operand(kStringRepresentationMask));
6622 __ And(t4, t4, Operand(kStringRepresentationMask));
6623 __ Branch(&string_add_runtime, ne, t4, Operand(zero_reg));
6624 6623
6625 // Now check if both strings have the same encoding (ASCII/Two-byte). 6624 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize);
6626 // a0: first string 6625 Label skip_first_add;
6627 // a1: second string 6626 __ Branch(&skip_first_add, ne, t4, Operand(zero_reg));
6627 __ Branch(USE_DELAY_SLOT, &first_prepared);
6628 __ addiu(t3, a0, SeqAsciiString::kHeaderSize - kHeapObjectTag);
6629 __ bind(&skip_first_add);
6630 // External string: rule out short external string and load string resource.
6631 STATIC_ASSERT(kShortExternalStringTag != 0);
6632 __ And(t4, t0, Operand(kShortExternalStringMask));
6633 __ Branch(&call_runtime, ne, t4, Operand(zero_reg));
6634 __ lw(t3, FieldMemOperand(a0, ExternalString::kResourceDataOffset));
6635 __ bind(&first_prepared);
6636
6637 STATIC_ASSERT(kSeqStringTag == 0);
6638 __ And(t4, t1, Operand(kStringRepresentationMask));
6639 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize);
6640 Label skip_second_add;
6641 __ Branch(&skip_second_add, ne, t4, Operand(zero_reg));
6642 __ Branch(USE_DELAY_SLOT, &second_prepared);
6643 __ addiu(a1, a1, SeqAsciiString::kHeaderSize - kHeapObjectTag);
6644 __ bind(&skip_second_add);
6645 // External string: rule out short external string and load string resource.
6646 STATIC_ASSERT(kShortExternalStringTag != 0);
6647 __ And(t4, t1, Operand(kShortExternalStringMask));
6648 __ Branch(&call_runtime, ne, t4, Operand(zero_reg));
6649 __ lw(a1, FieldMemOperand(a1, ExternalString::kResourceDataOffset));
6650 __ bind(&second_prepared);
6651
6652 Label non_ascii_string_add_flat_result;
6653 // t3: first character of first string
6654 // a1: first character of second string
6628 // a2: length of first string 6655 // a2: length of first string
6629 // a3: length of second string 6656 // a3: length of second string
6630 // t0: first string instance type
6631 // t1: second string instance type
6632 // t2: sum of lengths. 6657 // t2: sum of lengths.
6633 Label non_ascii_string_add_flat_result; 6658 // Both strings have the same encoding.
6634 ASSERT(IsPowerOf2(kStringEncodingMask)); // Just one bit to test. 6659 STATIC_ASSERT(kTwoByteStringTag == 0);
6635 __ xor_(t3, t1, t0); 6660 __ And(t4, t1, Operand(kStringEncodingMask));
6636 __ And(t3, t3, Operand(kStringEncodingMask)); 6661 __ Branch(&non_ascii_string_add_flat_result, eq, t4, Operand(zero_reg));
6637 __ Branch(&string_add_runtime, ne, t3, Operand(zero_reg));
6638 // And see if it's ASCII (0) or two-byte (1).
6639 __ And(t3, t0, Operand(kStringEncodingMask));
6640 __ Branch(&non_ascii_string_add_flat_result, eq, t3, Operand(zero_reg));
6641 6662
6642 // Both strings are sequential ASCII strings. We also know that they are 6663 __ AllocateAsciiString(v0, t2, t0, t1, t5, &call_runtime);
6643 // short (since the sum of the lengths is less than kMinNonFlatLength). 6664 __ Addu(t2, v0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6644 // t2: length of resulting flat string 6665 // v0: result string.
6645 __ AllocateAsciiString(t3, t2, t0, t1, t4, &string_add_runtime); 6666 // t3: first character of first string.
6646 // Locate first character of result. 6667 // a1: first character of second string
6647 __ Addu(t2, t3, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6648 // Locate first character of first argument.
6649 __ Addu(a0, a0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6650 // a0: first character of first string.
6651 // a1: second string.
6652 // a2: length of first string. 6668 // a2: length of first string.
6653 // a3: length of second string. 6669 // a3: length of second string.
6654 // t2: first character of result. 6670 // t2: first character of result.
6655 // t3: result string.
6656 StringHelper::GenerateCopyCharacters(masm, t2, a0, a2, t0, true);
6657 6671
6658 // Load second argument and locate first character. 6672 StringHelper::GenerateCopyCharacters(masm, t2, t3, a2, t0, true);
6659 __ Addu(a1, a1, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
6660 // a1: first character of second string.
6661 // a3: length of second string.
6662 // t2: next character of result. 6673 // t2: next character of result.
6663 // t3: result string.
6664 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, true); 6674 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, true);
6665 __ mov(v0, t3);
6666 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); 6675 __ IncrementCounter(counters->string_add_native(), 1, a2, a3);
6667 __ Addu(sp, sp, Operand(2 * kPointerSize)); 6676 __ DropAndRet(2);
6668 __ Ret();
6669 6677
6670 __ bind(&non_ascii_string_add_flat_result); 6678 __ bind(&non_ascii_string_add_flat_result);
6671 // Both strings are sequential two byte strings. 6679 __ AllocateTwoByteString(v0, t2, t0, t1, t5, &call_runtime);
6672 // a0: first string. 6680 __ Addu(t2, v0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
6673 // a1: second string. 6681 // v0: result string.
6674 // a2: length of first string. 6682 // t3: first character of first string.
6675 // a3: length of second string. 6683 // a1: first character of second string.
6676 // t2: sum of length of strings.
6677 __ AllocateTwoByteString(t3, t2, t0, t1, t4, &string_add_runtime);
6678 // a0: first string.
6679 // a1: second string.
6680 // a2: length of first string.
6681 // a3: length of second string.
6682 // t3: result string.
6683
6684 // Locate first character of result.
6685 __ Addu(t2, t3, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
6686 // Locate first character of first argument.
6687 __ Addu(a0, a0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
6688
6689 // a0: first character of first string.
6690 // a1: second string.
6691 // a2: length of first string. 6684 // a2: length of first string.
6692 // a3: length of second string. 6685 // a3: length of second string.
6693 // t2: first character of result. 6686 // t2: first character of result.
6694 // t3: result string. 6687 StringHelper::GenerateCopyCharacters(masm, t2, t3, a2, t0, false);
6695 StringHelper::GenerateCopyCharacters(masm, t2, a0, a2, t0, false); 6688 // t2: next character of result.
6696
6697 // Locate first character of second argument.
6698 __ Addu(a1, a1, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
6699
6700 // a1: first character of second string.
6701 // a3: length of second string.
6702 // t2: next character of result (after copy of first string).
6703 // t3: result string.
6704 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, false); 6689 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, false);
6705 6690
6706 __ mov(v0, t3);
6707 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); 6691 __ IncrementCounter(counters->string_add_native(), 1, a2, a3);
6708 __ Addu(sp, sp, Operand(2 * kPointerSize)); 6692 __ DropAndRet(2);
6709 __ Ret();
6710 6693
6711 // Just jump to runtime to add the two strings. 6694 // Just jump to runtime to add the two strings.
6712 __ bind(&string_add_runtime); 6695 __ bind(&call_runtime);
6713 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 6696 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
6714 6697
6715 if (call_builtin.is_linked()) { 6698 if (call_builtin.is_linked()) {
6716 __ bind(&call_builtin); 6699 __ bind(&call_builtin);
6717 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); 6700 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION);
6718 } 6701 }
6719 } 6702 }
6720 6703
6721 6704
6722 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm, 6705 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
7650 __ Ret(USE_DELAY_SLOT); 7633 __ Ret(USE_DELAY_SLOT);
7651 __ mov(v0, a0); 7634 __ mov(v0, a0);
7652 } 7635 }
7653 7636
7654 7637
7655 #undef __ 7638 #undef __
7656 7639
7657 } } // namespace v8::internal 7640 } } // namespace v8::internal
7658 7641
7659 #endif // V8_TARGET_ARCH_MIPS 7642 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698