ce9b19ae3283c572c81de55ec7adf344a552cf9e
[bootcensus] / src / libc / string_asm.s
1 # pcboot - bootable PC demo/game kernel
2 # Copyright (C) 2018  John Tsiombikas <nuclear@member.fsf.org>
3
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8
9 # This program 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
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17         # standard C memset
18         .global memset
19 memset:
20         push %ebp
21         mov %esp, %ebp
22         push %edi
23
24         mov 8(%ebp), %edi
25         mov 12(%ebp), %al
26         mov %al, %ah
27         mov %ax, %cx
28         shl $16, %eax
29         mov %cx, %ax
30         mov 16(%ebp), %ecx
31
32         cmp $0, %ecx
33         jz msdone
34
35         mov %edi, %edx
36         and $3, %edx
37         jz msmain
38         jmp *mspre_tab(,%edx,4)
39
40 mspre_tab: .long msmain, mspre1, mspre2, mspre3
41 mspre1: stosb
42         dec %ecx
43 mspre2: stosb
44         dec %ecx
45 mspre3: stosb
46         dec %ecx
47         jz msdone
48
49 msmain:
50         push %ecx
51         shr $2, %ecx
52         rep stosl
53         pop %ecx
54
55         and $3, %ecx
56         jmp *mspost_tab(,%ecx,4)
57
58 mspost_tab: .long msdone, mspost1, mspost2, mspost3
59 mspost3:stosb
60 mspost2:stosb
61 mspost1:stosb
62
63 msdone:
64         pop %edi
65         pop %ebp
66         ret
67
68
69         # same as memset but copies 16bit values, and the count is the number
70         # of 16bit values to copy, not bytes.
71         .global memset16
72 memset16:
73         push %ebp
74         mov %esp, %ebp
75         push %edi
76
77         mov 8(%ebp), %edi
78         mov 12(%ebp), %ax
79         shl $16, %eax
80         mov 12(%ebp), %ax
81         mov 16(%ebp), %ecx
82
83         cmp $0, %ecx
84         jz ms16done
85
86         mov %edi, %edx
87         and $3, %edx
88         jz ms16main
89         jmp *ms16pre_tab(,%edx,4)
90
91 ms16pre_tab: .long ms16main, ms16pre1, ms16pre2, ms16pre3
92 ms16pre3:
93         # unaligned by +3:
94         # same as next one, but jump to ms16main instead of falling through
95         mov %al, (%edi)
96         mov %ah, -1(%edi,%ecx,2)
97         rol $8, %eax
98         inc %edi
99         dec %ecx
100         jz ms16done
101         jmp ms16main
102 ms16pre1:
103         # unaligned by +1:
104         # - write low byte at edi
105         # - write high byte at the end
106         # - rotate by 8 for the rest
107         # - decrement ecx
108         mov %al, (%edi)
109         mov %ah, -1(%edi,%ecx,2)
110         rol $8, %eax
111         inc %edi
112         dec %ecx
113         jz ms16done
114 ms16pre2:
115         # unaligned by +2
116         stosw
117         dec %ecx
118         jz ms16done
119
120 ms16main:
121         push %ecx
122         shr $1, %ecx
123         rep stosl
124         pop %ecx
125
126         and $1, %ecx
127         jz ms16done
128         stosw
129 ms16done:
130
131         pop %edi
132         pop %ebp
133         ret
134
135         # standard C memcpy
136         .global memcpy
137 memcpy:
138         push %ebp
139         mov %esp, %ebp
140         push %edi
141         push %esi
142
143         mov 8(%ebp), %edi
144         mov 12(%ebp), %esi
145         mov 16(%ebp), %ecx
146
147         cmp $0, %ecx
148         jz mcdone
149
150         mov %ecx, %edx
151         shr $2, %ecx
152         rep movsl
153
154         and $3, %edx
155         jmp *mcpost_tab(,%edx,4)
156
157 mcpost_tab: .long mcdone, mcpost1, mcpost2, mcpost3
158 mcpost3:movsb
159 mcpost2:movsb
160 mcpost1:movsb
161
162 mcdone:
163         pop %esi
164         pop %edi
165         pop %ebp
166         ret