moving some standard library functions to assembly
[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         jmp *mspre_tab(,%edx,4)
38
39 mspre_tab: .long msmain, mspre1, mspre2, mspre3
40 mspre1: stosb
41         dec %ecx
42 mspre2: stosb
43         dec %ecx
44 mspre3: stosb
45         dec %ecx
46         jz msdone
47
48 msmain:
49         push %ecx
50         shr $2, %ecx
51         rep stosl
52         pop %ecx
53
54         and $3, %ecx
55         jmp *mspost_tab(,%ecx,4)
56
57 mspost_tab: .long msdone, mspost1, mspost2, mspost3
58 mspost3:stosb
59 mspost2:stosb
60 mspost1:stosb
61
62 msdone:
63         pop %edi
64         pop %ebp
65         ret
66
67
68         # same as memset but copies 16bit values, and the count is the number
69         # of 16bit values to copy, not bytes.
70         .global memset16
71 memset16:
72         push %ebp
73         mov %esp, %ebp
74         push %edi
75
76         mov 8(%ebp), %edi
77         mov 12(%ebp), %ax
78         shl $16, %eax
79         mov 12(%ebp), %ax
80         mov 16(%ebp), %ecx
81
82         cmp $0, %ecx
83         jz ms16done
84
85         mov %edi, %edx
86         and $3, %edx
87         jmp *ms16pre_tab(,%edx,4)
88
89 ms16pre_tab: .long ms16main, ms16pre1, ms16pre2, ms16pre3
90 ms16pre3:
91         # unaligned by +3:
92         # same as next one, but jump to ms16main instead of falling through
93         mov %al, (%edi)
94         mov %ah, -1(%edi,%ecx,2)
95         rol $8, %eax
96         inc %edi
97         dec %ecx
98         jz ms16done
99         jmp ms16main
100 ms16pre1:
101         # unaligned by +1:
102         # - write low byte at edi
103         # - write high byte at the end
104         # - rotate by 8 for the rest
105         # - decrement ecx
106         mov %al, (%edi)
107         mov %ah, -1(%edi,%ecx,2)
108         rol $8, %eax
109         inc %edi
110         dec %ecx
111         jz ms16done
112 ms16pre2:
113         # unaligned by +2
114         stosw
115         dec %ecx
116         jz ms16done
117
118 ms16main:
119         push %ecx
120         shr $1, %ecx
121         rep stosl
122         pop %ecx
123
124         and $1, %ecx
125         jz ms16done
126         stosw
127 ms16done:
128
129         pop %edi
130         pop %ebp
131         ret
132
133         # standard C memcpy
134         .global memcpy
135 memcpy:
136         push %ebp
137         mov %esp, %ebp
138         push %edi
139         push %esi
140
141         mov 8(%ebp), %edi
142         mov 12(%ebp), %esi
143         mov 16(%ebp), %ecx
144
145         cmp $0, %ecx
146         jz mcdone
147
148         mov %edi, %edx
149         and $3, %edx
150         jmp *mcpre_tab(,%edx,4)
151
152 mcpre_tab: .long mcmain, mcpre1, mcpre2, mcpre3
153 mcpre1: movsw
154         dec %ecx
155 mcpre2: movsw
156         dec %ecx
157 mcpre3: movsw
158         dec %ecx
159         jz mcdone
160
161 mcmain:
162         push %ecx
163         shr $2, %ecx
164         rep movsl
165         pop %ecx
166
167         and $3, %ecx
168         jmp *mcpost_tab(,%ecx,4)
169
170 mcpost_tab: .long mcdone, mcpost1, mcpost2, mcpost3
171 mcpost3:movsb
172 mcpost2:movsb
173 mcpost1:movsb
174
175 mcdone:
176         pop %esi
177         pop %edi
178         pop %ebp
179         ret