Update.
[glibc.git] / sysdeps / alpha / bzero.S
blobc614fc1a6ea569f9a86c85efac7f130a233d0a43
1 /* Copyright (C) 1996 Free Software Foundation, Inc.
2    Contributed by Richard Henderson (rth@tamu.edu)
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB.  If
18 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 Cambridge, MA 02139, USA.  */
21 /* Fill a block of memory with zeros.  Optimized for the Alpha architecture:
23    - memory accessed as aligned quadwords only
24    - destination memory not read unless needed for good cache behaviour
25    - basic blocks arranged to optimize branch prediction for full-quadword
26      aligned memory blocks.
27    - partial head and tail quadwords constructed with byte-mask instructions
29    This is generally scheduled for the EV5 (got to look out for my own
30    interests :-), but with EV4 needs in mind.  There *should* be no more
31    stalls for the EV4 than there are for the EV5.
35 #include <sysdep.h>
37         .set noat
38         .set noreorder
40         .text
42 /* There is a problem with either gdb (as of 4.16) or gas (as of 2.7) that
43    doesn't like putting the entry point for a procedure somewhere in the
44    middle of the procedure descriptor.  Work around this by putting the main
45    loop in its own procedure descriptor.  */
47         /* On entry to this basic block:
48            t3 == loop counter
49            t4 == bytes in partial final word
50            a0 == possibly misaligned destination pointer  */
52         .ent bzero_loop
53         .align 3
54 bzero_loop:
55         .frame sp, 0, ra, 0
56         .prologue 0
58         beq     t3, $tail       #
59         blbc    t3, 0f          # skip single store if count even
61         stq_u   zero, 0(a0)     # e0    : store one word
62         subq    t3, 1, t3       # .. e1 :
63         addq    a0, 8, a0       # e0    :
64         beq     t3, $tail       # .. e1 :
66 0:      stq_u   zero, 0(a0)     # e0    : store two words
67         subq    t3, 2, t3       # .. e1 :
68         stq_u   zero, 8(a0)     # e0    :
69         addq    a0, 16, a0      # .. e1 :
70         bne     t3, 0b          # e1    :
72 $tail:  bne     t4, 1f          # is there a tail to do?
73         ret                     # no
75 1:      ldq_u   t0, 0(a0)       # yes, load original data
76         mskqh   t0, t4, t0      #
77         stq_u   t0, 0(a0)       #
78         ret                     #
80         .end bzero_loop
82 ENTRY(bzero)
83 #ifdef PROF
84         ldgp    gp, 0(pv)
85         lda     AT, _mcount
86         jsr     AT, (AT), _mcount
87         .prologue 1
88 #else
89         .prologue 0
90 #endif
92         mov     a0, v0          # e0    : move return value in place
93         beq     a1, $done       # .. e1 : early exit for zero-length store
94         and     a0, 7, t1       # e0    :
95         addq    a1, t1, a1      # e1    : add dest misalignment to count
96         srl     a1, 3, t3       # e0    : loop = count >> 3
97         and     a1, 7, t4       # .. e1 : find number of bytes in tail
98         unop                    #       :
99         beq     t1, bzero_loop  # e1    : aligned head, jump right in
101         ldq_u   t0, 0(a0)       # e0    : load original data to mask into
102         cmpult  a1, 8, t2       # .. e1 : is this a sub-word set?
103         bne     t2, $oneq       # e1    :
105         mskql   t0, a0, t0      # e0    : we span words.  finish this partial
106         subq    t3, 1, t3       # e0    :
107         addq    a0, 8, a0       # .. e1 :
108         stq_u   t0, -8(a0)      # e0    :
109         br      bzero_loop      # .. e1 :
111         .align 3
112 $oneq:
113         mskql   t0, a0, t2      # e0    :
114         mskqh   t0, a1, t3      # e0    :
115         or      t2, t3, t0      # e1    :
116         stq_u   t0, 0(a0)       # e0    :
118 $done:  ret
120         END(bzero)