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