uboot/arch/blackfin/lib/memset.S
<<
>>
Prefs
   1/*
   2 * File: memset.S
   3 *
   4 * Copyright 2004-2007 Analog Devices Inc.
   5 * Enter bugs at http://blackfin.uclinux.org/
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, see the file COPYING, or write
  19 * to the Free Software Foundation, Inc.,
  20 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  21 */
  22
  23.align 2
  24
  25/*
  26 * C Library function MEMSET
  27 * R0 = address (leave unchanged to form result)
  28 * R1 = filler byte
  29 * R2 = count
  30 * Favours word aligned data.
  31 */
  32
  33.globl _memset;
  34.type _memset, STT_FUNC;
  35_memset:
  36        P0 = R0 ;              /* P0 = address */
  37        P2 = R2 ;              /* P2 = count   */
  38        R3 = R0 + R2;          /* end          */
  39        CC = R2 <= 7(IU);
  40        IF CC JUMP  .Ltoo_small;
  41        R1 = R1.B (Z);         /* R1 = fill char */
  42        R2 =  3;
  43        R2 = R0 & R2;          /* addr bottom two bits */
  44        CC =  R2 == 0;             /* AZ set if zero.   */
  45        IF !CC JUMP  .Lforce_align ;  /* Jump if addr not aligned. */
  46
  47.Laligned:
  48        P1 = P2 >> 2;          /* count = n/4        */
  49        R2 = R1 <<  8;         /* create quad filler */
  50        R2.L = R2.L + R1.L(NS);
  51        R2.H = R2.L + R1.H(NS);
  52        P2 = R3;
  53
  54        LSETUP (.Lquad_loop , .Lquad_loop) LC0=P1;
  55.Lquad_loop:
  56        [P0++] = R2;
  57
  58        CC = P0 == P2;
  59        IF !CC JUMP .Lbytes_left;
  60        RTS;
  61
  62.Lbytes_left:
  63        R2 = R3;                /* end point */
  64        R3 = P0;                /* current position */
  65        R2 = R2 - R3;           /* bytes left */
  66        P2 = R2;
  67
  68.Ltoo_small:
  69        CC = P2 == 0;           /* Check zero count */
  70        IF CC JUMP .Lfinished;    /* Unusual */
  71
  72.Lbytes:
  73        LSETUP (.Lbyte_loop , .Lbyte_loop) LC0=P2;
  74.Lbyte_loop:
  75        B[P0++] = R1;
  76
  77.Lfinished:
  78        RTS;
  79
  80.Lforce_align:
  81        CC = BITTST (R0, 0);  /* odd byte */
  82        R0 = 4;
  83        R0 = R0 - R2;
  84        P1 = R0;
  85        R0 = P0;                    /* Recover return address */
  86        IF !CC JUMP .Lskip1;
  87        B[P0++] = R1;
  88.Lskip1:
  89        CC = R2 <= 2;          /* 2 bytes */
  90        P2 -= P1;              /* reduce count */
  91        IF !CC JUMP .Laligned;
  92        B[P0++] = R1;
  93        B[P0++] = R1;
  94        JUMP .Laligned;
  95
  96.size _memset, .-_memset
  97