blob: 92ca7807e4aceafcb4f9920db8d5cb3eb1a1ed7c [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;
Ian Rogers408f79a2011-08-23 18:22:33 -070056 // References plus 2 words for SIRT header
57 size_t sirt_size = (ReferenceCount() + 2) * kPointerSize;
Ian Rogers0d666d82011-08-14 16:03:46 -070058 // Plus return value spill area size
Ian Rogers408f79a2011-08-23 18:22:33 -070059 return RoundUp(frame_data_size + sirt_size + SizeOfReturnValue(),
60 kStackAlignment);
Ian Rogers0d666d82011-08-14 16:03:46 -070061}
62
Ian Rogers7a99c112011-09-07 12:48:27 -070063size_t JniCallingConvention::OutArgSize() {
64 return RoundUp(NumberOfOutgoingStackArgs() * kPointerSize, kStackAlignment);
65}
66
Ian Rogers762400c2011-08-23 12:14:16 -070067size_t JniCallingConvention::ReturnPcOffset() {
68 // Return PC is pushed at the top of the frame by the call into the method
69 return FrameSize() - kPointerSize;
70}
71
72
Ian Rogers0d666d82011-08-14 16:03:46 -070073size_t JniCallingConvention::SpillAreaSize() {
74 // No spills, return address was pushed at the top of the frame
75 return 0;
76}
77
Elliott Hughes90a33692011-08-30 13:27:07 -070078void JniCallingConvention::ComputeRegsToSpillPreCall(std::vector<ManagedRegister>& regs) {
Ian Rogers0d666d82011-08-14 16:03:46 -070079 // No live values in registers (everything is on the stack) so never anything
80 // to preserve.
Ian Rogers0d666d82011-08-14 16:03:46 -070081}
82
Carl Shapiroe2d373e2011-07-25 15:20:06 -070083bool JniCallingConvention::IsOutArgRegister(ManagedRegister) {
84 return false; // Everything is passed by stack
85}
86
Ian Rogersb033c752011-07-20 12:22:35 -070087bool JniCallingConvention::IsCurrentParamInRegister() {
88 return false; // Everything is passed by stack
89}
90
91bool JniCallingConvention::IsCurrentParamOnStack() {
92 return true; // Everything is passed by stack
93}
94
95ManagedRegister JniCallingConvention::CurrentParamRegister() {
96 LOG(FATAL) << "Should not reach here";
97 return ManagedRegister::NoRegister();
98}
99
100FrameOffset JniCallingConvention::CurrentParamStackOffset() {
Ian Rogersb033c752011-07-20 12:22:35 -0700101 return FrameOffset(displacement_.Int32Value() - OutArgSize() +
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700102 (itr_slots_ * kPointerSize));
Ian Rogersb033c752011-07-20 12:22:35 -0700103}
104
105size_t JniCallingConvention::NumberOfOutgoingStackArgs() {
Ian Rogers7a99c112011-09-07 12:48:27 -0700106 size_t static_args = GetMethod()->IsStatic() ? 1 : 0; // count jclass
107 // regular argument parameters and this
108 size_t param_args = GetMethod()->NumArgs() +
109 GetMethod()->NumLongOrDoubleArgs();
110 return static_args + param_args + 1; // count JNIEnv*
Ian Rogersb033c752011-07-20 12:22:35 -0700111}
112
113} // namespace art