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