code_generator_arm64.h revision 840e5461a85f8908f51e7f6cd562a9129ff0e7ce
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" 225319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "nodes.h" 235319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "parallel_move_resolver.h" 245319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "utils/arm64/assembler_arm64.h" 255319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "a64/disasm-a64.h" 265319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "a64/macro-assembler-a64.h" 275319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "arch/arm64/quick_method_frame_info_arm64.h" 285319defdf502fc4569316473846b83180ec08035Alexandre Rames 295319defdf502fc4569316473846b83180ec08035Alexandre Ramesnamespace art { 305319defdf502fc4569316473846b83180ec08035Alexandre Ramesnamespace arm64 { 315319defdf502fc4569316473846b83180ec08035Alexandre Rames 325319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass CodeGeneratorARM64; 3367555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Ramesclass SlowPathCodeARM64; 345319defdf502fc4569316473846b83180ec08035Alexandre Rames 3586a8d7afc7f00ff0f5ea7b8aaf4d50514250a4e6Nicolas Geoffray// Use a local definition to prevent copying mistakes. 3686a8d7afc7f00ff0f5ea7b8aaf4d50514250a4e6Nicolas Geoffraystatic constexpr size_t kArm64WordSize = kArm64PointerSize; 3786a8d7afc7f00ff0f5ea7b8aaf4d50514250a4e6Nicolas Geoffray 385319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic const vixl::Register kParameterCoreRegisters[] = { 395319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::x1, vixl::x2, vixl::x3, vixl::x4, vixl::x5, vixl::x6, vixl::x7 405319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 415319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 425319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic const vixl::FPRegister kParameterFPRegisters[] = { 435319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::d0, vixl::d1, vixl::d2, vixl::d3, vixl::d4, vixl::d5, vixl::d6, vixl::d7 445319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 455319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic constexpr size_t kParameterFPRegistersLength = arraysize(kParameterFPRegisters); 465319defdf502fc4569316473846b83180ec08035Alexandre Rames 475319defdf502fc4569316473846b83180ec08035Alexandre Ramesconst vixl::Register tr = vixl::x18; // Thread Register 485319defdf502fc4569316473846b83180ec08035Alexandre Rames 495319defdf502fc4569316473846b83180ec08035Alexandre Ramesconst vixl::CPURegList vixl_reserved_core_registers(vixl::ip0, vixl::ip1); 50a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Ramesconst vixl::CPURegList vixl_reserved_fp_registers(vixl::d31); 5102164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescuconst vixl::CPURegList runtime_reserved_core_registers(tr, vixl::lr); 525b4b898ed8725242ee6b7229b94467c3ea3054c8Nicolas Geoffrayconst vixl::CPURegList quick_callee_saved_registers(vixl::CPURegister::kRegister, 535b4b898ed8725242ee6b7229b94467c3ea3054c8Nicolas Geoffray vixl::kXRegSize, 545b4b898ed8725242ee6b7229b94467c3ea3054c8Nicolas Geoffray kArm64CalleeSaveRefSpills); 555319defdf502fc4569316473846b83180ec08035Alexandre Rames 56a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre RamesLocation ARM64ReturnLocation(Primitive::Type return_type); 57a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames 585319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass InvokeDexCallingConvention : public CallingConvention<vixl::Register, vixl::FPRegister> { 595319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 605319defdf502fc4569316473846b83180ec08035Alexandre Rames InvokeDexCallingConvention() 615319defdf502fc4569316473846b83180ec08035Alexandre Rames : CallingConvention(kParameterCoreRegisters, 625319defdf502fc4569316473846b83180ec08035Alexandre Rames kParameterCoreRegistersLength, 635319defdf502fc4569316473846b83180ec08035Alexandre Rames kParameterFPRegisters, 645319defdf502fc4569316473846b83180ec08035Alexandre Rames kParameterFPRegistersLength) {} 655319defdf502fc4569316473846b83180ec08035Alexandre Rames 665319defdf502fc4569316473846b83180ec08035Alexandre Rames Location GetReturnLocation(Primitive::Type return_type) { 67a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames return ARM64ReturnLocation(return_type); 685319defdf502fc4569316473846b83180ec08035Alexandre Rames } 695319defdf502fc4569316473846b83180ec08035Alexandre Rames 705319defdf502fc4569316473846b83180ec08035Alexandre Rames 715319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 725319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); 735319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 745319defdf502fc4569316473846b83180ec08035Alexandre Rames 755319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass InvokeDexCallingConventionVisitor { 765319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 77a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames InvokeDexCallingConventionVisitor() : gp_index_(0), fp_index_(0), stack_index_(0) {} 785319defdf502fc4569316473846b83180ec08035Alexandre Rames 795319defdf502fc4569316473846b83180ec08035Alexandre Rames Location GetNextLocation(Primitive::Type type); 805319defdf502fc4569316473846b83180ec08035Alexandre Rames Location GetReturnLocation(Primitive::Type return_type) { 815319defdf502fc4569316473846b83180ec08035Alexandre Rames return calling_convention.GetReturnLocation(return_type); 825319defdf502fc4569316473846b83180ec08035Alexandre Rames } 835319defdf502fc4569316473846b83180ec08035Alexandre Rames 845319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 855319defdf502fc4569316473846b83180ec08035Alexandre Rames InvokeDexCallingConvention calling_convention; 865319defdf502fc4569316473846b83180ec08035Alexandre Rames // The current index for core registers. 875319defdf502fc4569316473846b83180ec08035Alexandre Rames uint32_t gp_index_; 88a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames // The current index for floating-point registers. 89a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames uint32_t fp_index_; 905319defdf502fc4569316473846b83180ec08035Alexandre Rames // The current stack index. 915319defdf502fc4569316473846b83180ec08035Alexandre Rames uint32_t stack_index_; 925319defdf502fc4569316473846b83180ec08035Alexandre Rames 935319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); 945319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 955319defdf502fc4569316473846b83180ec08035Alexandre Rames 965319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass InstructionCodeGeneratorARM64 : public HGraphVisitor { 975319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 985319defdf502fc4569316473846b83180ec08035Alexandre Rames InstructionCodeGeneratorARM64(HGraph* graph, CodeGeneratorARM64* codegen); 995319defdf502fc4569316473846b83180ec08035Alexandre Rames 1005319defdf502fc4569316473846b83180ec08035Alexandre Rames#define DECLARE_VISIT_INSTRUCTION(name, super) \ 101de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Visit##name(H##name* instr) OVERRIDE; 1025319defdf502fc4569316473846b83180ec08035Alexandre Rames FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 1035319defdf502fc4569316473846b83180ec08035Alexandre Rames#undef DECLARE_VISIT_INSTRUCTION 1045319defdf502fc4569316473846b83180ec08035Alexandre Rames 1055319defdf502fc4569316473846b83180ec08035Alexandre Rames void LoadCurrentMethod(XRegister reg); 1065319defdf502fc4569316473846b83180ec08035Alexandre Rames 1075319defdf502fc4569316473846b83180ec08035Alexandre Rames Arm64Assembler* GetAssembler() const { return assembler_; } 10867555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames vixl::MacroAssembler* GetVIXLAssembler() { return GetAssembler()->vixl_masm_; } 1095319defdf502fc4569316473846b83180ec08035Alexandre Rames 1105319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 11167555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void GenerateClassInitializationCheck(SlowPathCodeARM64* slow_path, vixl::Register class_reg); 11202d81cc8d162a31f0664249535456775e397b608Serban Constantinescu void GenerateMemoryBarrier(MemBarrierKind kind); 11302164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescu void GenerateSuspendCheck(HSuspendCheck* instruction, HBasicBlock* successor); 11467555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void HandleBinaryOp(HBinaryOperation* instr); 11502164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescu void HandleShift(HBinaryOperation* instr); 1165319defdf502fc4569316473846b83180ec08035Alexandre Rames 1175319defdf502fc4569316473846b83180ec08035Alexandre Rames Arm64Assembler* const assembler_; 1185319defdf502fc4569316473846b83180ec08035Alexandre Rames CodeGeneratorARM64* const codegen_; 1195319defdf502fc4569316473846b83180ec08035Alexandre Rames 1205319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorARM64); 1215319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 1225319defdf502fc4569316473846b83180ec08035Alexandre Rames 1235319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass LocationsBuilderARM64 : public HGraphVisitor { 1245319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 1255319defdf502fc4569316473846b83180ec08035Alexandre Rames explicit LocationsBuilderARM64(HGraph* graph, CodeGeneratorARM64* codegen) 1265319defdf502fc4569316473846b83180ec08035Alexandre Rames : HGraphVisitor(graph), codegen_(codegen) {} 1275319defdf502fc4569316473846b83180ec08035Alexandre Rames 1285319defdf502fc4569316473846b83180ec08035Alexandre Rames#define DECLARE_VISIT_INSTRUCTION(name, super) \ 129de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Visit##name(H##name* instr) OVERRIDE; 1305319defdf502fc4569316473846b83180ec08035Alexandre Rames FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 1315319defdf502fc4569316473846b83180ec08035Alexandre Rames#undef DECLARE_VISIT_INSTRUCTION 1325319defdf502fc4569316473846b83180ec08035Alexandre Rames 1335319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 13467555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void HandleBinaryOp(HBinaryOperation* instr); 13502164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescu void HandleShift(HBinaryOperation* instr); 1365319defdf502fc4569316473846b83180ec08035Alexandre Rames void HandleInvoke(HInvoke* instr); 1375319defdf502fc4569316473846b83180ec08035Alexandre Rames 1385319defdf502fc4569316473846b83180ec08035Alexandre Rames CodeGeneratorARM64* const codegen_; 1395319defdf502fc4569316473846b83180ec08035Alexandre Rames InvokeDexCallingConventionVisitor parameter_visitor_; 1405319defdf502fc4569316473846b83180ec08035Alexandre Rames 1415319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(LocationsBuilderARM64); 1425319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 1435319defdf502fc4569316473846b83180ec08035Alexandre Rames 1443e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Ramesclass ParallelMoveResolverARM64 : public ParallelMoveResolver { 1453e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames public: 1463e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames ParallelMoveResolverARM64(ArenaAllocator* allocator, CodeGeneratorARM64* codegen) 1473e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames : ParallelMoveResolver(allocator), codegen_(codegen) {} 1483e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1493e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void EmitMove(size_t index) OVERRIDE; 1503e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void EmitSwap(size_t index) OVERRIDE; 1513e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void RestoreScratch(int reg) OVERRIDE; 1523e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void SpillScratch(int reg) OVERRIDE; 1533e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1543e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames private: 1553e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames Arm64Assembler* GetAssembler() const; 1563e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames vixl::MacroAssembler* GetVIXLAssembler() const { 1573e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames return GetAssembler()->vixl_masm_; 1583e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames } 1593e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1603e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames CodeGeneratorARM64* const codegen_; 1613e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1623e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverARM64); 1633e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames}; 1643e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 1655319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass CodeGeneratorARM64 : public CodeGenerator { 1665319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 1675319defdf502fc4569316473846b83180ec08035Alexandre Rames explicit CodeGeneratorARM64(HGraph* graph); 168de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray virtual ~CodeGeneratorARM64() {} 1695319defdf502fc4569316473846b83180ec08035Alexandre Rames 170de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void GenerateFrameEntry() OVERRIDE; 171de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void GenerateFrameExit() OVERRIDE; 1725319defdf502fc4569316473846b83180ec08035Alexandre Rames 1735319defdf502fc4569316473846b83180ec08035Alexandre Rames static const vixl::CPURegList& GetFramePreservedRegisters() { 1745319defdf502fc4569316473846b83180ec08035Alexandre Rames static const vixl::CPURegList frame_preserved_regs = 1755319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::CPURegList(vixl::CPURegister::kRegister, vixl::kXRegSize, vixl::lr.Bit()); 1765319defdf502fc4569316473846b83180ec08035Alexandre Rames return frame_preserved_regs; 1775319defdf502fc4569316473846b83180ec08035Alexandre Rames } 1785319defdf502fc4569316473846b83180ec08035Alexandre Rames static int GetFramePreservedRegistersSize() { 1795319defdf502fc4569316473846b83180ec08035Alexandre Rames return GetFramePreservedRegisters().TotalSizeInBytes(); 1805319defdf502fc4569316473846b83180ec08035Alexandre Rames } 1815319defdf502fc4569316473846b83180ec08035Alexandre Rames 182de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Bind(HBasicBlock* block) OVERRIDE; 1835319defdf502fc4569316473846b83180ec08035Alexandre Rames 1845319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::Label* GetLabelOf(HBasicBlock* block) const { 1855319defdf502fc4569316473846b83180ec08035Alexandre Rames return block_labels_ + block->GetBlockId(); 1865319defdf502fc4569316473846b83180ec08035Alexandre Rames } 1875319defdf502fc4569316473846b83180ec08035Alexandre Rames 188de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE; 1895319defdf502fc4569316473846b83180ec08035Alexandre Rames 190de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray size_t GetWordSize() const OVERRIDE { 1915319defdf502fc4569316473846b83180ec08035Alexandre Rames return kArm64WordSize; 1925319defdf502fc4569316473846b83180ec08035Alexandre Rames } 1935319defdf502fc4569316473846b83180ec08035Alexandre Rames 19467555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE { 19567555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames vixl::Label* block_entry_label = GetLabelOf(block); 19667555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames DCHECK(block_entry_label->IsBound()); 19767555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames return block_entry_label->location(); 198de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray } 199de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray 200de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray size_t FrameEntrySpillSize() const OVERRIDE; 2015319defdf502fc4569316473846b83180ec08035Alexandre Rames 202de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray HGraphVisitor* GetLocationBuilder() OVERRIDE { return &location_builder_; } 203de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray HGraphVisitor* GetInstructionVisitor() OVERRIDE { return &instruction_visitor_; } 204de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray Arm64Assembler* GetAssembler() OVERRIDE { return &assembler_; } 20567555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames vixl::MacroAssembler* GetVIXLAssembler() { return GetAssembler()->vixl_masm_; } 2065319defdf502fc4569316473846b83180ec08035Alexandre Rames 2075319defdf502fc4569316473846b83180ec08035Alexandre Rames // Emit a write barrier. 2085319defdf502fc4569316473846b83180ec08035Alexandre Rames void MarkGCCard(vixl::Register object, vixl::Register value); 2095319defdf502fc4569316473846b83180ec08035Alexandre Rames 2105319defdf502fc4569316473846b83180ec08035Alexandre Rames // Register allocation. 2115319defdf502fc4569316473846b83180ec08035Alexandre Rames 212de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void SetupBlockedRegisters() const OVERRIDE; 2135319defdf502fc4569316473846b83180ec08035Alexandre Rames // AllocateFreeRegister() is only used when allocating registers locally 2145319defdf502fc4569316473846b83180ec08035Alexandre Rames // during CompileBaseline(). 215de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE; 2165319defdf502fc4569316473846b83180ec08035Alexandre Rames 217de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray Location GetStackLocation(HLoadLocal* load) const OVERRIDE; 2185319defdf502fc4569316473846b83180ec08035Alexandre Rames 2193e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id); 2203e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id); 2213e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id); 2223e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id); 2235319defdf502fc4569316473846b83180ec08035Alexandre Rames 2245319defdf502fc4569316473846b83180ec08035Alexandre Rames // The number of registers that can be allocated. The register allocator may 2255319defdf502fc4569316473846b83180ec08035Alexandre Rames // decide to reserve and not use a few of them. 2265319defdf502fc4569316473846b83180ec08035Alexandre Rames // We do not consider registers sp, xzr, wzr. They are either not allocatable 2275319defdf502fc4569316473846b83180ec08035Alexandre Rames // (xzr, wzr), or make for poor allocatable registers (sp alignment 2285319defdf502fc4569316473846b83180ec08035Alexandre Rames // requirements, etc.). This also facilitates our task as all other registers 2295319defdf502fc4569316473846b83180ec08035Alexandre Rames // can easily be mapped via to or from their type and index or code. 230a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames static const int kNumberOfAllocatableRegisters = vixl::kNumberOfRegisters - 1; 231a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames static const int kNumberOfAllocatableFPRegisters = vixl::kNumberOfFPRegisters; 2325319defdf502fc4569316473846b83180ec08035Alexandre Rames static constexpr int kNumberOfAllocatableRegisterPairs = 0; 2335319defdf502fc4569316473846b83180ec08035Alexandre Rames 234de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; 235de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; 2365319defdf502fc4569316473846b83180ec08035Alexandre Rames 237de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray InstructionSet GetInstructionSet() const OVERRIDE { 2385319defdf502fc4569316473846b83180ec08035Alexandre Rames return InstructionSet::kArm64; 2395319defdf502fc4569316473846b83180ec08035Alexandre Rames } 2405319defdf502fc4569316473846b83180ec08035Alexandre Rames 241de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Initialize() OVERRIDE { 2425319defdf502fc4569316473846b83180ec08035Alexandre Rames HGraph* graph = GetGraph(); 2435319defdf502fc4569316473846b83180ec08035Alexandre Rames int length = graph->GetBlocks().Size(); 2445319defdf502fc4569316473846b83180ec08035Alexandre Rames block_labels_ = graph->GetArena()->AllocArray<vixl::Label>(length); 2455319defdf502fc4569316473846b83180ec08035Alexandre Rames for (int i = 0; i < length; ++i) { 2465319defdf502fc4569316473846b83180ec08035Alexandre Rames new(block_labels_ + i) vixl::Label(); 2475319defdf502fc4569316473846b83180ec08035Alexandre Rames } 2485319defdf502fc4569316473846b83180ec08035Alexandre Rames } 2495319defdf502fc4569316473846b83180ec08035Alexandre Rames 25032f5b4d2c8c9b52e9522941c159577b21752d0faSerban Constantinescu void Finalize(CodeAllocator* allocator) OVERRIDE; 25132f5b4d2c8c9b52e9522941c159577b21752d0faSerban Constantinescu 252fc19de8b201475231751b9df08fce01a093e5c2bAlexandre Rames // Code generation helpers. 25367555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void MoveConstant(vixl::CPURegister destination, HConstant* constant); 2543e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames // The type is optional. When specified it must be coherent with the 2553e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames // locations, and is used for optimisation and debugging. 2563e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void MoveLocation(Location destination, Location source, 2573e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames Primitive::Type type = Primitive::kPrimVoid); 2583e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void SwapLocations(Location loc_1, Location loc_2); 25967555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void Load(Primitive::Type type, vixl::CPURegister dst, const vixl::MemOperand& src); 26067555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void Store(Primitive::Type type, vixl::CPURegister rt, const vixl::MemOperand& dst); 26167555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void LoadCurrentMethod(vixl::Register current_method); 26202d81cc8d162a31f0664249535456775e397b608Serban Constantinescu void LoadAcquire(Primitive::Type type, vixl::CPURegister dst, const vixl::MemOperand& src); 26302d81cc8d162a31f0664249535456775e397b608Serban Constantinescu void StoreRelease(Primitive::Type type, vixl::CPURegister rt, const vixl::MemOperand& dst); 26467555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames 26567555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames // Generate code to invoke a runtime entry point. 26667555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void InvokeRuntime(int32_t offset, HInstruction* instruction, uint32_t dex_pc); 267fc19de8b201475231751b9df08fce01a093e5c2bAlexandre Rames 2683e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames ParallelMoveResolverARM64* GetMoveResolver() { return &move_resolver_; } 269f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray 270840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { 271840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray return false; 272840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray } 273840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray 2745319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 2755319defdf502fc4569316473846b83180ec08035Alexandre Rames // Labels for each block that will be compiled. 2765319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::Label* block_labels_; 2775319defdf502fc4569316473846b83180ec08035Alexandre Rames 2785319defdf502fc4569316473846b83180ec08035Alexandre Rames LocationsBuilderARM64 location_builder_; 2795319defdf502fc4569316473846b83180ec08035Alexandre Rames InstructionCodeGeneratorARM64 instruction_visitor_; 2803e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames ParallelMoveResolverARM64 move_resolver_; 2815319defdf502fc4569316473846b83180ec08035Alexandre Rames Arm64Assembler assembler_; 2825319defdf502fc4569316473846b83180ec08035Alexandre Rames 2835319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM64); 2845319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 2855319defdf502fc4569316473846b83180ec08035Alexandre Rames 2863e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Ramesinline Arm64Assembler* ParallelMoveResolverARM64::GetAssembler() const { 2873e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames return codegen_->GetAssembler(); 2883e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames} 2893e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 2905319defdf502fc4569316473846b83180ec08035Alexandre Rames} // namespace arm64 2915319defdf502fc4569316473846b83180ec08035Alexandre Rames} // namespace art 2925319defdf502fc4569316473846b83180ec08035Alexandre Rames 2935319defdf502fc4569316473846b83180ec08035Alexandre Rames#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM64_H_ 294