1a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /*
2a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * String's indexOf.
3a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *
4a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * Requires a0 to have been previously checked for null.  Will
5a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * return index of match of a1 in v0.
6a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *
7a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * IMPORTANT NOTE:
8a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *
9a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * This code relies on hard-coded offsets for string objects, and must be
10a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * kept in sync wth definitions in UtfString.h  See asm-constants.h
11a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *
12a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * On entry:
13a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *    a0:   string object pointer
14a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *    a1:   char to match
15a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *    a2:   Starting offset in string data
16a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     */
17a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
18a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     lw    t0, STRING_FIELDOFF_OFFSET(a0)
19a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     lw    t1, STRING_FIELDOFF_COUNT(a0)
20a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     lw    v0, STRING_FIELDOFF_VALUE(a0)
21a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
22a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /*
23a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * At this point, we have:
24a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *    v0: object pointer
25a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *    a1: char to match
26a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *    a2: starting offset
27a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *    t0: offset
28a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *    t1: string length
29a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     */
30a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
31a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* Point to first element */
32a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     addu  v0, 16                    # point to contents[0]
33a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
34a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* Build pointer to start of string data */
35a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     sll   t7, t0, 1                 # multiply offset by 2
36a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     addu  v0, v0, t7
37a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
38a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* Save a copy of starting data in v1 */
39a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     move  v1, v0
40a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
41a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* Clamp start to [0..count] */
42a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     slt   t7, a2, zero
43a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     movn  a2, zero, t7
44a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     sgt   t7, a2, t1
45a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     movn  a2, t1, t7
46a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
47a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* Build pointer to start of data to compare */
48a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     sll   t7, a2, 1                # multiply offset by 2
49a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     addu  v0, v0, t7
50a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
51a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* Compute iteration count */
52a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     subu  a3, t1, a2
53a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
54a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /*
55a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * At this point we have:
56a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *   v0: start of data to test
57a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *   a1: char to compare
58a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *   a3: iteration count
59a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *   v1: original start of string
60a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     *   t0-t7 available for loading string data
61a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     */
62a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     subu  a3, 4
63a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     bltz  a3, indexof_remainder
64a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
65a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamindexof_loop4:
66a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     lhu   t0, 0(v0)
67a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     beq   t0, a1, match_0
68a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     lhu   t0, 2(v0)
69a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     beq   t0, a1, match_1
70a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     lhu   t0, 4(v0)
71a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     beq   t0, a1, match_2
72a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     lhu   t0, 6(v0)
73a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     beq   t0, a1, match_3
74a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     addu  v0, 8                     # offset to contents[i+4]
75a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     subu  a3, 4
76a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     bgez  a3, indexof_loop4
77a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
78a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamindexof_remainder:
79a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     addu  a3, 4
80a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     beqz  a3, indexof_nomatch
81a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
82a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamindexof_loop1:
83a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     lhu   t0, 0(v0)
84a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     beq   t0, a1, match_0
85a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     addu  v0, 2                     # offset to contents[i+1]
86a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     subu  a3, 1
87a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     bnez  a3, indexof_loop1
88a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
89a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamindexof_nomatch:
90a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     li    v0, -1
91a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     RETURN
92a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
93a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhammatch_0:
94a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     subu  v0, v1
95a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     sra   v0, v0, 1                 # divide by 2
96a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     RETURN
97a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhammatch_1:
98a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     addu  v0, 2
99a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     subu  v0, v1
100a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     sra   v0, v0, 1                 # divide by 2
101a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     RETURN
102a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhammatch_2:
103a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     addu  v0, 4
104a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     subu  v0, v1
105a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     sra   v0, v0, 1                 # divide by 2
106a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     RETURN
107a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhammatch_3:
108a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     addu  v0, 6
109a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     subu  v0, v1
110a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     sra   v0, v0, 1                 # divide by 2
111a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     RETURN
112