[444] | 1 | #if defined __thumb__ |
---|
| 2 | |
---|
| 3 | #include "../../string/memcmp.c" |
---|
| 4 | |
---|
| 5 | #else |
---|
| 6 | |
---|
| 7 | #include <string.h> |
---|
| 8 | #include "xscale.h" |
---|
| 9 | |
---|
| 10 | int |
---|
| 11 | memcmp (const void * s1, const void * s2, size_t len) |
---|
| 12 | { |
---|
| 13 | int result; |
---|
| 14 | asm ( |
---|
| 15 | #ifndef __OPTIMIZE_SIZE__ |
---|
| 16 | "\n\ |
---|
| 17 | cmp %2, #0x3 @ Is the length a multiple of four ?\n\ |
---|
| 18 | bls 6f @ no = goto SLOW CHECK\n\ |
---|
| 19 | and r2, %0, #0x3 @ get alignment of first pointer\n\ |
---|
| 20 | and r3, %1, #0x3 @ get alignment of second pointer\n\ |
---|
| 21 | cmp r2, r3 @ Do the two pointers share the same alignment ?\n\ |
---|
| 22 | bne 6f @ no = goto SLOW CHECK\n\ |
---|
| 23 | mov lr, %0 @ copy first pointer into LR\n\ |
---|
| 24 | mov r4, %1 @ copy second pointer into R4\n\ |
---|
| 25 | cmp r2, #0x0 @ Are we comparing word aligned pointers ?\n\ |
---|
| 26 | beq 3f @ yes = goto START WORD CHECK LOOP\n\ |
---|
| 27 | b 1f @ jump to LOOP TEST\n\ |
---|
| 28 | 0: @ LOOP START\n\ |
---|
| 29 | ldrb r2, [lr], #1 @ load byte from LR, post inc.\n\ |
---|
| 30 | " PRELOADSTR("lr") " @ preload\n\ |
---|
| 31 | ldrb r3, [r4], #1 @ load byte from R4, post inc.\n\ |
---|
| 32 | " PRELOADSTR("r4") " @ preload\n\ |
---|
| 33 | cmp r2, r3 @ are the two bytes the same ?\n\ |
---|
| 34 | bne 5f @ no = goto EXIT\n\ |
---|
| 35 | tst lr, #0x3 @ has the LR become word aligned ?\n\ |
---|
| 36 | bne 1f @ no = skip the next test\n\ |
---|
| 37 | cmp %2, #4 @ is the count >= 4 ?\n\ |
---|
| 38 | bhs 3f @ yes = goto START WORD CHECK LOOP\n\ |
---|
| 39 | 1: @ LOOP TEST\n\ |
---|
| 40 | sub %2, %2, #1 @ decrement count by one\n\ |
---|
| 41 | cmn %2, #0x1 @ has the count reached -1 ?\n\ |
---|
| 42 | bne 0b @ no = loop back to LOOP START\n\ |
---|
| 43 | b 4f @ goto PASS END\n\ |
---|
| 44 | \n\ |
---|
| 45 | 0: @ ??\n\ |
---|
| 46 | cmp %2, #0x7 @ Is the count a multiple of 8 ?\n\ |
---|
| 47 | bls 3f @ no = goto ???\n\ |
---|
| 48 | ldmia lr,{r2, r3} @ get two words from first pointer, post inc\n\ |
---|
| 49 | ldmia r4,{r5, r6} @ get two words from second pointer, post inc\n\ |
---|
| 50 | sub %2, %2, #0x4 @ decrement count by 4\n\ |
---|
| 51 | cmp r2, r5 @ has the count reached ????\n\ |
---|
| 52 | bne 1f @ no = goto\n\ |
---|
| 53 | sub %2, %2, #0x4 @ decrement the count by 4\n\ |
---|
| 54 | add lr, lr, #0x4 @ add 4 to first pointer\n\ |
---|
| 55 | add r4, r4, #0x4 @ add 4 to second pointer\n\ |
---|
| 56 | cmp r3, r6 @ ???\n\ |
---|
| 57 | beq 0b @ goto ???\n\ |
---|
| 58 | 1: @ ??\n\ |
---|
| 59 | add %2, %2, #0x4 @ Add four to count\n\ |
---|
| 60 | sub %0, lr, #0x4 @ decrement first pointer by 4\n\ |
---|
| 61 | sub %1, r4, #0x4 @ decrement second pointer by 4\n\ |
---|
| 62 | b 6f @ goto SLOW CHECK\n\ |
---|
| 63 | \n\ |
---|
| 64 | 3: @ START WORD CHECK LOOP\n\ |
---|
| 65 | cmp %2, #0x3 @ is the count <= 3 ?\n\ |
---|
| 66 | bls 1f @ yes = goto CHECK BYTES BY HAND\n\ |
---|
| 67 | ldr r2, [lr], #4 @ get word from LR, post inc\n\ |
---|
| 68 | ldr r3, [r4], #4 @ get word from R4, post inc\n\ |
---|
| 69 | sub %2, %2, #4 @ decrement count by 4\n\ |
---|
| 70 | cmp r2, r3 @ are the two words the same ?\n\ |
---|
| 71 | bne 1f @ no = goto CHECK WORD CONTENTS\n\ |
---|
| 72 | 0: @ WORD CHECK LOOP\n\ |
---|
| 73 | cmp %2, #0x3 @ is the count <= 3 ?\n\ |
---|
| 74 | bls 1f @ yes = goto CHECK BYTES BY HAND\n\ |
---|
| 75 | ldr r2, [lr], #4 @ load word from LR, post inc\n\ |
---|
| 76 | " PRELOADSTR("lr") " @ preload\n\ |
---|
| 77 | ldr r3, [r4], #4 @ load word from R4, post inc\n\ |
---|
| 78 | " PRELOADSTR("r4") " @ preload\n\ |
---|
| 79 | sub %2, %2, #4 @ decrement count by 4\n\ |
---|
| 80 | cmp r2, r3 @ are the two words the same ?\n\ |
---|
| 81 | beq 0b @ yes = goto WORD CHECK LOOP\n\ |
---|
| 82 | 1: @ CHECK BYTES BY HAND\n\ |
---|
| 83 | sub %0, lr, #0x4 @ move LR back a word and put into first pointer\n\ |
---|
| 84 | sub %1, r4, #0x4 @ move R4 back a word and put into second pointer\n\ |
---|
| 85 | add %2, %2, #4 @ increment the count by 4\n\ |
---|
| 86 | @ fall through into SLOW CHECK" |
---|
| 87 | #endif /* !__OPTIMIZE_SIZE__ */ |
---|
| 88 | "\n\ |
---|
| 89 | 6: @ SLOW CHECK\n\ |
---|
| 90 | sub %2, %2, #1 @ Decrement the count by one\n\ |
---|
| 91 | cmn %2, #0x1 @ Has the count reached -1 ?\n\ |
---|
| 92 | beq 4f @ Yes - we are finished, goto PASS END\n\ |
---|
| 93 | 0: @ LOOP1\n\ |
---|
| 94 | ldrb r2, [%0], #1 @ get byte from first pointer\n\ |
---|
| 95 | " PRELOADSTR("%0") " @ preload first pointer\n\ |
---|
| 96 | ldrb r3, [%1], #1 @ get byte from second pointer\n\ |
---|
| 97 | " PRELOADSTR("%1") " @ preload second pointer\n\ |
---|
| 98 | cmp r2, r3 @ compare the two loaded bytes\n\ |
---|
| 99 | bne 5f @ if they are not equal goto EXIT\n\ |
---|
| 100 | sub %2, %2, #1 @ decremented count by 1\n\ |
---|
| 101 | cmn %2, #0x1 @ has the count reached -1 ?\n\ |
---|
| 102 | bne 0b @ no = then go back to LOOP1\n\ |
---|
| 103 | 4: @ PASS END\n\ |
---|
| 104 | mov r3, r2 @ Default return value is 0\n\ |
---|
| 105 | 5: @ EXIT\n\ |
---|
| 106 | rsb %0, r3, r2 @ return difference between last two bytes loaded" |
---|
| 107 | : "=r" (result), "=&r" (s2), "=&r" (len) |
---|
| 108 | : "0" (s1), "1" (s2), "2" (len) |
---|
| 109 | : "r2", "r3", "r4", "r5", "r6", "cc", "lr"); |
---|
| 110 | return result; |
---|
| 111 | } |
---|
| 112 | #endif |
---|