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