Chromium Code Reviews| Index: runtime/vm/assembler_mips.h |
| =================================================================== |
| --- runtime/vm/assembler_mips.h (revision 25539) |
| +++ runtime/vm/assembler_mips.h (working copy) |
| @@ -22,6 +22,8 @@ |
| // The MIPS32® Instruction Set" in short "VolII-A" |
| namespace dart { |
| +DECLARE_FLAG(bool, mips_far_branches); |
|
regis
2013/07/26 22:30:38
'mips_' is not really needed, but since I understa
zra
2013/07/26 23:29:03
Changed to use_far_branches, and I'll use the same
|
| + |
| // Forward declarations. |
| class RuntimeEntry; |
| @@ -854,76 +856,80 @@ |
| } |
| void BranchEqual(Register rd, int32_t value, Label* l) { |
| - ASSERT(rd != CMPRES); |
| - LoadImmediate(CMPRES, value); |
| - beq(rd, CMPRES, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + beq(rd, CMPRES2, l); |
| } |
| void BranchEqual(Register rd, const Object& object, Label* l) { |
| - ASSERT(rd != CMPRES); |
| - LoadObject(CMPRES, object); |
| - beq(rd, CMPRES, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadObject(CMPRES2, object); |
| + beq(rd, CMPRES2, l); |
| } |
| void BranchNotEqual(Register rd, int32_t value, Label* l) { |
| - ASSERT(rd != CMPRES); |
| - LoadImmediate(CMPRES, value); |
| - bne(rd, CMPRES, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + bne(rd, CMPRES2, l); |
| } |
| void BranchNotEqual(Register rd, const Object& object, Label* l) { |
| - ASSERT(rd != CMPRES); |
| - LoadObject(CMPRES, object); |
| - bne(rd, CMPRES, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadObject(CMPRES2, object); |
| + bne(rd, CMPRES2, l); |
| } |
| void BranchSignedGreater(Register rd, Register rs, Label* l) { |
| - slt(CMPRES, rs, rd); // CMPRES = rd > rs ? 1 : 0. |
| - bne(CMPRES, ZR, l); |
| + slt(CMPRES2, rs, rd); // CMPRES2 = rd > rs ? 1 : 0. |
| + bne(CMPRES2, ZR, l); |
| } |
| void BranchSignedGreater(Register rd, int32_t value, Label* l) { |
| - LoadImmediate(CMPRES, value); |
| - BranchSignedGreater(rd, CMPRES, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + BranchSignedGreater(rd, CMPRES2, l); |
| } |
| void BranchUnsignedGreater(Register rd, Register rs, Label* l) { |
| - sltu(CMPRES, rs, rd); |
| - bne(CMPRES, ZR, l); |
| + sltu(CMPRES2, rs, rd); |
| + bne(CMPRES2, ZR, l); |
| } |
| void BranchUnsignedGreater(Register rd, int32_t value, Label* l) { |
| - LoadImmediate(CMPRES, value); |
| - BranchUnsignedGreater(rd, CMPRES, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + BranchUnsignedGreater(rd, CMPRES2, l); |
| } |
| void BranchSignedGreaterEqual(Register rd, Register rs, Label* l) { |
| - slt(CMPRES, rd, rs); // CMPRES = rd < rs ? 1 : 0. |
| - beq(CMPRES, ZR, l); // If CMPRES = 0, then rd >= rs. |
| + slt(CMPRES2, rd, rs); // CMPRES2 = rd < rs ? 1 : 0. |
| + beq(CMPRES2, ZR, l); // If CMPRES2 = 0, then rd >= rs. |
| } |
| void BranchSignedGreaterEqual(Register rd, int32_t value, Label* l) { |
| if (Utils::IsInt(kImmBits, value)) { |
| - slti(CMPRES, rd, Immediate(value)); |
| - beq(CMPRES, ZR, l); |
| + slti(CMPRES2, rd, Immediate(value)); |
| + beq(CMPRES2, ZR, l); |
| } else { |
| - LoadImmediate(CMPRES, value); |
| - BranchSignedGreaterEqual(rd, CMPRES, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + BranchSignedGreaterEqual(rd, CMPRES2, l); |
| } |
| } |
| void BranchUnsignedGreaterEqual(Register rd, Register rs, Label* l) { |
| - sltu(CMPRES, rd, rs); // CMPRES = rd < rs ? 1 : 0. |
| - beq(CMPRES, ZR, l); |
| + sltu(CMPRES2, rd, rs); // CMPRES2 = rd < rs ? 1 : 0. |
| + beq(CMPRES2, ZR, l); |
| } |
| void BranchUnsignedGreaterEqual(Register rd, int32_t value, Label* l) { |
| if (Utils::IsUint(kImmBits, value)) { |
| - sltiu(CMPRES, rd, Immediate(value)); |
| - beq(CMPRES, ZR, l); |
| + sltiu(CMPRES2, rd, Immediate(value)); |
| + beq(CMPRES2, ZR, l); |
| } else { |
| - LoadImmediate(CMPRES, value); |
| - BranchUnsignedGreaterEqual(rd, CMPRES, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + BranchUnsignedGreaterEqual(rd, CMPRES2, l); |
| } |
| } |
| @@ -933,11 +939,12 @@ |
| void BranchSignedLess(Register rd, int32_t value, Label* l) { |
| if (Utils::IsInt(kImmBits, value)) { |
| - slti(CMPRES, rd, Immediate(value)); |
| - bne(CMPRES, ZR, l); |
| + slti(CMPRES2, rd, Immediate(value)); |
| + bne(CMPRES2, ZR, l); |
| } else { |
| - LoadImmediate(CMPRES, value); |
| - BranchSignedGreater(CMPRES, rd, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + BranchSignedGreater(CMPRES2, rd, l); |
| } |
| } |
| @@ -947,11 +954,12 @@ |
| void BranchUnsignedLess(Register rd, int32_t value, Label* l) { |
| if (Utils::IsUint(kImmBits, value)) { |
| - sltiu(CMPRES, rd, Immediate(value)); |
| - bne(CMPRES, ZR, l); |
| + sltiu(CMPRES2, rd, Immediate(value)); |
| + bne(CMPRES2, ZR, l); |
| } else { |
| - LoadImmediate(CMPRES, value); |
| - BranchUnsignedGreater(CMPRES, rd, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + BranchUnsignedGreater(CMPRES2, rd, l); |
| } |
| } |
| @@ -960,8 +968,9 @@ |
| } |
| void BranchSignedLessEqual(Register rd, int32_t value, Label* l) { |
| - LoadImmediate(CMPRES, value); |
| - BranchSignedGreaterEqual(CMPRES, rd, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + BranchSignedGreaterEqual(CMPRES2, rd, l); |
| } |
| void BranchUnsignedLessEqual(Register rd, Register rs, Label* l) { |
| @@ -969,8 +978,9 @@ |
| } |
| void BranchUnsignedLessEqual(Register rd, int32_t value, Label* l) { |
| - LoadImmediate(CMPRES, value); |
| - BranchUnsignedGreaterEqual(CMPRES, rd, l); |
| + ASSERT(rd != CMPRES2); |
| + LoadImmediate(CMPRES2, value); |
| + BranchUnsignedGreaterEqual(CMPRES2, rd, l); |
| } |
| void Push(Register rt) { |
| @@ -1029,6 +1039,19 @@ |
| lwc1(hi, Address(base, offset + kWordSize)); |
| } |
| + // dest gets the address of the following instruction. If preserve ra is true |
| + // RA is preserved using CMPRES1 as a temporary. |
| + void GetNextPC(Register dest, bool preserve_ra) { |
|
regis
2013/07/26 22:30:38
The caller does not see that CMPRES1 is trashed. I
zra
2013/07/26 23:29:03
Done.
|
| + if (preserve_ra) { |
| + mov(CMPRES1, RA); |
| + } |
| + EmitRegImmType(REGIMM, R0, BGEZAL, 1); |
| + mov(dest, RA); |
| + if (preserve_ra) { |
| + mov(RA, CMPRES1); |
| + } |
| + } |
| + |
| void ReserveAlignedFrameSpace(intptr_t frame_space); |
| // Create a frame for calling into runtime that preserves all volatile |
| @@ -1182,61 +1205,15 @@ |
| func << kCop1FnShift); |
| } |
| - void EmitBranch(Opcode b, Register rs, Register rt, Label* label) { |
| - if (label->IsBound()) { |
| - // Relative destination from an instruction after the branch. |
| - const int32_t dest = |
| - label->Position() - (buffer_.Size() + Instr::kInstrSize); |
| - const uint16_t dest_off = EncodeBranchOffset(dest, 0); |
| - EmitIType(b, rs, rt, dest_off); |
| - } else { |
| - const int position = buffer_.Size(); |
| - const uint16_t dest_off = EncodeBranchOffset(label->position_, 0); |
| - EmitIType(b, rs, rt, dest_off); |
| - label->LinkTo(position); |
| - } |
| - } |
| - void EmitRegImmBranch(RtRegImm b, Register rs, Label* label) { |
| - if (label->IsBound()) { |
| - // Relative destination from an instruction after the branch. |
| - const int32_t dest = |
| - label->Position() - (buffer_.Size() + Instr::kInstrSize); |
| - const uint16_t dest_off = EncodeBranchOffset(dest, 0); |
| - EmitRegImmType(REGIMM, rs, b, dest_off); |
| - } else { |
| - const int position = buffer_.Size(); |
| - const uint16_t dest_off = EncodeBranchOffset(label->position_, 0); |
| - EmitRegImmType(REGIMM, rs, b, dest_off); |
| - label->LinkTo(position); |
| - } |
| - } |
| + void EmitFarJump(int32_t offset, bool link); |
| + void EmitFarBranch(Opcode b, Register rs, Register rt, int32_t offset); |
| + void EmitFarRegImmBranch(RtRegImm b, Register rs, int32_t offset); |
| + void EmitFarFpuBranch(bool kind, int32_t offset); |
| + void EmitBranch(Opcode b, Register rs, Register rt, Label* label); |
| + void EmitRegImmBranch(RtRegImm b, Register rs, Label* label); |
| + void EmitFpuBranch(bool kind, Label *label); |
| - void EmitFpuBranch(bool kind, Label *label) { |
| - const int32_t b16 = kind ? (1 << 16) : 0; // Bit 16 set for branch on true. |
| - if (label->IsBound()) { |
| - // Relative destination from an instruction after the branch. |
| - const int32_t dest = |
| - label->Position() - (buffer_.Size() + Instr::kInstrSize); |
| - const uint16_t dest_off = EncodeBranchOffset(dest, 0); |
| - Emit(COP1 << kOpcodeShift | |
| - COP1_BC << kCop1SubShift | |
| - b16 | |
| - dest_off); |
| - } else { |
| - const int position = buffer_.Size(); |
| - const uint16_t dest_off = EncodeBranchOffset(label->position_, 0); |
| - Emit(COP1 << kOpcodeShift | |
| - COP1_BC << kCop1SubShift | |
| - b16 | |
| - dest_off); |
| - label->LinkTo(position); |
| - } |
| - } |
| - |
| - static int32_t EncodeBranchOffset(int32_t offset, int32_t instr); |
| - static int DecodeBranchOffset(int32_t instr); |
| - |
| void EmitBranchDelayNop() { |
| Emit(Instr::kNopInstruction); // Branch delay NOP. |
| delay_slot_available_ = true; |