blob: 942084952a25765c27cbecff203ad8ff9c3dd6e7 [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() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070046 return FrameOffset(displacement_.Int32Value() + (itr_slots_ * kPointerSize));
Ian Rogersb033c752011-07-20 12:22:35 -070047}
48
49// JNI calling convention
50
Ian Rogers0d666d82011-08-14 16:03:46 -070051size_t JniCallingConvention::FrameSize() {
52 // Return address and Method*
53 size_t frame_data_size = 2 * kPointerSize;
54 // Handles plus 2 words for SHB header
55 size_t handle_area_size = (HandleCount() + 2) * kPointerSize;
56 // Plus return value spill area size
57 return RoundUp(frame_data_size + handle_area_size + SizeOfReturnValue(), 16);
58}
59
60size_t JniCallingConvention::SpillAreaSize() {
61 // No spills, return address was pushed at the top of the frame
62 return 0;
63}
64
65std::vector<ManagedRegister>* JniCallingConvention::ComputeRegsToSpillPreCall()
66{
67 // No live values in registers (everything is on the stack) so never anything
68 // to preserve.
69 return new std::vector<ManagedRegister>();
70}
71
Carl Shapiroe2d373e2011-07-25 15:20:06 -070072bool JniCallingConvention::IsOutArgRegister(ManagedRegister) {
73 return false; // Everything is passed by stack
74}
75
Ian Rogersb033c752011-07-20 12:22:35 -070076bool JniCallingConvention::IsCurrentParamInRegister() {
77 return false; // Everything is passed by stack
78}
79
80bool JniCallingConvention::IsCurrentParamOnStack() {
81 return true; // Everything is passed by stack
82}
83
84ManagedRegister JniCallingConvention::CurrentParamRegister() {
85 LOG(FATAL) << "Should not reach here";
86 return ManagedRegister::NoRegister();
87}
88
89FrameOffset JniCallingConvention::CurrentParamStackOffset() {
Ian Rogersb033c752011-07-20 12:22:35 -070090 return FrameOffset(displacement_.Int32Value() - OutArgSize() +
Shih-wei Liao5381cf92011-07-27 00:28:04 -070091 (itr_slots_ * kPointerSize));
Ian Rogersb033c752011-07-20 12:22:35 -070092}
93
94size_t JniCallingConvention::NumberOfOutgoingStackArgs() {
95 return GetMethod()->NumArgs() + GetMethod()->NumLongOrDoubleArgs();
96}
97
98} // namespace art