blob: ed95eb023172bad67829602286ff88ab1486ce50 [file] [log] [blame]
Ian Rogersb033c752011-07-20 12:22:35 -07001// Copyright 2011 Google Inc. All Rights Reserved.
Ian Rogersb033c752011-07-20 12:22:35 -07002
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07003#include "calling_convention.h"
4#include "logging.h"
5#include "utils.h"
Ian Rogersb033c752011-07-20 12:22:35 -07006
7namespace art {
8
9ManagedRegister CallingConvention::MethodRegister() {
10 return ManagedRegister::FromCpuRegister(EDI);
11}
12
13ManagedRegister CallingConvention::InterproceduralScratchRegister() {
14 return ManagedRegister::FromCpuRegister(ECX);
15}
16
17ManagedRegister CallingConvention::ReturnRegister() {
Ian Rogers45a76cb2011-07-21 22:00:15 -070018 const Method *method = GetMethod();
19 if (method->IsReturnAFloatOrDouble()) {
Ian Rogersb033c752011-07-20 12:22:35 -070020 return ManagedRegister::FromX87Register(ST0);
Ian Rogers45a76cb2011-07-21 22:00:15 -070021 } else if (method->IsReturnALong()) {
Ian Rogersb033c752011-07-20 12:22:35 -070022 return ManagedRegister::FromRegisterPair(EAX_EDX);
Ian Rogers45a76cb2011-07-21 22:00:15 -070023 } else if (method->IsReturnVoid()) {
24 return ManagedRegister::NoRegister();
Ian Rogersb033c752011-07-20 12:22:35 -070025 } else {
26 return ManagedRegister::FromCpuRegister(EAX);
27 }
28}
29
30// Managed runtime calling convention
31
32bool ManagedRuntimeCallingConvention::IsCurrentParamInRegister() {
33 return false; // Everything is passed by stack
34}
35
36bool ManagedRuntimeCallingConvention::IsCurrentParamOnStack() {
37 return true; // Everything is passed by stack
38}
39
40ManagedRegister ManagedRuntimeCallingConvention::CurrentParamRegister() {
41 LOG(FATAL) << "Should not reach here";
42 return ManagedRegister::NoRegister();
43}
44
45FrameOffset ManagedRuntimeCallingConvention::CurrentParamStackOffset() {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070046 return FrameOffset(displacement_.Int32Value() + // displacement
47 kPointerSize + // Method*
48 (itr_slots_ * kPointerSize)); // offset into in args
Ian Rogersb033c752011-07-20 12:22:35 -070049}
50
51// JNI calling convention
52
Ian Rogers0d666d82011-08-14 16:03:46 -070053size_t JniCallingConvention::FrameSize() {
54 // Return address and Method*
55 size_t frame_data_size = 2 * kPointerSize;
56 // Handles plus 2 words for SHB header
57 size_t handle_area_size = (HandleCount() + 2) * kPointerSize;
58 // Plus return value spill area size
59 return RoundUp(frame_data_size + handle_area_size + SizeOfReturnValue(), 16);
60}
61
62size_t JniCallingConvention::SpillAreaSize() {
63 // No spills, return address was pushed at the top of the frame
64 return 0;
65}
66
67std::vector<ManagedRegister>* JniCallingConvention::ComputeRegsToSpillPreCall()
68{
69 // No live values in registers (everything is on the stack) so never anything
70 // to preserve.
71 return new std::vector<ManagedRegister>();
72}
73
Carl Shapiroe2d373e2011-07-25 15:20:06 -070074bool JniCallingConvention::IsOutArgRegister(ManagedRegister) {
75 return false; // Everything is passed by stack
76}
77
Ian Rogersb033c752011-07-20 12:22:35 -070078bool JniCallingConvention::IsCurrentParamInRegister() {
79 return false; // Everything is passed by stack
80}
81
82bool JniCallingConvention::IsCurrentParamOnStack() {
83 return true; // Everything is passed by stack
84}
85
86ManagedRegister JniCallingConvention::CurrentParamRegister() {
87 LOG(FATAL) << "Should not reach here";
88 return ManagedRegister::NoRegister();
89}
90
91FrameOffset JniCallingConvention::CurrentParamStackOffset() {
Ian Rogersb033c752011-07-20 12:22:35 -070092 return FrameOffset(displacement_.Int32Value() - OutArgSize() +
Shih-wei Liao5381cf92011-07-27 00:28:04 -070093 (itr_slots_ * kPointerSize));
Ian Rogersb033c752011-07-20 12:22:35 -070094}
95
96size_t JniCallingConvention::NumberOfOutgoingStackArgs() {
97 return GetMethod()->NumArgs() + GetMethod()->NumLongOrDoubleArgs();
98}
99
100} // namespace art