code_generator_arm64.h revision 77520bca97ec44e3758510cebd0f20e3bb4584ea
15319defdf502fc4569316473846b83180ec08035Alexandre Rames/* 25319defdf502fc4569316473846b83180ec08035Alexandre Rames * Copyright (C) 2014 The Android Open Source Project 35319defdf502fc4569316473846b83180ec08035Alexandre Rames * 45319defdf502fc4569316473846b83180ec08035Alexandre Rames * Licensed under the Apache License, Version 2.0 (the "License"); 55319defdf502fc4569316473846b83180ec08035Alexandre Rames * you may not use this file except in compliance with the License. 65319defdf502fc4569316473846b83180ec08035Alexandre Rames * You may obtain a copy of the License at 75319defdf502fc4569316473846b83180ec08035Alexandre Rames * 85319defdf502fc4569316473846b83180ec08035Alexandre Rames * http://www.apache.org/licenses/LICENSE-2.0 95319defdf502fc4569316473846b83180ec08035Alexandre Rames * 105319defdf502fc4569316473846b83180ec08035Alexandre Rames * Unless required by applicable law or agreed to in writing, software 115319defdf502fc4569316473846b83180ec08035Alexandre Rames * distributed under the License is distributed on an "AS IS" BASIS, 125319defdf502fc4569316473846b83180ec08035Alexandre Rames * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135319defdf502fc4569316473846b83180ec08035Alexandre Rames * See the License for the specific language governing permissions and 145319defdf502fc4569316473846b83180ec08035Alexandre Rames * limitations under the License. 155319defdf502fc4569316473846b83180ec08035Alexandre Rames */ 165319defdf502fc4569316473846b83180ec08035Alexandre Rames 175319defdf502fc4569316473846b83180ec08035Alexandre Rames#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM64_H_ 185319defdf502fc4569316473846b83180ec08035Alexandre Rames#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM64_H_ 195319defdf502fc4569316473846b83180ec08035Alexandre Rames 205319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "code_generator.h" 2102d81cc8d162a31f0664249535456775e397b608Serban Constantinescu#include "dex/compiler_enums.h" 22cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle#include "driver/compiler_options.h" 235319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "nodes.h" 245319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "parallel_move_resolver.h" 255319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "utils/arm64/assembler_arm64.h" 265319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "a64/disasm-a64.h" 275319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "a64/macro-assembler-a64.h" 285319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "arch/arm64/quick_method_frame_info_arm64.h" 295319defdf502fc4569316473846b83180ec08035Alexandre Rames 305319defdf502fc4569316473846b83180ec08035Alexandre Ramesnamespace art { 315319defdf502fc4569316473846b83180ec08035Alexandre Ramesnamespace arm64 { 325319defdf502fc4569316473846b83180ec08035Alexandre Rames 335319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass CodeGeneratorARM64; 3467555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Ramesclass SlowPathCodeARM64; 355319defdf502fc4569316473846b83180ec08035Alexandre Rames 3686a8d7afc7f00ff0f5ea7b8aaf4d50514250a4e6Nicolas Geoffray// Use a local definition to prevent copying mistakes. 3786a8d7afc7f00ff0f5ea7b8aaf4d50514250a4e6Nicolas Geoffraystatic constexpr size_t kArm64WordSize = kArm64PointerSize; 3886a8d7afc7f00ff0f5ea7b8aaf4d50514250a4e6Nicolas Geoffray 395319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic const vixl::Register kParameterCoreRegisters[] = { 405319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::x1, vixl::x2, vixl::x3, vixl::x4, vixl::x5, vixl::x6, vixl::x7 415319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 425319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 435319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic const vixl::FPRegister kParameterFPRegisters[] = { 445319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::d0, vixl::d1, vixl::d2, vixl::d3, vixl::d4, vixl::d5, vixl::d6, vixl::d7 455319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 465319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic constexpr size_t kParameterFPRegistersLength = arraysize(kParameterFPRegisters); 475319defdf502fc4569316473846b83180ec08035Alexandre Rames 485319defdf502fc4569316473846b83180ec08035Alexandre Ramesconst vixl::Register tr = vixl::x18; // Thread Register 495319defdf502fc4569316473846b83180ec08035Alexandre Rames 505319defdf502fc4569316473846b83180ec08035Alexandre Ramesconst vixl::CPURegList vixl_reserved_core_registers(vixl::ip0, vixl::ip1); 51a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Ramesconst vixl::CPURegList vixl_reserved_fp_registers(vixl::d31); 5202164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescuconst vixl::CPURegList runtime_reserved_core_registers(tr, vixl::lr); 535b4b898ed8725242ee6b7229b94467c3ea3054c8Nicolas Geoffrayconst vixl::CPURegList quick_callee_saved_registers(vixl::CPURegister::kRegister, 545b4b898ed8725242ee6b7229b94467c3ea3054c8Nicolas Geoffray vixl::kXRegSize, 555b4b898ed8725242ee6b7229b94467c3ea3054c8Nicolas Geoffray kArm64CalleeSaveRefSpills); 565319defdf502fc4569316473846b83180ec08035Alexandre Rames 57a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre RamesLocation ARM64ReturnLocation(Primitive::Type return_type); 58a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames 595319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass InvokeDexCallingConvention : public CallingConvention<vixl::Register, vixl::FPRegister> { 605319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 615319defdf502fc4569316473846b83180ec08035Alexandre Rames InvokeDexCallingConvention() 625319defdf502fc4569316473846b83180ec08035Alexandre Rames : CallingConvention(kParameterCoreRegisters, 635319defdf502fc4569316473846b83180ec08035Alexandre Rames kParameterCoreRegistersLength, 645319defdf502fc4569316473846b83180ec08035Alexandre Rames kParameterFPRegisters, 655319defdf502fc4569316473846b83180ec08035Alexandre Rames kParameterFPRegistersLength) {} 665319defdf502fc4569316473846b83180ec08035Alexandre Rames 675319defdf502fc4569316473846b83180ec08035Alexandre Rames Location GetReturnLocation(Primitive::Type return_type) { 68a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames return ARM64ReturnLocation(return_type); 695319defdf502fc4569316473846b83180ec08035Alexandre Rames } 705319defdf502fc4569316473846b83180ec08035Alexandre Rames 715319defdf502fc4569316473846b83180ec08035Alexandre Rames 725319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 735319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); 745319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 755319defdf502fc4569316473846b83180ec08035Alexandre Rames 765319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass InvokeDexCallingConventionVisitor { 775319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 78a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames InvokeDexCallingConventionVisitor() : gp_index_(0), fp_index_(0), stack_index_(0) {} 795319defdf502fc4569316473846b83180ec08035Alexandre Rames 805319defdf502fc4569316473846b83180ec08035Alexandre Rames Location GetNextLocation(Primitive::Type type); 815319defdf502fc4569316473846b83180ec08035Alexandre Rames Location GetReturnLocation(Primitive::Type return_type) { 825319defdf502fc4569316473846b83180ec08035Alexandre Rames return calling_convention.GetReturnLocation(return_type); 835319defdf502fc4569316473846b83180ec08035Alexandre Rames } 845319defdf502fc4569316473846b83180ec08035Alexandre Rames 855319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 865319defdf502fc4569316473846b83180ec08035Alexandre Rames InvokeDexCallingConvention calling_convention; 875319defdf502fc4569316473846b83180ec08035Alexandre Rames // The current index for core registers. 885319defdf502fc4569316473846b83180ec08035Alexandre Rames uint32_t gp_index_; 89a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames // The current index for floating-point registers. 90a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames uint32_t fp_index_; 915319defdf502fc4569316473846b83180ec08035Alexandre Rames // The current stack index. 925319defdf502fc4569316473846b83180ec08035Alexandre Rames uint32_t stack_index_; 935319defdf502fc4569316473846b83180ec08035Alexandre Rames 945319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); 955319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 965319defdf502fc4569316473846b83180ec08035Alexandre Rames 975319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass InstructionCodeGeneratorARM64 : public HGraphVisitor { 985319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 995319defdf502fc4569316473846b83180ec08035Alexandre Rames InstructionCodeGeneratorARM64(HGraph* graph, CodeGeneratorARM64* codegen); 1005319defdf502fc4569316473846b83180ec08035Alexandre Rames 1015319defdf502fc4569316473846b83180ec08035Alexandre Rames#define DECLARE_VISIT_INSTRUCTION(name, super) \ 102de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Visit##name(H##name* instr) OVERRIDE; 1035319defdf502fc4569316473846b83180ec08035Alexandre Rames FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 1045319defdf502fc4569316473846b83180ec08035Alexandre Rames#undef DECLARE_VISIT_INSTRUCTION 1055319defdf502fc4569316473846b83180ec08035Alexandre Rames 1065319defdf502fc4569316473846b83180ec08035Alexandre Rames void LoadCurrentMethod(XRegister reg); 1075319defdf502fc4569316473846b83180ec08035Alexandre Rames 1085319defdf502fc4569316473846b83180ec08035Alexandre Rames Arm64Assembler* GetAssembler() const { return assembler_; } 10967555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames vixl::MacroAssembler* GetVIXLAssembler() { return GetAssembler()->vixl_masm_; } 1105319defdf502fc4569316473846b83180ec08035Alexandre Rames 1115319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 11267555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void GenerateClassInitializationCheck(SlowPathCodeARM64* slow_path, vixl::Register class_reg); 11302d81cc8d162a31f0664249535456775e397b608Serban Constantinescu void GenerateMemoryBarrier(MemBarrierKind kind); 11402164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescu void GenerateSuspendCheck(HSuspendCheck* instruction, HBasicBlock* successor); 11567555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void HandleBinaryOp(HBinaryOperation* instr); 11602164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescu void HandleShift(HBinaryOperation* instr); 117cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle void GenerateImplicitNullCheck(HNullCheck* instruction); 118cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle void GenerateExplicitNullCheck(HNullCheck* instruction); 1195319defdf502fc4569316473846b83180ec08035Alexandre Rames 1205319defdf502fc4569316473846b83180ec08035Alexandre Rames Arm64Assembler* const assembler_; 1215319defdf502fc4569316473846b83180ec08035Alexandre Rames CodeGeneratorARM64* const codegen_; 1225319defdf502fc4569316473846b83180ec08035Alexandre Rames 1235319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorARM64); 1245319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 1255319defdf502fc4569316473846b83180ec08035Alexandre Rames 1265319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass LocationsBuilderARM64 : public HGraphVisitor { 1275319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 1285319defdf502fc4569316473846b83180ec08035Alexandre Rames explicit LocationsBuilderARM64(HGraph* graph, CodeGeneratorARM64* codegen) 1295319defdf502fc4569316473846b83180ec08035Alexandre Rames : HGraphVisitor(graph), codegen_(codegen) {} 1305319defdf502fc4569316473846b83180ec08035Alexandre Rames 1315319defdf502fc4569316473846b83180ec08035Alexandre Rames#define DECLARE_VISIT_INSTRUCTION(name, super) \ 132de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Visit##name(H##name* instr) OVERRIDE; 1335319defdf502fc4569316473846b83180ec08035Alexandre Rames FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 1345319defdf502fc4569316473846b83180ec08035Alexandre Rames#undef DECLARE_VISIT_INSTRUCTION 1355319defdf502fc4569316473846b83180ec08035Alexandre Rames 1365319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 13767555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void HandleBinaryOp(HBinaryOperation* instr); 13802164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescu void HandleShift(HBinaryOperation* instr); 1395319defdf502fc4569316473846b83180ec08035Alexandre Rames void HandleInvoke(HInvoke* instr); 1405319defdf502fc4569316473846b83180ec08035Alexandre Rames 1415319defdf502fc4569316473846b83180ec08035Alexandre Rames CodeGeneratorARM64* const codegen_; 1425319defdf502fc4569316473846b83180ec08035Alexandre Rames InvokeDexCallingConventionVisitor parameter_visitor_; 1435319defdf502fc4569316473846b83180ec08035Alexandre Rames 1445319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(LocationsBuilderARM64); 1455319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 1465319defdf502fc4569316473846b83180ec08035Alexandre Rames 1473e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Ramesclass ParallelMoveResolverARM64 : public ParallelMoveResolver { 1483e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames public: 1493e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames ParallelMoveResolverARM64(ArenaAllocator* allocator, CodeGeneratorARM64* codegen) 1503e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames : ParallelMoveResolver(allocator), codegen_(codegen) {} 1513e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1523e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void EmitMove(size_t index) OVERRIDE; 1533e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void EmitSwap(size_t index) OVERRIDE; 1543e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void RestoreScratch(int reg) OVERRIDE; 1553e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void SpillScratch(int reg) OVERRIDE; 1563e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1573e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames private: 1583e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames Arm64Assembler* GetAssembler() const; 1593e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames vixl::MacroAssembler* GetVIXLAssembler() const { 1603e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames return GetAssembler()->vixl_masm_; 1613e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames } 1623e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1633e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames CodeGeneratorARM64* const codegen_; 1643e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1653e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverARM64); 1663e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames}; 1673e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1685319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass CodeGeneratorARM64 : public CodeGenerator { 1695319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 170cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle CodeGeneratorARM64(HGraph* graph, const CompilerOptions& compiler_options); 171de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray virtual ~CodeGeneratorARM64() {} 1725319defdf502fc4569316473846b83180ec08035Alexandre Rames 173de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void GenerateFrameEntry() OVERRIDE; 174de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void GenerateFrameExit() OVERRIDE; 1755319defdf502fc4569316473846b83180ec08035Alexandre Rames 1765319defdf502fc4569316473846b83180ec08035Alexandre Rames static const vixl::CPURegList& GetFramePreservedRegisters() { 1775319defdf502fc4569316473846b83180ec08035Alexandre Rames static const vixl::CPURegList frame_preserved_regs = 1785319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::CPURegList(vixl::CPURegister::kRegister, vixl::kXRegSize, vixl::lr.Bit()); 1795319defdf502fc4569316473846b83180ec08035Alexandre Rames return frame_preserved_regs; 1805319defdf502fc4569316473846b83180ec08035Alexandre Rames } 1815319defdf502fc4569316473846b83180ec08035Alexandre Rames static int GetFramePreservedRegistersSize() { 1825319defdf502fc4569316473846b83180ec08035Alexandre Rames return GetFramePreservedRegisters().TotalSizeInBytes(); 1835319defdf502fc4569316473846b83180ec08035Alexandre Rames } 1845319defdf502fc4569316473846b83180ec08035Alexandre Rames 185de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Bind(HBasicBlock* block) OVERRIDE; 1865319defdf502fc4569316473846b83180ec08035Alexandre Rames 1875319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::Label* GetLabelOf(HBasicBlock* block) const { 1885319defdf502fc4569316473846b83180ec08035Alexandre Rames return block_labels_ + block->GetBlockId(); 1895319defdf502fc4569316473846b83180ec08035Alexandre Rames } 1905319defdf502fc4569316473846b83180ec08035Alexandre Rames 191de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE; 1925319defdf502fc4569316473846b83180ec08035Alexandre Rames 193de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray size_t GetWordSize() const OVERRIDE { 1945319defdf502fc4569316473846b83180ec08035Alexandre Rames return kArm64WordSize; 1955319defdf502fc4569316473846b83180ec08035Alexandre Rames } 1965319defdf502fc4569316473846b83180ec08035Alexandre Rames 197f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell size_t GetFloatingPointSpillSlotSize() const OVERRIDE { 198f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell // Allocated in D registers, which are word sized. 199f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell return kArm64WordSize; 200f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell } 201f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell 20267555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE { 20367555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames vixl::Label* block_entry_label = GetLabelOf(block); 20467555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames DCHECK(block_entry_label->IsBound()); 20567555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames return block_entry_label->location(); 206de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray } 207de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray 208de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray size_t FrameEntrySpillSize() const OVERRIDE; 2095319defdf502fc4569316473846b83180ec08035Alexandre Rames 210de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray HGraphVisitor* GetLocationBuilder() OVERRIDE { return &location_builder_; } 211de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray HGraphVisitor* GetInstructionVisitor() OVERRIDE { return &instruction_visitor_; } 212de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray Arm64Assembler* GetAssembler() OVERRIDE { return &assembler_; } 21367555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames vixl::MacroAssembler* GetVIXLAssembler() { return GetAssembler()->vixl_masm_; } 2145319defdf502fc4569316473846b83180ec08035Alexandre Rames 2155319defdf502fc4569316473846b83180ec08035Alexandre Rames // Emit a write barrier. 2165319defdf502fc4569316473846b83180ec08035Alexandre Rames void MarkGCCard(vixl::Register object, vixl::Register value); 2175319defdf502fc4569316473846b83180ec08035Alexandre Rames 2185319defdf502fc4569316473846b83180ec08035Alexandre Rames // Register allocation. 2195319defdf502fc4569316473846b83180ec08035Alexandre Rames 220de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void SetupBlockedRegisters() const OVERRIDE; 2215319defdf502fc4569316473846b83180ec08035Alexandre Rames // AllocateFreeRegister() is only used when allocating registers locally 2225319defdf502fc4569316473846b83180ec08035Alexandre Rames // during CompileBaseline(). 223de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE; 2245319defdf502fc4569316473846b83180ec08035Alexandre Rames 225de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray Location GetStackLocation(HLoadLocal* load) const OVERRIDE; 2265319defdf502fc4569316473846b83180ec08035Alexandre Rames 2273e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id); 2283e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id); 2293e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id); 2303e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id); 2315319defdf502fc4569316473846b83180ec08035Alexandre Rames 2325319defdf502fc4569316473846b83180ec08035Alexandre Rames // The number of registers that can be allocated. The register allocator may 2335319defdf502fc4569316473846b83180ec08035Alexandre Rames // decide to reserve and not use a few of them. 2345319defdf502fc4569316473846b83180ec08035Alexandre Rames // We do not consider registers sp, xzr, wzr. They are either not allocatable 2355319defdf502fc4569316473846b83180ec08035Alexandre Rames // (xzr, wzr), or make for poor allocatable registers (sp alignment 2365319defdf502fc4569316473846b83180ec08035Alexandre Rames // requirements, etc.). This also facilitates our task as all other registers 2375319defdf502fc4569316473846b83180ec08035Alexandre Rames // can easily be mapped via to or from their type and index or code. 238a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames static const int kNumberOfAllocatableRegisters = vixl::kNumberOfRegisters - 1; 239a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames static const int kNumberOfAllocatableFPRegisters = vixl::kNumberOfFPRegisters; 2405319defdf502fc4569316473846b83180ec08035Alexandre Rames static constexpr int kNumberOfAllocatableRegisterPairs = 0; 2415319defdf502fc4569316473846b83180ec08035Alexandre Rames 242de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; 243de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; 2445319defdf502fc4569316473846b83180ec08035Alexandre Rames 245de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray InstructionSet GetInstructionSet() const OVERRIDE { 2465319defdf502fc4569316473846b83180ec08035Alexandre Rames return InstructionSet::kArm64; 2475319defdf502fc4569316473846b83180ec08035Alexandre Rames } 2485319defdf502fc4569316473846b83180ec08035Alexandre Rames 249de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Initialize() OVERRIDE { 2505319defdf502fc4569316473846b83180ec08035Alexandre Rames HGraph* graph = GetGraph(); 2515319defdf502fc4569316473846b83180ec08035Alexandre Rames int length = graph->GetBlocks().Size(); 2525319defdf502fc4569316473846b83180ec08035Alexandre Rames block_labels_ = graph->GetArena()->AllocArray<vixl::Label>(length); 2535319defdf502fc4569316473846b83180ec08035Alexandre Rames for (int i = 0; i < length; ++i) { 2545319defdf502fc4569316473846b83180ec08035Alexandre Rames new(block_labels_ + i) vixl::Label(); 2555319defdf502fc4569316473846b83180ec08035Alexandre Rames } 2565319defdf502fc4569316473846b83180ec08035Alexandre Rames } 2575319defdf502fc4569316473846b83180ec08035Alexandre Rames 25832f5b4d2c8c9b52e9522941c159577b21752d0faSerban Constantinescu void Finalize(CodeAllocator* allocator) OVERRIDE; 25932f5b4d2c8c9b52e9522941c159577b21752d0faSerban Constantinescu 260fc19de8b201475231751b9df08fce01a093e5c2bAlexandre Rames // Code generation helpers. 26167555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void MoveConstant(vixl::CPURegister destination, HConstant* constant); 2623e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames // The type is optional. When specified it must be coherent with the 2633e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames // locations, and is used for optimisation and debugging. 2643e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void MoveLocation(Location destination, Location source, 2653e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames Primitive::Type type = Primitive::kPrimVoid); 2663e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void SwapLocations(Location loc_1, Location loc_2); 26767555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void Load(Primitive::Type type, vixl::CPURegister dst, const vixl::MemOperand& src); 26867555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void Store(Primitive::Type type, vixl::CPURegister rt, const vixl::MemOperand& dst); 26967555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void LoadCurrentMethod(vixl::Register current_method); 27077520bca97ec44e3758510cebd0f20e3bb4584eaCalin Juravle void LoadAcquire(HInstruction* instruction, vixl::CPURegister dst, const vixl::MemOperand& src); 27102d81cc8d162a31f0664249535456775e397b608Serban Constantinescu void StoreRelease(Primitive::Type type, vixl::CPURegister rt, const vixl::MemOperand& dst); 27267555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames 27367555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames // Generate code to invoke a runtime entry point. 27467555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void InvokeRuntime(int32_t offset, HInstruction* instruction, uint32_t dex_pc); 275fc19de8b201475231751b9df08fce01a093e5c2bAlexandre Rames 2763e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames ParallelMoveResolverARM64* GetMoveResolver() { return &move_resolver_; } 277f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray 278840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { 279840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray return false; 280840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray } 281840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray 2825319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 2835319defdf502fc4569316473846b83180ec08035Alexandre Rames // Labels for each block that will be compiled. 2845319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::Label* block_labels_; 2855319defdf502fc4569316473846b83180ec08035Alexandre Rames 2865319defdf502fc4569316473846b83180ec08035Alexandre Rames LocationsBuilderARM64 location_builder_; 2875319defdf502fc4569316473846b83180ec08035Alexandre Rames InstructionCodeGeneratorARM64 instruction_visitor_; 2883e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames ParallelMoveResolverARM64 move_resolver_; 2895319defdf502fc4569316473846b83180ec08035Alexandre Rames Arm64Assembler assembler_; 2905319defdf502fc4569316473846b83180ec08035Alexandre Rames 2915319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM64); 2925319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 2935319defdf502fc4569316473846b83180ec08035Alexandre Rames 2943e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Ramesinline Arm64Assembler* ParallelMoveResolverARM64::GetAssembler() const { 2953e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames return codegen_->GetAssembler(); 2963e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames} 2973e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 2985319defdf502fc4569316473846b83180ec08035Alexandre Rames} // namespace arm64 2995319defdf502fc4569316473846b83180ec08035Alexandre Rames} // namespace art 3005319defdf502fc4569316473846b83180ec08035Alexandre Rames 3015319defdf502fc4569316473846b83180ec08035Alexandre Rames#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM64_H_ 302