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

Side by Side Diff: src/x64/macro-assembler-x64.h

Issue 21014003: Optionally use 31-bits SMI value for 64-bit system (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed danno's comments Created 7 years, 4 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 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 // Store the function for the given builtin in the target register. 368 // Store the function for the given builtin in the target register.
369 void GetBuiltinFunction(Register target, Builtins::JavaScript id); 369 void GetBuiltinFunction(Register target, Builtins::JavaScript id);
370 370
371 // Store the code object for the given builtin in the target register. 371 // Store the code object for the given builtin in the target register.
372 void GetBuiltinEntry(Register target, Builtins::JavaScript id); 372 void GetBuiltinEntry(Register target, Builtins::JavaScript id);
373 373
374 374
375 // --------------------------------------------------------------------------- 375 // ---------------------------------------------------------------------------
376 // Smi tagging, untagging and operations on tagged smis. 376 // Smi tagging, untagging and operations on tagged smis.
377 377
378 class SmiInstructionWrapper {
danno 2013/08/19 21:47:44 My general feedback to this class is that it's too
379 public:
380 SmiInstructionWrapper() { }
381 virtual ~SmiInstructionWrapper() { }
382 virtual bool NeedsCheckOverflow() const = 0;
383 virtual bool NeedsCheckMinusZero() const = 0;
danno 2013/08/19 21:47:44 You never call NeedsCheckMinusZero anywhere. Can y
haitao.feng 2013/08/20 15:09:30 I have planned to use it for SmiMul. If the caller
danno 2013/08/20 15:58:14 Yes, but this is specific to the Mul operation, se
haitao.feng 2013/08/21 13:18:03 We will handle this when https://codereview.chromi
384 virtual bool NeedsKeepSourceOperandsIntact() const = 0;
danno 2013/08/19 21:47:44 I think you can avoid this one, too. See my commen
385 virtual void BailoutIf(Condition cc) const = 0;
386 };
387
388 class SafeSmiInstructionWrapper : public SmiInstructionWrapper {
danno 2013/08/19 21:47:44 This class is never used, please remove it.
haitao.feng 2013/08/20 15:09:30 I have planned to unify the interface. So the curr
389 public:
390 SafeSmiInstructionWrapper() { }
391 virtual ~SafeSmiInstructionWrapper() { }
392 virtual bool NeedsCheckOverflow() const { return false; }
393 virtual bool NeedsCheckMinusZero() const { return false; }
394 virtual bool NeedsKeepSourceOperandsIntact() const { return false; }
395 virtual void BailoutIf(Condition cc) const { }
396 };
397
398 class StrictSmiInstructionWrapper : public SmiInstructionWrapper {
399 public:
400 StrictSmiInstructionWrapper(MacroAssembler* macro_assembler,
401 Label* on_invalid,
402 Label::Distance near_jump = Label::kFar)
403 : macro_assembler_(macro_assembler),
404 on_invalid_(on_invalid),
405 near_jump_(near_jump) { }
406 virtual ~StrictSmiInstructionWrapper() { }
407 virtual bool NeedsCheckOverflow() const { return true; }
408 virtual bool NeedsCheckMinusZero() const { return true; }
409 virtual bool NeedsKeepSourceOperandsIntact() const { return true; }
410 virtual void BailoutIf(Condition cc) const {
411 ASSERT_NOT_NULL(on_invalid_);
412 macro_assembler_->j(cc, on_invalid_, near_jump_);
413 }
414
415 private:
416 MacroAssembler* macro_assembler_;
417 Label* on_invalid_;
418 Label::Distance near_jump_;
419 };
420
378 void InitializeSmiConstantRegister() { 421 void InitializeSmiConstantRegister() {
379 movq(kSmiConstantRegister, 422 movq(kSmiConstantRegister,
380 reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)), 423 reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)),
381 RelocInfo::NONE64); 424 RelocInfo::NONE64);
382 } 425 }
383 426
427 // Support for constant splitting.
428 bool IsUnsafeInt(const int x);
danno 2013/08/19 21:47:44 shouldn't this be a int32_t just to be clear?
haitao.feng 2013/08/20 15:09:30 I will change this when I gather all the SMI funct
429 void SafeMove(Register dst, Smi* src);
430 void SafePush(Smi* src);
431
384 // Conversions between tagged smi values and non-tagged integer values. 432 // Conversions between tagged smi values and non-tagged integer values.
385 433
386 // Tag an integer value. The result must be known to be a valid smi value. 434 // Tag an integer value. The result must be known to be a valid smi value.
387 // Only uses the low 32 bits of the src register. Sets the N and Z flags 435 // Only uses the low 32 bits of the src register. Sets the N and Z flags
388 // based on the value of the resulting smi. 436 // based on the value of the resulting smi.
389 void Integer32ToSmi(Register dst, Register src); 437 void Integer32ToSmi(Register dst, Register src);
390 438
391 // Stores an integer32 value into a memory field that already holds a smi. 439 // Stores an integer32 value into a memory field that already holds a smi.
392 void Integer32ToSmiField(const Operand& dst, Register src); 440 void Integer32ToSmiField(const Operand& dst, Register src);
393 441
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 // and to one if it isn't. 525 // and to one if it isn't.
478 void CheckSmiToIndicator(Register dst, Register src); 526 void CheckSmiToIndicator(Register dst, Register src);
479 void CheckSmiToIndicator(Register dst, const Operand& src); 527 void CheckSmiToIndicator(Register dst, const Operand& src);
480 528
481 // Test-and-jump functions. Typically combines a check function 529 // Test-and-jump functions. Typically combines a check function
482 // above with a conditional jump. 530 // above with a conditional jump.
483 531
484 // Jump if the value cannot be represented by a smi. 532 // Jump if the value cannot be represented by a smi.
485 void JumpIfNotValidSmiValue(Register src, Label* on_invalid, 533 void JumpIfNotValidSmiValue(Register src, Label* on_invalid,
486 Label::Distance near_jump = Label::kFar); 534 Label::Distance near_jump = Label::kFar);
535 // Jump if the value can be represented by a smi.
536 void JumpIfValidSmiValue(Register src, Label* on_valid,
537 Label::Distance near_jump = Label::kFar);
487 538
488 // Jump if the unsigned integer value cannot be represented by a smi. 539 // Jump if the unsigned integer value cannot be represented by a smi.
489 void JumpIfUIntNotValidSmiValue(Register src, Label* on_invalid, 540 void JumpIfUIntNotValidSmiValue(Register src, Label* on_invalid,
490 Label::Distance near_jump = Label::kFar); 541 Label::Distance near_jump = Label::kFar);
542 // Jump if the unsigned integer value can be represented by a smi.
543 void JumpIfUIntValidSmiValue(Register src, Label* on_valid,
544 Label::Distance near_jump = Label::kFar);
545
491 546
492 // Jump to label if the value is a tagged smi. 547 // Jump to label if the value is a tagged smi.
493 void JumpIfSmi(Register src, 548 void JumpIfSmi(Register src,
494 Label* on_smi, 549 Label* on_smi,
495 Label::Distance near_jump = Label::kFar); 550 Label::Distance near_jump = Label::kFar);
496 551
497 // Jump to label if the value is not a tagged smi. 552 // Jump to label if the value is not a tagged smi.
498 void JumpIfNotSmi(Register src, 553 void JumpIfNotSmi(Register src,
499 Label* on_not_smi, 554 Label* on_not_smi,
500 Label::Distance near_jump = Label::kFar); 555 Label::Distance near_jump = Label::kFar);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 597
543 // Add an integer constant to a tagged smi, giving a tagged smi as result. 598 // Add an integer constant to a tagged smi, giving a tagged smi as result.
544 // No overflow testing on the result is done. 599 // No overflow testing on the result is done.
545 void SmiAddConstant(const Operand& dst, Smi* constant); 600 void SmiAddConstant(const Operand& dst, Smi* constant);
546 601
547 // Add an integer constant to a tagged smi, giving a tagged smi as result, 602 // Add an integer constant to a tagged smi, giving a tagged smi as result,
548 // or jumping to a label if the result cannot be represented by a smi. 603 // or jumping to a label if the result cannot be represented by a smi.
549 void SmiAddConstant(Register dst, 604 void SmiAddConstant(Register dst,
550 Register src, 605 Register src,
551 Smi* constant, 606 Smi* constant,
552 Label* on_not_smi_result, 607 const SmiInstructionWrapper& wrapper);
553 Label::Distance near_jump = Label::kFar);
554 608
555 // Subtract an integer constant from a tagged smi, giving a tagged smi as 609 // Subtract an integer constant from a tagged smi, giving a tagged smi as
556 // result. No testing on the result is done. Sets the N and Z flags 610 // result. No testing on the result is done. Sets the N and Z flags
557 // based on the value of the resulting integer. 611 // based on the value of the resulting integer.
558 void SmiSubConstant(Register dst, Register src, Smi* constant); 612 void SmiSubConstant(Register dst, Register src, Smi* constant);
559 613
560 // Subtract an integer constant from a tagged smi, giving a tagged smi as 614 // Subtract an integer constant from a tagged smi, giving a tagged smi as
561 // result, or jumping to a label if the result cannot be represented by a smi. 615 // result, or bailout if the result cannot be represented by a smi.
562 void SmiSubConstant(Register dst, 616 void SmiSubConstant(Register dst,
563 Register src, 617 Register src,
564 Smi* constant, 618 Smi* constant,
565 Label* on_not_smi_result, 619 const SmiInstructionWrapper& wrapper);
566 Label::Distance near_jump = Label::kFar);
567 620
568 // Negating a smi can give a negative zero or too large positive value. 621 // Negating a smi can give a negative zero or too large positive value.
569 // NOTICE: This operation jumps on success, not failure! 622 // NOTICE: This operation jumps on success, not failure!
570 void SmiNeg(Register dst, 623 void SmiNeg(Register dst,
571 Register src, 624 Register src,
572 Label* on_smi_result, 625 Label* on_smi_result,
573 Label::Distance near_jump = Label::kFar); 626 Label::Distance near_jump = Label::kFar);
574 627
575 // Adds smi values and return the result as a smi. 628 // Adds smi values and return the result as a smi.
576 // If dst is src1, then src1 will be destroyed, even if
577 // the operation is unsuccessful.
578 void SmiAdd(Register dst, 629 void SmiAdd(Register dst,
579 Register src1, 630 Register src1,
580 Register src2, 631 Register src2,
581 Label* on_not_smi_result, 632 const SmiInstructionWrapper& wrapper);
582 Label::Distance near_jump = Label::kFar);
583 void SmiAdd(Register dst, 633 void SmiAdd(Register dst,
584 Register src1, 634 Register src1,
585 const Operand& src2, 635 const Operand& src2,
586 Label* on_not_smi_result, 636 const SmiInstructionWrapper& wrapper);
587 Label::Distance near_jump = Label::kFar);
588
589 void SmiAdd(Register dst, 637 void SmiAdd(Register dst,
590 Register src1, 638 Register src1,
591 Register src2); 639 Register src2);
592 640
593 // Subtracts smi values and return the result as a smi. 641 // Subtracts smi values and return the result as a smi.
594 // If dst is src1, then src1 will be destroyed, even if
595 // the operation is unsuccessful.
596 void SmiSub(Register dst, 642 void SmiSub(Register dst,
597 Register src1, 643 Register src1,
598 Register src2, 644 Register src2,
599 Label* on_not_smi_result, 645 const SmiInstructionWrapper& wrapper);
600 Label::Distance near_jump = Label::kFar);
601 646
602 void SmiSub(Register dst, 647 void SmiSub(Register dst,
603 Register src1, 648 Register src1,
604 Register src2); 649 Register src2);
605 650
606 void SmiSub(Register dst, 651 void SmiSub(Register dst,
607 Register src1, 652 Register src1,
608 const Operand& src2, 653 const Operand& src2,
609 Label* on_not_smi_result, 654 const SmiInstructionWrapper& wrapper);
610 Label::Distance near_jump = Label::kFar);
611 655
612 void SmiSub(Register dst, 656 void SmiSub(Register dst,
613 Register src1, 657 Register src1,
614 const Operand& src2); 658 const Operand& src2);
615 659
616 // Multiplies smi values and return the result as a smi, 660 // Multiplies smi values and return the result as a smi,
617 // if possible. 661 // if possible.
618 // If dst is src1, then src1 will be destroyed, even if 662 // If dst is src1, then src1 will be destroyed, even if
619 // the operation is unsuccessful. 663 // the operation is unsuccessful.
620 void SmiMul(Register dst, 664 void SmiMul(Register dst,
(...skipping 22 matching lines...) Expand all
643 void SmiNot(Register dst, Register src); 687 void SmiNot(Register dst, Register src);
644 void SmiAnd(Register dst, Register src1, Register src2); 688 void SmiAnd(Register dst, Register src1, Register src2);
645 void SmiOr(Register dst, Register src1, Register src2); 689 void SmiOr(Register dst, Register src1, Register src2);
646 void SmiXor(Register dst, Register src1, Register src2); 690 void SmiXor(Register dst, Register src1, Register src2);
647 void SmiAndConstant(Register dst, Register src1, Smi* constant); 691 void SmiAndConstant(Register dst, Register src1, Smi* constant);
648 void SmiOrConstant(Register dst, Register src1, Smi* constant); 692 void SmiOrConstant(Register dst, Register src1, Smi* constant);
649 void SmiXorConstant(Register dst, Register src1, Smi* constant); 693 void SmiXorConstant(Register dst, Register src1, Smi* constant);
650 694
651 void SmiShiftLeftConstant(Register dst, 695 void SmiShiftLeftConstant(Register dst,
652 Register src, 696 Register src,
653 int shift_value); 697 int shift_value,
698 const SmiInstructionWrapper& wrapper);
654 void SmiShiftLogicalRightConstant(Register dst, 699 void SmiShiftLogicalRightConstant(Register dst,
655 Register src, 700 Register src,
656 int shift_value, 701 int shift_value,
657 Label* on_not_smi_result, 702 Label* on_not_smi_result,
658 Label::Distance near_jump = Label::kFar); 703 Label::Distance near_jump = Label::kFar);
659 void SmiShiftArithmeticRightConstant(Register dst, 704 void SmiShiftArithmeticRightConstant(Register dst,
660 Register src, 705 Register src,
661 int shift_value); 706 int shift_value);
662 707
663 // Shifts a smi value to the left, and returns the result if that is a smi. 708 // Shifts a smi value to the left, and returns the result if that is a smi.
664 // Uses and clobbers rcx, so dst may not be rcx. 709 // Uses and clobbers rcx, so dst may not be rcx.
665 void SmiShiftLeft(Register dst, 710 void SmiShiftLeft(Register dst,
666 Register src1, 711 Register src1,
667 Register src2); 712 Register src2,
713 Label* on_not_smi_result);
668 // Shifts a smi value to the right, shifting in zero bits at the top, and 714 // Shifts a smi value to the right, shifting in zero bits at the top, and
669 // returns the unsigned intepretation of the result if that is a smi. 715 // returns the unsigned intepretation of the result if that is a smi.
670 // Uses and clobbers rcx, so dst may not be rcx. 716 // Uses and clobbers rcx, so dst may not be rcx.
671 void SmiShiftLogicalRight(Register dst, 717 void SmiShiftLogicalRight(Register dst,
672 Register src1, 718 Register src1,
673 Register src2, 719 Register src2,
674 Label* on_not_smi_result, 720 Label* on_not_smi_result,
675 Label::Distance near_jump = Label::kFar); 721 Label::Distance near_jump = Label::kFar);
676 // Shifts a smi value to the right, sign extending the top, and 722 // Shifts a smi value to the right, sign extending the top, and
677 // returns the signed intepretation of the result. That will always 723 // returns the signed intepretation of the result. That will always
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 } 761 }
716 762
717 void Move(const Operand& dst, Smi* source) { 763 void Move(const Operand& dst, Smi* source) {
718 Register constant = GetSmiConstant(source); 764 Register constant = GetSmiConstant(source);
719 movq(dst, constant); 765 movq(dst, constant);
720 } 766 }
721 767
722 void Push(Smi* smi); 768 void Push(Smi* smi);
723 void Test(const Operand& dst, Smi* source); 769 void Test(const Operand& dst, Smi* source);
724 770
771 void PushInt64AsTwoSmis(Register src, Register scratch = kScratchRegister);
772 void PopInt64AsTwoSmis(Register dst, Register scratch = kScratchRegister);
773 static bool IsUnsafeSmiOperator(Token::Value op);
725 774
726 // --------------------------------------------------------------------------- 775 // ---------------------------------------------------------------------------
727 // String macros. 776 // String macros.
728 777
729 // If object is a string, its map is loaded into object_map. 778 // If object is a string, its map is loaded into object_map.
730 void JumpIfNotString(Register object, 779 void JumpIfNotString(Register object,
731 Register object_map, 780 Register object_map,
732 Label* not_string, 781 Label* not_string,
733 Label::Distance near_jump = Label::kFar); 782 Label::Distance near_jump = Label::kFar);
734 783
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 // --------------------------------------------------------------------------- 816 // ---------------------------------------------------------------------------
768 // Macro instructions. 817 // Macro instructions.
769 818
770 // Load a register with a long value as efficiently as possible. 819 // Load a register with a long value as efficiently as possible.
771 void Set(Register dst, int64_t x); 820 void Set(Register dst, int64_t x);
772 void Set(const Operand& dst, int64_t x); 821 void Set(const Operand& dst, int64_t x);
773 822
774 // Move if the registers are not identical. 823 // Move if the registers are not identical.
775 void Move(Register target, Register source); 824 void Move(Register target, Register source);
776 825
777 // Support for constant splitting.
778 bool IsUnsafeInt(const int x);
779 void SafeMove(Register dst, Smi* src);
780 void SafePush(Smi* src);
781
782 // Bit-field support. 826 // Bit-field support.
783 void TestBit(const Operand& dst, int bit_index); 827 void TestBit(const Operand& dst, int bit_index);
784 828
785 // Handle support 829 // Handle support
786 void Move(Register dst, Handle<Object> source); 830 void Move(Register dst, Handle<Object> source);
787 void Move(const Operand& dst, Handle<Object> source); 831 void Move(const Operand& dst, Handle<Object> source);
788 void Cmp(Register dst, Handle<Object> source); 832 void Cmp(Register dst, Handle<Object> source);
789 void Cmp(const Operand& dst, Handle<Object> source); 833 void Cmp(const Operand& dst, Handle<Object> source);
790 void Cmp(Register dst, Smi* src); 834 void Cmp(Register dst, Smi* src);
791 void Cmp(const Operand& dst, Smi* src); 835 void Cmp(const Operand& dst, Smi* src);
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 masm->popfq(); \ 1585 masm->popfq(); \
1542 } \ 1586 } \
1543 masm-> 1587 masm->
1544 #else 1588 #else
1545 #define ACCESS_MASM(masm) masm-> 1589 #define ACCESS_MASM(masm) masm->
1546 #endif 1590 #endif
1547 1591
1548 } } // namespace v8::internal 1592 } } // namespace v8::internal
1549 1593
1550 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ 1594 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698