1    /*
2     * String's compareTo.
3     *
4     * Requires r0/r1 to have been previously checked for null.  Will
5     * return negative if this's string is < comp, 0 if they are the
6     * same and positive if >.
7     *
8     * IMPORTANT NOTE:
9     *
10     * This code relies on hard-coded offsets for string objects, and must be
11     * kept in sync with definitions in UtfString.h.  See asm-constants.h
12     *
13     * On entry:
14     *    r0:   this object pointer
15     *    r1:   comp object pointer
16     *
17     */
18
19    mov    r2, r0         @ this to r2, opening up r0 for return value
20    subs   r0, r2, r1     @ Same?
21    bxeq   lr
22
23    ldr    r4, [r2, #STRING_FIELDOFF_OFFSET]
24    ldr    r9, [r1, #STRING_FIELDOFF_OFFSET]
25    ldr    r7, [r2, #STRING_FIELDOFF_COUNT]
26    ldr    r10, [r1, #STRING_FIELDOFF_COUNT]
27    ldr    r2, [r2, #STRING_FIELDOFF_VALUE]
28    ldr    r1, [r1, #STRING_FIELDOFF_VALUE]
29
30    /*
31     * At this point, we have:
32     *    value:  r2/r1
33     *    offset: r4/r9
34     *    count:  r7/r10
35     * We're going to compute
36     *    r11 <- countDiff
37     *    r10 <- minCount
38     */
39     subs  r11, r7, r10
40     movls r10, r7
41
42     /* Now, build pointers to the string data */
43     add   r2, r2, r4, lsl #1
44     add   r1, r1, r9, lsl #1
45     /*
46      * Note: data pointers point to previous element so we can use pre-index
47      * mode with base writeback.
48      */
49     add   r2, #16-2   @ offset to contents[-1]
50     add   r1, #16-2   @ offset to contents[-1]
51
52     /*
53      * At this point we have:
54      *   r2: *this string data
55      *   r1: *comp string data
56      *   r10: iteration count for comparison
57      *   r11: value to return if the first part of the string is equal
58      *   r0: reserved for result
59      *   r3, r4, r7, r8, r9, r12 available for loading string data
60      */
61
62    subs  r10, #2
63    blt   do_remainder2
64
65      /*
66       * Unroll the first two checks so we can quickly catch early mismatch
67       * on long strings (but preserve incoming alignment)
68       */
69
70    ldrh  r3, [r2, #2]!
71    ldrh  r4, [r1, #2]!
72    ldrh  r7, [r2, #2]!
73    ldrh  r8, [r1, #2]!
74    subs  r0, r3, r4
75    subeqs  r0, r7, r8
76    bxne  lr
77    cmp   r10, #28
78    bgt   do_memcmp16
79    subs  r10, #3
80    blt   do_remainder
81
82loopback_triple:
83    ldrh  r3, [r2, #2]!
84    ldrh  r4, [r1, #2]!
85    ldrh  r7, [r2, #2]!
86    ldrh  r8, [r1, #2]!
87    ldrh  r9, [r2, #2]!
88    ldrh  r12,[r1, #2]!
89    subs  r0, r3, r4
90    subeqs  r0, r7, r8
91    subeqs  r0, r9, r12
92    bxne  lr
93    subs  r10, #3
94    bge   loopback_triple
95
96do_remainder:
97    adds  r10, #3
98    beq   returnDiff
99
100loopback_single:
101    ldrh  r3, [r2, #2]!
102    ldrh  r4, [r1, #2]!
103    subs  r0, r3, r4
104    bxne  lr
105    subs  r10, #1
106    bne     loopback_single
107
108returnDiff:
109    mov   r0, r11
110    bx    lr
111
112do_remainder2:
113    adds  r10, #2
114    bne   loopback_single
115    mov   r0, r11
116    bx    lr
117
118    /* Long string case */
119do_memcmp16:
120    mov   r4, lr
121    ldr   lr, .Lmemcmp16
122    mov   r7, r11
123    add   r0, r2, #2
124    add   r1, r1, #2
125    mov   r2, r10
126    blx   lr
127    cmp   r0, #0
128    bxne  r4
129    mov   r0, r7
130    bx    r4
131
132.Lmemcmp16:
133    .word __memcmp16
134