Make entrypoints Thumb2.
Save the 64bit shifts that are more efficient as ARM code.
Move the standard .S set up code to asm_support_arm.S.
Change-Id: I38b95a88a3658e311020b59abfbe16f843b509ff
diff --git a/runtime/arch/arm/asm_support_arm.S b/runtime/arch/arm/asm_support_arm.S
index 559788f..ee4484b 100644
--- a/runtime/arch/arm/asm_support_arm.S
+++ b/runtime/arch/arm/asm_support_arm.S
@@ -19,7 +19,24 @@
#include "asm_support_arm.h"
+.cfi_sections .debug_frame
+.syntax unified
+.arch armv7-a
+.thumb
+
.macro ENTRY name
+ .thumb_func
+ .type \name, #function
+ .global \name
+ /* Cache alignment for function entry */
+ .balign 16
+\name:
+ .cfi_startproc
+ .fnstart
+.endm
+
+.macro ARM_ENTRY name
+ .arm
.type \name, #function
.global \name
/* Cache alignment for function entry */
diff --git a/runtime/arch/arm/jni_entrypoints_arm.S b/runtime/arch/arm/jni_entrypoints_arm.S
index f51f121..4a69644 100644
--- a/runtime/arch/arm/jni_entrypoints_arm.S
+++ b/runtime/arch/arm/jni_entrypoints_arm.S
@@ -16,8 +16,6 @@
#include "asm_support_arm.S"
- .cfi_sections .debug_frame
-
/*
* Jni dlsym lookup stub.
*/
@@ -34,11 +32,14 @@
mov r12, r0 @ save result in r12
add sp, #12 @ restore stack pointer
.cfi_adjust_cfa_offset -12
+ cbz r0, 1f @ is method code null?
pop {r0, r1, r2, r3, lr} @ restore regs
.cfi_adjust_cfa_offset -20
- cmp r12, #0 @ is method code null?
- bxne r12 @ if non-null, tail call to method's code
- bx lr @ otherwise, return to caller to handle exception
+ bx r12 @ if non-null, tail call to method's code
+1:
+ .cfi_adjust_cfa_offset 20
+ pop {r0, r1, r2, r3, pc} @ restore regs and return to caller to handle exception
+ .cfi_adjust_cfa_offset -20
END art_jni_dlsym_lookup_stub
/*
diff --git a/runtime/arch/arm/portable_entrypoints_arm.S b/runtime/arch/arm/portable_entrypoints_arm.S
index 073efdc..ac519d5 100644
--- a/runtime/arch/arm/portable_entrypoints_arm.S
+++ b/runtime/arch/arm/portable_entrypoints_arm.S
@@ -16,8 +16,6 @@
#include "asm_support_arm.S"
- .cfi_sections .debug_frame
-
/*
* Portable invocation stub.
* On entry:
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index d9bb433..a77ce01 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -16,8 +16,6 @@
#include "asm_support_arm.S"
- .cfi_sections .debug_frame
-
/* Deliver the given exception */
.extern artDeliverExceptionFromCode
/* Deliver an exception pending on a thread */
@@ -112,6 +110,18 @@
.cfi_adjust_cfa_offset -48
.endm
+.macro RETURN_IF_RESULT_IS_ZERO
+ cbnz r0, 1f @ result non-zero branch over
+ bx lr @ return
+1:
+.endm
+
+.macro RETURN_IF_RESULT_IS_NON_ZERO
+ cbz r0, 1f @ result zero branch over
+ bx lr @ return
+1:
+.endm
+
/*
* Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
* exception is Thread::Current()->exception_
@@ -218,8 +228,9 @@
.cfi_adjust_cfa_offset -16
mov r12, r1 @ save Method*->code_
RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
- cmp r0, #0 @ did we find the target?
- bxne r12 @ tail call to target if so
+ cbz r0, 1f @ did we find the target? if not go to exception delivery
+ bx r12 @ tail call to target
+1:
DELIVER_PENDING_EXCEPTION
END \c_name
.endm
@@ -281,7 +292,7 @@
/*
* On entry r0 is uint32_t* gprs_ and r1 is uint32_t* fprs_
*/
-ENTRY art_quick_do_long_jump
+ARM_ENTRY art_quick_do_long_jump
vldm r1, {s0-s31} @ load all fprs from argument fprs_
ldr r2, [r0, #60] @ r2 = r15 (PC from gprs_ 60=4*15)
add r0, r0, #12 @ increment r0 to skip gprs_[0..2] 12=4*3
@@ -302,8 +313,7 @@
mov r3, sp @ pass SP
bl artHandleFillArrayDataFromCode @ (Array*, const DexFile::Payload*, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success?
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_handle_fill_data
@@ -325,12 +335,11 @@
.extern artUnlockObjectFromCode
ENTRY art_quick_unlock_object
SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case exception allocation triggers GC
- mov r1, r9 @ pass Thread::Current
- mov r2, sp @ pass SP
- bl artUnlockObjectFromCode @ (Object* obj, Thread*, SP)
+ mov r1, r9 @ pass Thread::Current
+ mov r2, sp @ pass SP
+ bl artUnlockObjectFromCode @ (Object* obj, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success?
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_unlock_object
@@ -344,8 +353,7 @@
mov r3, sp @ pass SP
bl artCheckCastFromCode @ (Class* a, Class* b, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success?
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_check_cast
@@ -360,8 +368,7 @@
mov r3, sp @ pass SP
bl artCanPutArrayElementFromCode @ (Object* element, Class* array_class, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success?
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_can_put_array_element
@@ -378,8 +385,7 @@
@ artInitializeStaticStorageFromCode(uint32_t type_idx, Method* referrer, Thread*, SP)
bl artInitializeStaticStorageFromCode
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is non-null
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_initialize_static_storage
@@ -394,8 +400,7 @@
@ artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*, SP)
bl artInitializeTypeFromCode
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is non-null
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_initialize_type
@@ -411,8 +416,7 @@
@ artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx, Method* referrer, Thread*, SP)
bl artInitializeTypeAndVerifyAccessFromCode
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is non-null
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_initialize_type_and_verify_access
@@ -426,10 +430,11 @@
mov r2, r9 @ pass Thread::Current
mov r3, sp @ pass SP
bl artGet32StaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
- ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
+ ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r12, #0 @ success if no exception is pending
- bxeq lr @ return on success
+ cbnz r1, 1f @ success if no exception pending
+ bx lr @ return on success
+1:
DELIVER_PENDING_EXCEPTION
END art_quick_get32_static
@@ -443,10 +448,11 @@
mov r2, r9 @ pass Thread::Current
mov r3, sp @ pass SP
bl artGet64StaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
- ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
+ ldr r2, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r12, #0 @ success if no exception is pending
- bxeq lr @ return on success
+ cbnz r2, 1f @ success if no exception pending
+ bx lr @ return on success
+1:
DELIVER_PENDING_EXCEPTION
END art_quick_get64_static
@@ -460,10 +466,11 @@
mov r2, r9 @ pass Thread::Current
mov r3, sp @ pass SP
bl artGetObjStaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
- ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
+ ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r12, #0 @ success if no exception is pending
- bxeq lr @ return on success
+ cbnz r1, 1f @ success if no exception pending
+ bx lr @ return on success
+1:
DELIVER_PENDING_EXCEPTION
END art_quick_get_obj_static
@@ -479,10 +486,11 @@
str r12, [sp, #-16]! @ expand the frame and pass SP
bl artGet32InstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP)
add sp, #16 @ strip the extra frame
- ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
+ ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r12, #0 @ success if no exception is pending
- bxeq lr @ return on success
+ cbnz r1, 1f @ success if no exception pending
+ bx lr @ return on success
+1:
DELIVER_PENDING_EXCEPTION
END art_quick_get32_instance
@@ -501,10 +509,11 @@
bl artGet64InstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP)
add sp, #16 @ strip the extra frame
.cfi_adjust_cfa_offset -16
- ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
+ ldr r2, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r12, #0 @ success if no exception is pending
- bxeq lr @ return on success
+ cbnz r2, 1f @ success if no exception pending
+ bx lr @ return on success
+1:
DELIVER_PENDING_EXCEPTION
END art_quick_get64_instance
@@ -523,10 +532,11 @@
bl artGetObjInstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP)
add sp, #16 @ strip the extra frame
.cfi_adjust_cfa_offset -16
- ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
+ ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r12, #0 @ success if no exception is pending
- bxeq lr @ return on success
+ cbnz r1, 1f @ success if no exception pending
+ bx lr @ return on success
+1:
DELIVER_PENDING_EXCEPTION
END art_quick_get_obj_instance
@@ -546,8 +556,7 @@
add sp, #16 @ strip the extra frame
.cfi_adjust_cfa_offset -16
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is 0
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_set32_static
@@ -572,8 +581,7 @@
bl artSet64StaticFromCode @ (field_idx, referrer, new_val, Thread*, SP)
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
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_set64_static
@@ -593,8 +601,7 @@
add sp, #16 @ strip the extra frame
.cfi_adjust_cfa_offset -16
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is 0
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_set_obj_static
@@ -618,8 +625,7 @@
add sp, #16 @ release out args
.cfi_adjust_cfa_offset -16
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here
- cmp r0, #0 @ success if result is 0
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_set32_instance
@@ -641,8 +647,7 @@
add sp, #16 @ release out args
.cfi_adjust_cfa_offset -16
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here
- cmp r0, #0 @ success if result is 0
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_set64_instance
@@ -665,8 +670,7 @@
add sp, #16 @ release out args
.cfi_adjust_cfa_offset -16
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here
- cmp r0, #0 @ success if result is 0
- bxeq lr @ return on success
+ RETURN_IF_RESULT_IS_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_set_obj_instance
@@ -684,8 +688,7 @@
@ artResolveStringFromCode(Method* referrer, uint32_t string_idx, Thread*, SP)
bl artResolveStringFromCode
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is non-null
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_resolve_string
@@ -699,8 +702,7 @@
mov r3, sp @ pass SP
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
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_alloc_object
@@ -715,8 +717,7 @@
mov r3, sp @ pass SP
bl artAllocObjectFromCodeWithAccessCheck @ (uint32_t type_idx, Method* method, Thread*, SP)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is non-null
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_alloc_object_with_access_check
@@ -736,8 +737,7 @@
add sp, #16 @ strip the extra frame
.cfi_adjust_cfa_offset -16
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is non-null
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_alloc_array
@@ -758,8 +758,7 @@
add sp, #16 @ strip the extra frame
.cfi_adjust_cfa_offset -16
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is non-null
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_alloc_array_with_access_check
@@ -779,8 +778,7 @@
add sp, #16 @ strip the extra frame
.cfi_adjust_cfa_offset -16
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is non-null
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_check_and_alloc_array
@@ -800,8 +798,7 @@
add sp, #16 @ strip the extra frame
.cfi_adjust_cfa_offset -16
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cmp r0, #0 @ success if result is non-null
- bxne lr @ return on success
+ RETURN_IF_RESULT_IS_NON_ZERO
DELIVER_PENDING_EXCEPTION
END art_quick_check_and_alloc_array_with_access_check
@@ -812,8 +809,9 @@
ENTRY art_quick_test_suspend
ldrh r0, [rSELF, #THREAD_FLAGS_OFFSET]
mov rSUSPEND, #SUSPEND_CHECK_INTERVAL @ reset rSUSPEND to SUSPEND_CHECK_INTERVAL
- cmp r0, #0 @ check Thread::Current()->suspend_count_ == 0
- bxeq lr @ return if suspend_count_ == 0
+ cbnz r0, 1f @ check Thread::Current()->suspend_count_ == 0
+ bx lr @ return if suspend_count_ == 0
+1:
mov r0, rSELF
SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves for stack crawl
mov r1, sp
@@ -833,12 +831,13 @@
mov r2, r9 @ pass Thread::Current
mov r3, sp @ pass SP
blx artQuickProxyInvokeHandler @ (Method* proxy method, receiver, Thread*, SP)
- ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
+ ldr r2, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
ldr lr, [sp, #44] @ restore lr
add sp, #48 @ pop frame
.cfi_adjust_cfa_offset -48
- cmp r12, #0 @ success if no exception is pending
- bxeq lr @ return on success
+ cbnz r2, 1f @ success if no exception is pending
+ bx lr @ return on success
+1:
DELIVER_PENDING_EXCEPTION
END art_quick_proxy_invoke_handler
@@ -848,8 +847,7 @@
mov r2, r9 @ pass Thread::Current
mov r3, sp @ pass SP
blx artQuickResolutionTrampoline @ (Method* called, receiver, Thread*, SP)
- cmp r0, #0 @ is code pointer null?
- beq 1f @ goto exception
+ cbz r0, 1f @ is code pointer null? goto exception
mov r12, r0
ldr r0, [sp, #0] @ load resolved method in r0
ldr r1, [sp, #8] @ restore non-callee save r1
@@ -869,12 +867,13 @@
mov r1, r9 @ pass Thread::Current
mov r2, sp @ pass SP
blx artQuickToInterpreterBridge @ (Method* method, Thread*, SP)
- ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
+ ldr r2, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
ldr lr, [sp, #44] @ restore lr
add sp, #48 @ pop frame
.cfi_adjust_cfa_offset -48
- cmp r12, #0 @ success if no exception is pending
- bxeq lr @ return on success
+ cbnz r2, 1f @ success if no exception is pending
+ bx lr @ return on success
+1:
DELIVER_PENDING_EXCEPTION
END art_quick_to_interpreter_bridge
@@ -993,7 +992,7 @@
* r2: shift count
*/
/* shl-long vAA, vBB, vCC */
-ENTRY art_quick_shl_long
+ARM_ENTRY art_quick_shl_long @ ARM code as thumb code requires spills
and r2, r2, #63 @ r2<- r2 & 0x3f
mov r1, r1, asl r2 @ r1<- r1 << r2
rsb r3, r2, #32 @ r3<- 32 - r2
@@ -1015,7 +1014,7 @@
* r2: shift count
*/
/* shr-long vAA, vBB, vCC */
-ENTRY art_quick_shr_long
+ARM_ENTRY art_quick_shr_long @ ARM code as thumb code requires spills
and r2, r2, #63 @ r0<- r0 & 0x3f
mov r0, r0, lsr r2 @ r0<- r2 >> r2
rsb r3, r2, #32 @ r3<- 32 - r2
@@ -1037,7 +1036,7 @@
* r2: shift count
*/
/* ushr-long vAA, vBB, vCC */
-ENTRY art_quick_ushr_long
+ARM_ENTRY art_quick_ushr_long @ ARM code as thumb code requires spills
and r2, r2, #63 @ r0<- r0 & 0x3f
mov r0, r0, lsr r2 @ r0<- r2 >> r2
rsb r3, r2, #32 @ r3<- 32 - r2
@@ -1070,8 +1069,10 @@
/* Clamp start to [0..count] */
cmp r2, #0
+ it lt
movlt r2, #0
cmp r2, r3
+ it gt
movgt r2, r3
/* Build a pointer to the start of string data */
@@ -1167,8 +1168,10 @@
.extern __memcmp16
ENTRY art_quick_string_compareto
mov r2, r0 @ this to r2, opening up r0 for return value
- subs r0, r2, r1 @ Same?
- bxeq lr
+ sub r0, r2, r1 @ Same?
+ cbnz r0,1f
+ bx lr
+1: @ Same strings, return.
push {r4, r7-r12, lr} @ 8 words - keep alignment
.save {r4, r7-r12, lr}
@@ -1199,6 +1202,7 @@
* r10 <- minCount
*/
subs r11, r7, r10
+ it ls
movls r10, r7
/* Now, build pointers to the string data */
@@ -1234,7 +1238,8 @@
ldrh r7, [r2, #2]!
ldrh r8, [r1, #2]!
subs r0, r3, r4
- subeqs r0, r7, r8
+ it eq
+ subseq r0, r7, r8
bne done
cmp r10, #28
bgt do_memcmp16
@@ -1249,8 +1254,10 @@
ldrh r9, [r2, #2]!
ldrh r12,[r1, #2]!
subs r0, r3, r4
- subeqs r0, r7, r8
- subeqs r0, r9, r12
+ it eq
+ subseq r0, r7, r8
+ it eq
+ subseq r0, r9, r12
bne done
subs r10, #3
bge loopback_triple
@@ -1285,6 +1292,7 @@
mov r2, r10
bl __memcmp16
cmp r0, #0
+ it eq
moveq r0, r7
done:
pop {r4, r7-r12, pc}