1b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith/* 2b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Copyright (C) 2014 The Android Open Source Project 3b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 4b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Licensed under the Apache License, Version 2.0 (the "License"); 5b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * you may not use this file except in compliance with the License. 6b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * You may obtain a copy of the License at 7b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 8b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * http://www.apache.org/licenses/LICENSE-2.0 9b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 10b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Unless required by applicable law or agreed to in writing, software 11b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * distributed under the License is distributed on an "AS IS" BASIS, 12b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * See the License for the specific language governing permissions and 14b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * limitations under the License. 15b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 16b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 17b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith#include <stdint.h> 18b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 19b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith#include "context_arm64.h" 20b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 2180afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/bit_utils.h" 227624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko#include "quick/quick_method_frame_info.h" 23524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray#include "thread-inl.h" 24b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 25b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteithnamespace art { 26b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteithnamespace arm64 { 27b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 280bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertzstatic constexpr uint64_t gZero = 0; 29b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 30b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteithvoid Arm64Context::Reset() { 3180afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko std::fill_n(gprs_, arraysize(gprs_), nullptr); 3280afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko std::fill_n(fprs_, arraysize(fprs_), nullptr); 33b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith gprs_[SP] = &sp_; 34639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe gprs_[kPC] = &pc_; 35639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe gprs_[X0] = &arg0_; 36b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Initialize registers with easy to spot debug values. 37b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith sp_ = Arm64Context::kBadGprBase + SP; 38639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe pc_ = Arm64Context::kBadGprBase + kPC; 39639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe arg0_ = 0; 40b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith} 41b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 42524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffrayvoid Arm64Context::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& frame_info) { 4380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko int spill_pos = 0; 4480afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko 4580afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko // Core registers come first, from the highest down to the lowest. 4680afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko for (uint32_t core_reg : HighToLowBits(frame_info.CoreSpillMask())) { 47524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray gprs_[core_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); 4880afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko ++spill_pos; 49b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith } 5080afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask())); 51b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 5280afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko // FP registers come second, from the highest down to the lowest. 5380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko for (uint32_t fp_reg : HighToLowBits(frame_info.FpSpillMask())) { 54524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray fprs_[fp_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); 5580afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko ++spill_pos; 56b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith } 5780afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) + POPCOUNT(frame_info.FpSpillMask())); 58b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith} 59b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 6096ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertzvoid Arm64Context::SetGPR(uint32_t reg, uintptr_t value) { 61639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe DCHECK_LT(reg, arraysize(gprs_)); 62639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe // Note: we use kPC == XZR, so do not ensure that reg != XZR. 6396ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertz DCHECK(IsAccessibleGPR(reg)); 64b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith DCHECK_NE(gprs_[reg], &gZero); // Can't overwrite this static value since they are never reset. 6596ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertz *gprs_[reg] = value; 660bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz} 670bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz 6896ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertzvoid Arm64Context::SetFPR(uint32_t reg, uintptr_t value) { 690bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz DCHECK_LT(reg, static_cast<uint32_t>(kNumberOfDRegisters)); 7096ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertz DCHECK(IsAccessibleFPR(reg)); 710bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz DCHECK_NE(fprs_[reg], &gZero); // Can't overwrite this static value since they are never reset. 7296ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertz *fprs_[reg] = value; 73b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith} 74b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 75b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteithvoid Arm64Context::SmashCallerSaves() { 76b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // This needs to be 0 because we want a null/zero return value. 77b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith gprs_[X0] = const_cast<uint64_t*>(&gZero); 780bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X1] = nullptr; 790bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X2] = nullptr; 800bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X3] = nullptr; 810bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X4] = nullptr; 820bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X5] = nullptr; 830bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X6] = nullptr; 840bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X7] = nullptr; 850bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X8] = nullptr; 860bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X9] = nullptr; 870bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X10] = nullptr; 880bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X11] = nullptr; 890bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X12] = nullptr; 900bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X13] = nullptr; 910bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X14] = nullptr; 920bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[X15] = nullptr; 939bd88b0933a372e6a7b64b850868e6a7998567e2Serban Constantinescu gprs_[X18] = nullptr; 94b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 956cf80102b5f308f2a5326869343ea0d19109a7fbAndreas Gampe // d0-d7, d16-d31 are caller-saved; d8-d15 are callee-saved. 966cf80102b5f308f2a5326869343ea0d19109a7fbAndreas Gampe 970bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D0] = nullptr; 980bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D1] = nullptr; 990bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D2] = nullptr; 1000bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D3] = nullptr; 1010bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D4] = nullptr; 1020bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D5] = nullptr; 1030bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D6] = nullptr; 1040bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D7] = nullptr; 1050bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz 1060bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D16] = nullptr; 1070bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D17] = nullptr; 1080bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D18] = nullptr; 1090bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D19] = nullptr; 1100bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D20] = nullptr; 1110bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D21] = nullptr; 1120bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D22] = nullptr; 1130bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D23] = nullptr; 1140bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D24] = nullptr; 1150bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D25] = nullptr; 1160bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D26] = nullptr; 1170bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D27] = nullptr; 1180bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D28] = nullptr; 1190bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D29] = nullptr; 1200bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D30] = nullptr; 1210bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[D31] = nullptr; 122b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith} 123b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 124794ad76e8d5b5b9132819d5b08a0570e27615644Andreas Gampeextern "C" NO_RETURN void art_quick_do_long_jump(uint64_t*, uint64_t*); 125b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 126b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteithvoid Arm64Context::DoLongJump() { 127639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe uint64_t gprs[arraysize(gprs_)]; 1280bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz uint64_t fprs[kNumberOfDRegisters]; 129b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 130a304f97c97d38af73afe6b49259ac4faf0902123Alexandre Rames // The long jump routine called below expects to find the value for SP at index 31. 131a304f97c97d38af73afe6b49259ac4faf0902123Alexandre Rames DCHECK_EQ(SP, 31); 132a304f97c97d38af73afe6b49259ac4faf0902123Alexandre Rames 133639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe for (size_t i = 0; i < arraysize(gprs_); ++i) { 1340bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs[i] = gprs_[i] != nullptr ? *gprs_[i] : Arm64Context::kBadGprBase + i; 135b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith } 136b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith for (size_t i = 0; i < kNumberOfDRegisters; ++i) { 1375b09ea0af468d9232cf725ac7f7e73c145892c5cVladimir Marko fprs[i] = fprs_[i] != nullptr ? *fprs_[i] : Arm64Context::kBadFprBase + i; 138b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith } 139b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith DCHECK_EQ(reinterpret_cast<uintptr_t>(Thread::Current()), gprs[TR]); 140b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith art_quick_do_long_jump(gprs, fprs); 141b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith} 142b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 143b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith} // namespace arm64 144b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith} // namespace art 145