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

Side by Side Diff: src/mips/assembler-mips.h

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 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/messages.js ('k') | src/mips/assembler-mips.cc » ('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 (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 321
322 friend class Assembler; 322 friend class Assembler;
323 friend class MacroAssembler; 323 friend class MacroAssembler;
324 }; 324 };
325 325
326 326
327 // On MIPS we have only one adressing mode with base_reg + offset. 327 // On MIPS we have only one adressing mode with base_reg + offset.
328 // Class MemOperand represents a memory operand in load and store instructions. 328 // Class MemOperand represents a memory operand in load and store instructions.
329 class MemOperand : public Operand { 329 class MemOperand : public Operand {
330 public: 330 public:
331
332 explicit MemOperand(Register rn, int32_t offset = 0); 331 explicit MemOperand(Register rn, int32_t offset = 0);
332 int32_t offset() const { return offset_; }
333 333
334 private: 334 private:
335 int32_t offset_; 335 int32_t offset_;
336 336
337 friend class Assembler; 337 friend class Assembler;
338 }; 338 };
339 339
340 340
341 // CpuFeatures keeps track of which features are supported by the target CPU. 341 // CpuFeatures keeps track of which features are supported by the target CPU.
342 // Supported features must be enabled by a Scope before use. 342 // Supported features must be enabled by a Scope before use.
(...skipping 22 matching lines...) Expand all
365 return IsSupported(f); 365 return IsSupported(f);
366 } 366 }
367 unsigned enabled = static_cast<unsigned>(isolate->enabled_cpu_features()); 367 unsigned enabled = static_cast<unsigned>(isolate->enabled_cpu_features());
368 return (enabled & (1u << f)) != 0; 368 return (enabled & (1u << f)) != 0;
369 } 369 }
370 #endif 370 #endif
371 371
372 // Enable a specified feature within a scope. 372 // Enable a specified feature within a scope.
373 class Scope BASE_EMBEDDED { 373 class Scope BASE_EMBEDDED {
374 #ifdef DEBUG 374 #ifdef DEBUG
375
375 public: 376 public:
376 explicit Scope(CpuFeature f) { 377 explicit Scope(CpuFeature f) {
377 unsigned mask = 1u << f; 378 unsigned mask = 1u << f;
378 ASSERT(CpuFeatures::IsSupported(f)); 379 ASSERT(CpuFeatures::IsSupported(f));
379 ASSERT(!Serializer::enabled() || 380 ASSERT(!Serializer::enabled() ||
380 (CpuFeatures::found_by_runtime_probing_ & mask) == 0); 381 (CpuFeatures::found_by_runtime_probing_ & mask) == 0);
381 isolate_ = Isolate::UncheckedCurrent(); 382 isolate_ = Isolate::UncheckedCurrent();
382 old_enabled_ = 0; 383 old_enabled_ = 0;
383 if (isolate_ != NULL) { 384 if (isolate_ != NULL) {
384 old_enabled_ = static_cast<unsigned>(isolate_->enabled_cpu_features()); 385 old_enabled_ = static_cast<unsigned>(isolate_->enabled_cpu_features());
385 isolate_->set_enabled_cpu_features(old_enabled_ | mask); 386 isolate_->set_enabled_cpu_features(old_enabled_ | mask);
386 } 387 }
387 } 388 }
388 ~Scope() { 389 ~Scope() {
389 ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_); 390 ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_);
390 if (isolate_ != NULL) { 391 if (isolate_ != NULL) {
391 isolate_->set_enabled_cpu_features(old_enabled_); 392 isolate_->set_enabled_cpu_features(old_enabled_);
392 } 393 }
393 } 394 }
394 private: 395
396 private:
395 Isolate* isolate_; 397 Isolate* isolate_;
396 unsigned old_enabled_; 398 unsigned old_enabled_;
397 #else 399 #else
398 public: 400
401 public:
399 explicit Scope(CpuFeature f) {} 402 explicit Scope(CpuFeature f) {}
400 #endif 403 #endif
401 }; 404 };
402 405
403 class TryForceFeatureScope BASE_EMBEDDED { 406 class TryForceFeatureScope BASE_EMBEDDED {
404 public: 407 public:
405 explicit TryForceFeatureScope(CpuFeature f) 408 explicit TryForceFeatureScope(CpuFeature f)
406 : old_supported_(CpuFeatures::supported_) { 409 : old_supported_(CpuFeatures::supported_) {
407 if (CanForce()) { 410 if (CanForce()) {
408 CpuFeatures::supported_ |= (1u << f); 411 CpuFeatures::supported_ |= (1u << f);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 // 474 //
472 // Label L; // unbound label 475 // Label L; // unbound label
473 // j(cc, &L); // forward branch to unbound label 476 // j(cc, &L); // forward branch to unbound label
474 // bind(&L); // bind label to the current pc 477 // bind(&L); // bind label to the current pc
475 // j(cc, &L); // backward branch to bound label 478 // j(cc, &L); // backward branch to bound label
476 // bind(&L); // illegal: a label may be bound only once 479 // bind(&L); // illegal: a label may be bound only once
477 // 480 //
478 // Note: The same Label can be used for forward and backward branches 481 // Note: The same Label can be used for forward and backward branches
479 // but it may be bound only once. 482 // but it may be bound only once.
480 void bind(Label* L); // Binds an unbound label L to current code position. 483 void bind(Label* L); // Binds an unbound label L to current code position.
484 // Determines if Label is bound and near enough so that branch instruction
485 // can be used to reach it, instead of jump instruction.
486 bool is_near(Label* L);
481 487
482 // Returns the branch offset to the given label from the current code 488 // Returns the branch offset to the given label from the current code
483 // position. Links the label to the current position if it is still unbound. 489 // position. Links the label to the current position if it is still unbound.
484 // Manages the jump elimination optimization if the second parameter is true. 490 // Manages the jump elimination optimization if the second parameter is true.
485 int32_t branch_offset(Label* L, bool jump_elimination_allowed); 491 int32_t branch_offset(Label* L, bool jump_elimination_allowed);
486 int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) { 492 int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) {
487 int32_t o = branch_offset(L, jump_elimination_allowed); 493 int32_t o = branch_offset(L, jump_elimination_allowed);
488 ASSERT((o & 3) == 0); // Assert the offset is aligned. 494 ASSERT((o & 3) == 0); // Assert the offset is aligned.
489 return o >> 2; 495 return o >> 2;
490 } 496 }
497 uint32_t jump_address(Label* L);
491 498
492 // Puts a labels target address at the given position. 499 // Puts a labels target address at the given position.
493 // The high 8 bits are set to zero. 500 // The high 8 bits are set to zero.
494 void label_at_put(Label* L, int at_offset); 501 void label_at_put(Label* L, int at_offset);
495 502
496 // Read/Modify the code target address in the branch/call instruction at pc. 503 // Read/Modify the code target address in the branch/call instruction at pc.
497 static Address target_address_at(Address pc); 504 static Address target_address_at(Address pc);
498 static void set_target_address_at(Address pc, Address target); 505 static void set_target_address_at(Address pc, Address target);
499 506
500 // This sets the branch destination (which gets loaded at the call address). 507 // This sets the branch destination (which gets loaded at the call address).
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 void sb(Register rd, const MemOperand& rs); 675 void sb(Register rd, const MemOperand& rs);
669 void sh(Register rd, const MemOperand& rs); 676 void sh(Register rd, const MemOperand& rs);
670 void sw(Register rd, const MemOperand& rs); 677 void sw(Register rd, const MemOperand& rs);
671 void swl(Register rd, const MemOperand& rs); 678 void swl(Register rd, const MemOperand& rs);
672 void swr(Register rd, const MemOperand& rs); 679 void swr(Register rd, const MemOperand& rs);
673 680
674 681
675 //-------------Misc-instructions-------------- 682 //-------------Misc-instructions--------------
676 683
677 // Break / Trap instructions. 684 // Break / Trap instructions.
678 void break_(uint32_t code); 685 void break_(uint32_t code, bool break_as_stop = false);
686 void stop(const char* msg, uint32_t code = kMaxStopCode);
679 void tge(Register rs, Register rt, uint16_t code); 687 void tge(Register rs, Register rt, uint16_t code);
680 void tgeu(Register rs, Register rt, uint16_t code); 688 void tgeu(Register rs, Register rt, uint16_t code);
681 void tlt(Register rs, Register rt, uint16_t code); 689 void tlt(Register rs, Register rt, uint16_t code);
682 void tltu(Register rs, Register rt, uint16_t code); 690 void tltu(Register rs, Register rt, uint16_t code);
683 void teq(Register rs, Register rt, uint16_t code); 691 void teq(Register rs, Register rt, uint16_t code);
684 void tne(Register rs, Register rt, uint16_t code); 692 void tne(Register rs, Register rt, uint16_t code);
685 693
686 // Move from HI/LO register. 694 // Move from HI/LO register.
687 void mfhi(Register rd); 695 void mfhi(Register rd);
688 void mflo(Register rd); 696 void mflo(Register rd);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 void c(FPUCondition cond, SecondaryField fmt, 772 void c(FPUCondition cond, SecondaryField fmt,
765 FPURegister ft, FPURegister fs, uint16_t cc = 0); 773 FPURegister ft, FPURegister fs, uint16_t cc = 0);
766 774
767 void bc1f(int16_t offset, uint16_t cc = 0); 775 void bc1f(int16_t offset, uint16_t cc = 0);
768 void bc1f(Label* L, uint16_t cc = 0) { bc1f(branch_offset(L, false)>>2, cc); } 776 void bc1f(Label* L, uint16_t cc = 0) { bc1f(branch_offset(L, false)>>2, cc); }
769 void bc1t(int16_t offset, uint16_t cc = 0); 777 void bc1t(int16_t offset, uint16_t cc = 0);
770 void bc1t(Label* L, uint16_t cc = 0) { bc1t(branch_offset(L, false)>>2, cc); } 778 void bc1t(Label* L, uint16_t cc = 0) { bc1t(branch_offset(L, false)>>2, cc); }
771 void fcmp(FPURegister src1, const double src2, FPUCondition cond); 779 void fcmp(FPURegister src1, const double src2, FPUCondition cond);
772 780
773 // Check the code size generated from label to here. 781 // Check the code size generated from label to here.
774 int InstructionsGeneratedSince(Label* l) { 782 int SizeOfCodeGeneratedSince(Label* label) {
775 return (pc_offset() - l->pos()) / kInstrSize; 783 return pc_offset() - label->pos();
784 }
785
786 // Check the number of instructions generated from label to here.
787 int InstructionsGeneratedSince(Label* label) {
788 return SizeOfCodeGeneratedSince(label) / kInstrSize;
776 } 789 }
777 790
778 // Class for scoping postponing the trampoline pool generation. 791 // Class for scoping postponing the trampoline pool generation.
779 class BlockTrampolinePoolScope { 792 class BlockTrampolinePoolScope {
780 public: 793 public:
781 explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) { 794 explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) {
782 assem_->StartBlockTrampolinePool(); 795 assem_->StartBlockTrampolinePool();
783 } 796 }
784 ~BlockTrampolinePoolScope() { 797 ~BlockTrampolinePoolScope() {
785 assem_->EndBlockTrampolinePool(); 798 assem_->EndBlockTrampolinePool();
786 } 799 }
787 800
788 private: 801 private:
789 Assembler* assem_; 802 Assembler* assem_;
790 803
791 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope); 804 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
792 }; 805 };
793 806
807 // Class for postponing the assembly buffer growth. Typically used for
808 // sequences of instructions that must be emitted as a unit, before
809 // buffer growth (and relocation) can occur.
810 // This blocking scope is not nestable.
811 class BlockGrowBufferScope {
812 public:
813 explicit BlockGrowBufferScope(Assembler* assem) : assem_(assem) {
814 assem_->StartBlockGrowBuffer();
815 }
816 ~BlockGrowBufferScope() {
817 assem_->EndBlockGrowBuffer();
818 }
819
820 private:
821 Assembler* assem_;
822
823 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
824 };
825
794 // Debugging. 826 // Debugging.
795 827
796 // Mark address of the ExitJSFrame code. 828 // Mark address of the ExitJSFrame code.
797 void RecordJSReturn(); 829 void RecordJSReturn();
798 830
799 // Mark address of a debug break slot. 831 // Mark address of a debug break slot.
800 void RecordDebugBreakSlot(); 832 void RecordDebugBreakSlot();
801 833
802 // Record the AST id of the CallIC being compiled, so that it can be placed 834 // Record the AST id of the CallIC being compiled, so that it can be placed
803 // in the relocation information. 835 // in the relocation information.
804 void RecordAstId(unsigned ast_id) { ast_id_for_reloc_info_ = ast_id; } 836 void RecordAstId(unsigned ast_id) { ast_id_for_reloc_info_ = ast_id; }
805 837
806 // Record a comment relocation entry that can be used by a disassembler. 838 // Record a comment relocation entry that can be used by a disassembler.
807 // Use --code-comments to enable. 839 // Use --code-comments to enable.
808 void RecordComment(const char* msg); 840 void RecordComment(const char* msg);
809 841
842 static int RelocateInternalReference(byte* pc, intptr_t pc_delta);
843
810 // Writes a single byte or word of data in the code stream. Used for 844 // Writes a single byte or word of data in the code stream. Used for
811 // inline tables, e.g., jump-tables. 845 // inline tables, e.g., jump-tables.
812 void db(uint8_t data); 846 void db(uint8_t data);
813 void dd(uint32_t data); 847 void dd(uint32_t data);
814 848
815 int32_t pc_offset() const { return pc_ - buffer_; } 849 int32_t pc_offset() const { return pc_ - buffer_; }
816 850
817 PositionsRecorder* positions_recorder() { return &positions_recorder_; } 851 PositionsRecorder* positions_recorder() { return &positions_recorder_; }
818 852
819 // Postpone the generation of the trampoline pool for the specified number of 853 // Postpone the generation of the trampoline pool for the specified number of
(...skipping 16 matching lines...) Expand all
836 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } 870 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
837 void instr_at_put(int pos, Instr instr) { 871 void instr_at_put(int pos, Instr instr) {
838 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; 872 *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
839 } 873 }
840 874
841 // Check if an instruction is a branch of some kind. 875 // Check if an instruction is a branch of some kind.
842 static bool IsBranch(Instr instr); 876 static bool IsBranch(Instr instr);
843 static bool IsBeq(Instr instr); 877 static bool IsBeq(Instr instr);
844 static bool IsBne(Instr instr); 878 static bool IsBne(Instr instr);
845 879
880 static bool IsJump(Instr instr);
881 static bool IsJ(Instr instr);
882 static bool IsLui(Instr instr);
883 static bool IsOri(Instr instr);
884
846 static bool IsNop(Instr instr, unsigned int type); 885 static bool IsNop(Instr instr, unsigned int type);
847 static bool IsPop(Instr instr); 886 static bool IsPop(Instr instr);
848 static bool IsPush(Instr instr); 887 static bool IsPush(Instr instr);
849 static bool IsLwRegFpOffset(Instr instr); 888 static bool IsLwRegFpOffset(Instr instr);
850 static bool IsSwRegFpOffset(Instr instr); 889 static bool IsSwRegFpOffset(Instr instr);
851 static bool IsLwRegFpNegOffset(Instr instr); 890 static bool IsLwRegFpNegOffset(Instr instr);
852 static bool IsSwRegFpNegOffset(Instr instr); 891 static bool IsSwRegFpNegOffset(Instr instr);
853 892
854 static Register GetRtReg(Instr instr); 893 static Register GetRtReg(Instr instr);
855 static Register GetRsReg(Instr instr); 894 static Register GetRsReg(Instr instr);
856 static Register GetRdReg(Instr instr); 895 static Register GetRdReg(Instr instr);
857 896
858 static uint32_t GetRt(Instr instr); 897 static uint32_t GetRt(Instr instr);
859 static uint32_t GetRtField(Instr instr); 898 static uint32_t GetRtField(Instr instr);
860 static uint32_t GetRs(Instr instr); 899 static uint32_t GetRs(Instr instr);
861 static uint32_t GetRsField(Instr instr); 900 static uint32_t GetRsField(Instr instr);
862 static uint32_t GetRd(Instr instr); 901 static uint32_t GetRd(Instr instr);
863 static uint32_t GetRdField(Instr instr); 902 static uint32_t GetRdField(Instr instr);
864 static uint32_t GetSa(Instr instr); 903 static uint32_t GetSa(Instr instr);
865 static uint32_t GetSaField(Instr instr); 904 static uint32_t GetSaField(Instr instr);
866 static uint32_t GetOpcodeField(Instr instr); 905 static uint32_t GetOpcodeField(Instr instr);
906 static uint32_t GetFunction(Instr instr);
907 static uint32_t GetFunctionField(Instr instr);
867 static uint32_t GetImmediate16(Instr instr); 908 static uint32_t GetImmediate16(Instr instr);
868 static uint32_t GetLabelConst(Instr instr); 909 static uint32_t GetLabelConst(Instr instr);
869 910
870 static int32_t GetBranchOffset(Instr instr); 911 static int32_t GetBranchOffset(Instr instr);
871 static bool IsLw(Instr instr); 912 static bool IsLw(Instr instr);
872 static int16_t GetLwOffset(Instr instr); 913 static int16_t GetLwOffset(Instr instr);
873 static Instr SetLwOffset(Instr instr, int16_t offset); 914 static Instr SetLwOffset(Instr instr, int16_t offset);
874 915
875 static bool IsSw(Instr instr); 916 static bool IsSw(Instr instr);
876 static Instr SetSwOffset(Instr instr, int16_t offset); 917 static Instr SetSwOffset(Instr instr, int16_t offset);
877 static bool IsAddImmediate(Instr instr); 918 static bool IsAddImmediate(Instr instr);
878 static Instr SetAddImmediateOffset(Instr instr, int16_t offset); 919 static Instr SetAddImmediateOffset(Instr instr, int16_t offset);
879 920
880 static bool IsAndImmediate(Instr instr); 921 static bool IsAndImmediate(Instr instr);
881 922
882 void CheckTrampolinePool(bool force_emit = false); 923 void CheckTrampolinePool();
883 924
884 protected: 925 protected:
885 // Relocation for a type-recording IC has the AST id added to it. This 926 // Relocation for a type-recording IC has the AST id added to it. This
886 // member variable is a way to pass the information from the call site to 927 // member variable is a way to pass the information from the call site to
887 // the relocation info. 928 // the relocation info.
888 unsigned ast_id_for_reloc_info_; 929 unsigned ast_id_for_reloc_info_;
889 930
890 bool emit_debug_code() const { return emit_debug_code_; } 931 bool emit_debug_code() const { return emit_debug_code_; }
891 932
892 int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; } 933 int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; }
(...skipping 12 matching lines...) Expand all
905 946
906 // Block the emission of the trampoline pool before pc_offset. 947 // Block the emission of the trampoline pool before pc_offset.
907 void BlockTrampolinePoolBefore(int pc_offset) { 948 void BlockTrampolinePoolBefore(int pc_offset) {
908 if (no_trampoline_pool_before_ < pc_offset) 949 if (no_trampoline_pool_before_ < pc_offset)
909 no_trampoline_pool_before_ = pc_offset; 950 no_trampoline_pool_before_ = pc_offset;
910 } 951 }
911 952
912 void StartBlockTrampolinePool() { 953 void StartBlockTrampolinePool() {
913 trampoline_pool_blocked_nesting_++; 954 trampoline_pool_blocked_nesting_++;
914 } 955 }
956
915 void EndBlockTrampolinePool() { 957 void EndBlockTrampolinePool() {
916 trampoline_pool_blocked_nesting_--; 958 trampoline_pool_blocked_nesting_--;
917 } 959 }
918 960
919 bool is_trampoline_pool_blocked() const { 961 bool is_trampoline_pool_blocked() const {
920 return trampoline_pool_blocked_nesting_ > 0; 962 return trampoline_pool_blocked_nesting_ > 0;
921 } 963 }
922 964
923 bool has_exception() const { 965 bool has_exception() const {
924 return internal_trampoline_exception_; 966 return internal_trampoline_exception_;
925 } 967 }
926 968
969 bool is_trampoline_emitted() const {
970 return trampoline_emitted_;
971 }
972
973 // Temporarily block automatic assembly buffer growth.
974 void StartBlockGrowBuffer() {
975 ASSERT(!block_buffer_growth_);
976 block_buffer_growth_ = true;
977 }
978
979 void EndBlockGrowBuffer() {
980 ASSERT(block_buffer_growth_);
981 block_buffer_growth_ = false;
982 }
983
984 bool is_buffer_growth_blocked() const {
985 return block_buffer_growth_;
986 }
987
927 private: 988 private:
928 // Code buffer: 989 // Code buffer:
929 // The buffer into which code and relocation info are generated. 990 // The buffer into which code and relocation info are generated.
930 byte* buffer_; 991 byte* buffer_;
931 int buffer_size_; 992 int buffer_size_;
932 // True if the assembler owns the buffer, false if buffer is external. 993 // True if the assembler owns the buffer, false if buffer is external.
933 bool own_buffer_; 994 bool own_buffer_;
934 995
935 // Buffer size and constant pool distance are checked together at regular 996 // Buffer size and constant pool distance are checked together at regular
936 // intervals of kBufferCheckInterval emitted bytes. 997 // intervals of kBufferCheckInterval emitted bytes.
(...skipping 16 matching lines...) Expand all
953 1014
954 int next_buffer_check_; // pc offset of next buffer check. 1015 int next_buffer_check_; // pc offset of next buffer check.
955 1016
956 // Emission of the trampoline pool may be blocked in some code sequences. 1017 // Emission of the trampoline pool may be blocked in some code sequences.
957 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. 1018 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero.
958 int no_trampoline_pool_before_; // Block emission before this pc offset. 1019 int no_trampoline_pool_before_; // Block emission before this pc offset.
959 1020
960 // Keep track of the last emitted pool to guarantee a maximal distance. 1021 // Keep track of the last emitted pool to guarantee a maximal distance.
961 int last_trampoline_pool_end_; // pc offset of the end of the last pool. 1022 int last_trampoline_pool_end_; // pc offset of the end of the last pool.
962 1023
1024 // Automatic growth of the assembly buffer may be blocked for some sequences.
1025 bool block_buffer_growth_; // Block growth when true.
1026
963 // Relocation information generation. 1027 // Relocation information generation.
964 // Each relocation is encoded as a variable size value. 1028 // Each relocation is encoded as a variable size value.
965 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 1029 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
966 RelocInfoWriter reloc_info_writer; 1030 RelocInfoWriter reloc_info_writer;
967 1031
968 // The bound position, before this we cannot do instruction elimination. 1032 // The bound position, before this we cannot do instruction elimination.
969 int last_bound_pos_; 1033 int last_bound_pos_;
970 1034
971 // Code emission. 1035 // Code emission.
972 inline void CheckBuffer(); 1036 inline void CheckBuffer();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 1097
1034 void GenInstrJump(Opcode opcode, 1098 void GenInstrJump(Opcode opcode,
1035 uint32_t address); 1099 uint32_t address);
1036 1100
1037 // Helpers. 1101 // Helpers.
1038 void LoadRegPlusOffsetToAt(const MemOperand& src); 1102 void LoadRegPlusOffsetToAt(const MemOperand& src);
1039 1103
1040 // Labels. 1104 // Labels.
1041 void print(Label* L); 1105 void print(Label* L);
1042 void bind_to(Label* L, int pos); 1106 void bind_to(Label* L, int pos);
1043 void link_to(Label* L, Label* appendix);
1044 void next(Label* L); 1107 void next(Label* L);
1045 1108
1046 // One trampoline consists of: 1109 // One trampoline consists of:
1047 // - space for trampoline slots, 1110 // - space for trampoline slots,
1048 // - space for labels. 1111 // - space for labels.
1049 // 1112 //
1050 // Space for trampoline slots is equal to slot_count * 2 * kInstrSize. 1113 // Space for trampoline slots is equal to slot_count * 2 * kInstrSize.
1051 // Space for trampoline slots preceeds space for labels. Each label is of one 1114 // Space for trampoline slots preceeds space for labels. Each label is of one
1052 // instruction size, so total amount for labels is equal to 1115 // instruction size, so total amount for labels is equal to
1053 // label_count * kInstrSize. 1116 // label_count * kInstrSize.
1054 class Trampoline { 1117 class Trampoline {
1055 public: 1118 public:
1056 Trampoline(int start, int slot_count, int label_count) { 1119 Trampoline() {
1120 start_ = 0;
1121 next_slot_ = 0;
1122 free_slot_count_ = 0;
1123 end_ = 0;
1124 }
1125 Trampoline(int start, int slot_count) {
1057 start_ = start; 1126 start_ = start;
1058 next_slot_ = start; 1127 next_slot_ = start;
1059 free_slot_count_ = slot_count; 1128 free_slot_count_ = slot_count;
1060 next_label_ = start + slot_count * 2 * kInstrSize; 1129 end_ = start + slot_count * kTrampolineSlotsSize;
1061 free_label_count_ = label_count;
1062 end_ = next_label_ + (label_count - 1) * kInstrSize;
1063 } 1130 }
1064 int start() { 1131 int start() {
1065 return start_; 1132 return start_;
1066 } 1133 }
1067 int end() { 1134 int end() {
1068 return end_; 1135 return end_;
1069 } 1136 }
1070 int take_slot() { 1137 int take_slot() {
1071 int trampoline_slot = kInvalidSlotPos; 1138 int trampoline_slot = kInvalidSlotPos;
1072 if (free_slot_count_ <= 0) { 1139 if (free_slot_count_ <= 0) {
1073 // We have run out of space on trampolines. 1140 // We have run out of space on trampolines.
1074 // Make sure we fail in debug mode, so we become aware of each case 1141 // Make sure we fail in debug mode, so we become aware of each case
1075 // when this happens. 1142 // when this happens.
1076 ASSERT(0); 1143 ASSERT(0);
1077 // Internal exception will be caught. 1144 // Internal exception will be caught.
1078 } else { 1145 } else {
1079 trampoline_slot = next_slot_; 1146 trampoline_slot = next_slot_;
1080 free_slot_count_--; 1147 free_slot_count_--;
1081 next_slot_ += 2*kInstrSize; 1148 next_slot_ += kTrampolineSlotsSize;
1082 } 1149 }
1083 return trampoline_slot; 1150 return trampoline_slot;
1084 } 1151 }
1085 int take_label() {
1086 int label_pos = next_label_;
1087 ASSERT(free_label_count_ > 0);
1088 free_label_count_--;
1089 next_label_ += kInstrSize;
1090 return label_pos;
1091 }
1092 private: 1152 private:
1093 int start_; 1153 int start_;
1094 int end_; 1154 int end_;
1095 int next_slot_; 1155 int next_slot_;
1096 int free_slot_count_; 1156 int free_slot_count_;
1097 int next_label_;
1098 int free_label_count_;
1099 }; 1157 };
1100 1158
1101 int32_t get_label_entry(int32_t pos, bool next_pool = true); 1159 int32_t get_trampoline_entry(int32_t pos);
1102 int32_t get_trampoline_entry(int32_t pos, bool next_pool = true); 1160 int unbound_labels_count_;
1103 1161 // If trampoline is emitted, generated code is becoming large. As this is
1104 static const int kSlotsPerTrampoline = 2304; 1162 // already a slow case which can possibly break our code generation for the
1105 static const int kLabelsPerTrampoline = 8; 1163 // extreme case, we use this information to trigger different mode of
1106 static const int kTrampolineInst = 1164 // branch instruction generation, where we use jump instructions rather
1107 2 * kSlotsPerTrampoline + kLabelsPerTrampoline; 1165 // than regular branch instructions.
1108 static const int kTrampolineSize = kTrampolineInst * kInstrSize; 1166 bool trampoline_emitted_;
1167 static const int kTrampolineSlotsSize = 4 * kInstrSize;
1109 static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; 1168 static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
1110 static const int kMaxDistBetweenPools =
1111 kMaxBranchOffset - 2 * kTrampolineSize;
1112 static const int kInvalidSlotPos = -1; 1169 static const int kInvalidSlotPos = -1;
1113 1170
1114 List<Trampoline> trampolines_; 1171 Trampoline trampoline_;
1115 bool internal_trampoline_exception_; 1172 bool internal_trampoline_exception_;
1116 1173
1117 friend class RegExpMacroAssemblerMIPS; 1174 friend class RegExpMacroAssemblerMIPS;
1118 friend class RelocInfo; 1175 friend class RelocInfo;
1119 friend class CodePatcher; 1176 friend class CodePatcher;
1120 friend class BlockTrampolinePoolScope; 1177 friend class BlockTrampolinePoolScope;
1121 1178
1122 PositionsRecorder positions_recorder_; 1179 PositionsRecorder positions_recorder_;
1123 bool emit_debug_code_; 1180 bool emit_debug_code_;
1124 friend class PositionsRecorder; 1181 friend class PositionsRecorder;
1125 friend class EnsureSpace; 1182 friend class EnsureSpace;
1126 }; 1183 };
1127 1184
1128 1185
1129 class EnsureSpace BASE_EMBEDDED { 1186 class EnsureSpace BASE_EMBEDDED {
1130 public: 1187 public:
1131 explicit EnsureSpace(Assembler* assembler) { 1188 explicit EnsureSpace(Assembler* assembler) {
1132 assembler->CheckBuffer(); 1189 assembler->CheckBuffer();
1133 } 1190 }
1134 }; 1191 };
1135 1192
1136 } } // namespace v8::internal 1193 } } // namespace v8::internal
1137 1194
1138 #endif // V8_ARM_ASSEMBLER_MIPS_H_ 1195 #endif // V8_ARM_ASSEMBLER_MIPS_H_
OLDNEW
« no previous file with comments | « src/messages.js ('k') | src/mips/assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698