Chromium Code Reviews| Index: src/mips/assembler-mips.cc |
| diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc |
| index 182183f547bc9f7f7bf81baffbac69c228c4cd50..48d5879d422b2e7349fb8cce5e833bead68e64ef 100644 |
| --- a/src/mips/assembler-mips.cc |
| +++ b/src/mips/assembler-mips.cc |
| @@ -674,7 +674,6 @@ int Assembler::target_at(int32_t pos) { |
| } |
| } |
| // Check we have a branch or jump instruction. |
|
paul.l...
2015/02/09 20:14:38
Since you deleted the DCHECK, you need to remove t
balazs.kilvady
2015/02/09 20:22:36
Done.
|
| - DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr)); |
| // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming |
| // the compiler uses arithmectic shifts for signed integers. |
| if (IsBranch(instr)) { |
| @@ -702,7 +701,7 @@ int Assembler::target_at(int32_t pos) { |
| DCHECK(pos > delta); |
| return pos - delta; |
| } |
| - } else { |
| + } else if (IsJ(instr)) { |
| int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; |
| if (imm28 == kEndOfJumpChain) { |
| // EndOfChain sentinel is returned directly, not relative to pc or pos. |
| @@ -714,6 +713,14 @@ int Assembler::target_at(int32_t pos) { |
| DCHECK(pos > delta); |
| return pos - delta; |
| } |
| + } else { // IsLabel(instr) |
| + int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; |
| + if (imm28 == kEndOfJumpChain) { |
| + // EndOfChain sentinel is returned directly, not relative to pc or pos. |
| + return kEndOfChain; |
| + } else { |
| + return pos + imm28; |
| + } |
| } |
| } |
| @@ -728,7 +735,6 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos) { |
| return; |
| } |
| - DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr)); |
| if (IsBranch(instr)) { |
| int32_t imm18 = target_pos - (pos + kBranchPCOffset); |
| DCHECK((imm18 & 3) == 0); |
| @@ -752,7 +758,7 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos) { |
| instr_lui | ((imm & kHiMask) >> kLuiShift)); |
| instr_at_put(pos + 1 * Assembler::kInstrSize, |
| instr_ori | (imm & kImm16Mask)); |
| - } else { |
| + } else if (IsJ(instr)) { |
| uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
| imm28 &= kImm28Mask; |
| DCHECK((imm28 & 3) == 0); |
| @@ -762,6 +768,9 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos) { |
| DCHECK(is_uint26(imm26)); |
| instr_at_put(pos, instr | (imm26 & kImm26Mask)); |
| + } else { |
| + uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
| + instr_at_put(pos, imm); |
| } |
| } |
| @@ -816,7 +825,6 @@ void Assembler::bind_to(Label* L, int pos) { |
| } |
| target_at_put(fixup_pos, pos); |
| } else { |
| - DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr)); |
| target_at_put(fixup_pos, pos); |
| } |
| } |
| @@ -2358,7 +2366,6 @@ void Assembler::RecordDeoptReason(const int reason, const int raw_position) { |
| int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) { |
| Instr instr = instr_at(pc); |
| - DCHECK(IsJ(instr) || IsLui(instr)); |
| if (IsLui(instr)) { |
| Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize); |
| Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize); |
| @@ -2379,7 +2386,7 @@ int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) { |
| instr_at_put(pc + 1 * Assembler::kInstrSize, |
| instr_ori | (imm & kImm16Mask)); |
| return 2; // Number of instructions patched. |
| - } else { |
| + } else if (IsJ(instr)) { |
| uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; |
| if (static_cast<int32_t>(imm28) == kEndOfJumpChain) { |
| return 0; // Number of instructions patched. |
| @@ -2394,6 +2401,14 @@ int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) { |
| instr_at_put(pc, instr | (imm26 & kImm26Mask)); |
| return 1; // Number of instructions patched. |
| + } else { // IsLabel(instr) |
| + int32_t* p = reinterpret_cast<int32_t*>(pc); |
| + uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; |
| + if (static_cast<int32_t>(imm28) == kEndOfJumpChain) { |
| + return 0; // Number of instructions patched. |
| + } |
| + *p += pc_delta; |
| + return 1; // Number of instructions patched. |
| } |
| } |
| @@ -2458,6 +2473,35 @@ void Assembler::dd(uint32_t data) { |
| } |
| +void Assembler::dd(Label* label) { |
| + CheckBuffer(); |
| + RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); |
| + if (label->is_bound()) { |
| + uint32_t data = reinterpret_cast<uint32_t>(buffer_ + label->pos()); |
| + *reinterpret_cast<uint32_t*>(pc_) = data; |
| + pc_ += sizeof(uint32_t); |
| + } else { |
| + int target_pos; |
| + if (label->is_linked()) { |
| + // Point to previous instruction that uses the link. |
| + target_pos = label->pos(); |
| + } else { |
| + // First entry of the link chain points to itself. |
| + target_pos = pc_offset(); |
| + } |
| + label->link_to(pc_offset()); |
| + // Encode internal reference to unbound label. We set the least significant |
| + // bit to distinguish unbound internal references in GrowBuffer() below. |
| + int diff = target_pos - pc_offset(); |
| + DCHECK_EQ(0, diff & 3); |
| + int imm26 = diff >> 2; |
| + DCHECK(is_int26(imm26)); |
| + // Emit special LABEL instruction. |
| + emit(LABEL | (imm26 & kImm26Mask)); |
| + } |
| +} |
| + |
| + |
| void Assembler::emit_code_stub_address(Code* stub) { |
| CheckBuffer(); |
| *reinterpret_cast<uint32_t*>(pc_) = |