OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [machine/] [z8k/] [memcmp.S] - Rev 816

Compare with Previous | Blame | View Log

/*
 * memcmp routine for Z8000
 * Copyright (C) 2004 Christian Groessler <chris@groessler.org>
 *
 * Permission to use, copy, modify, and distribute this file
 * for any purpose is hereby granted without fee, provided that
 * the above copyright notice and this notice appears in all
 * copies.
 *
 * This file is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

/* int memcmp(const void *b1, const void *b2, size_t length);
 */

        name    "memcmp.S"

        .text
        even
global  _memcmp

_memcmp:

#ifdef __Z8001__
        segm

#ifdef __STD_CALL__
        ldl     rr6,rr14(#4)
        ldl     rr4,rr14(#8)
        ldl     rr2,rr14(#12)
#endif

/* rr2  - length        (high word ignored)
 * rr4  - b2
 * rr6  - b1
 */

        clr     r1              /* initialize return value */
        testl   rr2
        jr      z,finish

        bitb    rl7,#0          /* odd b1? */
        jr      nz,testb2
        bitb    rl5,#0          /* odd b2? */
        jr      nz,odd_cmp      /* b1 even, b2 odd */
        jr      t,even_cmp

testb2:
        bitb    rl5,#0
        jr      z,odd_cmp       /* b2 even, b1 odd */

        cpsib   @rr6,@rr4,r3,eq
        jr      z,beq           /* bytes are the same */
        jr      t,byte_diff

beq:    jr      ov,finish       /* jump if r3 is zero now */

/* compare words */
even_cmp:
        ld      r2,r3           /* remember length */
        srl     r3,#1
        jr      z,no_words

        cpsir   @rr6,@rr4,r3,ne
        jr      nz,no_words

        dec     r7,#2
        dec     r5,#2           /* point to different bytes */
        ldk     r3,#2
        jr      t,odd_cmp

no_words:
        bitb    rl2,#0          /* odd length? */
        jr      z,finish

        cpsib   @rr6,@rr4,r3,eq
        jr      z,finish        /* last bytes are the same */
        jr      t,byte_diff

/* compare bytes */
odd_cmp:
        cpsirb  @rr6,@rr4,r3,ne
        jr      nz,finish

byte_diff:
        dec     r7,#1
        dec     r5,#1           /* point to different bytes */

        ldb     rl1,@rr6
        clr     r0
        ldb     rl0,@rr4
        sub     r1,r0

finish:                         /* set return value */
#ifdef __STD_CALL__
        ld      r7,r1
#else
        ld      r2,r1
#endif


#else           /* above Z8001, below Z8002 */


        unsegm

#ifdef __STD_CALL__
        ld      r7,r15(#2)
        ld      r6,r15(#4)
        ld      r5,r15(#6)
#endif

/* r5  - length
 * r6  - b2
 * r7  - b1
 */

        clr     r1              /* initialize return value */
        test    r5
        jr      z,finish

        bitb    rl7,#0          /* odd destination address? */
        jr      nz,testb2
        bitb    rl6,#0          /* odd source address? */
        jr      nz,odd_cmp      /* b1 even, b2 odd */
        jr      t,even_cmp

testb2:
        bitb    rl6,#0
        jr      z,odd_cmp       /* b2 even, b1 odd */

        cpsib   @r7,@r6,r5,eq
        jr      z,beq           /* bytes are the same */
        jr      t,byte_diff

beq:    jr      ov,finish       /* jump if r3 is zero now */

/* compare words */
even_cmp:
        ld      r4,r5           /* remember length */
        srl     r5,#1
        jr      z,no_words

        cpsir   @r7,@r6,r5,ne
        jr      nz,no_words

        dec     r7,#2
        dec     r6,#2           /* point to different bytes */
        ldk     r5,#2
        jr      t,odd_cmp

no_words:
        bitb    rl4,#0          /* odd length? */
        jr      z,finish

        cpsib   @r7,@r6,r4,eq
        jr      z,finish        /* last bytes are the same */
        jr      t,byte_diff

/* compare bytes */
odd_cmp:
        cpsirb  @r7,@r6,r5,ne
        jr      nz,finish

byte_diff:
        dec     r7,#1
        dec     r6,#1           /* point to different bytes */

        ldb     rl1,@r7
        clr     r0
        ldb     rl0,@r6
        sub     r1,r0

finish:
#ifdef __STD_CALL__
        ld      r7,r1
#else
        ld      r2,r1
#endif

#endif  /* Z8002 */

        ret
        .end

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.