From 19f6c696bbb7a17d8ac521b316c40f9cbef32151 Mon Sep 17 00:00:00 2001 From: Alexey Frunze Date: Wed, 30 Nov 2016 19:19:55 -0800 Subject: MIPS64: Improve method invocation. Improvements include: - support for all kinds of method loads and static/direct calls - 32-bit and 64-bit literals for the above and future work - shorter instruction sequences for recursive static/direct calls Also: - include the MIPS64 dinsu instruction (missed earlier) and minor clean-up in the disassembler - properly prefix constant names with 'k' in relative patcher tests Test: test-art-host-gtest Test: booted MIPS64 (with 2nd arch MIPS32R6) in QEMU Test: "make -j1 ART_TEST_DEFAULT_COMPILER=false ART_TEST_OPTIMIZING=true ART_TEST_INTERPRETER=false ART_TEST_JIT=false ART_TEST_PIC_TEST=true test-art-target-run-test64" Change-Id: I19876fa5316b68531af7dfddfce90d2068433116 --- compiler/utils/mips64/assembler_mips64.h | 126 ++++++++++++++++++++++++++----- 1 file changed, 108 insertions(+), 18 deletions(-) (limited to 'compiler/utils/mips64/assembler_mips64.h') diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index 238cb9d765..08a55ed41f 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -17,9 +17,11 @@ #ifndef ART_COMPILER_UTILS_MIPS64_ASSEMBLER_MIPS64_H_ #define ART_COMPILER_UTILS_MIPS64_ASSEMBLER_MIPS64_H_ +#include #include #include +#include "base/arena_containers.h" #include "base/enums.h" #include "base/macros.h" #include "constants_mips64.h" @@ -312,6 +314,49 @@ class Mips64Label : public Label { DISALLOW_COPY_AND_ASSIGN(Mips64Label); }; +// Assembler literal is a value embedded in code, retrieved using a PC-relative load. +class Literal { + public: + static constexpr size_t kMaxSize = 8; + + Literal(uint32_t size, const uint8_t* data) + : label_(), size_(size) { + DCHECK_LE(size, Literal::kMaxSize); + memcpy(data_, data, size); + } + + template + T GetValue() const { + DCHECK_EQ(size_, sizeof(T)); + T value; + memcpy(&value, data_, sizeof(T)); + return value; + } + + uint32_t GetSize() const { + return size_; + } + + const uint8_t* GetData() const { + return data_; + } + + Mips64Label* GetLabel() { + return &label_; + } + + const Mips64Label* GetLabel() const { + return &label_; + } + + private: + Mips64Label label_; + const uint32_t size_; + uint8_t data_[kMaxSize]; + + DISALLOW_COPY_AND_ASSIGN(Literal); +}; + // Slowpath entered when Thread::Current()->_exception is non-null. class Mips64ExceptionSlowPath { public: @@ -341,6 +386,8 @@ class Mips64Assembler FINAL : public Assembler, public JNIMacroAssemblerAdapter(kArenaAllocAssembler)), + long_literals_(arena->Adapter(kArenaAllocAssembler)), last_position_adjustment_(0), last_old_position_(0), last_branch_id_(0) { @@ -386,18 +433,18 @@ class Mips64Assembler FINAL : public Assembler, public JNIMacroAssembler + Literal* NewLiteral(typename Identity::type value) { + static_assert(std::is_integral::value, "T must be an integral type."); + return NewLiteral(sizeof(value), reinterpret_cast(&value)); + } + + // Load label address using PC-relative loads. To be used with data labels in the literal / + // jump table area only and not with regular code labels. + void LoadLabelAddress(GpuRegister dest_reg, Mips64Label* label); + + // Create a new literal with the given data. + Literal* NewLiteral(size_t size, const uint8_t* data); + + // Load literal using PC-relative loads. + void LoadLiteral(GpuRegister dest_reg, LoadOperandType load_type, Literal* literal); + void Bc(Mips64Label* label); - void Jialc(Mips64Label* label, GpuRegister indirect_reg); + void Balc(Mips64Label* label); void Bltc(GpuRegister rs, GpuRegister rt, Mips64Label* label); void Bltzc(GpuRegister rt, Mips64Label* label); void Bgtzc(GpuRegister rt, Mips64Label* label); @@ -756,12 +825,15 @@ class Mips64Assembler FINAL : public Assembler, public JNIMacroAssembler for literal labels to allow insertions at the end + // without invalidating pointers and references to existing elements. + ArenaDeque literals_; + ArenaDeque long_literals_; // 64-bit literals separated for alignment reasons. + // Data for AdjustedPosition(), see the description there. uint32_t last_position_adjustment_; uint32_t last_old_position_; -- cgit v1.2.3-59-g8ed1b