linux/arch/blackfin/lib/memcmp.S
<<
>>
Prefs
   1/*
   2 * Copyright 2004-2009 Analog Devices Inc.
   3 *
   4 * Licensed under the ADI 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