From 96b6682d2d65f94c262590ef88bafdc70171ab8c Mon Sep 17 00:00:00 2001 From: Alexey Frunze Date: Sat, 10 Sep 2016 02:32:44 -0700 Subject: MIPS32: Implement table-based packed switch Test: booted MIPS32R2 in QEMU Test: test-art-target-run-test-optimizing (MIPS32R2) on CI20 Test: booted MIPS64 (with 2nd arch MIPS32R6) in QEMU Test: test-art-target-run-test-optimizing (MIPS32R6) in QEMU Test: test-art-host-gtest Change-Id: I2e1a65ff1ba9406b84351ba7998f853b1ce4aef9 --- compiler/utils/mips/assembler_mips.h | 65 ++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'compiler/utils/mips/assembler_mips.h') diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h index d50c439418..099620ccb8 100644 --- a/compiler/utils/mips/assembler_mips.h +++ b/compiler/utils/mips/assembler_mips.h @@ -126,6 +126,36 @@ class Literal { DISALLOW_COPY_AND_ASSIGN(Literal); }; +// Jump table: table of labels emitted after the literals. Similar to literals. +class JumpTable { + public: + explicit JumpTable(std::vector&& labels) + : label_(), labels_(std::move(labels)) { + } + + uint32_t GetSize() const { + return static_cast(labels_.size()) * sizeof(uint32_t); + } + + const std::vector& GetData() const { + return labels_; + } + + MipsLabel* GetLabel() { + return &label_; + } + + const MipsLabel* GetLabel() const { + return &label_; + } + + private: + MipsLabel label_; + std::vector labels_; + + DISALLOW_COPY_AND_ASSIGN(JumpTable); +}; + // Slowpath entered when Thread::Current()->_exception is non-null. class MipsExceptionSlowPath { public: @@ -158,6 +188,7 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssemblerAdapter(kArenaAllocAssembler)), + jump_tables_(arena->Adapter(kArenaAllocAssembler)), last_position_adjustment_(0), last_old_position_(0), last_branch_id_(0), @@ -685,6 +716,11 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler(&value)); } + // Load label address using the base register (for R2 only) or using PC-relative loads + // (for R6 only; base_reg must be ZERO). To be used with data labels in the literal / + // jump table area only and not with regular code labels. + void LoadLabelAddress(Register dest_reg, Register base_reg, MipsLabel* label); + // Create a new literal with the given data. Literal* NewLiteral(size_t size, const uint8_t* data); @@ -692,6 +728,12 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler&& labels); + // // Overridden common assembler high-level functionality. // @@ -935,24 +977,32 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler literals_; + // Jump table list. + ArenaDeque jump_tables_; + // There's no PC-relative addressing on MIPS32R2. So, in order to access literals relative to PC // we get PC using the NAL instruction. This label marks the position within the assembler buffer // that PC (from NAL) points to. -- cgit v1.2.3-59-g8ed1b