context_arm.cc revision 0399dde18753aa9bd2bd0d7cf60beef154d164a4
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 19bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers#include "object.h" 20bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 21bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersnamespace art { 22bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersnamespace arm { 23bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 24bdb0391258abc54bf77c676e36847d28a783bfe5Ian RogersArmContext::ArmContext() { 2567375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers#ifndef NDEBUG 26ad42e1327fca837531e4feac8841de3960c4df45Ian Rogers // Initialize registers with easy to spot debug values 27362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes for (int i = 0; i < 16; i++) { 289c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes gprs_[i] = kBadGprBase + i; 29bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 30362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes for (int i = 0; i < 32; i++) { 319c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes fprs_[i] = kBadFprBase + i; 3215fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers } 3367375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers#endif 34bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 35bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 360399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersvoid ArmContext::FillCalleeSaves(const StackVisitor& fr) { 37bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers Method* method = fr.GetMethod(); 38bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers uint32_t core_spills = method->GetCoreSpillMask(); 3915fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers uint32_t fp_core_spills = method->GetFpSpillMask(); 40bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers size_t spill_count = __builtin_popcount(core_spills); 4115fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers size_t fp_spill_count = __builtin_popcount(fp_core_spills); 420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers size_t frame_size = method->GetFrameSizeInBytes(); 43bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers if (spill_count > 0) { 44bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Lowest number spill is furthest away, walk registers and fill into context 45bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers int j = 1; 46362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes for (int i = 0; i < 16; i++) { 47bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers if (((core_spills >> i) & 1) != 0) { 480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers gprs_[i] = fr.LoadCalleeSave(spill_count - j, frame_size); 49bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers j++; 50bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 51bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 52bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 5315fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers if (fp_spill_count > 0) { 5415fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers // Lowest number spill is furthest away, walk registers and fill into context 5515fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers int j = 1; 56362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes for (int i = 0; i < 32; i++) { 5715fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers if (((fp_core_spills >> i) & 1) != 0) { 580399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers fprs_[i] = fr.LoadCalleeSave(spill_count + fp_spill_count - j, frame_size); 5915fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers j++; 6015fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers } 6115fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers } 6215fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers } 63bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 64bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 659c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughesvoid ArmContext::SmashCallerSaves() { 669c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes gprs_[0] = 0; // This needs to be 0 because we want a null/zero return value. 679c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes gprs_[1] = kBadGprBase + 1; 689c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes gprs_[2] = kBadGprBase + 2; 699c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes gprs_[3] = kBadGprBase + 3; 709c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes gprs_[IP] = kBadGprBase + IP; 719c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes gprs_[LR] = kBadGprBase + LR; 729c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes} 739c750f9b6283f62b3e6a93c0c6b2838abde5000eElliott Hughes 7457b86d47b66322693a070185fadfb43cb9c12eabIan Rogersextern "C" void art_do_long_jump(uint32_t*, uint32_t*); 7557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 76bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersvoid ArmContext::DoLongJump() { 776f495f2898a418f87e2a919e04fe23521bb0b9e9Brian Carlstrom art_do_long_jump(&gprs_[0], &fprs_[S0]); 78bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 79bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 80bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} // namespace arm 81bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} // namespace art 82