Index: src/mips/assembler-mips.h |
diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h |
index 1a83b7389136abbf542fb9e1220c3cce37e45655..5277af4420d28d5aa1412b52771889ea25f9e572 100644 |
--- a/src/mips/assembler-mips.h |
+++ b/src/mips/assembler-mips.h |
@@ -480,6 +480,9 @@ class Assembler : public AssemblerBase { |
// Note: The same Label can be used for forward and backward branches |
// but it may be bound only once. |
void bind(Label* L); // Binds an unbound label L to current code position. |
+ // Determines if Label is bound and near enough so that branch instruction |
+ // can be used to reach it, instead of jump instruction. |
+ bool is_near(Label* L); |
// Returns the branch offset to the given label from the current code |
// position. Links the label to the current position if it is still unbound. |
@@ -490,6 +493,7 @@ class Assembler : public AssemblerBase { |
ASSERT((o & 3) == 0); // Assert the offset is aligned. |
return o >> 2; |
} |
+ uint32_t jump_address(Label* L); |
// Puts a labels target address at the given position. |
// The high 8 bits are set to zero. |
@@ -640,9 +644,9 @@ class Assembler : public AssemblerBase { |
void nor(Register rd, Register rs, Register rt); |
void andi(Register rd, Register rs, int32_t j); |
- void ori(Register rd, Register rs, int32_t j); |
+ void ori(Register rd, Register rs, int32_t j, bool check_buffer = true); |
Søren Thygesen Gjesse
2011/06/24 13:05:15
This boolean flag seems rather obscure - when shou
Paul Lind
2011/06/28 06:53:14
Agree that it was confusing. I have removed the fl
|
void xori(Register rd, Register rs, int32_t j); |
- void lui(Register rd, int32_t j); |
+ void lui(Register rd, int32_t j, bool check_buffer = true); |
// Shifts. |
// Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop |
@@ -810,6 +814,8 @@ class Assembler : public AssemblerBase { |
// Use --code-comments to enable. |
void RecordComment(const char* msg); |
+ static void RelocateInternalReference(byte* pc, intptr_t pc_delta); |
+ |
// Writes a single byte or word of data in the code stream. Used for |
// inline tables, e.g., jump-tables. |
void db(uint8_t data); |
@@ -846,6 +852,11 @@ class Assembler : public AssemblerBase { |
static bool IsBeq(Instr instr); |
static bool IsBne(Instr instr); |
+ static bool IsJump(Instr instr); |
+ static bool IsJ(Instr instr); |
+ static bool IsLui(Instr instr); |
+ static bool IsOri(Instr instr); |
+ |
static bool IsNop(Instr instr, unsigned int type); |
static bool IsPop(Instr instr); |
static bool IsPush(Instr instr); |
@@ -867,6 +878,8 @@ class Assembler : public AssemblerBase { |
static uint32_t GetSa(Instr instr); |
static uint32_t GetSaField(Instr instr); |
static uint32_t GetOpcodeField(Instr instr); |
+ static uint32_t GetFunction(Instr instr); |
+ static uint32_t GetFunctionField(Instr instr); |
static uint32_t GetImmediate16(Instr instr); |
static uint32_t GetLabelConst(Instr instr); |
@@ -882,7 +895,7 @@ class Assembler : public AssemblerBase { |
static bool IsAndImmediate(Instr instr); |
- void CheckTrampolinePool(bool force_emit = false); |
+ void CheckTrampolinePool(); |
protected: |
// Relocation for a type-recording IC has the AST id added to it. This |
@@ -927,6 +940,10 @@ class Assembler : public AssemblerBase { |
return internal_trampoline_exception_; |
} |
+ bool is_trampoline_emitted() const { |
+ return trampoline_emitted_; |
+ } |
+ |
private: |
// Code buffer: |
// The buffer into which code and relocation info are generated. |
@@ -943,8 +960,10 @@ class Assembler : public AssemblerBase { |
// The relocation writer's position is at least kGap bytes below the end of |
// the generated instructions. This is so that multi-instruction sequences do |
// not have to check for overflow. The same is true for writes of large |
- // relocation info entries. |
- static const int kGap = 32; |
+ // relocation info entries. MIPS uses 8 bytes more than other architectures, |
+ // because it does not check for this gap when instructions with internal |
+ // reference relocation info are emitted. |
+ static const int kGap = 40; |
byte* pc_; // The program counter - moves forward. |
@@ -974,7 +993,7 @@ class Assembler : public AssemblerBase { |
// Code emission. |
inline void CheckBuffer(); |
void GrowBuffer(); |
- inline void emit(Instr x); |
+ inline void emit(Instr x, bool check_buffer = true); |
inline void CheckTrampolinePoolQuick(); |
// Instruction generation. |
@@ -1023,7 +1042,8 @@ class Assembler : public AssemblerBase { |
void GenInstrImmediate(Opcode opcode, |
Register rs, |
Register rt, |
- int32_t j); |
+ int32_t j, |
+ bool check_buffer = true); |
void GenInstrImmediate(Opcode opcode, |
Register rs, |
SecondaryField SF, |
@@ -1043,7 +1063,6 @@ class Assembler : public AssemblerBase { |
// Labels. |
void print(Label* L); |
void bind_to(Label* L, int pos); |
- void link_to(Label* L, Label* appendix); |
void next(Label* L); |
// One trampoline consists of: |
@@ -1056,13 +1075,17 @@ class Assembler : public AssemblerBase { |
// label_count * kInstrSize. |
class Trampoline { |
public: |
- Trampoline(int start, int slot_count, int label_count) { |
+ Trampoline() { |
+ start_ = 0; |
+ next_slot_ = 0; |
+ free_slot_count_ = 0; |
+ end_ = 0; |
+ } |
+ Trampoline(int start, int slot_count) { |
start_ = start; |
next_slot_ = start; |
free_slot_count_ = slot_count; |
- next_label_ = start + slot_count * 2 * kInstrSize; |
- free_label_count_ = label_count; |
- end_ = next_label_ + (label_count - 1) * kInstrSize; |
+ end_ = start + slot_count * kTrampolineSlotsSize; |
} |
int start() { |
return start_; |
@@ -1081,41 +1104,30 @@ class Assembler : public AssemblerBase { |
} else { |
trampoline_slot = next_slot_; |
free_slot_count_--; |
- next_slot_ += 2*kInstrSize; |
+ next_slot_ += kTrampolineSlotsSize; |
} |
return trampoline_slot; |
} |
- int take_label() { |
- int label_pos = next_label_; |
- ASSERT(free_label_count_ > 0); |
- free_label_count_--; |
- next_label_ += kInstrSize; |
- return label_pos; |
- } |
- |
private: |
int start_; |
int end_; |
int next_slot_; |
int free_slot_count_; |
- int next_label_; |
- int free_label_count_; |
}; |
- int32_t get_label_entry(int32_t pos, bool next_pool = true); |
- int32_t get_trampoline_entry(int32_t pos, bool next_pool = true); |
- |
- static const int kSlotsPerTrampoline = 2304; |
- static const int kLabelsPerTrampoline = 8; |
- static const int kTrampolineInst = |
- 2 * kSlotsPerTrampoline + kLabelsPerTrampoline; |
- static const int kTrampolineSize = kTrampolineInst * kInstrSize; |
+ int32_t get_trampoline_entry(int32_t pos); |
+ int unbound_labels_count; |
+ // If trampoline is emitted, generated code is becoming large. As this is |
+ // already a slow case which can possibly break our code generation for |
Søren Thygesen Gjesse
2011/06/24 13:05:15
for -> for the / in the
Paul Lind
2011/06/28 06:53:14
Done.
|
+ // extreme case, we use this information to trigger different mode for |
Søren Thygesen Gjesse
2011/06/24 13:05:15
for -> of
Paul Lind
2011/06/28 06:53:14
Done.
|
+ // branch instruction generation, where we use jump instructions rather |
+ // than regular branch instructions. |
+ bool trampoline_emitted_; |
+ static const int kTrampolineSlotsSize = 4 * kInstrSize; |
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; |
- static const int kMaxDistBetweenPools = |
- kMaxBranchOffset - 2 * kTrampolineSize; |
static const int kInvalidSlotPos = -1; |
- List<Trampoline> trampolines_; |
+ Trampoline trampoline_; |
bool internal_trampoline_exception_; |
friend class RegExpMacroAssemblerMIPS; |