12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 17bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers#include "context_arm.h" 18bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 193d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier#include "art_method-inl.h" 2041b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko#include "base/bit_utils.h" 217624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko#include "quick/quick_method_frame_info.h" 22bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 23bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersnamespace art { 24bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersnamespace arm { 25bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 260bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertzstatic constexpr uint32_t gZero = 0; 276702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier 286702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartiervoid ArmContext::Reset() { 2941b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko std::fill_n(gprs_, arraysize(gprs_), nullptr); 3041b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko std::fill_n(fprs_, arraysize(fprs_), nullptr); 316702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier gprs_[SP] = &sp_; 326702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier gprs_[PC] = &pc_; 336702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier // Initialize registers with easy to spot debug values. 346702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier sp_ = ArmContext::kBadGprBase + SP; 356702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier pc_ = ArmContext::kBadGprBase + PC; 36bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 37bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 380399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersvoid ArmContext::FillCalleeSaves(const StackVisitor& fr) { 393d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method = fr.GetMethod(); 407624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko const QuickMethodFrameInfo frame_info = method->GetQuickFrameInfo(); 4141b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko int spill_pos = 0; 4241b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko 4341b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko // Core registers come first, from the highest down to the lowest. 4441b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko uint32_t core_regs = frame_info.CoreSpillMask(); 4541b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko DCHECK_EQ(0u, core_regs & (static_cast<uint32_t>(-1) << kNumberOfCoreRegisters)); 4641b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko for (uint32_t core_reg : HighToLowBits(core_regs)) { 4741b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko gprs_[core_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes()); 4841b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko ++spill_pos; 49bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 5041b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask())); 5141b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko 5241b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko // FP registers come second, from the highest down to the lowest. 5341b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko for (uint32_t fp_reg : HighToLowBits(frame_info.FpSpillMask())) { 5441b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko fprs_[fp_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes()); 5541b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko ++spill_pos; 5615fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers } 5741b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) + POPCOUNT(frame_info.FpSpillMask())); 58bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 59bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 6096ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertzvoid ArmContext::SetGPR(uint32_t reg, uintptr_t value) { 61d74e41b1cce5373aa24fd2fbea735173f6113d5aBrian Carlstrom DCHECK_LT(reg, static_cast<uint32_t>(kNumberOfCoreRegisters)); 6296ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertz DCHECK(IsAccessibleGPR(reg)); 637934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom DCHECK_NE(gprs_[reg], &gZero); // Can't overwrite this static value since they are never reset. 6496ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertz *gprs_[reg] = value; 650bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz} 660bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz 6796ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertzvoid ArmContext::SetFPR(uint32_t reg, uintptr_t value) { 680bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz DCHECK_LT(reg, static_cast<uint32_t>(kNumberOfSRegisters)); 6996ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertz DCHECK(IsAccessibleFPR(reg)); 700bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz DCHECK_NE(fprs_[reg], &gZero); // Can't overwrite this static value since they are never reset. 7196ba8dc82e7bd859106af837623fe8b2e9e772c3Sebastien Hertz *fprs_[reg] = value; 726702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier} 736702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier 749c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughesvoid ArmContext::SmashCallerSaves() { 756702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier // This needs to be 0 because we want a null/zero return value. 766702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier gprs_[R0] = const_cast<uint32_t*>(&gZero); 776702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier gprs_[R1] = const_cast<uint32_t*>(&gZero); 780bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[R2] = nullptr; 790bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[R3] = nullptr; 805667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu 815667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S0] = nullptr; 825667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S1] = nullptr; 835667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S2] = nullptr; 845667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S3] = nullptr; 855667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S4] = nullptr; 865667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S5] = nullptr; 875667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S6] = nullptr; 885667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S7] = nullptr; 895667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S8] = nullptr; 905667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S9] = nullptr; 915667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S10] = nullptr; 925667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S11] = nullptr; 935667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S12] = nullptr; 945667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S13] = nullptr; 955667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S14] = nullptr; 965667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu fprs_[S15] = nullptr; 979c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes} 989c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes 99794ad76e8d5b5b9132819d5b08a0570e27615644Andreas Gampeextern "C" NO_RETURN void art_quick_do_long_jump(uint32_t*, uint32_t*); 10057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 101bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersvoid ArmContext::DoLongJump() { 1020bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz uintptr_t gprs[kNumberOfCoreRegisters]; 1030bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz uint32_t fprs[kNumberOfSRegisters]; 1046702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier for (size_t i = 0; i < kNumberOfCoreRegisters; ++i) { 1050bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs[i] = gprs_[i] != nullptr ? *gprs_[i] : ArmContext::kBadGprBase + i; 1066702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier } 1076702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier for (size_t i = 0; i < kNumberOfSRegisters; ++i) { 1080bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs[i] = fprs_[i] != nullptr ? *fprs_[i] : ArmContext::kBadFprBase + i; 1096702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier } 1106702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier DCHECK_EQ(reinterpret_cast<uintptr_t>(Thread::Current()), gprs[TR]); 1118dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chien art_quick_do_long_jump(gprs, fprs); 112bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 113bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 114bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} // namespace arm 115bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} // namespace art 116