summaryrefslogtreecommitdiff
path: root/compiler/utils/mips/assembler_mips.h
diff options
context:
space:
mode:
author Alexey Frunze <Alexey.Frunze@imgtec.com> 2017-07-31 18:43:18 -0700
committer Alexey Frunze <Alexey.Frunze@imgtec.com> 2017-08-18 15:29:31 -0700
commita663d9d5b32a525794a2b98fa43da54dd7c79e3b (patch)
tree88c643ca5ebfb0dfe11f45a9b232f9a2592fb043 /compiler/utils/mips/assembler_mips.h
parentb9463674919ba91fe131e65785ad67b4202e86b9 (diff)
MIPS32: Allow some patched instructions in delay slots
Test: test-art-host-gtest Test: booted MIPS64 (with 2nd arch MIPS32R6) in QEMU Test: test-art-target-gtest32 Test: testrunner.py --target --optimizing --32 Test: same tests as above on CI20 Test: booted MIPS32R2 in QEMU Change-Id: I7e1ba59993008014d0115ae20c56e0a71fef0fb0
Diffstat (limited to 'compiler/utils/mips/assembler_mips.h')
-rw-r--r--compiler/utils/mips/assembler_mips.h31
1 files changed, 27 insertions, 4 deletions
diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h
index 7f9d5763f1..0f163ac83f 100644
--- a/compiler/utils/mips/assembler_mips.h
+++ b/compiler/utils/mips/assembler_mips.h
@@ -80,6 +80,12 @@ class MipsLabel : public Label {
MipsLabel(MipsLabel&& src)
: Label(std::move(src)), prev_branch_id_plus_one_(src.prev_branch_id_plus_one_) {}
+ void AdjustBoundPosition(int delta) {
+ CHECK(IsBound());
+ // Bound label's position is negative, hence decrementing it.
+ position_ -= delta;
+ }
+
private:
uint32_t prev_branch_id_plus_one_; // To get distance from preceding branch, if any.
@@ -215,6 +221,7 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi
// Emit Machine Instructions.
void Addu(Register rd, Register rs, Register rt);
+ void Addiu(Register rt, Register rs, uint16_t imm16, MipsLabel* patcher_label);
void Addiu(Register rt, Register rs, uint16_t imm16);
void Subu(Register rd, Register rs, Register rt);
@@ -272,6 +279,7 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi
void Lb(Register rt, Register rs, uint16_t imm16);
void Lh(Register rt, Register rs, uint16_t imm16);
+ void Lw(Register rt, Register rs, uint16_t imm16, MipsLabel* patcher_label);
void Lw(Register rt, Register rs, uint16_t imm16);
void Lwl(Register rt, Register rs, uint16_t imm16);
void Lwr(Register rt, Register rs, uint16_t imm16);
@@ -287,6 +295,7 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi
void Sb(Register rt, Register rs, uint16_t imm16);
void Sh(Register rt, Register rs, uint16_t imm16);
+ void Sw(Register rt, Register rs, uint16_t imm16, MipsLabel* patcher_label);
void Sw(Register rt, Register rs, uint16_t imm16);
void Swl(Register rt, Register rs, uint16_t imm16);
void Swr(Register rt, Register rs, uint16_t imm16);
@@ -1288,6 +1297,9 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi
uint32_t cc_ins_mask_;
// Branches never operate on the LO and HI registers, hence there's
// no mask for LO and HI.
+
+ // Label for patchable instructions to allow moving them into delay slots.
+ MipsLabel* patcher_label_;
};
// Delay slot finite state machine's (DS FSM's) state. The FSM state is updated
@@ -1440,8 +1452,9 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi
// Various helpers for branch delay slot management.
bool CanHaveDelayedInstruction(const DelaySlot& delay_slot) const;
- void SetDelayedInstruction(uint32_t instruction);
+ void SetDelayedInstruction(uint32_t instruction, MipsLabel* patcher_label = nullptr);
uint32_t GetDelayedInstruction() const;
+ MipsLabel* GetPatcherLabel() const;
void DecrementLocations();
// Returns the bit size of the signed offset that the branch instruction can handle.
@@ -1526,6 +1539,8 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi
// kUnfillableDelaySlot if none and unfillable
// (the latter is only used for unconditional R2
// branches).
+
+ MipsLabel* patcher_label_; // Patcher label for the instruction in the delay slot.
};
friend std::ostream& operator<<(std::ostream& os, const Branch::Type& rhs);
friend std::ostream& operator<<(std::ostream& os, const Branch::OffsetBits& rhs);
@@ -1580,9 +1595,14 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi
uint32_t fpr_outs_mask,
uint32_t fpr_ins_mask,
uint32_t cc_outs_mask,
- uint32_t cc_ins_mask);
+ uint32_t cc_ins_mask,
+ MipsLabel* patcher_label = nullptr);
void DsFsmInstrNop(uint32_t instruction);
- void DsFsmInstrRrr(uint32_t instruction, Register out, Register in1, Register in2);
+ void DsFsmInstrRrr(uint32_t instruction,
+ Register out,
+ Register in1,
+ Register in2,
+ MipsLabel* patcher_label = nullptr);
void DsFsmInstrRrrr(uint32_t instruction, Register in1_out, Register in2, Register in3);
void DsFsmInstrFff(uint32_t instruction, FRegister out, FRegister in1, FRegister in2);
void DsFsmInstrFfff(uint32_t instruction, FRegister in1_out, FRegister in2, FRegister in3);
@@ -1605,12 +1625,15 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi
const Branch* GetBranch(uint32_t branch_id) const;
uint32_t GetBranchLocationOrPcRelBase(const MipsAssembler::Branch* branch) const;
uint32_t GetBranchOrPcRelBaseForEncoding(const MipsAssembler::Branch* branch) const;
+ void BindRelativeToPrecedingBranch(MipsLabel* label,
+ uint32_t prev_branch_id_plus_one,
+ uint32_t position);
void EmitLiterals();
void ReserveJumpTableSpace();
void EmitJumpTables();
void PromoteBranches();
- void EmitBranch(Branch* branch);
+ void EmitBranch(uint32_t branch_id);
void EmitBranches();
void PatchCFI(size_t number_of_delayed_adjust_pcs);