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
|
|