17fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao/*
27fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * Copyright (C) 2011 The Android Open Source Project
37fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao *
47fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * Licensed under the Apache License, Version 2.0 (the "License");
57fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * you may not use this file except in compliance with the License.
67fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * You may obtain a copy of the License at
77fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao *
87fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao *      http://www.apache.org/licenses/LICENSE-2.0
97fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao *
107fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * Unless required by applicable law or agreed to in writing, software
117fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * distributed under the License is distributed on an "AS IS" BASIS,
127fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * See the License for the specific language governing permissions and
147fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * limitations under the License.
157fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao */
167fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
177fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao#include "context_mips.h"
187fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
19ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method.h"
208e26b311e0ede3847e9425d715055f79624c17e4Ian Rogers#include "mirror/object-inl.h"
214a4552d3e4ca7575f2de3e60d9db9d46c0da96e1Brian Carlstrom#include "stack.h"
227fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
237fbee0731b14b5bf392a4254f5cd84685ab517dajeffhaonamespace art {
247fbee0731b14b5bf392a4254f5cd84685ab517dajeffhaonamespace mips {
257fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
266702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartierstatic const uint32_t gZero = 0;
276702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier
286702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartiervoid MipsContext::Reset() {
296702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  for (size_t i = 0; i < kNumberOfCoreRegisters; i++) {
306702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier    gprs_[i] = NULL;
317fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  }
326702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  for (size_t i = 0; i < kNumberOfFRegisters; i++) {
336702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier    fprs_[i] = NULL;
347fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  }
356702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  gprs_[SP] = &sp_;
366702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  gprs_[RA] = &ra_;
376702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  // Initialize registers with easy to spot debug values.
386702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  sp_ = MipsContext::kBadGprBase + SP;
396702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  ra_ = MipsContext::kBadGprBase + RA;
407fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao}
417fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
427fbee0731b14b5bf392a4254f5cd84685ab517dajeffhaovoid MipsContext::FillCalleeSaves(const StackVisitor& fr) {
43ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  mirror::ArtMethod* method = fr.GetMethod();
447fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  uint32_t core_spills = method->GetCoreSpillMask();
457fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  uint32_t fp_core_spills = method->GetFpSpillMask();
467fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  size_t spill_count = __builtin_popcount(core_spills);
477fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  size_t fp_spill_count = __builtin_popcount(fp_core_spills);
487fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  size_t frame_size = method->GetFrameSizeInBytes();
497fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  if (spill_count > 0) {
506702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier    // Lowest number spill is farthest away, walk registers and fill into context.
517fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    int j = 1;
526702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier    for (size_t i = 0; i < kNumberOfCoreRegisters; i++) {
537fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      if (((core_spills >> i) & 1) != 0) {
546702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier        gprs_[i] = fr.CalleeSaveAddress(spill_count - j, frame_size);
557fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao        j++;
567fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      }
577fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    }
587fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  }
597fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  if (fp_spill_count > 0) {
606702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier    // Lowest number spill is farthest away, walk registers and fill into context.
617fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    int j = 1;
626702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier    for (size_t i = 0; i < kNumberOfFRegisters; i++) {
637fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      if (((fp_core_spills >> i) & 1) != 0) {
646702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier        fprs_[i] = fr.CalleeSaveAddress(spill_count + fp_spill_count - j, frame_size);
657fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao        j++;
667fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      }
677fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    }
687fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  }
697fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao}
707fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
716702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartiervoid MipsContext::SetGPR(uint32_t reg, uintptr_t value) {
728b1ce16de070672f0ab1a30f40853513734ff128Brian Carlstrom  CHECK_LT(reg, static_cast<uint32_t>(kNumberOfCoreRegisters));
737934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  CHECK_NE(gprs_[reg], &gZero);  // Can't overwrite this static value since they are never reset.
746702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  CHECK(gprs_[reg] != NULL);
756702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  *gprs_[reg] = value;
766702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier}
776702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier
787fbee0731b14b5bf392a4254f5cd84685ab517dajeffhaovoid MipsContext::SmashCallerSaves() {
796702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  // This needs to be 0 because we want a null/zero return value.
806702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  gprs_[V0] = const_cast<uint32_t*>(&gZero);
816702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  gprs_[V1] = const_cast<uint32_t*>(&gZero);
826702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  gprs_[A1] = NULL;
836702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  gprs_[A2] = NULL;
846702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  gprs_[A3] = NULL;
857fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao}
867fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
878dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chienextern "C" void art_quick_do_long_jump(uint32_t*, uint32_t*);
887fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
897fbee0731b14b5bf392a4254f5cd84685ab517dajeffhaovoid MipsContext::DoLongJump() {
906702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  uintptr_t gprs[kNumberOfCoreRegisters];
916702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  uint32_t fprs[kNumberOfFRegisters];
926702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  for (size_t i = 0; i < kNumberOfCoreRegisters; ++i) {
936702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier    gprs[i] = gprs_[i] != NULL ? *gprs_[i] : MipsContext::kBadGprBase + i;
946702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  }
956702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  for (size_t i = 0; i < kNumberOfFRegisters; ++i) {
966702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier    fprs[i] = fprs_[i] != NULL ? *fprs_[i] : MipsContext::kBadGprBase + i;
976702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier  }
988dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chien  art_quick_do_long_jump(gprs, fprs);
997fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao}
1007fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
1017fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao}  // namespace mips
1027fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao}  // namespace art
103