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