blob: 54bde47321c657d3e400b9afbdc3c6faa3998be3 [file] [log] [blame]
/*
* String's compareTo.
*
* Requires r0/r1 to have been previously checked for null. Will
* return negative if this's string is < comp, 0 if they are the
* same and positive if >.
*
* IMPORTANT NOTE:
*
* This code relies on hard-coded offsets for string objects, and must be
* kept in sync with definitions in UtfString.h. See asm-constants.h
*
* On entry:
* r0: this object pointer
* r1: comp object pointer
*
*/
mov r2, r0 @ this to r2, opening up r0 for return value
subs r0, r2, r1 @ Same?
bxeq lr
ldr r4, [r2, #STRING_FIELDOFF_OFFSET]
ldr r9, [r1, #STRING_FIELDOFF_OFFSET]
ldr r7, [r2, #STRING_FIELDOFF_COUNT]
ldr r10, [r1, #STRING_FIELDOFF_COUNT]
ldr r2, [r2, #STRING_FIELDOFF_VALUE]
ldr r1, [r1, #STRING_FIELDOFF_VALUE]
/*
* At this point, we have:
* value: r2/r1
* offset: r4/r9
* count: r7/r10
* We're going to compute
* r11 <- countDiff
* r10 <- minCount
*/
subs r11, r7, r10
movls r10, r7
/* Now, build pointers to the string data */
add r2, r2, r4, lsl #1
add r1, r1, r9, lsl #1
/*
* Note: data pointers point to previous element so we can use pre-index
* mode with base writeback.
*/
add r2, #16-2 @ offset to contents[-1]
add r1, #16-2 @ offset to contents[-1]
/*
* At this point we have:
* r2: *this string data
* r1: *comp string data
* r10: iteration count for comparison
* r11: value to return if the first part of the string is equal
* r0: reserved for result
* r3, r4, r7, r8, r9, r12 available for loading string data
*/
subs r10, #2
blt do_remainder2
/*
* Unroll the first two checks so we can quickly catch early mismatch
* on long strings (but preserve incoming alignment)
*/
ldrh r3, [r2, #2]!
ldrh r4, [r1, #2]!
ldrh r7, [r2, #2]!
ldrh r8, [r1, #2]!
subs r0, r3, r4
subeqs r0, r7, r8
bxne lr
cmp r10, #28
bgt do_memcmp16
subs r10, #3
blt do_remainder
loopback_triple:
ldrh r3, [r2, #2]!
ldrh r4, [r1, #2]!
ldrh r7, [r2, #2]!
ldrh r8, [r1, #2]!
ldrh r9, [r2, #2]!
ldrh r12,[r1, #2]!
subs r0, r3, r4
subeqs r0, r7, r8
subeqs r0, r9, r12
bxne lr
subs r10, #3
bge loopback_triple
do_remainder:
adds r10, #3
beq returnDiff
loopback_single:
ldrh r3, [r2, #2]!
ldrh r4, [r1, #2]!
subs r0, r3, r4
bxne lr
subs r10, #1
bne loopback_single
returnDiff:
mov r0, r11
bx lr
do_remainder2:
adds r10, #2
bne loopback_single
mov r0, r11
bx lr
/* Long string case */
do_memcmp16:
mov r4, lr
ldr lr, .Lmemcmp16
mov r7, r11
add r0, r2, #2
add r1, r1, #2
mov r2, r10
blx lr
cmp r0, #0
bxne r4
mov r0, r7
bx r4
.Lmemcmp16:
.word __memcmp16