Various assembly fixes.
Change-Id: I42655af8dc3d7201d53c3393cdc585d9faa8cb82
diff --git a/src/assembler_arm.cc b/src/assembler_arm.cc
index cd0c5f5..e1976d7 100644
--- a/src/assembler_arm.cc
+++ b/src/assembler_arm.cc
@@ -1046,6 +1046,14 @@
Emit(encoding);
}
+void ArmAssembler::bx(Register rm, Condition cond) {
+ CHECK_NE(rm, kNoRegister);
+ CHECK_NE(cond, kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B24 | B21 | (0xfff << 8) | B4 |
+ (static_cast<int32_t>(rm) << kRmShift);
+ Emit(encoding);
+}
void ArmAssembler::MarkExceptionHandler(Label* label) {
EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
diff --git a/src/assembler_arm.h b/src/assembler_arm.h
index 3f979c6..e1d43e4 100644
--- a/src/assembler_arm.h
+++ b/src/assembler_arm.h
@@ -346,6 +346,7 @@
void b(Label* label, Condition cond = AL);
void bl(Label* label, Condition cond = AL);
void blx(Register rm, Condition cond = AL);
+ void bx(Register rm, Condition cond = AL);
// Macros.
// Add signed constant value to rd. May clobber IP.
diff --git a/src/jni_internal_arm.cc b/src/jni_internal_arm.cc
index 93380b1..f1ed092 100644
--- a/src/jni_internal_arm.cc
+++ b/src/jni_internal_arm.cc
@@ -46,7 +46,7 @@
// Move the managed thread pointer into R9.
__ mov(R9, ShifterOperand(R2));
- // Reset R4 to suspend check intercal
+ // Reset R4 to suspend check interval
__ LoadImmediate(R4, SUSPEND_CHECK_INTERVAL);
// Move frame down for arguments less 3 pushed values above
@@ -106,15 +106,10 @@
__ blx(IP);
// If the method returns a value, store it to the result pointer.
- char ch = method->GetShorty()->CharAt(0);
- if (ch != 'V') {
+ if (!method->IsReturnVoid()) {
// Load the result JValue pointer of the stub caller's out args.
__ LoadFromOffset(kLoadWord, IP, SP, frame_size);
- if (ch == 'D' || ch == 'J') {
- __ StoreToOffset(kStoreWordPair, R0, IP, 0);
- } else {
- __ StoreToOffset(kStoreWord, R0, IP, 0);
- }
+ __ StoreToOffset(method->IsReturnALongOrDouble() ? kStoreWordPair : kStoreWord, R0, IP, 0);
}
// Remove the frame less the spilled R4, R9 and LR
diff --git a/src/object.h b/src/object.h
index 80a4ce9..e5036e6 100644
--- a/src/object.h
+++ b/src/object.h
@@ -755,6 +755,10 @@
bool IsReturnALong() const;
+ bool IsReturnALongOrDouble() const {
+ return IsReturnALong() || IsReturnADouble();
+ }
+
bool IsReturnVoid() const;
// "Args" may refer to any of the 3 levels of "Args."
diff --git a/src/runtime_support_asm.S b/src/runtime_support_asm.S
index 2017c40..38eaf82 100644
--- a/src/runtime_support_asm.S
+++ b/src/runtime_support_asm.S
@@ -182,7 +182,7 @@
bl artHandleFillArrayDataFromCode @ (Array* array, const uint16_t* table, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success?
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_lock_object_from_code
@@ -209,7 +209,7 @@
bl artUnlockObjectFromCode @ (Object* obj, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success?
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_check_cast_from_code
@@ -224,7 +224,7 @@
bl artCheckCastFromCode @ (Class* a, Class* b, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success?
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_can_put_array_element_from_code
@@ -235,14 +235,14 @@
*/
art_can_put_array_element_from_code:
cmp r0, #0 @ return if element == NULL
- moveq pc, lr
+ bxeq lr
SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case exception allocation triggers GC
mov r2, r9 @ pass Thread::Current
mov r3, sp @ pass SP
bl artCanPutArrayElementFromCode @ (Object* element, Class* array_class, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success?
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_initialize_static_storage_from_code
@@ -260,7 +260,7 @@
bl artInitializeStaticStorageFromCode
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success if result is non-null
- movne pc, lr @ return on success
+ bxne lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_find_instance_field_from_code
@@ -275,7 +275,7 @@
bl artFindInstanceFieldFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success if result is non-null
- movne pc, lr @ return on success
+ bxne lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_get32_static_from_code
@@ -291,7 +291,7 @@
ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r12, #0 @ success if no exception is pending
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_get64_static_from_code
@@ -307,7 +307,7 @@
ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r12, #0 @ success if no exception is pending
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_get_obj_static_from_code
@@ -323,7 +323,7 @@
ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r12, #0 @ success if no exception is pending
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_set32_static_from_code
@@ -338,7 +338,7 @@
bl artSet32StaticFromCode @ (field_idx, referrer, new_val, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success if result is 0
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_set64_static_from_code
@@ -355,7 +355,7 @@
add sp, #16 @ release out args
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here
cmp r0, #0 @ success if result is 0
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_set_obj_static_from_code
@@ -370,7 +370,7 @@
bl artSetObjStaticFromCode @ (field_idx, referrer, new_val, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success if result is 0
- moveq pc, lr @ return on success
+ bxeq lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_alloc_object_from_code
@@ -385,7 +385,7 @@
bl artAllocObjectFromCode @ (uint32_t type_idx, Method* method, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success if result is non-null
- movne pc, lr @ return on success
+ bxne lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_alloc_array_from_code
@@ -401,7 +401,7 @@
bl artAllocArrayFromCode
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success if result is non-null
- movne pc, lr @ return on success
+ bxne lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_check_and_alloc_array_from_code
@@ -417,7 +417,7 @@
bl artCheckAndAllocArrayFromCode
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
cmp r0, #0 @ success if result is non-null
- movne pc, lr @ return on success
+ bxne lr @ return on success
DELIVER_PENDING_EXCEPTION
.global art_test_suspend
diff --git a/src/stub_arm.cc b/src/stub_arm.cc
index bb36415..b959377 100644
--- a/src/stub_arm.cc
+++ b/src/stub_arm.cc
@@ -32,7 +32,7 @@
// Restore registers which may have been modified by GC and R0 which will now hold the method*
__ DecreaseFrameSize(12);
__ PopList(save);
- __ mov(PC, ShifterOperand(R12)); // Leaf call to method's code
+ __ bx(R12); // Leaf call to method's code
__ bkpt(0);
@@ -89,11 +89,11 @@
__ LoadFromOffset(kLoadWord, R12, TR, OFFSETOF_MEMBER(Thread, pFindNativeMethod));
__ blx(R12);
__ mov(R12, ShifterOperand(R0)); // Save result of FindNativeMethod in R12
- __ AddConstant(SP, 12); // Restore registers (including outgoing arguments)
+ __ AddConstant(SP, 12); // Restore registers (including outgoing arguments)
__ PopList(save);
__ cmp(R12, ShifterOperand(0));
- __ mov(PC, ShifterOperand(R12), NE); // If R12 != 0 tail call into native code
- __ mov(PC, ShifterOperand(LR)); // Return to caller to handle exception
+ __ bx(R12, NE); // If R12 != 0 tail call into native code
+ __ bx(LR); // Return to caller to handle exception
assembler->EmitSlowPaths();