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 20cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko#include "arch/arm64/quick_method_frame_info_arm64.h" 215319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "code_generator.h" 22e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle#include "common_arm64.h" 2302d81cc8d162a31f0664249535456775e397b608Serban Constantinescu#include "dex/compiler_enums.h" 24cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle#include "driver/compiler_options.h" 255319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "nodes.h" 265319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "parallel_move_resolver.h" 275319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "utils/arm64/assembler_arm64.h" 28cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko#include "utils/string_reference.h" 2982e52ce8364e3e1c644d0d3b3b4f61364bf7089aSerban Constantinescu#include "vixl/a64/disasm-a64.h" 3082e52ce8364e3e1c644d0d3b3b4f61364bf7089aSerban Constantinescu#include "vixl/a64/macro-assembler-a64.h" 315319defdf502fc4569316473846b83180ec08035Alexandre Rames 325319defdf502fc4569316473846b83180ec08035Alexandre Ramesnamespace art { 335319defdf502fc4569316473846b83180ec08035Alexandre Ramesnamespace arm64 { 345319defdf502fc4569316473846b83180ec08035Alexandre Rames 355319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass CodeGeneratorARM64; 36878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe 3786a8d7afc7f00ff0f5ea7b8aaf4d50514250a4e6Nicolas Geoffray// Use a local definition to prevent copying mistakes. 3886a8d7afc7f00ff0f5ea7b8aaf4d50514250a4e6Nicolas Geoffraystatic constexpr size_t kArm64WordSize = kArm64PointerSize; 3986a8d7afc7f00ff0f5ea7b8aaf4d50514250a4e6Nicolas Geoffray 405319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic const vixl::Register kParameterCoreRegisters[] = { 415319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::x1, vixl::x2, vixl::x3, vixl::x4, vixl::x5, vixl::x6, vixl::x7 425319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 435319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 445319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic const vixl::FPRegister kParameterFPRegisters[] = { 455319defdf502fc4569316473846b83180ec08035Alexandre Rames vixl::d0, vixl::d1, vixl::d2, vixl::d3, vixl::d4, vixl::d5, vixl::d6, vixl::d7 465319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 475319defdf502fc4569316473846b83180ec08035Alexandre Ramesstatic constexpr size_t kParameterFPRegistersLength = arraysize(kParameterFPRegisters); 485319defdf502fc4569316473846b83180ec08035Alexandre Rames 499bd88b0933a372e6a7b64b850868e6a7998567e2Serban Constantinescuconst vixl::Register tr = vixl::x19; // Thread Register 50e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierstatic const vixl::Register kArtMethodRegister = vixl::x0; // Method register on invoke. 515319defdf502fc4569316473846b83180ec08035Alexandre Rames 525319defdf502fc4569316473846b83180ec08035Alexandre Ramesconst vixl::CPURegList vixl_reserved_core_registers(vixl::ip0, vixl::ip1); 53a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Ramesconst vixl::CPURegList vixl_reserved_fp_registers(vixl::d31); 545319defdf502fc4569316473846b83180ec08035Alexandre Rames 5569a503050fb8a7b3a79b2cd2cdc2d8fbc594575dZheng Xuconst vixl::CPURegList runtime_reserved_core_registers(tr, vixl::lr); 563d087decd1886b818adcccd4f16802e5e54dd03eSerban Constantinescu 579bd88b0933a372e6a7b64b850868e6a7998567e2Serban Constantinescu// Callee-saved registers AAPCS64 (without x19 - Thread Register) 583d087decd1886b818adcccd4f16802e5e54dd03eSerban Constantinescuconst vixl::CPURegList callee_saved_core_registers(vixl::CPURegister::kRegister, 593d087decd1886b818adcccd4f16802e5e54dd03eSerban Constantinescu vixl::kXRegSize, 609bd88b0933a372e6a7b64b850868e6a7998567e2Serban Constantinescu vixl::x20.code(), 613d087decd1886b818adcccd4f16802e5e54dd03eSerban Constantinescu vixl::x30.code()); 623d087decd1886b818adcccd4f16802e5e54dd03eSerban Constantinescuconst vixl::CPURegList callee_saved_fp_registers(vixl::CPURegister::kFPRegister, 633d087decd1886b818adcccd4f16802e5e54dd03eSerban Constantinescu vixl::kDRegSize, 643d087decd1886b818adcccd4f16802e5e54dd03eSerban Constantinescu vixl::d8.code(), 653d087decd1886b818adcccd4f16802e5e54dd03eSerban Constantinescu vixl::d15.code()); 66a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre RamesLocation ARM64ReturnLocation(Primitive::Type return_type); 67a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames 68878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampeclass SlowPathCodeARM64 : public SlowPathCode { 69878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe public: 709cd6d378bd573cdc14d049d32bdd22a97fa4d84aDavid Srbecky explicit SlowPathCodeARM64(HInstruction* instruction) 719cd6d378bd573cdc14d049d32bdd22a97fa4d84aDavid Srbecky : SlowPathCode(instruction), entry_label_(), exit_label_() {} 72878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe 73878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe vixl::Label* GetEntryLabel() { return &entry_label_; } 74878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe vixl::Label* GetExitLabel() { return &exit_label_; } 75878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe 76da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu void SaveLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) OVERRIDE; 77da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu void RestoreLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) OVERRIDE; 78da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu 79878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe private: 80878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe vixl::Label entry_label_; 81878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe vixl::Label exit_label_; 82878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe 83878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe DISALLOW_COPY_AND_ASSIGN(SlowPathCodeARM64); 84878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe}; 85878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe 86c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Ramesclass JumpTableARM64 : public DeletableArenaObject<kArenaAllocSwitchTable> { 873927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu public: 883927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu explicit JumpTableARM64(HPackedSwitch* switch_instr) 893927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu : switch_instr_(switch_instr), table_start_() {} 903927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu 913927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu vixl::Label* GetTableStartLabel() { return &table_start_; } 923927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu 933927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu void EmitTable(CodeGeneratorARM64* codegen); 943927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu 953927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu private: 963927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu HPackedSwitch* const switch_instr_; 973927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu vixl::Label table_start_; 983927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu 993927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu DISALLOW_COPY_AND_ASSIGN(JumpTableARM64); 1003927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu}; 1013927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu 102d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffraystatic const vixl::Register kRuntimeParameterCoreRegisters[] = 103d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray { vixl::x0, vixl::x1, vixl::x2, vixl::x3, vixl::x4, vixl::x5, vixl::x6, vixl::x7 }; 104d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffraystatic constexpr size_t kRuntimeParameterCoreRegistersLength = 105d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray arraysize(kRuntimeParameterCoreRegisters); 106d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffraystatic const vixl::FPRegister kRuntimeParameterFpuRegisters[] = 107d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray { vixl::d0, vixl::d1, vixl::d2, vixl::d3, vixl::d4, vixl::d5, vixl::d6, vixl::d7 }; 108d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffraystatic constexpr size_t kRuntimeParameterFpuRegistersLength = 109d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray arraysize(kRuntimeParameterCoreRegisters); 110d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray 111d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffrayclass InvokeRuntimeCallingConvention : public CallingConvention<vixl::Register, vixl::FPRegister> { 112d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray public: 113d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 114d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray 115d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray InvokeRuntimeCallingConvention() 116d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray : CallingConvention(kRuntimeParameterCoreRegisters, 117d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray kRuntimeParameterCoreRegistersLength, 118d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray kRuntimeParameterFpuRegisters, 119e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier kRuntimeParameterFpuRegistersLength, 120e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier kArm64PointerSize) {} 121d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray 122d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray Location GetReturnLocation(Primitive::Type return_type); 123d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray 124d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray private: 125d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention); 126d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray}; 127d75948ac93a4a317feaf136cae78823071234ba5Nicolas Geoffray 1285319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass InvokeDexCallingConvention : public CallingConvention<vixl::Register, vixl::FPRegister> { 1295319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 1305319defdf502fc4569316473846b83180ec08035Alexandre Rames InvokeDexCallingConvention() 1315319defdf502fc4569316473846b83180ec08035Alexandre Rames : CallingConvention(kParameterCoreRegisters, 1325319defdf502fc4569316473846b83180ec08035Alexandre Rames kParameterCoreRegistersLength, 1335319defdf502fc4569316473846b83180ec08035Alexandre Rames kParameterFPRegisters, 134e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier kParameterFPRegistersLength, 135e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier kArm64PointerSize) {} 1365319defdf502fc4569316473846b83180ec08035Alexandre Rames 137fd88f16100cceafbfde1b4f095f17e89444d6fa8Nicolas Geoffray Location GetReturnLocation(Primitive::Type return_type) const { 138a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames return ARM64ReturnLocation(return_type); 1395319defdf502fc4569316473846b83180ec08035Alexandre Rames } 1405319defdf502fc4569316473846b83180ec08035Alexandre Rames 1415319defdf502fc4569316473846b83180ec08035Alexandre Rames 1425319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 1435319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); 1445319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 1455319defdf502fc4569316473846b83180ec08035Alexandre Rames 1462d27c8e338af7262dbd4aaa66127bb8fa1758b86Roland Levillainclass InvokeDexCallingConventionVisitorARM64 : public InvokeDexCallingConventionVisitor { 1475319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 1482d27c8e338af7262dbd4aaa66127bb8fa1758b86Roland Levillain InvokeDexCallingConventionVisitorARM64() {} 1492d27c8e338af7262dbd4aaa66127bb8fa1758b86Roland Levillain virtual ~InvokeDexCallingConventionVisitorARM64() {} 1505319defdf502fc4569316473846b83180ec08035Alexandre Rames 1512d27c8e338af7262dbd4aaa66127bb8fa1758b86Roland Levillain Location GetNextLocation(Primitive::Type type) OVERRIDE; 152fd88f16100cceafbfde1b4f095f17e89444d6fa8Nicolas Geoffray Location GetReturnLocation(Primitive::Type return_type) const OVERRIDE { 1535319defdf502fc4569316473846b83180ec08035Alexandre Rames return calling_convention.GetReturnLocation(return_type); 1545319defdf502fc4569316473846b83180ec08035Alexandre Rames } 155fd88f16100cceafbfde1b4f095f17e89444d6fa8Nicolas Geoffray Location GetMethodLocation() const OVERRIDE; 1565319defdf502fc4569316473846b83180ec08035Alexandre Rames 1575319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 1585319defdf502fc4569316473846b83180ec08035Alexandre Rames InvokeDexCallingConvention calling_convention; 1592d27c8e338af7262dbd4aaa66127bb8fa1758b86Roland Levillain 1602d27c8e338af7262dbd4aaa66127bb8fa1758b86Roland Levillain DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitorARM64); 1615319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 1625319defdf502fc4569316473846b83180ec08035Alexandre Rames 163e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravleclass FieldAccessCallingConventionARM64 : public FieldAccessCallingConvention { 164e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle public: 165e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle FieldAccessCallingConventionARM64() {} 166e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle 167e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle Location GetObjectLocation() const OVERRIDE { 168e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle return helpers::LocationFrom(vixl::x1); 169e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle } 170e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle Location GetFieldIndexLocation() const OVERRIDE { 171e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle return helpers::LocationFrom(vixl::x0); 172e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle } 173e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle Location GetReturnLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { 174e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle return helpers::LocationFrom(vixl::x0); 175e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle } 176e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE { 177e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle return Primitive::Is64BitType(type) 178e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle ? helpers::LocationFrom(vixl::x2) 179e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle : (is_instance 180e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle ? helpers::LocationFrom(vixl::x2) 181e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle : helpers::LocationFrom(vixl::x1)); 182e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle } 183e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle Location GetFpuLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { 184e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle return helpers::LocationFrom(vixl::d0); 185e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle } 186e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle 187e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle private: 188e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConventionARM64); 189e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle}; 190e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle 19142249c3602c3d0243396ee3627ffb5906aa77c1eAart Bikclass InstructionCodeGeneratorARM64 : public InstructionCodeGenerator { 1925319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 1935319defdf502fc4569316473846b83180ec08035Alexandre Rames InstructionCodeGeneratorARM64(HGraph* graph, CodeGeneratorARM64* codegen); 1945319defdf502fc4569316473846b83180ec08035Alexandre Rames 1955319defdf502fc4569316473846b83180ec08035Alexandre Rames#define DECLARE_VISIT_INSTRUCTION(name, super) \ 196de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Visit##name(H##name* instr) OVERRIDE; 197ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames 198ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION) 199ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames FOR_EACH_CONCRETE_INSTRUCTION_ARM64(DECLARE_VISIT_INSTRUCTION) 2004a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko FOR_EACH_CONCRETE_INSTRUCTION_SHARED(DECLARE_VISIT_INSTRUCTION) 201ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames 2025319defdf502fc4569316473846b83180ec08035Alexandre Rames#undef DECLARE_VISIT_INSTRUCTION 2035319defdf502fc4569316473846b83180ec08035Alexandre Rames 204ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames void VisitInstruction(HInstruction* instruction) OVERRIDE { 205ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames LOG(FATAL) << "Unreachable instruction " << instruction->DebugName() 206ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames << " (id " << instruction->GetId() << ")"; 207ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames } 208ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames 2095319defdf502fc4569316473846b83180ec08035Alexandre Rames Arm64Assembler* GetAssembler() const { return assembler_; } 21067555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames vixl::MacroAssembler* GetVIXLAssembler() { return GetAssembler()->vixl_masm_; } 2115319defdf502fc4569316473846b83180ec08035Alexandre Rames 2125319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 21367555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void GenerateClassInitializationCheck(SlowPathCodeARM64* slow_path, vixl::Register class_reg); 21402164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescu void GenerateSuspendCheck(HSuspendCheck* instruction, HBasicBlock* successor); 21567555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void HandleBinaryOp(HBinaryOperation* instr); 21644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain 21707276db28d654594e0e86e9e467cad393f752e6eNicolas Geoffray void HandleFieldSet(HInstruction* instruction, 21807276db28d654594e0e86e9e467cad393f752e6eNicolas Geoffray const FieldInfo& field_info, 21907276db28d654594e0e86e9e467cad393f752e6eNicolas Geoffray bool value_can_be_null); 22009a99965bb27649f5b1d373f76bfbec6a2500c9eAlexandre Rames void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info); 2215f7b58ea1adfc0639dd605b65f59198d3763f801Vladimir Marko void HandleCondition(HCondition* instruction); 22244015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain 22344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Generate a heap reference load using one register `out`: 22444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // 22544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // out <- *(out + offset) 22644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // 22744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // while honoring heap poisoning and/or read barriers (if any). 22844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // 22944015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Location `maybe_temp` is used when generating a read barrier and 23044015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // shall be a register in that case; it may be an invalid location 23144015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // otherwise. 23244015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void GenerateReferenceLoadOneRegister(HInstruction* instruction, 23344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location out, 23444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain uint32_t offset, 23544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location maybe_temp); 23644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Generate a heap reference load using two different registers 23744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // `out` and `obj`: 23844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // 23944015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // out <- *(obj + offset) 24044015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // 24144015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // while honoring heap poisoning and/or read barriers (if any). 24244015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // 24344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Location `maybe_temp` is used when generating a Baker's (fast 24444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // path) read barrier and shall be a register in that case; it may 24544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // be an invalid location otherwise. 24644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void GenerateReferenceLoadTwoRegisters(HInstruction* instruction, 24744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location out, 24844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location obj, 24944015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain uint32_t offset, 25044015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location maybe_temp); 25144015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Generate a GC root reference load: 25244015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // 25344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // root <- *(obj + offset) 25444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // 25544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // while honoring read barriers (if any). 25644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void GenerateGcRootFieldLoad(HInstruction* instruction, 25744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location root, 25844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain vixl::Register obj, 259cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t offset, 260cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Label* fixup_label = nullptr); 26144015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain 2621a65388f1d86bb232c2e44fecb44cebe13105d2eRoland Levillain // Generate a floating-point comparison. 2631a65388f1d86bb232c2e44fecb44cebe13105d2eRoland Levillain void GenerateFcmp(HInstruction* instruction); 2641a65388f1d86bb232c2e44fecb44cebe13105d2eRoland Levillain 26502164b352a1474c616771582ca9a73a2cc514c1fSerban Constantinescu void HandleShift(HBinaryOperation* instr); 266d43b3ac88cd46b8815890188c9c2b9a3f1564648Mingyao Yang void GenerateTestAndBranch(HInstruction* instruction, 2670debae7bc89eb05f7a2bf7dccd223318fad7c88dDavid Brazdil size_t condition_input_index, 268d43b3ac88cd46b8815890188c9c2b9a3f1564648Mingyao Yang vixl::Label* true_target, 2690debae7bc89eb05f7a2bf7dccd223318fad7c88dDavid Brazdil vixl::Label* false_target); 270c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu void DivRemOneOrMinusOne(HBinaryOperation* instruction); 271c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu void DivRemByPowerOfTwo(HBinaryOperation* instruction); 272c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction); 273c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu void GenerateDivRemIntegral(HBinaryOperation* instruction); 274fc6a86ab2b70781e72b807c1798b83829ca7f931David Brazdil void HandleGoto(HInstruction* got, HBasicBlock* successor); 2755319defdf502fc4569316473846b83180ec08035Alexandre Rames 2765319defdf502fc4569316473846b83180ec08035Alexandre Rames Arm64Assembler* const assembler_; 2775319defdf502fc4569316473846b83180ec08035Alexandre Rames CodeGeneratorARM64* const codegen_; 2785319defdf502fc4569316473846b83180ec08035Alexandre Rames 2795319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorARM64); 2805319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 2815319defdf502fc4569316473846b83180ec08035Alexandre Rames 2825319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass LocationsBuilderARM64 : public HGraphVisitor { 2835319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 2843887c468d731420e929e6ad3acf190d5431e94fcRoland Levillain LocationsBuilderARM64(HGraph* graph, CodeGeneratorARM64* codegen) 2855319defdf502fc4569316473846b83180ec08035Alexandre Rames : HGraphVisitor(graph), codegen_(codegen) {} 2865319defdf502fc4569316473846b83180ec08035Alexandre Rames 2875319defdf502fc4569316473846b83180ec08035Alexandre Rames#define DECLARE_VISIT_INSTRUCTION(name, super) \ 288de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Visit##name(H##name* instr) OVERRIDE; 289ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames 290ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION) 291ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames FOR_EACH_CONCRETE_INSTRUCTION_ARM64(DECLARE_VISIT_INSTRUCTION) 2924a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko FOR_EACH_CONCRETE_INSTRUCTION_SHARED(DECLARE_VISIT_INSTRUCTION) 293ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames 2945319defdf502fc4569316473846b83180ec08035Alexandre Rames#undef DECLARE_VISIT_INSTRUCTION 2955319defdf502fc4569316473846b83180ec08035Alexandre Rames 296ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames void VisitInstruction(HInstruction* instruction) OVERRIDE { 297ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames LOG(FATAL) << "Unreachable instruction " << instruction->DebugName() 298ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames << " (id " << instruction->GetId() << ")"; 299ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames } 300ef20f71e16f035a39a329c8524d7e59ca6a11f04Alexandre Rames 3015319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 30267555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void HandleBinaryOp(HBinaryOperation* instr); 30309a99965bb27649f5b1d373f76bfbec6a2500c9eAlexandre Rames void HandleFieldSet(HInstruction* instruction); 30409a99965bb27649f5b1d373f76bfbec6a2500c9eAlexandre Rames void HandleFieldGet(HInstruction* instruction); 3055319defdf502fc4569316473846b83180ec08035Alexandre Rames void HandleInvoke(HInvoke* instr); 3065f7b58ea1adfc0639dd605b65f59198d3763f801Vladimir Marko void HandleCondition(HCondition* instruction); 30709a99965bb27649f5b1d373f76bfbec6a2500c9eAlexandre Rames void HandleShift(HBinaryOperation* instr); 3085319defdf502fc4569316473846b83180ec08035Alexandre Rames 3095319defdf502fc4569316473846b83180ec08035Alexandre Rames CodeGeneratorARM64* const codegen_; 3102d27c8e338af7262dbd4aaa66127bb8fa1758b86Roland Levillain InvokeDexCallingConventionVisitorARM64 parameter_visitor_; 3115319defdf502fc4569316473846b83180ec08035Alexandre Rames 3125319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(LocationsBuilderARM64); 3135319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 3145319defdf502fc4569316473846b83180ec08035Alexandre Rames 315ad4450e5c3ffaa9566216cc6fafbf5c11186c467Zheng Xuclass ParallelMoveResolverARM64 : public ParallelMoveResolverNoSwap { 3163e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames public: 3173e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames ParallelMoveResolverARM64(ArenaAllocator* allocator, CodeGeneratorARM64* codegen) 318ad4450e5c3ffaa9566216cc6fafbf5c11186c467Zheng Xu : ParallelMoveResolverNoSwap(allocator), codegen_(codegen), vixl_temps_() {} 3193e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 320ad4450e5c3ffaa9566216cc6fafbf5c11186c467Zheng Xu protected: 321ad4450e5c3ffaa9566216cc6fafbf5c11186c467Zheng Xu void PrepareForEmitNativeCode() OVERRIDE; 322ad4450e5c3ffaa9566216cc6fafbf5c11186c467Zheng Xu void FinishEmitNativeCode() OVERRIDE; 323ad4450e5c3ffaa9566216cc6fafbf5c11186c467Zheng Xu Location AllocateScratchLocationFor(Location::Kind kind) OVERRIDE; 324ad4450e5c3ffaa9566216cc6fafbf5c11186c467Zheng Xu void FreeScratchLocation(Location loc) OVERRIDE; 3253e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames void EmitMove(size_t index) OVERRIDE; 3263e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 3273e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames private: 3283e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames Arm64Assembler* GetAssembler() const; 3293e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames vixl::MacroAssembler* GetVIXLAssembler() const { 3303e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames return GetAssembler()->vixl_masm_; 3313e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames } 3323e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 3333e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames CodeGeneratorARM64* const codegen_; 334ad4450e5c3ffaa9566216cc6fafbf5c11186c467Zheng Xu vixl::UseScratchRegisterScope vixl_temps_; 3353e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 3363e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverARM64); 3373e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames}; 3383e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 3395319defdf502fc4569316473846b83180ec08035Alexandre Ramesclass CodeGeneratorARM64 : public CodeGenerator { 3405319defdf502fc4569316473846b83180ec08035Alexandre Rames public: 341579885a26d761f5ba9550f2a1cd7f0f598c2e1e3Serban Constantinescu CodeGeneratorARM64(HGraph* graph, 342579885a26d761f5ba9550f2a1cd7f0f598c2e1e3Serban Constantinescu const Arm64InstructionSetFeatures& isa_features, 343ecc4366670e12b4812ef1653f7c8d52234ca1b1fSerban Constantinescu const CompilerOptions& compiler_options, 344ecc4366670e12b4812ef1653f7c8d52234ca1b1fSerban Constantinescu OptimizingCompilerStats* stats = nullptr); 345de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray virtual ~CodeGeneratorARM64() {} 3465319defdf502fc4569316473846b83180ec08035Alexandre Rames 347de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void GenerateFrameEntry() OVERRIDE; 348de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void GenerateFrameExit() OVERRIDE; 3495319defdf502fc4569316473846b83180ec08035Alexandre Rames 350da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu vixl::CPURegList GetFramePreservedCoreRegisters() const; 351da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu vixl::CPURegList GetFramePreservedFPRegisters() const; 3525319defdf502fc4569316473846b83180ec08035Alexandre Rames 353de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Bind(HBasicBlock* block) OVERRIDE; 3545319defdf502fc4569316473846b83180ec08035Alexandre Rames 355c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames vixl::Label* GetLabelOf(HBasicBlock* block) { 356c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames block = FirstNonEmptyBlock(block); 357c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames return &(block_labels_[block->GetBlockId()]); 3585319defdf502fc4569316473846b83180ec08035Alexandre Rames } 3595319defdf502fc4569316473846b83180ec08035Alexandre Rames 360de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray size_t GetWordSize() const OVERRIDE { 3615319defdf502fc4569316473846b83180ec08035Alexandre Rames return kArm64WordSize; 3625319defdf502fc4569316473846b83180ec08035Alexandre Rames } 3635319defdf502fc4569316473846b83180ec08035Alexandre Rames 364f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell size_t GetFloatingPointSpillSlotSize() const OVERRIDE { 365f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell // Allocated in D registers, which are word sized. 366f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell return kArm64WordSize; 367f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell } 368f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell 369c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames uintptr_t GetAddressOf(HBasicBlock* block) OVERRIDE { 37067555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames vixl::Label* block_entry_label = GetLabelOf(block); 37167555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames DCHECK(block_entry_label->IsBound()); 37267555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames return block_entry_label->location(); 373de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray } 374de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray 375de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray HGraphVisitor* GetLocationBuilder() OVERRIDE { return &location_builder_; } 376de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray HGraphVisitor* GetInstructionVisitor() OVERRIDE { return &instruction_visitor_; } 377de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray Arm64Assembler* GetAssembler() OVERRIDE { return &assembler_; } 378eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames const Arm64Assembler& GetAssembler() const OVERRIDE { return assembler_; } 37967555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames vixl::MacroAssembler* GetVIXLAssembler() { return GetAssembler()->vixl_masm_; } 3805319defdf502fc4569316473846b83180ec08035Alexandre Rames 3815319defdf502fc4569316473846b83180ec08035Alexandre Rames // Emit a write barrier. 38207276db28d654594e0e86e9e467cad393f752e6eNicolas Geoffray void MarkGCCard(vixl::Register object, vixl::Register value, bool value_can_be_null); 3835319defdf502fc4569316473846b83180ec08035Alexandre Rames 38444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void GenerateMemoryBarrier(MemBarrierKind kind); 38544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain 3865319defdf502fc4569316473846b83180ec08035Alexandre Rames // Register allocation. 3875319defdf502fc4569316473846b83180ec08035Alexandre Rames 38858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil void SetupBlockedRegisters() const OVERRIDE; 3895319defdf502fc4569316473846b83180ec08035Alexandre Rames 390da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE; 391da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE; 392da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE; 393da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE; 3945319defdf502fc4569316473846b83180ec08035Alexandre Rames 3955319defdf502fc4569316473846b83180ec08035Alexandre Rames // The number of registers that can be allocated. The register allocator may 3965319defdf502fc4569316473846b83180ec08035Alexandre Rames // decide to reserve and not use a few of them. 3975319defdf502fc4569316473846b83180ec08035Alexandre Rames // We do not consider registers sp, xzr, wzr. They are either not allocatable 3985319defdf502fc4569316473846b83180ec08035Alexandre Rames // (xzr, wzr), or make for poor allocatable registers (sp alignment 3995319defdf502fc4569316473846b83180ec08035Alexandre Rames // requirements, etc.). This also facilitates our task as all other registers 4005319defdf502fc4569316473846b83180ec08035Alexandre Rames // can easily be mapped via to or from their type and index or code. 401a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames static const int kNumberOfAllocatableRegisters = vixl::kNumberOfRegisters - 1; 402a89086e3be94fb262c4c4feb15241b30616c3b8fAlexandre Rames static const int kNumberOfAllocatableFPRegisters = vixl::kNumberOfFPRegisters; 4035319defdf502fc4569316473846b83180ec08035Alexandre Rames static constexpr int kNumberOfAllocatableRegisterPairs = 0; 4045319defdf502fc4569316473846b83180ec08035Alexandre Rames 405de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; 406de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; 4075319defdf502fc4569316473846b83180ec08035Alexandre Rames 408de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray InstructionSet GetInstructionSet() const OVERRIDE { 4095319defdf502fc4569316473846b83180ec08035Alexandre Rames return InstructionSet::kArm64; 4105319defdf502fc4569316473846b83180ec08035Alexandre Rames } 4115319defdf502fc4569316473846b83180ec08035Alexandre Rames 412579885a26d761f5ba9550f2a1cd7f0f598c2e1e3Serban Constantinescu const Arm64InstructionSetFeatures& GetInstructionSetFeatures() const { 413579885a26d761f5ba9550f2a1cd7f0f598c2e1e3Serban Constantinescu return isa_features_; 414579885a26d761f5ba9550f2a1cd7f0f598c2e1e3Serban Constantinescu } 415579885a26d761f5ba9550f2a1cd7f0f598c2e1e3Serban Constantinescu 416de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray void Initialize() OVERRIDE { 417c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames block_labels_.resize(GetGraph()->GetBlocks().size()); 4185319defdf502fc4569316473846b83180ec08035Alexandre Rames } 4195319defdf502fc4569316473846b83180ec08035Alexandre Rames 420c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames JumpTableARM64* CreateJumpTable(HPackedSwitch* switch_instr) { 421c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames jump_tables_.emplace_back(new (GetGraph()->GetArena()) JumpTableARM64(switch_instr)); 422c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames return jump_tables_.back().get(); 4233927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu } 4243927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu 42532f5b4d2c8c9b52e9522941c159577b21752d0faSerban Constantinescu void Finalize(CodeAllocator* allocator) OVERRIDE; 42632f5b4d2c8c9b52e9522941c159577b21752d0faSerban Constantinescu 427fc19de8b201475231751b9df08fce01a093e5c2bAlexandre Rames // Code generation helpers. 42867555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void MoveConstant(vixl::CPURegister destination, HConstant* constant); 429175dc732c80e6f2afd83209348124df349290ba8Calin Juravle void MoveConstant(Location destination, int32_t value) OVERRIDE; 430e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle void MoveLocation(Location dst, Location src, Primitive::Type dst_type) OVERRIDE; 431e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle void AddLocationAsTemp(Location location, LocationSummary* locations) OVERRIDE; 432e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle 43367555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames void Load(Primitive::Type type, vixl::CPURegister dst, const vixl::MemOperand& src); 43444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void Store(Primitive::Type type, vixl::CPURegister src, const vixl::MemOperand& dst); 43544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void LoadAcquire(HInstruction* instruction, 43644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain vixl::CPURegister dst, 43744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain const vixl::MemOperand& src, 43844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain bool needs_null_check); 43944015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void StoreRelease(Primitive::Type type, vixl::CPURegister src, const vixl::MemOperand& dst); 44067555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames 44167555f7e9a05a9d436e034f67ae683bbf02d072dAlexandre Rames // Generate code to invoke a runtime entry point. 442175dc732c80e6f2afd83209348124df349290ba8Calin Juravle void InvokeRuntime(QuickEntrypointEnum entrypoint, 443175dc732c80e6f2afd83209348124df349290ba8Calin Juravle HInstruction* instruction, 444175dc732c80e6f2afd83209348124df349290ba8Calin Juravle uint32_t dex_pc, 445175dc732c80e6f2afd83209348124df349290ba8Calin Juravle SlowPathCode* slow_path) OVERRIDE; 446175dc732c80e6f2afd83209348124df349290ba8Calin Juravle 447eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray void InvokeRuntime(int32_t offset, 448eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray HInstruction* instruction, 449eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray uint32_t dex_pc, 450eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray SlowPathCode* slow_path); 451fc19de8b201475231751b9df08fce01a093e5c2bAlexandre Rames 452e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames ParallelMoveResolverARM64* GetMoveResolver() OVERRIDE { return &move_resolver_; } 453f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray 454840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { 455840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray return false; 456840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray } 457840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray 458cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // Check if the desired_string_load_kind is supported. If it is, return it, 459cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // otherwise return a fall-back kind that should be used instead. 460cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko HLoadString::LoadKind GetSupportedLoadStringKind( 461cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko HLoadString::LoadKind desired_string_load_kind) OVERRIDE; 462cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 463dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko // Check if the desired_dispatch_info is supported. If it is, return it, 464dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko // otherwise return a fall-back info that should be used instead. 465dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch( 466dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info, 467dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko MethodReference target_method) OVERRIDE; 468dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko 46985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE; 47085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE; 47185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 47285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe void MoveFromReturnRegister(Location trg ATTRIBUTE_UNUSED, 47385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe Primitive::Type type ATTRIBUTE_UNUSED) OVERRIDE { 47485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe UNIMPLEMENTED(FATAL); 47585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 476878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe 477cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // Add a new PC-relative string patch for an instruction and return the label 478cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // to be bound before the instruction. The instruction will be either the 479cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // ADRP (pass `adrp_label = null`) or the ADD (pass `adrp_label` pointing 480cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // to the associated ADRP patch label). 481cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Label* NewPcRelativeStringPatch(const DexFile& dex_file, 482cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t string_index, 483cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Label* adrp_label = nullptr); 484cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 485cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // Add a new PC-relative dex cache array patch for an instruction and return 486cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // the label to be bound before the instruction. The instruction will be 487cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // either the ADRP (pass `adrp_label = null`) or the LDR (pass `adrp_label` 488cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // pointing to the associated ADRP patch label). 489cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Label* NewPcRelativeDexCacheArrayPatch(const DexFile& dex_file, 490cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t element_offset, 491cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Label* adrp_label = nullptr); 492cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 493cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Literal<uint32_t>* DeduplicateBootImageStringLiteral(const DexFile& dex_file, 494cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t string_index); 495cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Literal<uint32_t>* DeduplicateBootImageAddressLiteral(uint64_t address); 496cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Literal<uint64_t>* DeduplicateDexCacheAddressLiteral(uint64_t address); 497cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 498581550137ee3a068a14224870e71aeee924a0646Vladimir Marko void EmitLinkerPatches(ArenaVector<LinkerPatch>* linker_patches) OVERRIDE; 499581550137ee3a068a14224870e71aeee924a0646Vladimir Marko 50044015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Fast path implementation of ReadBarrier::Barrier for a heap 50144015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // reference field load when Baker's read barriers are used. 50244015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void GenerateFieldLoadWithBakerReadBarrier(HInstruction* instruction, 50344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location ref, 50444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain vixl::Register obj, 50544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain uint32_t offset, 50644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain vixl::Register temp, 50744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain bool needs_null_check, 50844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain bool use_load_acquire); 50944015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Fast path implementation of ReadBarrier::Barrier for a heap 51044015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // reference array load when Baker's read barriers are used. 51144015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void GenerateArrayLoadWithBakerReadBarrier(HInstruction* instruction, 51244015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location ref, 51344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain vixl::Register obj, 51444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain uint32_t data_offset, 51544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location index, 51644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain vixl::Register temp, 51744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain bool needs_null_check); 51844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain 51944015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Generate a read barrier for a heap reference within `instruction` 52044015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // using a slow path. 52122ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // 52222ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // A read barrier for an object reference read from the heap is 52322ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // implemented as a call to the artReadBarrierSlow runtime entry 52422ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // point, which is passed the values in locations `ref`, `obj`, and 52522ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // `offset`: 52622ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // 52722ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // mirror::Object* artReadBarrierSlow(mirror::Object* ref, 52822ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // mirror::Object* obj, 52922ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // uint32_t offset); 53022ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // 53122ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // The `out` location contains the value returned by 53222ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // artReadBarrierSlow. 53322ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // 53422ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // When `index` is provided (i.e. for array accesses), the offset 53522ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // value passed to artReadBarrierSlow is adjusted to take `index` 53622ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // into account. 53744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void GenerateReadBarrierSlow(HInstruction* instruction, 53844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location out, 53944015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location ref, 54044015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location obj, 54144015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain uint32_t offset, 54244015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location index = Location::NoLocation()); 54344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain 54444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // If read barriers are enabled, generate a read barrier for a heap 54544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // reference using a slow path. If heap poisoning is enabled, also 54644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // unpoison the reference in `out`. 54744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void MaybeGenerateReadBarrierSlow(HInstruction* instruction, 54844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location out, 54944015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location ref, 55044015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location obj, 55144015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain uint32_t offset, 55244015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location index = Location::NoLocation()); 55344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain 55444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Generate a read barrier for a GC root within `instruction` using 55544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // a slow path. 55622ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // 55722ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // A read barrier for an object reference GC root is implemented as 55822ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // a call to the artReadBarrierForRootSlow runtime entry point, 55922ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // which is passed the value in location `root`: 56022ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // 56122ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root); 56222ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // 56322ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // The `out` location contains the value returned by 56422ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain // artReadBarrierForRootSlow. 56544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root); 56622ccc3a93d32fa6991535eaebb17daf5abaf4ebfRoland Levillain 567c7098ff991bb4e00a800d315d1c36f52a9cb0149David Srbecky void GenerateNop(); 568c7098ff991bb4e00a800d315d1c36f52a9cb0149David Srbecky 5692ae48182573da7087bffc2873730bc758ec29696Calin Juravle void GenerateImplicitNullCheck(HNullCheck* instruction); 5702ae48182573da7087bffc2873730bc758ec29696Calin Juravle void GenerateExplicitNullCheck(HNullCheck* instruction); 5712ae48182573da7087bffc2873730bc758ec29696Calin Juravle 5725319defdf502fc4569316473846b83180ec08035Alexandre Rames private: 57344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // Factored implementation of GenerateFieldLoadWithBakerReadBarrier 57444015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain // and GenerateArrayLoadWithBakerReadBarrier. 57544015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain void GenerateReferenceLoadWithBakerReadBarrier(HInstruction* instruction, 57644015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location ref, 57744015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain vixl::Register obj, 57844015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain uint32_t offset, 57944015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain Location index, 58044015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain vixl::Register temp, 58144015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain bool needs_null_check, 58244015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain bool use_load_acquire); 58344015868a5ed9f6915d510ade42e84949b719e3aRoland Levillain 584581550137ee3a068a14224870e71aeee924a0646Vladimir Marko using Uint64ToLiteralMap = ArenaSafeMap<uint64_t, vixl::Literal<uint64_t>*>; 585cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko using Uint32ToLiteralMap = ArenaSafeMap<uint32_t, vixl::Literal<uint32_t>*>; 586581550137ee3a068a14224870e71aeee924a0646Vladimir Marko using MethodToLiteralMap = ArenaSafeMap<MethodReference, 587581550137ee3a068a14224870e71aeee924a0646Vladimir Marko vixl::Literal<uint64_t>*, 588581550137ee3a068a14224870e71aeee924a0646Vladimir Marko MethodReferenceComparator>; 589cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko using BootStringToLiteralMap = ArenaSafeMap<StringReference, 590cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Literal<uint32_t>*, 591cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko StringReferenceValueComparator>; 592581550137ee3a068a14224870e71aeee924a0646Vladimir Marko 593cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Literal<uint32_t>* DeduplicateUint32Literal(uint32_t value, Uint32ToLiteralMap* map); 594581550137ee3a068a14224870e71aeee924a0646Vladimir Marko vixl::Literal<uint64_t>* DeduplicateUint64Literal(uint64_t value); 595581550137ee3a068a14224870e71aeee924a0646Vladimir Marko vixl::Literal<uint64_t>* DeduplicateMethodLiteral(MethodReference target_method, 596581550137ee3a068a14224870e71aeee924a0646Vladimir Marko MethodToLiteralMap* map); 597581550137ee3a068a14224870e71aeee924a0646Vladimir Marko vixl::Literal<uint64_t>* DeduplicateMethodAddressLiteral(MethodReference target_method); 598581550137ee3a068a14224870e71aeee924a0646Vladimir Marko vixl::Literal<uint64_t>* DeduplicateMethodCodeLiteral(MethodReference target_method); 599581550137ee3a068a14224870e71aeee924a0646Vladimir Marko 600cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // The PcRelativePatchInfo is used for PC-relative addressing of dex cache arrays 601cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // and boot image strings. The only difference is the interpretation of the offset_or_index. 602cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko struct PcRelativePatchInfo { 603cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko PcRelativePatchInfo(const DexFile& dex_file, uint32_t off_or_idx) 604cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko : target_dex_file(dex_file), offset_or_index(off_or_idx), label(), pc_insn_label() { } 605581550137ee3a068a14224870e71aeee924a0646Vladimir Marko 606581550137ee3a068a14224870e71aeee924a0646Vladimir Marko const DexFile& target_dex_file; 607cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // Either the dex cache array element offset or the string index. 608cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t offset_or_index; 609581550137ee3a068a14224870e71aeee924a0646Vladimir Marko vixl::Label label; 610581550137ee3a068a14224870e71aeee924a0646Vladimir Marko vixl::Label* pc_insn_label; 611581550137ee3a068a14224870e71aeee924a0646Vladimir Marko }; 612581550137ee3a068a14224870e71aeee924a0646Vladimir Marko 613cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Label* NewPcRelativePatch(const DexFile& dex_file, 614cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t offset_or_index, 615cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko vixl::Label* adrp_label, 616cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko ArenaDeque<PcRelativePatchInfo>* patches); 617cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 6183927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu void EmitJumpTables(); 6193927c8b8361336f1b16aae6eb2ed7577b20560f4Zheng Xu 6205319defdf502fc4569316473846b83180ec08035Alexandre Rames // Labels for each block that will be compiled. 621c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames // We use a deque so that the `vixl::Label` objects do not move in memory. 622c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames ArenaDeque<vixl::Label> block_labels_; // Indexed by block id. 6231cf95287364948689f6a1a320567acd7728e94a3Nicolas Geoffray vixl::Label frame_entry_label_; 624c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames ArenaVector<std::unique_ptr<JumpTableARM64>> jump_tables_; 6255319defdf502fc4569316473846b83180ec08035Alexandre Rames 6265319defdf502fc4569316473846b83180ec08035Alexandre Rames LocationsBuilderARM64 location_builder_; 6275319defdf502fc4569316473846b83180ec08035Alexandre Rames InstructionCodeGeneratorARM64 instruction_visitor_; 6283e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames ParallelMoveResolverARM64 move_resolver_; 6295319defdf502fc4569316473846b83180ec08035Alexandre Rames Arm64Assembler assembler_; 630579885a26d761f5ba9550f2a1cd7f0f598c2e1e3Serban Constantinescu const Arm64InstructionSetFeatures& isa_features_; 6315319defdf502fc4569316473846b83180ec08035Alexandre Rames 632cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // Deduplication map for 32-bit literals, used for non-patchable boot image addresses. 633cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko Uint32ToLiteralMap uint32_literals_; 634cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // Deduplication map for 64-bit literals, used for non-patchable method address, method code 635cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // or string dex cache address. 636581550137ee3a068a14224870e71aeee924a0646Vladimir Marko Uint64ToLiteralMap uint64_literals_; 637581550137ee3a068a14224870e71aeee924a0646Vladimir Marko // Method patch info, map MethodReference to a literal for method address and method code. 638581550137ee3a068a14224870e71aeee924a0646Vladimir Marko MethodToLiteralMap method_patches_; 639581550137ee3a068a14224870e71aeee924a0646Vladimir Marko MethodToLiteralMap call_patches_; 640581550137ee3a068a14224870e71aeee924a0646Vladimir Marko // Relative call patch info. 641581550137ee3a068a14224870e71aeee924a0646Vladimir Marko // Using ArenaDeque<> which retains element addresses on push/emplace_back(). 642581550137ee3a068a14224870e71aeee924a0646Vladimir Marko ArenaDeque<MethodPatchInfo<vixl::Label>> relative_call_patches_; 643581550137ee3a068a14224870e71aeee924a0646Vladimir Marko // PC-relative DexCache access info. 644cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko ArenaDeque<PcRelativePatchInfo> pc_relative_dex_cache_patches_; 645cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // Deduplication map for boot string literals for kBootImageLinkTimeAddress. 646cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko BootStringToLiteralMap boot_image_string_patches_; 647cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // PC-relative String patch info. 648cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko ArenaDeque<PcRelativePatchInfo> pc_relative_string_patches_; 649cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko // Deduplication map for patchable boot image addresses. 650cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko Uint32ToLiteralMap boot_image_address_patches_; 651581550137ee3a068a14224870e71aeee924a0646Vladimir Marko 6525319defdf502fc4569316473846b83180ec08035Alexandre Rames DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM64); 6535319defdf502fc4569316473846b83180ec08035Alexandre Rames}; 6545319defdf502fc4569316473846b83180ec08035Alexandre Rames 6553e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Ramesinline Arm64Assembler* ParallelMoveResolverARM64::GetAssembler() const { 6563e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames return codegen_->GetAssembler(); 6573e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames} 6583e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames 6595319defdf502fc4569316473846b83180ec08035Alexandre Rames} // namespace arm64 6605319defdf502fc4569316473846b83180ec08035Alexandre Rames} // namespace art 6615319defdf502fc4569316473846b83180ec08035Alexandre Rames 6625319defdf502fc4569316473846b83180ec08035Alexandre Rames#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM64_H_ 663