blob: 9598647462defd2fbb0fbe66e3c838a0dc266cb3 [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
Ian Rogers2c8f6532011-09-02 17:16:34 -07003#include "calling_convention_x86.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07004#include "logging.h"
Ian Rogers2c8f6532011-09-02 17:16:34 -07005#include "managed_register_x86.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07006#include "utils.h"
Ian Rogersb033c752011-07-20 12:22:35 -07007
8namespace art {
Ian Rogers2c8f6532011-09-02 17:16:34 -07009namespace x86 {
Ian Rogersb033c752011-07-20 12:22:35 -070010
Ian Rogers2c8f6532011-09-02 17:16:34 -070011// Calling convention
12
13ManagedRegister X86ManagedRuntimeCallingConvention::InterproceduralScratchRegister() {
14 return X86ManagedRegister::FromCpuRegister(ECX);
Ian Rogersb033c752011-07-20 12:22:35 -070015}
16
Ian Rogers2c8f6532011-09-02 17:16:34 -070017ManagedRegister X86JniCallingConvention::InterproceduralScratchRegister() {
18 return X86ManagedRegister::FromCpuRegister(ECX);
Ian Rogersb033c752011-07-20 12:22:35 -070019}
20
Ian Rogers2c8f6532011-09-02 17:16:34 -070021static ManagedRegister ReturnRegisterForMethod(Method* method) {
Ian Rogers45a76cb2011-07-21 22:00:15 -070022 if (method->IsReturnAFloatOrDouble()) {
Ian Rogers2c8f6532011-09-02 17:16:34 -070023 return X86ManagedRegister::FromX87Register(ST0);
Ian Rogers45a76cb2011-07-21 22:00:15 -070024 } else if (method->IsReturnALong()) {
Ian Rogers2c8f6532011-09-02 17:16:34 -070025 return X86ManagedRegister::FromRegisterPair(EAX_EDX);
Ian Rogers45a76cb2011-07-21 22:00:15 -070026 } else if (method->IsReturnVoid()) {
27 return ManagedRegister::NoRegister();
Ian Rogersb033c752011-07-20 12:22:35 -070028 } else {
Ian Rogers2c8f6532011-09-02 17:16:34 -070029 return X86ManagedRegister::FromCpuRegister(EAX);
Ian Rogersb033c752011-07-20 12:22:35 -070030 }
31}
32
Ian Rogers2c8f6532011-09-02 17:16:34 -070033ManagedRegister X86ManagedRuntimeCallingConvention::ReturnRegister() {
34 return ReturnRegisterForMethod(GetMethod());
35}
36
37ManagedRegister X86JniCallingConvention::ReturnRegister() {
38 return ReturnRegisterForMethod(GetMethod());
39}
40
Ian Rogersb033c752011-07-20 12:22:35 -070041// Managed runtime calling convention
42
Ian Rogers2c8f6532011-09-02 17:16:34 -070043ManagedRegister X86ManagedRuntimeCallingConvention::MethodRegister() {
Ian Rogers67375ac2011-09-14 00:55:44 -070044 return X86ManagedRegister::FromCpuRegister(EAX);
Ian Rogers2c8f6532011-09-02 17:16:34 -070045}
46
47bool X86ManagedRuntimeCallingConvention::IsCurrentParamInRegister() {
Ian Rogersb033c752011-07-20 12:22:35 -070048 return false; // Everything is passed by stack
49}
50
Ian Rogers2c8f6532011-09-02 17:16:34 -070051bool X86ManagedRuntimeCallingConvention::IsCurrentParamOnStack() {
Ian Rogersb033c752011-07-20 12:22:35 -070052 return true; // Everything is passed by stack
53}
54
Ian Rogers2c8f6532011-09-02 17:16:34 -070055ManagedRegister X86ManagedRuntimeCallingConvention::CurrentParamRegister() {
Ian Rogersb033c752011-07-20 12:22:35 -070056 LOG(FATAL) << "Should not reach here";
57 return ManagedRegister::NoRegister();
58}
59
Ian Rogers2c8f6532011-09-02 17:16:34 -070060FrameOffset X86ManagedRuntimeCallingConvention::CurrentParamStackOffset() {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070061 return FrameOffset(displacement_.Int32Value() + // displacement
62 kPointerSize + // Method*
63 (itr_slots_ * kPointerSize)); // offset into in args
Ian Rogersb033c752011-07-20 12:22:35 -070064}
65
66// JNI calling convention
67
Ian Rogersbdb03912011-09-14 00:55:44 -070068std::vector<ManagedRegister> X86JniCallingConvention::callee_save_regs_;
69
Ian Rogers2c8f6532011-09-02 17:16:34 -070070size_t X86JniCallingConvention::FrameSize() {
Ian Rogers0d666d82011-08-14 16:03:46 -070071 // Return address and Method*
72 size_t frame_data_size = 2 * kPointerSize;
Ian Rogers408f79a2011-08-23 18:22:33 -070073 // References plus 2 words for SIRT header
74 size_t sirt_size = (ReferenceCount() + 2) * kPointerSize;
Ian Rogers0d666d82011-08-14 16:03:46 -070075 // Plus return value spill area size
Ian Rogers408f79a2011-08-23 18:22:33 -070076 return RoundUp(frame_data_size + sirt_size + SizeOfReturnValue(),
77 kStackAlignment);
Ian Rogers0d666d82011-08-14 16:03:46 -070078}
79
Ian Rogers2c8f6532011-09-02 17:16:34 -070080size_t X86JniCallingConvention::OutArgSize() {
Ian Rogers7a99c112011-09-07 12:48:27 -070081 return RoundUp(NumberOfOutgoingStackArgs() * kPointerSize, kStackAlignment);
82}
83
Ian Rogers2c8f6532011-09-02 17:16:34 -070084size_t X86JniCallingConvention::ReturnPcOffset() {
Ian Rogers762400c2011-08-23 12:14:16 -070085 // Return PC is pushed at the top of the frame by the call into the method
86 return FrameSize() - kPointerSize;
87}
88
Ian Rogersad42e132011-09-17 20:23:33 -070089bool X86JniCallingConvention::IsMethodRegisterClobberedPreCall() {
Ian Rogers67375ac2011-09-14 00:55:44 -070090 return GetMethod()->IsSynchronized(); // Monitor enter crushes the method register
Carl Shapiroe2d373e2011-07-25 15:20:06 -070091}
92
Ian Rogers2c8f6532011-09-02 17:16:34 -070093bool X86JniCallingConvention::IsCurrentParamInRegister() {
Ian Rogersb033c752011-07-20 12:22:35 -070094 return false; // Everything is passed by stack
95}
96
Ian Rogers2c8f6532011-09-02 17:16:34 -070097bool X86JniCallingConvention::IsCurrentParamOnStack() {
Ian Rogersb033c752011-07-20 12:22:35 -070098 return true; // Everything is passed by stack
99}
100
Ian Rogers2c8f6532011-09-02 17:16:34 -0700101ManagedRegister X86JniCallingConvention::CurrentParamRegister() {
Ian Rogersb033c752011-07-20 12:22:35 -0700102 LOG(FATAL) << "Should not reach here";
103 return ManagedRegister::NoRegister();
104}
105
Ian Rogers2c8f6532011-09-02 17:16:34 -0700106FrameOffset X86JniCallingConvention::CurrentParamStackOffset() {
Ian Rogersb033c752011-07-20 12:22:35 -0700107 return FrameOffset(displacement_.Int32Value() - OutArgSize() +
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700108 (itr_slots_ * kPointerSize));
Ian Rogersb033c752011-07-20 12:22:35 -0700109}
110
Ian Rogers2c8f6532011-09-02 17:16:34 -0700111size_t X86JniCallingConvention::NumberOfOutgoingStackArgs() {
Ian Rogers7a99c112011-09-07 12:48:27 -0700112 size_t static_args = GetMethod()->IsStatic() ? 1 : 0; // count jclass
113 // regular argument parameters and this
114 size_t param_args = GetMethod()->NumArgs() +
115 GetMethod()->NumLongOrDoubleArgs();
Ian Rogersbdb03912011-09-14 00:55:44 -0700116 return static_args + param_args + 2; // count JNIEnv* and return pc (pushed after Method*)
Ian Rogersb033c752011-07-20 12:22:35 -0700117}
118
Ian Rogers2c8f6532011-09-02 17:16:34 -0700119} // namespace x86
Ian Rogersb033c752011-07-20 12:22:35 -0700120} // namespace art