or1k: Add prctl wrapper to unwrap variadic args
[glibc.git] / sysdeps / alpha / memset.S
blobc64e3d7aa8f7cecfcb4080a9bb513ca93aaa4ca0
1 /* Copyright (C) 1996-2024 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library.  If not, see
16    <https://www.gnu.org/licenses/>.  */
18 /* Fill a block of memory with a character.  Optimized for the Alpha
19    architecture:
21    - memory accessed as aligned quadwords only
22    - destination memory not read unless needed for good cache behaviour
23    - basic blocks arranged to optimize branch prediction for full-quadword
24      aligned memory blocks.
25    - partial head and tail quadwords constructed with byte-mask instructions
27    This is generally scheduled for the EV5 (got to look out for my own
28    interests :-), but with EV4 needs in mind.  There *should* be no more
29    stalls for the EV4 than there are for the EV5.
33 #include <sysdep.h>
35         .set noat
36         .set noreorder
38         .text
39         .type   memset, @function
40         .globl  memset
41         .usepv  memset, USEPV_PROF
43         cfi_startproc
45         /* On entry to this basic block:
46            t3 == loop counter
47            t4 == bytes in partial final word
48            a0 == possibly misaligned destination pointer
49            a1 == replicated source character  */
51         .align 3
52 memset_loop:
53         beq     t3, $tail
54         blbc    t3, 0f          # skip single store if count even
56         stq_u   a1, 0(a0)       # e0    : store one word
57         subq    t3, 1, t3       # .. e1 :
58         addq    a0, 8, a0       # e0    :
59         beq     t3, $tail       # .. e1 :
61 0:      stq_u   a1, 0(a0)       # e0    : store two words
62         subq    t3, 2, t3       # .. e1 :
63         stq_u   a1, 8(a0)       # e0    :
64         addq    a0, 16, a0      # .. e1 :
65         bne     t3, 0b          # e1    :
67 $tail:  bne     t4, 1f          # is there a tail to do?
68         ret                     # no
70         .align 3
71 1:      ldq_u   t0, 0(a0)       # e1    : yes, load original data
72         mskql   a1, t4, t1      # .. e0 :
73         mskqh   t0, t4, t0      # e0    :
74         or      t0, t1, t0      # e1 (stall)
75         stq_u   t0, 0(a0)       # e0    :
76         ret                     # .. e1 :
78 memset:
79 #ifdef PROF
80         ldgp    gp, 0(pv)
81         lda     AT, _mcount
82         jsr     AT, (AT), _mcount
83 #endif
85         and     a1, 0xff, a1    # e0    : zero extend input character
86         mov     a0, v0          # .. e1 : move return value in place
87         sll     a1, 8, t0       # e0    : begin replicating the char
88         beq     a2, $done       # .. e1 : early exit for zero-length store
89         or      t0, a1, a1      # e0    :
90         and     a0, 7, t1       # .. e1 : dest misalignment
91         sll     a1, 16, t0      # e0    :
92         addq    a2, t1, a2      # .. e1 : add dest misalignment to count
93         or      t0, a1, a1      # e0    :
94         srl     a2, 3, t3       # .. e1 : loop = count >> 3
95         sll     a1, 32, t0      # e0    :
96         and     a2, 7, t4       # .. e1 : find number of bytes in tail
97         or      t0, a1, a1      # e0    : character replication done
99         beq     t1, memset_loop # .. e1 : aligned head, jump right in
101         ldq_u   t0, 0(a0)       # e1    : load original data to mask into
102         mskqh   a1, a0, t1      # .. e0 :
104         cmpult  a2, 8, t2       # e0    : is this a sub-word set?
105         bne     t2, $oneq       # .. e1 (zdb)
107         mskql   t0, a0, t0      # e0    : we span words.  finish this partial
108         subq    t3, 1, t3       # .. e1 :
109         addq    a0, 8, a0       # e0    :
110         or      t0, t1, t0      # .. e1 :
111         stq_u   t0, -8(a0)      # e0    :
112         br      memset_loop     # .. e1 :
114         .align 3
115 $oneq:
116         mskql   t1, a2, t1      # e0    : entire operation within one word
117         mskql   t0, a0, t2      # e0    :
118         mskqh   t0, a2, t3      # e0    :
119         or      t1, t2, t0      # .. e1 :
120         or      t0, t3, t0      # e1    :
121         stq_u   t0, 0(a0)       # e0 (stall)
123 $done:  ret
125         cfi_endproc
126 libc_hidden_builtin_def (memset)