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

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

Issue 6274009: ARM: Merging constants in simulator and assembler header files and other clea... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 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
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 23 matching lines...) Expand all
34 #include "regexp-macro-assembler.h" 34 #include "regexp-macro-assembler.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 39
40 #define __ ACCESS_MASM(masm) 40 #define __ ACCESS_MASM(masm)
41 41
42 static void EmitIdenticalObjectComparison(MacroAssembler* masm, 42 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
43 Label* slow, 43 Label* slow,
44 Condition cc, 44 Condition cond,
45 bool never_nan_nan); 45 bool never_nan_nan);
46 static void EmitSmiNonsmiComparison(MacroAssembler* masm, 46 static void EmitSmiNonsmiComparison(MacroAssembler* masm,
47 Register lhs, 47 Register lhs,
48 Register rhs, 48 Register rhs,
49 Label* lhs_not_nan, 49 Label* lhs_not_nan,
50 Label* slow, 50 Label* slow,
51 bool strict); 51 bool strict);
52 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc); 52 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cond);
53 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, 53 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
54 Register lhs, 54 Register lhs,
55 Register rhs); 55 Register rhs);
56 56
57 57
58 void FastNewClosureStub::Generate(MacroAssembler* masm) { 58 void FastNewClosureStub::Generate(MacroAssembler* masm) {
59 // Create a new closure from the given function info in new 59 // Create a new closure from the given function info in new
60 // space. Set the context to the current context in cp. 60 // space. Set the context to the current context in cp.
61 Label gc; 61 Label gc;
62 62
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kMantissaOffset)); 387 __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kMantissaOffset));
388 __ Ret(); 388 __ Ret();
389 } 389 }
390 390
391 391
392 // Handle the case where the lhs and rhs are the same object. 392 // Handle the case where the lhs and rhs are the same object.
393 // Equality is almost reflexive (everything but NaN), so this is a test 393 // Equality is almost reflexive (everything but NaN), so this is a test
394 // for "identity and not NaN". 394 // for "identity and not NaN".
395 static void EmitIdenticalObjectComparison(MacroAssembler* masm, 395 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
396 Label* slow, 396 Label* slow,
397 Condition cc, 397 Condition cond,
398 bool never_nan_nan) { 398 bool never_nan_nan) {
399 Label not_identical; 399 Label not_identical;
400 Label heap_number, return_equal; 400 Label heap_number, return_equal;
401 __ cmp(r0, r1); 401 __ cmp(r0, r1);
402 __ b(ne, &not_identical); 402 __ b(ne, &not_identical);
403 403
404 // The two objects are identical. If we know that one of them isn't NaN then 404 // The two objects are identical. If we know that one of them isn't NaN then
405 // we now know they test equal. 405 // we now know they test equal.
406 if (cc != eq || !never_nan_nan) { 406 if (cond != eq || !never_nan_nan) {
407 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), 407 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
408 // so we do the second best thing - test it ourselves. 408 // so we do the second best thing - test it ourselves.
409 // They are both equal and they are not both Smis so both of them are not 409 // They are both equal and they are not both Smis so both of them are not
410 // Smis. If it's not a heap number, then return equal. 410 // Smis. If it's not a heap number, then return equal.
411 if (cc == lt || cc == gt) { 411 if (cond == lt || cond == gt) {
412 __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE); 412 __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE);
413 __ b(ge, slow); 413 __ b(ge, slow);
414 } else { 414 } else {
415 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); 415 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
416 __ b(eq, &heap_number); 416 __ b(eq, &heap_number);
417 // Comparing JS objects with <=, >= is complicated. 417 // Comparing JS objects with <=, >= is complicated.
418 if (cc != eq) { 418 if (cond != eq) {
419 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE)); 419 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
420 __ b(ge, slow); 420 __ b(ge, slow);
421 // Normally here we fall through to return_equal, but undefined is 421 // Normally here we fall through to return_equal, but undefined is
422 // special: (undefined == undefined) == true, but 422 // special: (undefined == undefined) == true, but
423 // (undefined <= undefined) == false! See ECMAScript 11.8.5. 423 // (undefined <= undefined) == false! See ECMAScript 11.8.5.
424 if (cc == le || cc == ge) { 424 if (cond == le || cond == ge) {
425 __ cmp(r4, Operand(ODDBALL_TYPE)); 425 __ cmp(r4, Operand(ODDBALL_TYPE));
426 __ b(ne, &return_equal); 426 __ b(ne, &return_equal);
427 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); 427 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
428 __ cmp(r0, r2); 428 __ cmp(r0, r2);
429 __ b(ne, &return_equal); 429 __ b(ne, &return_equal);
430 if (cc == le) { 430 if (cond == le) {
431 // undefined <= undefined should fail. 431 // undefined <= undefined should fail.
432 __ mov(r0, Operand(GREATER)); 432 __ mov(r0, Operand(GREATER));
433 } else { 433 } else {
434 // undefined >= undefined should fail. 434 // undefined >= undefined should fail.
435 __ mov(r0, Operand(LESS)); 435 __ mov(r0, Operand(LESS));
436 } 436 }
437 __ Ret(); 437 __ Ret();
438 } 438 }
439 } 439 }
440 } 440 }
441 } 441 }
442 442
443 __ bind(&return_equal); 443 __ bind(&return_equal);
444 if (cc == lt) { 444 if (cond == lt) {
445 __ mov(r0, Operand(GREATER)); // Things aren't less than themselves. 445 __ mov(r0, Operand(GREATER)); // Things aren't less than themselves.
446 } else if (cc == gt) { 446 } else if (cond == gt) {
447 __ mov(r0, Operand(LESS)); // Things aren't greater than themselves. 447 __ mov(r0, Operand(LESS)); // Things aren't greater than themselves.
448 } else { 448 } else {
449 __ mov(r0, Operand(EQUAL)); // Things are <=, >=, ==, === themselves. 449 __ mov(r0, Operand(EQUAL)); // Things are <=, >=, ==, === themselves.
450 } 450 }
451 __ Ret(); 451 __ Ret();
452 452
453 if (cc != eq || !never_nan_nan) { 453 if (cond != eq || !never_nan_nan) {
454 // For less and greater we don't have to check for NaN since the result of 454 // For less and greater we don't have to check for NaN since the result of
455 // x < x is false regardless. For the others here is some code to check 455 // x < x is false regardless. For the others here is some code to check
456 // for NaN. 456 // for NaN.
457 if (cc != lt && cc != gt) { 457 if (cond != lt && cond != gt) {
458 __ bind(&heap_number); 458 __ bind(&heap_number);
459 // It is a heap number, so return non-equal if it's NaN and equal if it's 459 // It is a heap number, so return non-equal if it's NaN and equal if it's
460 // not NaN. 460 // not NaN.
461 461
462 // The representation of NaN values has all exponent bits (52..62) set, 462 // The representation of NaN values has all exponent bits (52..62) set,
463 // and not all mantissa bits (0..51) clear. 463 // and not all mantissa bits (0..51) clear.
464 // Read top bits of double representation (second word of value). 464 // Read top bits of double representation (second word of value).
465 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); 465 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
466 // Test that exponent bits are all set. 466 // Test that exponent bits are all set.
467 __ Sbfx(r3, r2, HeapNumber::kExponentShift, HeapNumber::kExponentBits); 467 __ Sbfx(r3, r2, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
468 // NaNs have all-one exponents so they sign extend to -1. 468 // NaNs have all-one exponents so they sign extend to -1.
469 __ cmp(r3, Operand(-1)); 469 __ cmp(r3, Operand(-1));
470 __ b(ne, &return_equal); 470 __ b(ne, &return_equal);
471 471
472 // Shift out flag and all exponent bits, retaining only mantissa. 472 // Shift out flag and all exponent bits, retaining only mantissa.
473 __ mov(r2, Operand(r2, LSL, HeapNumber::kNonMantissaBitsInTopWord)); 473 __ mov(r2, Operand(r2, LSL, HeapNumber::kNonMantissaBitsInTopWord));
474 // Or with all low-bits of mantissa. 474 // Or with all low-bits of mantissa.
475 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); 475 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
476 __ orr(r0, r3, Operand(r2), SetCC); 476 __ orr(r0, r3, Operand(r2), SetCC);
477 // For equal we already have the right value in r0: Return zero (equal) 477 // For equal we already have the right value in r0: Return zero (equal)
478 // if all bits in mantissa are zero (it's an Infinity) and non-zero if 478 // if all bits in mantissa are zero (it's an Infinity) and non-zero if
479 // not (it's a NaN). For <= and >= we need to load r0 with the failing 479 // not (it's a NaN). For <= and >= we need to load r0 with the failing
480 // value if it's a NaN. 480 // value if it's a NaN.
481 if (cc != eq) { 481 if (cond != eq) {
482 // All-zero means Infinity means equal. 482 // All-zero means Infinity means equal.
483 __ Ret(eq); 483 __ Ret(eq);
484 if (cc == le) { 484 if (cond == le) {
485 __ mov(r0, Operand(GREATER)); // NaN <= NaN should fail. 485 __ mov(r0, Operand(GREATER)); // NaN <= NaN should fail.
486 } else { 486 } else {
487 __ mov(r0, Operand(LESS)); // NaN >= NaN should fail. 487 __ mov(r0, Operand(LESS)); // NaN >= NaN should fail.
488 } 488 }
489 } 489 }
490 __ Ret(); 490 __ Ret();
491 } 491 }
492 // No fall through here. 492 // No fall through here.
493 } 493 }
494 494
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 // Convert rhs to a double in r0, r1. 581 // Convert rhs to a double in r0, r1.
582 __ mov(r7, Operand(rhs)); 582 __ mov(r7, Operand(rhs));
583 ConvertToDoubleStub stub2(r1, r0, r7, r6); 583 ConvertToDoubleStub stub2(r1, r0, r7, r6);
584 __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET); 584 __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
585 __ pop(lr); 585 __ pop(lr);
586 } 586 }
587 // Fall through to both_loaded_as_doubles. 587 // Fall through to both_loaded_as_doubles.
588 } 588 }
589 589
590 590
591 void EmitNanCheck(MacroAssembler* masm, Label* lhs_not_nan, Condition cc) { 591 void EmitNanCheck(MacroAssembler* masm, Label* lhs_not_nan, Condition cond) {
592 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset); 592 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset);
593 Register rhs_exponent = exp_first ? r0 : r1; 593 Register rhs_exponent = exp_first ? r0 : r1;
594 Register lhs_exponent = exp_first ? r2 : r3; 594 Register lhs_exponent = exp_first ? r2 : r3;
595 Register rhs_mantissa = exp_first ? r1 : r0; 595 Register rhs_mantissa = exp_first ? r1 : r0;
596 Register lhs_mantissa = exp_first ? r3 : r2; 596 Register lhs_mantissa = exp_first ? r3 : r2;
597 Label one_is_nan, neither_is_nan; 597 Label one_is_nan, neither_is_nan;
598 598
599 __ Sbfx(r4, 599 __ Sbfx(r4,
600 lhs_exponent, 600 lhs_exponent,
601 HeapNumber::kExponentShift, 601 HeapNumber::kExponentShift,
(...skipping 19 matching lines...) Expand all
621 __ mov(r4, 621 __ mov(r4,
622 Operand(rhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord), 622 Operand(rhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord),
623 SetCC); 623 SetCC);
624 __ b(ne, &one_is_nan); 624 __ b(ne, &one_is_nan);
625 __ cmp(rhs_mantissa, Operand(0, RelocInfo::NONE)); 625 __ cmp(rhs_mantissa, Operand(0, RelocInfo::NONE));
626 __ b(eq, &neither_is_nan); 626 __ b(eq, &neither_is_nan);
627 627
628 __ bind(&one_is_nan); 628 __ bind(&one_is_nan);
629 // NaN comparisons always fail. 629 // NaN comparisons always fail.
630 // Load whatever we need in r0 to make the comparison fail. 630 // Load whatever we need in r0 to make the comparison fail.
631 if (cc == lt || cc == le) { 631 if (cond == lt || cond == le) {
632 __ mov(r0, Operand(GREATER)); 632 __ mov(r0, Operand(GREATER));
633 } else { 633 } else {
634 __ mov(r0, Operand(LESS)); 634 __ mov(r0, Operand(LESS));
635 } 635 }
636 __ Ret(); 636 __ Ret();
637 637
638 __ bind(&neither_is_nan); 638 __ bind(&neither_is_nan);
639 } 639 }
640 640
641 641
642 // See comment at call site. 642 // See comment at call site.
643 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc) { 643 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm,
644 Condition cond) {
644 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset); 645 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset);
645 Register rhs_exponent = exp_first ? r0 : r1; 646 Register rhs_exponent = exp_first ? r0 : r1;
646 Register lhs_exponent = exp_first ? r2 : r3; 647 Register lhs_exponent = exp_first ? r2 : r3;
647 Register rhs_mantissa = exp_first ? r1 : r0; 648 Register rhs_mantissa = exp_first ? r1 : r0;
648 Register lhs_mantissa = exp_first ? r3 : r2; 649 Register lhs_mantissa = exp_first ? r3 : r2;
649 650
650 // r0, r1, r2, r3 have the two doubles. Neither is a NaN. 651 // r0, r1, r2, r3 have the two doubles. Neither is a NaN.
651 if (cc == eq) { 652 if (cond == eq) {
652 // Doubles are not equal unless they have the same bit pattern. 653 // Doubles are not equal unless they have the same bit pattern.
653 // Exception: 0 and -0. 654 // Exception: 0 and -0.
654 __ cmp(rhs_mantissa, Operand(lhs_mantissa)); 655 __ cmp(rhs_mantissa, Operand(lhs_mantissa));
655 __ orr(r0, rhs_mantissa, Operand(lhs_mantissa), LeaveCC, ne); 656 __ orr(r0, rhs_mantissa, Operand(lhs_mantissa), LeaveCC, ne);
656 // Return non-zero if the numbers are unequal. 657 // Return non-zero if the numbers are unequal.
657 __ Ret(ne); 658 __ Ret(ne);
658 659
659 __ sub(r0, rhs_exponent, Operand(lhs_exponent), SetCC); 660 __ sub(r0, rhs_exponent, Operand(lhs_exponent), SetCC);
660 // If exponents are equal then return 0. 661 // If exponents are equal then return 0.
661 __ Ret(eq); 662 __ Ret(eq);
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 __ orr(r2, r1, r0); 931 __ orr(r2, r1, r0);
931 __ tst(r2, Operand(kSmiTagMask)); 932 __ tst(r2, Operand(kSmiTagMask));
932 __ b(ne, &not_two_smis); 933 __ b(ne, &not_two_smis);
933 __ mov(r1, Operand(r1, ASR, 1)); 934 __ mov(r1, Operand(r1, ASR, 1));
934 __ sub(r0, r1, Operand(r0, ASR, 1)); 935 __ sub(r0, r1, Operand(r0, ASR, 1));
935 __ Ret(); 936 __ Ret();
936 __ bind(&not_two_smis); 937 __ bind(&not_two_smis);
937 } else if (FLAG_debug_code) { 938 } else if (FLAG_debug_code) {
938 __ orr(r2, r1, r0); 939 __ orr(r2, r1, r0);
939 __ tst(r2, Operand(kSmiTagMask)); 940 __ tst(r2, Operand(kSmiTagMask));
940 __ Assert(nz, "CompareStub: unexpected smi operands."); 941 __ Assert(ne, "CompareStub: unexpected smi operands.");
941 } 942 }
942 943
943 // NOTICE! This code is only reached after a smi-fast-case check, so 944 // NOTICE! This code is only reached after a smi-fast-case check, so
944 // it is certain that at least one operand isn't a smi. 945 // it is certain that at least one operand isn't a smi.
945 946
946 // Handle the case where the objects are identical. Either returns the answer 947 // Handle the case where the objects are identical. Either returns the answer
947 // or goes to slow. Only falls through if the objects were not identical. 948 // or goes to slow. Only falls through if the objects were not identical.
948 EmitIdenticalObjectComparison(masm, &slow, cc_, never_nan_nan_); 949 EmitIdenticalObjectComparison(masm, &slow, cc_, never_nan_nan_);
949 950
950 // If either is a Smi (we know that not both are), then they can only 951 // If either is a Smi (we know that not both are), then they can only
(...skipping 2327 matching lines...) Expand 10 before | Expand all | Expand 10 after
3278 STATIC_ASSERT(kSmiTag == 0); 3279 STATIC_ASSERT(kSmiTag == 0);
3279 __ tst(r0, Operand(kSmiTagMask)); 3280 __ tst(r0, Operand(kSmiTagMask));
3280 __ b(eq, &runtime); 3281 __ b(eq, &runtime);
3281 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); 3282 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
3282 __ b(ne, &runtime); 3283 __ b(ne, &runtime);
3283 3284
3284 // Check that the RegExp has been compiled (data contains a fixed array). 3285 // Check that the RegExp has been compiled (data contains a fixed array).
3285 __ ldr(regexp_data, FieldMemOperand(r0, JSRegExp::kDataOffset)); 3286 __ ldr(regexp_data, FieldMemOperand(r0, JSRegExp::kDataOffset));
3286 if (FLAG_debug_code) { 3287 if (FLAG_debug_code) {
3287 __ tst(regexp_data, Operand(kSmiTagMask)); 3288 __ tst(regexp_data, Operand(kSmiTagMask));
3288 __ Check(nz, "Unexpected type for RegExp data, FixedArray expected"); 3289 __ Check(ne, "Unexpected type for RegExp data, FixedArray expected");
3289 __ CompareObjectType(regexp_data, r0, r0, FIXED_ARRAY_TYPE); 3290 __ CompareObjectType(regexp_data, r0, r0, FIXED_ARRAY_TYPE);
3290 __ Check(eq, "Unexpected type for RegExp data, FixedArray expected"); 3291 __ Check(eq, "Unexpected type for RegExp data, FixedArray expected");
3291 } 3292 }
3292 3293
3293 // regexp_data: RegExp data (FixedArray) 3294 // regexp_data: RegExp data (FixedArray)
3294 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP. 3295 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
3295 __ ldr(r0, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset)); 3296 __ ldr(r0, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset));
3296 __ cmp(r0, Operand(Smi::FromInt(JSRegExp::IRREGEXP))); 3297 __ cmp(r0, Operand(Smi::FromInt(JSRegExp::IRREGEXP)));
3297 __ b(ne, &runtime); 3298 __ b(ne, &runtime);
3298 3299
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3381 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset)); 3382 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset));
3382 __ LoadRoot(r1, Heap::kEmptyStringRootIndex); 3383 __ LoadRoot(r1, Heap::kEmptyStringRootIndex);
3383 __ cmp(r0, r1); 3384 __ cmp(r0, r1);
3384 __ b(ne, &runtime); 3385 __ b(ne, &runtime);
3385 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); 3386 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
3386 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset)); 3387 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
3387 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); 3388 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
3388 // Is first part a flat string? 3389 // Is first part a flat string?
3389 STATIC_ASSERT(kSeqStringTag == 0); 3390 STATIC_ASSERT(kSeqStringTag == 0);
3390 __ tst(r0, Operand(kStringRepresentationMask)); 3391 __ tst(r0, Operand(kStringRepresentationMask));
3391 __ b(nz, &runtime); 3392 __ b(ne, &runtime);
3392 3393
3393 __ bind(&seq_string); 3394 __ bind(&seq_string);
3394 // subject: Subject string 3395 // subject: Subject string
3395 // regexp_data: RegExp data (FixedArray) 3396 // regexp_data: RegExp data (FixedArray)
3396 // r0: Instance type of subject string 3397 // r0: Instance type of subject string
3397 STATIC_ASSERT(4 == kAsciiStringTag); 3398 STATIC_ASSERT(4 == kAsciiStringTag);
3398 STATIC_ASSERT(kTwoByteStringTag == 0); 3399 STATIC_ASSERT(kTwoByteStringTag == 0);
3399 // Find the code object based on the assumptions above. 3400 // Find the code object based on the assumptions above.
3400 __ and_(r0, r0, Operand(kStringEncodingMask)); 3401 __ and_(r0, r0, Operand(kStringEncodingMask));
3401 __ mov(r3, Operand(r0, ASR, 2), SetCC); 3402 __ mov(r3, Operand(r0, ASR, 2), SetCC);
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
3829 __ LoadRoot(ip, Heap::kEmptyStringRootIndex); 3830 __ LoadRoot(ip, Heap::kEmptyStringRootIndex);
3830 __ cmp(result_, Operand(ip)); 3831 __ cmp(result_, Operand(ip));
3831 __ b(ne, &call_runtime_); 3832 __ b(ne, &call_runtime_);
3832 // Get the first of the two strings and load its instance type. 3833 // Get the first of the two strings and load its instance type.
3833 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset)); 3834 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset));
3834 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 3835 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
3835 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 3836 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
3836 // If the first cons component is also non-flat, then go to runtime. 3837 // If the first cons component is also non-flat, then go to runtime.
3837 STATIC_ASSERT(kSeqStringTag == 0); 3838 STATIC_ASSERT(kSeqStringTag == 0);
3838 __ tst(result_, Operand(kStringRepresentationMask)); 3839 __ tst(result_, Operand(kStringRepresentationMask));
3839 __ b(nz, &call_runtime_); 3840 __ b(ne, &call_runtime_);
3840 3841
3841 // Check for 1-byte or 2-byte string. 3842 // Check for 1-byte or 2-byte string.
3842 __ bind(&flat_string); 3843 __ bind(&flat_string);
3843 STATIC_ASSERT(kAsciiStringTag != 0); 3844 STATIC_ASSERT(kAsciiStringTag != 0);
3844 __ tst(result_, Operand(kStringEncodingMask)); 3845 __ tst(result_, Operand(kStringEncodingMask));
3845 __ b(nz, &ascii_string); 3846 __ b(ne, &ascii_string);
3846 3847
3847 // 2-byte string. 3848 // 2-byte string.
3848 // Load the 2-byte character code into the result register. We can 3849 // Load the 2-byte character code into the result register. We can
3849 // add without shifting since the smi tag size is the log2 of the 3850 // add without shifting since the smi tag size is the log2 of the
3850 // number of bytes in a two-byte character. 3851 // number of bytes in a two-byte character.
3851 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1 && kSmiShiftSize == 0); 3852 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1 && kSmiShiftSize == 0);
3852 __ add(scratch_, object_, Operand(scratch_)); 3853 __ add(scratch_, object_, Operand(scratch_));
3853 __ ldrh(result_, FieldMemOperand(scratch_, SeqTwoByteString::kHeaderSize)); 3854 __ ldrh(result_, FieldMemOperand(scratch_, SeqTwoByteString::kHeaderSize));
3854 __ jmp(&got_char_code); 3855 __ jmp(&got_char_code);
3855 3856
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3920 // StringCharFromCodeGenerator 3921 // StringCharFromCodeGenerator
3921 3922
3922 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) { 3923 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
3923 // Fast case of Heap::LookupSingleCharacterStringFromCode. 3924 // Fast case of Heap::LookupSingleCharacterStringFromCode.
3924 STATIC_ASSERT(kSmiTag == 0); 3925 STATIC_ASSERT(kSmiTag == 0);
3925 STATIC_ASSERT(kSmiShiftSize == 0); 3926 STATIC_ASSERT(kSmiShiftSize == 0);
3926 ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1)); 3927 ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
3927 __ tst(code_, 3928 __ tst(code_,
3928 Operand(kSmiTagMask | 3929 Operand(kSmiTagMask |
3929 ((~String::kMaxAsciiCharCode) << kSmiTagSize))); 3930 ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
3930 __ b(nz, &slow_case_); 3931 __ b(ne, &slow_case_);
3931 3932
3932 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex); 3933 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
3933 // At this point code register contains smi tagged ascii char code. 3934 // At this point code register contains smi tagged ascii char code.
3934 STATIC_ASSERT(kSmiTag == 0); 3935 STATIC_ASSERT(kSmiTag == 0);
3935 __ add(result_, result_, Operand(code_, LSL, kPointerSizeLog2 - kSmiTagSize)); 3936 __ add(result_, result_, Operand(code_, LSL, kPointerSizeLog2 - kSmiTagSize));
3936 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize)); 3937 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
3937 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 3938 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
3938 __ cmp(result_, Operand(ip)); 3939 __ cmp(result_, Operand(ip));
3939 __ b(eq, &slow_case_); 3940 __ b(eq, &slow_case_);
3940 __ bind(&exit_); 3941 __ bind(&exit_);
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
4367 void StringHelper::GenerateHashGetHash(MacroAssembler* masm, 4368 void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
4368 Register hash) { 4369 Register hash) {
4369 // hash += hash << 3; 4370 // hash += hash << 3;
4370 __ add(hash, hash, Operand(hash, LSL, 3)); 4371 __ add(hash, hash, Operand(hash, LSL, 3));
4371 // hash ^= hash >> 11; 4372 // hash ^= hash >> 11;
4372 __ eor(hash, hash, Operand(hash, ASR, 11)); 4373 __ eor(hash, hash, Operand(hash, ASR, 11));
4373 // hash += hash << 15; 4374 // hash += hash << 15;
4374 __ add(hash, hash, Operand(hash, LSL, 15), SetCC); 4375 __ add(hash, hash, Operand(hash, LSL, 15), SetCC);
4375 4376
4376 // if (hash == 0) hash = 27; 4377 // if (hash == 0) hash = 27;
4377 __ mov(hash, Operand(27), LeaveCC, nz); 4378 __ mov(hash, Operand(27), LeaveCC, ne);
4378 } 4379 }
4379 4380
4380 4381
4381 void SubStringStub::Generate(MacroAssembler* masm) { 4382 void SubStringStub::Generate(MacroAssembler* masm) {
4382 Label runtime; 4383 Label runtime;
4383 4384
4384 // Stack frame on entry. 4385 // Stack frame on entry.
4385 // lr: return address 4386 // lr: return address
4386 // sp[0]: to 4387 // sp[0]: to
4387 // sp[4]: from 4388 // sp[4]: from
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
5106 __ pop(r1); 5107 __ pop(r1);
5107 __ Jump(r2); 5108 __ Jump(r2);
5108 } 5109 }
5109 5110
5110 5111
5111 #undef __ 5112 #undef __
5112 5113
5113 } } // namespace v8::internal 5114 } } // namespace v8::internal
5114 5115
5115 #endif // V8_TARGET_ARCH_ARM 5116 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698