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 197624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko#include "mirror/art_method-inl.h" 2004d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers#include "mirror/object-inl.h" 217624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko#include "quick/quick_method_frame_info.h" 222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "stack.h" 232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "thread.h" 24bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 25bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersnamespace art { 26bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersnamespace arm { 27bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 280bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertzstatic constexpr uint32_t gZero = 0; 296702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier 306702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartiervoid ArmContext::Reset() { 316702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier for (size_t i = 0; i < kNumberOfCoreRegisters; i++) { 320bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[i] = nullptr; 33bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 346702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier for (size_t i = 0; i < kNumberOfSRegisters; i++) { 350bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs_[i] = nullptr; 3615fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers } 376702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier gprs_[SP] = &sp_; 386702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier gprs_[PC] = &pc_; 396702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier // Initialize registers with easy to spot debug values. 406702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier sp_ = ArmContext::kBadGprBase + SP; 416702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier pc_ = ArmContext::kBadGprBase + PC; 42bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 43bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 440399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersvoid ArmContext::FillCalleeSaves(const StackVisitor& fr) { 45ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method = fr.GetMethod(); 467624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko const QuickMethodFrameInfo frame_info = method->GetQuickFrameInfo(); 477624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko size_t spill_count = POPCOUNT(frame_info.CoreSpillMask()); 487624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko size_t fp_spill_count = POPCOUNT(frame_info.FpSpillMask()); 49bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers if (spill_count > 0) { 506702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier // Lowest number spill is farthest away, walk registers and fill into context 51bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers int j = 1; 526702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier for (size_t i = 0; i < kNumberOfCoreRegisters; i++) { 537624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko if (((frame_info.CoreSpillMask() >> i) & 1) != 0) { 547624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko gprs_[i] = fr.CalleeSaveAddress(spill_count - j, frame_info.FrameSizeInBytes()); 55bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers j++; 56bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 57bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 58bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 5915fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers if (fp_spill_count > 0) { 606702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier // Lowest number spill is farthest away, walk registers and fill into context 6115fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers int j = 1; 626702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier for (size_t i = 0; i < kNumberOfSRegisters; i++) { 637624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko if (((frame_info.FpSpillMask() >> i) & 1) != 0) { 647624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko fprs_[i] = fr.CalleeSaveAddress(spill_count + fp_spill_count - j, 657624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko frame_info.FrameSizeInBytes()); 6615fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers j++; 6715fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers } 6815fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers } 6915fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers } 70bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 71bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 720bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertzbool ArmContext::SetGPR(uint32_t reg, uintptr_t value) { 73d74e41b1cce5373aa24fd2fbea735173f6113d5aBrian Carlstrom DCHECK_LT(reg, static_cast<uint32_t>(kNumberOfCoreRegisters)); 747934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom DCHECK_NE(gprs_[reg], &gZero); // Can't overwrite this static value since they are never reset. 750bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz if (gprs_[reg] != nullptr) { 760bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz *gprs_[reg] = value; 770bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz return true; 780bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz } else { 790bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz return false; 800bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz } 810bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz} 820bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz 830bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertzbool ArmContext::SetFPR(uint32_t reg, uintptr_t value) { 840bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz DCHECK_LT(reg, static_cast<uint32_t>(kNumberOfSRegisters)); 850bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz DCHECK_NE(fprs_[reg], &gZero); // Can't overwrite this static value since they are never reset. 860bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz if (fprs_[reg] != nullptr) { 870bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz *fprs_[reg] = value; 880bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz return true; 890bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz } else { 900bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz return false; 910bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz } 926702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier} 936702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier 949c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughesvoid ArmContext::SmashCallerSaves() { 956702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier // This needs to be 0 because we want a null/zero return value. 966702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier gprs_[R0] = const_cast<uint32_t*>(&gZero); 976702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier gprs_[R1] = const_cast<uint32_t*>(&gZero); 980bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[R2] = nullptr; 990bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs_[R3] = nullptr; 1009c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes} 1019c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes 1028dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chienextern "C" void art_quick_do_long_jump(uint32_t*, uint32_t*); 10357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 104bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersvoid ArmContext::DoLongJump() { 1050bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz uintptr_t gprs[kNumberOfCoreRegisters]; 1060bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz uint32_t fprs[kNumberOfSRegisters]; 1076702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier for (size_t i = 0; i < kNumberOfCoreRegisters; ++i) { 1080bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz gprs[i] = gprs_[i] != nullptr ? *gprs_[i] : ArmContext::kBadGprBase + i; 1096702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier } 1106702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier for (size_t i = 0; i < kNumberOfSRegisters; ++i) { 1110bcb2902ec21393d71c94e63aa6733cb5311a0ccSebastien Hertz fprs[i] = fprs_[i] != nullptr ? *fprs_[i] : ArmContext::kBadFprBase + i; 1126702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier } 1136702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier DCHECK_EQ(reinterpret_cast<uintptr_t>(Thread::Current()), gprs[TR]); 1148dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chien art_quick_do_long_jump(gprs, fprs); 115bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 116bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 117bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} // namespace arm 118bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} // namespace art 119