1/* 2 * Copyright 2004-2009 Analog Devices Inc. 3 * 4 * Licensed under the Clear BSD license or the GPL-2 (or later) 5 */ 6 7#include <linux/linkage.h> 8 9/* int memcmp(const void *s1, const void *s2, size_t n); 10 * R0 = First Address (s1) 11 * R1 = Second Address (s2) 12 * R2 = count (n) 13 * 14 * Favours word aligned data. 15 */ 16 17.text 18 19.align 2 20 21ENTRY(_memcmp) 22 I1 = P3; 23 P0 = R0; /* P0 = s1 address */ 24 P3 = R1; /* P3 = s2 Address */ 25 P2 = R2 ; /* P2 = count */ 26 CC = R2 <= 7(IU); 27 IF CC JUMP .Ltoo_small; 28 I0 = R1; /* s2 */ 29 R1 = R1 | R0; /* OR addresses together */ 30 R1 <<= 30; /* check bottom two bits */ 31 CC = AZ; /* AZ set if zero. */ 32 IF !CC JUMP .Lbytes ; /* Jump if addrs not aligned. */ 33 34 P1 = P2 >> 2; /* count = n/4 */ 35 R3 = 3; 36 R2 = R2 & R3; /* remainder */ 37 P2 = R2; /* set remainder */ 38 39 LSETUP (.Lquad_loop_s, .Lquad_loop_e) LC0=P1; 40.Lquad_loop_s: 41#if ANOMALY_05000202 42 R0 = [P0++]; 43 R1 = [I0++]; 44#else 45 MNOP || R0 = [P0++] || R1 = [I0++]; 46#endif 47 CC = R0 == R1; 48 IF !CC JUMP .Lquad_different; 49.Lquad_loop_e: 50 NOP; 51 52 P3 = I0; /* s2 */ 53.Ltoo_small: 54 CC = P2 == 0; /* Check zero count*/ 55 IF CC JUMP .Lfinished; /* very unlikely*/ 56 57.Lbytes: 58 LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2; 59.Lbyte_loop_s: 60 R1 = B[P3++](Z); /* *s2 */ 61 R0 = B[P0++](Z); /* *s1 */ 62 CC = R0 == R1; 63 IF !CC JUMP .Ldifferent; 64.Lbyte_loop_e: 65 NOP; 66 67.Ldifferent: 68 R0 = R0 - R1; 69 P3 = I1; 70 RTS; 71 72.Lquad_different: 73 /* We've read two quads which don't match. 74 * Can't just compare them, because we're 75 * a little-endian machine, so the MSBs of 76 * the regs occur at later addresses in the 77 * string. 78 * Arrange to re-read those two quads again, 79 * byte-by-byte. 80 */ 81 P0 += -4; /* back up to the start of the */ 82 P3 = I0; /* quads, and increase the*/ 83 P2 += 4; /* remainder count*/ 84 P3 += -4; 85 JUMP .Lbytes; 86 87.Lfinished: 88 R0 = 0; 89 P3 = I1; 90 RTS; 91 92ENDPROC(_memcmp) 93