1ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu/* 2ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * Copyright (C) 2014 The Android Open Source Project 3ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * 4ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * Licensed under the Apache License, Version 2.0 (the "License"); 5ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * you may not use this file except in compliance with the License. 6ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * You may obtain a copy of the License at 7ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * 8ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * http://www.apache.org/licenses/LICENSE-2.0 9ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * 10ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * Unless required by applicable law or agreed to in writing, software 11ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * distributed under the License is distributed on an "AS IS" BASIS, 12ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu* See the License for the specific language governing permissions and 14ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * limitations under the License. 15ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu */ 16ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 17ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#ifndef ART_COMPILER_UTILS_ARM64_ASSEMBLER_ARM64_H_ 18ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#define ART_COMPILER_UTILS_ARM64_ASSEMBLER_ARM64_H_ 19ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 20b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith#include <stdint.h> 21700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory> 22700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <vector> 23ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 24ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "base/logging.h" 25ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "constants_arm64.h" 26ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "utils/arm64/managed_register_arm64.h" 27ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "utils/assembler.h" 28ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "offsets.h" 29ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "utils.h" 30ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "a64/macro-assembler-a64.h" 31ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "a64/disasm-a64.h" 32ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 33ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescunamespace art { 34ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescunamespace arm64 { 35ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 36ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#define MEM_OP(x...) vixl::MemOperand(x) 37ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#define COND_OP(x) static_cast<vixl::Condition>(x) 38ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 39ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuenum Condition { 40ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kNoCondition = -1, 41ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu EQ = 0, 42ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu NE = 1, 43ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu HS = 2, 44ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu LO = 3, 45ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu MI = 4, 46ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu PL = 5, 47ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu VS = 6, 48ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu VC = 7, 49ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu HI = 8, 50ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu LS = 9, 51ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu GE = 10, 52ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu LT = 11, 53ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu GT = 12, 54ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu LE = 13, 55ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu AL = 14, // Always. 56ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu NV = 15, // Behaves as always/al. 57ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kMaxCondition = 16, 58ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}; 59ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 60ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuenum LoadOperandType { 61ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kLoadSignedByte, 62ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kLoadUnsignedByte, 63ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kLoadSignedHalfword, 64ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kLoadUnsignedHalfword, 65ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kLoadWord, 66ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kLoadCoreWord, 67ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kLoadSWord, 68ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kLoadDWord 69ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}; 70ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 71ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuenum StoreOperandType { 72ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kStoreByte, 73ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kStoreHalfword, 74ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kStoreWord, 75ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kStoreCoreWord, 76ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kStoreSWord, 77ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu kStoreDWord 78ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}; 79ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 80ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuclass Arm64Exception; 81ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 82dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersclass Arm64Assembler FINAL : public Assembler { 83ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu public: 8475b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu Arm64Assembler() : vixl_buf_(new byte[kBufferSizeArm64]), 8575b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu vixl_masm_(new vixl::MacroAssembler(vixl_buf_, kBufferSizeArm64)) {} 86ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 87ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu virtual ~Arm64Assembler() { 880f89dac7336251f7921621a926319d461837840fSerban Constantinescu delete vixl_masm_; 89ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu delete[] vixl_buf_; 90ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu } 91ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 92ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Emit slow paths queued during assembly. 93ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void EmitSlowPaths(); 94ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 95ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Size of generated code. 96ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu size_t CodeSize() const; 97ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 98ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Copy instructions out of assembly buffer into the given region of memory. 99ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void FinalizeInstructions(const MemoryRegion& region); 100ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 101ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Emit code that will create an activation on the stack. 102ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void BuildFrame(size_t frame_size, ManagedRegister method_reg, 103ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu const std::vector<ManagedRegister>& callee_save_regs, 104dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers const ManagedRegisterEntrySpills& entry_spills) OVERRIDE; 105ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 106ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Emit code that will remove an activation from the stack. 107dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& callee_save_regs) 108dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OVERRIDE; 109ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 110dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void IncreaseFrameSize(size_t adjust) OVERRIDE; 111dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void DecreaseFrameSize(size_t adjust) OVERRIDE; 112ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 113ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Store routines. 114dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Store(FrameOffset offs, ManagedRegister src, size_t size) OVERRIDE; 115dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreRef(FrameOffset dest, ManagedRegister src) OVERRIDE; 116dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreRawPtr(FrameOffset dest, ManagedRegister src) OVERRIDE; 117dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister scratch) OVERRIDE; 11875b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu void StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm, ManagedRegister scratch) 119dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OVERRIDE; 12075b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu void StoreStackOffsetToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs, 121dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch) OVERRIDE; 12275b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu void StoreStackPointerToThread64(ThreadOffset<8> thr_offs) OVERRIDE; 123dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void StoreSpanning(FrameOffset dest, ManagedRegister src, FrameOffset in_off, 124dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch) OVERRIDE; 125ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 126ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Load routines. 127dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Load(ManagedRegister dest, FrameOffset src, size_t size) OVERRIDE; 12875b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu void LoadFromThread64(ManagedRegister dest, ThreadOffset<8> src, size_t size) OVERRIDE; 129dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE; 130dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadRef(ManagedRegister dest, ManagedRegister base, MemberOffset offs) OVERRIDE; 131dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs) OVERRIDE; 13275b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu void LoadRawPtrFromThread64(ManagedRegister dest, ThreadOffset<8> offs) OVERRIDE; 133dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 134ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Copying routines. 135dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Move(ManagedRegister dest, ManagedRegister src, size_t size) OVERRIDE; 13675b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu void CopyRawPtrFromThread64(FrameOffset fr_offs, ThreadOffset<8> thr_offs, 137dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch) OVERRIDE; 13875b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu void CopyRawPtrToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs, ManagedRegister scratch) 139dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OVERRIDE; 140dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister scratch) OVERRIDE; 141dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch, size_t size) OVERRIDE; 142dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, ManagedRegister scratch, 143dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t size) OVERRIDE; 144dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src, ManagedRegister scratch, 145dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t size) OVERRIDE; 146dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, ManagedRegister scratch, 147dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t size) OVERRIDE; 148dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Copy(ManagedRegister dest, Offset dest_offset, ManagedRegister src, Offset src_offset, 149dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch, size_t size) OVERRIDE; 150ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset, 151dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch, size_t size) OVERRIDE; 152dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void MemoryBarrier(ManagedRegister scratch) OVERRIDE; 153ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 154ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Sign extension. 155dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE; 156ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 157ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Zero extension. 158dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE; 159ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 160ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Exploit fast access in managed code to Thread::Current(). 161dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void GetCurrentThread(ManagedRegister tr) OVERRIDE; 162dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void GetCurrentThread(FrameOffset dest_offset, ManagedRegister scratch) OVERRIDE; 163ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 164eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // Set up out_reg to hold a Object** into the handle scope, or to be NULL if the 165ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // value is null and null_allowed. in_reg holds a possibly stale reference 166eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // that can be used to avoid loading the handle scope entry to see if the value is 167ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // NULL. 168eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier void CreateHandleScopeEntry(ManagedRegister out_reg, FrameOffset handlescope_offset, 169dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister in_reg, bool null_allowed) OVERRIDE; 170ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 171eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // Set up out_off to hold a Object** into the handle scope, or to be NULL if the 172ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // value is null and null_allowed. 173eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier void CreateHandleScopeEntry(FrameOffset out_off, FrameOffset handlescope_offset, 174dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ManagedRegister scratch, bool null_allowed) OVERRIDE; 175ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 176eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // src holds a handle scope entry (Object**) load this into dst. 177eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier void LoadReferenceFromHandleScope(ManagedRegister dst, ManagedRegister src) OVERRIDE; 178ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 179ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Heap::VerifyObject on src. In some cases (such as a reference to this) we 180ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // know that src may not be null. 181dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE; 182dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE; 183ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 184ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Call to address held at [base+offset]. 185dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Call(ManagedRegister base, Offset offset, ManagedRegister scratch) OVERRIDE; 186dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void Call(FrameOffset base, Offset offset, ManagedRegister scratch) OVERRIDE; 18775b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu void CallFromThread64(ThreadOffset<8> offset, ManagedRegister scratch) OVERRIDE; 188ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 189c6ee54e9a9fd67d24c63bd802ef2fe540a4f86a5Andreas Gampe // Jump to address (not setting link register) 190c6ee54e9a9fd67d24c63bd802ef2fe540a4f86a5Andreas Gampe void JumpTo(ManagedRegister m_base, Offset offs, ManagedRegister m_scratch); 191c6ee54e9a9fd67d24c63bd802ef2fe540a4f86a5Andreas Gampe 192ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Generate code to check if Thread::Current()->exception_ is non-null 193ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // and branch to a ExceptionSlowPath if it is. 194dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void ExceptionPoll(ManagedRegister scratch, size_t stack_adjust) OVERRIDE; 195ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 196ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu private: 197ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu static vixl::Register reg_x(int code) { 198ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu CHECK(code < kNumberOfCoreRegisters) << code; 199ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu if (code == SP) { 200ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu return vixl::sp; 20115523731549152276f23dcf94d81b1a9ce9c5038Serban Constantinescu } else if (code == XZR) { 20215523731549152276f23dcf94d81b1a9ce9c5038Serban Constantinescu return vixl::xzr; 203ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu } 204ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu return vixl::Register::XRegFromCode(code); 205ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu } 206ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 207ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu static vixl::Register reg_w(int code) { 208ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu return vixl::Register::WRegFromCode(code); 209ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu } 210ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 211ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu static vixl::FPRegister reg_d(int code) { 212ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu return vixl::FPRegister::DRegFromCode(code); 213ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu } 214ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 215ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu static vixl::FPRegister reg_s(int code) { 216ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu return vixl::FPRegister::SRegFromCode(code); 217ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu } 218ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 219ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Emits Exception block. 220ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void EmitExceptionPoll(Arm64Exception *exception); 221ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 222ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void StoreWToOffset(StoreOperandType type, WRegister source, 223ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu Register base, int32_t offset); 224ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void StoreToOffset(Register source, Register base, int32_t offset); 225ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void StoreSToOffset(SRegister source, Register base, int32_t offset); 226ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void StoreDToOffset(DRegister source, Register base, int32_t offset); 227ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 228ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void LoadImmediate(Register dest, int32_t value, Condition cond = AL); 229ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void Load(Arm64ManagedRegister dst, Register src, int32_t src_offset, size_t size); 230ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void LoadWFromOffset(LoadOperandType type, WRegister dest, 231ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu Register base, int32_t offset); 232ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void LoadFromOffset(Register dest, Register base, int32_t offset); 233ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void LoadSFromOffset(SRegister dest, Register base, int32_t offset); 234ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void LoadDFromOffset(DRegister dest, Register base, int32_t offset); 235ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void AddConstant(Register rd, int32_t value, Condition cond = AL); 236ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu void AddConstant(Register rd, Register rn, int32_t value, Condition cond = AL); 237ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 238ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Vixl buffer. 239ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu byte* vixl_buf_; 240ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 2410f89dac7336251f7921621a926319d461837840fSerban Constantinescu // Vixl assembler. 2420f89dac7336251f7921621a926319d461837840fSerban Constantinescu vixl::MacroAssembler* vixl_masm_; 243ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 244ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // List of exception blocks to generate at the end of the code cache. 245ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu std::vector<Arm64Exception*> exception_blocks_; 24615523731549152276f23dcf94d81b1a9ce9c5038Serban Constantinescu 24715523731549152276f23dcf94d81b1a9ce9c5038Serban Constantinescu // Used for testing. 24815523731549152276f23dcf94d81b1a9ce9c5038Serban Constantinescu friend class Arm64ManagedRegister_VixlRegisters_Test; 249ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}; 250ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 251ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuclass Arm64Exception { 252ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu private: 253ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu explicit Arm64Exception(Arm64ManagedRegister scratch, size_t stack_adjust) 254ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu : scratch_(scratch), stack_adjust_(stack_adjust) { 255ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu } 256ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 257ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu vixl::Label* Entry() { return &exception_entry_; } 258ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 259ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Register used for passing Thread::Current()->exception_ . 260ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu const Arm64ManagedRegister scratch_; 261ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 262ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu // Stack adjust for ExceptionPool. 263ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu const size_t stack_adjust_; 264ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 265ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu vixl::Label exception_entry_; 266ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 267ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu friend class Arm64Assembler; 268ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu DISALLOW_COPY_AND_ASSIGN(Arm64Exception); 269ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}; 270ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 271ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu} // namespace arm64 272ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu} // namespace art 273ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu 274ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#endif // ART_COMPILER_UTILS_ARM64_ASSEMBLER_ARM64_H_ 275