lin
2025-07-31 065ea569db06206874bbfa18eb25ff6121aec09b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* Optimised simple memory fill
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */
#include <asm/cache.h>
 
        .section .text
        .balign    L1_CACHE_BYTES
 
###############################################################################
#
# void *memset(void *dst, int c, size_t n)
#
###############################################################################
   .globl    memset
        .type    memset,@function
memset:
   movm    [d2,d3],(sp)
   mov    d0,(12,sp)
   mov    d1,(16,sp)
   mov    (20,sp),d2            # count
   mov    d0,a0                # dst
   mov    d0,e3                # the return value
 
   cmp    +0,d2
   beq    memset_done            # return if zero-length fill
 
   # see if the region parameters are four-byte aligned
   or    d0,d2,d3
   and    +3,d3
   bne    memset_1            # jump if not
 
   extbu    d1
   mov_asl    d1,d3,8,d1
   or_asl    d1,d3,8,d1
   or_asl    d1,d3,8,d1
   or    d3,d1
 
   # we want to transfer as much as we can in chunks of 32 bytes
   cmp    +31,d2
   bls    memset_4_remainder        # 4-byte aligned remainder
 
   add    -32,d2
   mov    +32,d3
 
memset_4_loop:
   mov    d1,(a0+)
   mov    d1,(a0+)
   mov    d1,(a0+)
   mov    d1,(a0+)
   mov    d1,(a0+)
   mov    d1,(a0+)
   mov    d1,(a0+)
   mov    d1,(a0+)
 
   sub    d3,d2
   bcc    memset_4_loop
 
   add    d3,d2
   beq    memset_4_no_remainder
 
memset_4_remainder:
   # cut 4-7 words down to 0-3
   cmp    +16,d2
   bcs    memset_4_three_or_fewer_words
   mov    d1,(a0+)
   mov    d1,(a0+)
   mov    d1,(a0+)
   mov    d1,(a0+)
   add    -16,d2
   beq    memset_4_no_remainder
 
   # copy the remaining 1, 2 or 3 words
memset_4_three_or_fewer_words:
   cmp    +8,d2
   bcs    memset_4_one_word
   beq    memset_4_two_words
   mov    d1,(a0+)
memset_4_two_words:
   mov    d1,(a0+)
memset_4_one_word:
   mov    d1,(a0+)
 
memset_4_no_remainder:
   # check we set the correct amount
   # TODO: REMOVE CHECK
   sub    e3,a0,d2
   mov    (20,sp),d1
   cmp    d2,d1
   beq    memset_done
   break
   break
   break
 
memset_done:
   mov    e3,a0
   ret    [d2,d3],8
 
   # handle misaligned copying
memset_1:
   add    -1,d2
   mov    +1,d3
   setlb                    # setlb requires the next insns
                       # to occupy exactly 4 bytes
 
   sub    d3,d2
   movbu    d1,(a0)
   inc    a0
   lcc
 
   mov    e3,a0
   ret    [d2,d3],8
 
memset_end:
   .size    memset, memset_end-memset