calling_convention_x86.cc revision 3e6a3bf797e49b7f449256455c7e522e888687d8
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 */
16b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "calling_convention_x86.h"
1857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
1907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
203e0acf673ce1fbb3932d288d7b52a6dc551a920fMathieu Chartier#include "handle_scope-inl.h"
21166db04e259ca51838c311891598664deeed85adIan Rogers#include "utils/x86/managed_register_x86.h"
22578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "utils.h"
23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art {
252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace x86 {
26b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers// Calling convention
282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
292c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::InterproceduralScratchRegister() {
302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  return X86ManagedRegister::FromCpuRegister(ECX);
31b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
32b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
332c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86JniCallingConvention::InterproceduralScratchRegister() {
342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  return X86ManagedRegister::FromCpuRegister(ECX);
35b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
36b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
37dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian RogersManagedRegister X86JniCallingConvention::ReturnScratchRegister() const {
38dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  return ManagedRegister::NoRegister();  // No free regs, so assembler uses push/pop
39dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers}
40dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers
41b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogersstatic ManagedRegister ReturnRegisterForShorty(const char* shorty, bool jni) {
42169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  if (shorty[0] == 'F' || shorty[0] == 'D') {
43b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    if (jni) {
44b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      return X86ManagedRegister::FromX87Register(ST0);
45b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    } else {
46b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      return X86ManagedRegister::FromXmmRegister(XMM0);
47b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    }
48169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  } else if (shorty[0] == 'J') {
492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    return X86ManagedRegister::FromRegisterPair(EAX_EDX);
50169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  } else if (shorty[0] == 'V') {
5145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers    return ManagedRegister::NoRegister();
52b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    return X86ManagedRegister::FromCpuRegister(EAX);
54b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
55b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
56b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
572c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::ReturnRegister() {
58b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  return ReturnRegisterForShorty(GetShorty(), false);
592c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}
602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
612c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86JniCallingConvention::ReturnRegister() {
62b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  return ReturnRegisterForShorty(GetShorty(), true);
632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}
642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
6500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan RogersManagedRegister X86JniCallingConvention::IntReturnRegister() {
6600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return X86ManagedRegister::FromCpuRegister(EAX);
6700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}
6800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Managed runtime calling convention
70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
712c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::MethodRegister() {
7267375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  return X86ManagedRegister::FromCpuRegister(EAX);
732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}
742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86ManagedRuntimeCallingConvention::IsCurrentParamInRegister() {
76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  return false;  // Everything is passed by stack
77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86ManagedRuntimeCallingConvention::IsCurrentParamOnStack() {
80966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  // We assume all parameters are on stack, args coming via registers are spilled as entry_spills.
81966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  return true;
82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
842c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::CurrentParamRegister() {
85966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  ManagedRegister res = ManagedRegister::NoRegister();
86966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  if (!IsCurrentParamAFloatOrDouble()) {
87966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell    switch (gpr_arg_count_) {
883e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell      case 0:
893e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        res = X86ManagedRegister::FromCpuRegister(ECX);
903e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        break;
913e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell      case 1:
923e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        res = X86ManagedRegister::FromCpuRegister(EDX);
933e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        break;
943e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell      case 2:
953e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        // Don't split a long between the last register and the stack.
963e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        if (IsCurrentParamALong()) {
973e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell          return ManagedRegister::NoRegister();
983e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        }
993e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        res = X86ManagedRegister::FromCpuRegister(EBX);
1003e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        break;
101966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell    }
102966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  } else if (itr_float_and_doubles_ < 4) {
103966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell    // First four float parameters are passed via XMM0..XMM3
104966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell    res = X86ManagedRegister::FromXmmRegister(
105966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell                                 static_cast<XmmRegister>(XMM0 + itr_float_and_doubles_));
106966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  }
107966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  return res;
108966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell}
109966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell
110966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellManagedRegister X86ManagedRuntimeCallingConvention::CurrentParamHighLongRegister() {
111966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  ManagedRegister res = ManagedRegister::NoRegister();
112966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  DCHECK(IsCurrentParamALong());
113966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  switch (gpr_arg_count_) {
114966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell    case 0: res = X86ManagedRegister::FromCpuRegister(EDX); break;
115966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell    case 1: res = X86ManagedRegister::FromCpuRegister(EBX); break;
116966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  }
117966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell  return res;
118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1202c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersFrameOffset X86ManagedRuntimeCallingConvention::CurrentParamStackOffset() {
121cdd1d2d3fee0711b8b11db99f2dfb80113520100Ian Rogers  return FrameOffset(displacement_.Int32Value() +   // displacement
122790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                     kFramePointerSize +                 // Method*
123790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers                     (itr_slots_ * kFramePointerSize));  // offset into in args
124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
126fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoconst ManagedRegisterEntrySpills& X86ManagedRuntimeCallingConvention::EntrySpills() {
127b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  // We spill the argument registers on X86 to free them up for scratch use, we then assume
128b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  // all arguments are on the stack.
129b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  if (entry_spills_.size() == 0) {
130966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell    ResetIterator(FrameOffset(0));
131966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell    while (HasNext()) {
132966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell      ManagedRegister in_reg = CurrentParamRegister();
1333e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell      bool is_long = IsCurrentParamALong();
134966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell      if (!in_reg.IsNoRegister()) {
135966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell        int32_t size = IsParamADouble(itr_args_) ? 8 : 4;
136966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell        int32_t spill_offset = CurrentParamStackOffset().Uint32Value();
137966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell        ManagedRegisterSpill spill(in_reg, size, spill_offset);
138966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell        entry_spills_.push_back(spill);
1393e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        if (is_long) {
1403e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell          // special case, as we need a second register here.
141966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell          in_reg = CurrentParamHighLongRegister();
1423e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell          DCHECK(!in_reg.IsNoRegister());
1433e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell          // We have to spill the second half of the long.
1443e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell          ManagedRegisterSpill spill2(in_reg, size, spill_offset + 4);
1453e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell          entry_spills_.push_back(spill2);
146966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell        }
147966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell
148966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell        // Keep track of the number of GPRs allocated.
149966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell        if (!IsCurrentParamAFloatOrDouble()) {
1503e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell          if (is_long) {
1513e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell            // Long was allocated in 2 registers.
1523e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell            gpr_arg_count_ += 2;
1533e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell          } else {
1543e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell            gpr_arg_count_++;
1553e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell          }
156b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers        }
1573e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell      } else if (is_long) {
1583e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        // We need to skip the unused last register, which is empty.
1593e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        // If we are already out of registers, this is harmless.
1603e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell        gpr_arg_count_ += 2;
161b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
162966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell      Next();
163b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    }
164b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
165b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  return entry_spills_;
166b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers}
167b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers
168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// JNI calling convention
169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
170703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhaoX86JniCallingConvention::X86JniCallingConvention(bool is_static, bool is_synchronized,
171703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao                                                 const char* shorty)
172790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers    : JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) {
173703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao  callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(EBP));
174703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao  callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(ESI));
175703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao  callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(EDI));
176703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao}
177703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao
178703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhaouint32_t X86JniCallingConvention::CoreSpillMask() const {
179703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao  return 1 << EBP | 1 << ESI | 1 << EDI | 1 << kNumberOfCpuRegisters;
180703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao}
181bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
1822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogerssize_t X86JniCallingConvention::FrameSize() {
183703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao  // Method*, return address and callee save area size, local reference segment state
184cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  size_t frame_data_size = sizeof(StackReference<mirror::ArtMethod>) +
185cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe      (2 + CalleeSaveRegisters().size()) * kFramePointerSize;
186eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  // References plus 2 words for HandleScope header
187cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe  size_t handle_scope_size = HandleScope::SizeOf(kFramePointerSize, ReferenceCount());
1880d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  // Plus return value spill area size
189eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  return RoundUp(frame_data_size + handle_scope_size + SizeOfReturnValue(), kStackAlignment);
1900d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers}
1910d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers
1922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogerssize_t X86JniCallingConvention::OutArgSize() {
193790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  return RoundUp(NumberOfOutgoingStackArgs() * kFramePointerSize, kStackAlignment);
1947a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers}
1957a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers
1962c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86JniCallingConvention::IsCurrentParamInRegister() {
197b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  return false;  // Everything is passed by stack.
198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86JniCallingConvention::IsCurrentParamOnStack() {
201b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  return true;  // Everything is passed by stack.
202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2042c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86JniCallingConvention::CurrentParamRegister() {
205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LOG(FATAL) << "Should not reach here";
206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  return ManagedRegister::NoRegister();
207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
208b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2092c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersFrameOffset X86JniCallingConvention::CurrentParamStackOffset() {
210790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers  return FrameOffset(displacement_.Int32Value() - OutArgSize() + (itr_slots_ * kFramePointerSize));
211b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
212b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogerssize_t X86JniCallingConvention::NumberOfOutgoingStackArgs() {
214169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  size_t static_args = IsStatic() ? 1 : 0;  // count jclass
2157a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers  // regular argument parameters and this
216169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  size_t param_args = NumArgs() + NumLongOrDoubleArgs();
21700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // count JNIEnv* and return pc (pushed after Method*)
21800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  size_t total_args = static_args + param_args + 2;
21900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return total_args;
220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}  // namespace x86
223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}  // namespace art
224