blob: a514351aca8ba83ff8437ed4e9b06ed94e3b3db8 [file] [log] [blame]
/*
* String's compareTo.
*
* Requires a0/a1 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:
* a0: this object pointer
* a1: comp object pointer
*
*/
subu v0, a0, a1 # Same?
bnez v0, 1f
RETURN
1:
lw t0, STRING_FIELDOFF_OFFSET(a0)
lw t1, STRING_FIELDOFF_OFFSET(a1)
lw t2, STRING_FIELDOFF_COUNT(a0)
lw a2, STRING_FIELDOFF_COUNT(a1)
lw a0, STRING_FIELDOFF_VALUE(a0)
lw a1, STRING_FIELDOFF_VALUE(a1)
/*
* At this point, we have this/comp:
* offset: t0/t1
* count: t2/a2
* value: a0/a1
* We're going to compute
* a3 <- countDiff
* a2 <- minCount
*/
subu a3, t2, a2 # a3<- countDiff
sleu t7, t2, a2
movn a2, t2, t7 # a2<- minCount
/*
* Note: data pointers point to first element.
*/
addu a0, 16 # point to contents[0]
addu a1, 16 # point to contents[0]
/* Now, build pointers to the string data */
sll t7, t0, 1 # multiply offset by 2
addu a0, a0, t7
sll t7, t1, 1 # multiply offset by 2
addu a1, a1, t7
/*
* At this point we have:
* a0: *this string data
* a1: *comp string data
* a2: iteration count for comparison
* a3: value to return if the first part of the string is equal
* v0: reserved for result
* t0-t5 available for loading string data
*/
subu a2, 2
bltz a2, do_remainder2
/*
* Unroll the first two checks so we can quickly catch early mismatch
* on long strings (but preserve incoming alignment)
*/
lhu t0, 0(a0)
lhu t1, 0(a1)
subu v0, t0, t1
beqz v0, 1f
RETURN
1:
lhu t2, 2(a0)
lhu t3, 2(a1)
subu v0, t2, t3
beqz v0, 2f
RETURN
2:
addu a0, 4 # offset to contents[2]
addu a1, 4 # offset to contents[2]
li t7, 28
bgt a2, t7, do_memcmp16
subu a2, 3
bltz a2, do_remainder
loopback_triple:
lhu t0, 0(a0)
lhu t1, 0(a1)
subu v0, t0, t1
beqz v0, 1f
RETURN
1:
lhu t2, 2(a0)
lhu t3, 2(a1)
subu v0, t2, t3
beqz v0, 2f
RETURN
2:
lhu t4, 4(a0)
lhu t5, 4(a1)
subu v0, t4, t5
beqz v0, 3f
RETURN
3:
addu a0, 6 # offset to contents[i+3]
addu a1, 6 # offset to contents[i+3]
subu a2, 3
bgez a2, loopback_triple
do_remainder:
addu a2, 3
beqz a2, returnDiff
loopback_single:
lhu t0, 0(a0)
lhu t1, 0(a1)
subu v0, t0, t1
bnez v0, 1f
addu a0, 2 # offset to contents[i+1]
addu a1, 2 # offset to contents[i+1]
subu a2, 1
bnez a2, loopback_single
returnDiff:
move v0, a3
1:
RETURN
do_remainder2:
addu a2, 2
bnez a2, loopback_single
move v0, a3
RETURN
/* Long string case */
do_memcmp16:
move rOBJ, a3 # save return value if strings are equal
JAL(__memcmp16)
seq t0, v0, zero
movn v0, rOBJ, t0 # overwrite return value if strings are equal
RETURN