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