Initial ARM JNI compiler support.
Change-Id: I85183eec9a2645e6cb074b4b18bc6af800a77e06
diff --git a/src/calling_convention_arm.cc b/src/calling_convention_arm.cc
index 7535389..f93dc9b 100644
--- a/src/calling_convention_arm.cc
+++ b/src/calling_convention_arm.cc
@@ -17,9 +17,9 @@
ManagedRegister CallingConvention::ReturnRegister() {
const Method *method = GetMethod();
if (GetMethod()->IsReturnAFloat()) {
- return ManagedRegister::FromSRegister(S0);
+ return ManagedRegister::FromCoreRegister(R0);
} else if (GetMethod()->IsReturnADouble()) {
- return ManagedRegister::FromDRegister(D0);
+ return ManagedRegister::FromRegisterPair(R0_R1);
} else if (method->IsReturnALong()) {
return ManagedRegister::FromRegisterPair(R0_R1);
} else if (method->IsReturnVoid()) {
@@ -44,8 +44,18 @@
};
ManagedRegister ManagedRuntimeCallingConvention::CurrentParamRegister() {
CHECK_LT(itr_position_, 3u);
- return
- ManagedRegister::FromCoreRegister(kManagedArgumentRegisters[itr_position_]);
+ const Method* method = GetMethod();
+ if (method->IsParamALongOrDouble(itr_position_)) {
+ // TODO: handle a long/double split between registers and the stack, also
+ // itr_position_ 0
+ if (itr_position_ != 1u) {
+ LOG(WARNING) << "Unimplemented";
+ }
+ return ManagedRegister::FromRegisterPair(R2_R3);
+ } else {
+ return
+ ManagedRegister::FromCoreRegister(kManagedArgumentRegisters[itr_position_]);
+ }
}
FrameOffset ManagedRuntimeCallingConvention::CurrentParamStackOffset() {
@@ -56,25 +66,41 @@
// JNI calling convention
+// Will reg be crushed by an outgoing argument?
+bool JniCallingConvention::IsOutArgRegister(ManagedRegister) {
+ // R0 holds the method register and will be crushed by the JNIEnv*
+ return true;
+}
+
bool JniCallingConvention::IsCurrentParamInRegister() {
- return itr_position_ < 4;
+ return (itr_position_ + itr_longs_and_doubles_) < 4;
}
bool JniCallingConvention::IsCurrentParamOnStack() {
- return itr_position_ >= 4;
+ return (itr_position_ + itr_longs_and_doubles_) >= 4;
}
static const Register kJniArgumentRegisters[] = {
R0, R1, R2, R3
};
ManagedRegister JniCallingConvention::CurrentParamRegister() {
- CHECK_LT(itr_position_, 4u);
- return
- ManagedRegister::FromCoreRegister(kJniArgumentRegisters[itr_position_]);
+ CHECK_LT(itr_position_ + itr_longs_and_doubles_, 4u);
+ const Method* method = GetMethod();
+ int arg_pos = itr_position_ - (method->IsStatic() ? 2 : 1);
+ if ((itr_position_ >= 2) && method->IsParamALongOrDouble(arg_pos)) {
+ // TODO: handle a long/double split between registers and the stack
+ if (itr_position_ != 2u) {
+ LOG(WARNING) << "Unimplemented";
+ }
+ return ManagedRegister::FromRegisterPair(R2_R3);
+ } else {
+ return
+ ManagedRegister::FromCoreRegister(kJniArgumentRegisters[itr_position_]);
+ }
}
FrameOffset JniCallingConvention::CurrentParamStackOffset() {
- CHECK_GE(itr_position_, 4u);
+ CHECK_GE(itr_position_ + itr_longs_and_doubles_, 4u);
return FrameOffset(displacement_.Int32Value() - OutArgSize()
+ ((itr_position_ + itr_longs_and_doubles_ - 4) * kPointerSize));
}