8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libbc / libc / crt / sparc / misalign.s
blobd497c953db177d694583a07f14d63b53d32e2152
1 ! .text
2 ! .asciz ident "%Z%%M% %I% %E% SMI"
3 ! .align 4
4 ! .seg "text"
6 ! Copyright 2005 Sun Microsystems, Inc. All rights reserved.
7 ! Use is subject to license terms.
8 !
9 ! CDDL HEADER START
11 ! The contents of this file are subject to the terms of the
12 ! Common Development and Distribution License, Version 1.0 only
13 ! (the "License"). You may not use this file except in compliance
14 ! with the License.
16 ! You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
17 ! or http://www.opensolaris.org/os/licensing.
18 ! See the License for the specific language governing permissions
19 ! and limitations under the License.
21 ! When distributing Covered Code, include this CDDL HEADER in each
22 ! file and include the License file at usr/src/OPENSOLARIS.LICENSE.
23 ! If applicable, add the following below this CDDL HEADER, with the
24 ! fields enclosed by brackets "[]" replaced with your own identifying
25 ! information: Portions Copyright [yyyy] [name of copyright owner]
27 ! CDDL HEADER END
31 ! C library routines for compiler support of misaligned memory
32 ! references. These are called when an in-line test reveals a
33 ! misaligned address.
36 .file "misalign.s"
38 #include <SYS.h>
40 !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
43 ! int ld_int(p)
44 ! char *p;
45 ! {
46 ! /*
47 ! * load 32-bit int from misaligned address
48 ! * cost(16-bit aligned case): 9 cycles
49 ! * cost(8-bit aligned case): 18 cycles
50 ! */
51 ! }
53 RTENTRY(.ld_int)
54 andcc %o0,1,%g0 ! test 16-bit alignment
55 be,a 1f ! fast case: two loads;
56 lduh [%o0+2],%o1 ! do first one in delay slot
58 ldub [%o0+3],%o3 ! slow case: load 4 bytes in <o0,o1,o2,o3>
59 ldub [%o0+2],%o2
60 ldub [%o0+1],%o1
61 ldub [%o0],%o0 ! note this has to be done last.
62 sll %o2,8,%o2
63 sll %o1,16,%o1
64 sll %o0,24,%o0
65 or %o1,%o0,%o0 ! put the pieces together.
66 or %o2,%o0,%o0
67 retl
68 or %o3,%o0,%o0
70 lduh [%o0],%o0 ! 2nd half of fast case
71 sll %o0,16,%o0 ! shift, concat, done.
72 retl
73 or %o0,%o1,%o0
74 SET_SIZE(.ld_int)
76 !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
79 ! float ld_float(p)
80 ! char *p;
81 ! {
82 ! /* load 32-bit float (not double!) from misaligned address */
83 ! }
85 RTENTRY(.ld_float)
86 save %sp,-SA(MINFRAME+8),%sp
87 andcc %i0,1,%g0 ! test for short alignment
88 be,a 1f
89 lduh [%i0],%o0 ! short aligned case: 2 loads, 2 stores
91 ldub [%i0],%o0 ! byte aligned case: 4 loads, 4 stores
92 ldub [%i0+1],%o1
93 ldub [%i0+2],%o2
94 ldub [%i0+3],%o3
95 stb %o0,[%fp-4]
96 stb %o1,[%fp-3]
97 stb %o2,[%fp-2]
98 b 2f
99 stb %o3,[%fp-1]
101 lduh [%i0+2],%o1 ! rest of short aligned case
102 sth %o0,[%fp-4]
103 sth %o1,[%fp-2]
105 ld [%fp-4],%f0 ! load FPU reg, done
107 restore
108 SET_SIZE(.ld_float)
110 !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
113 ! double ld_double(p)
114 ! char *p;
116 ! /* load 64-bit float from misaligned address */
119 RTENTRY(.ld_double)
120 save %sp,-SA(MINFRAME+8),%sp
121 andcc %i0,3,%g0 ! test for long alignment
122 be,a 1f ! long aligned case: 2 loads, no stores
123 ld [%i0],%f0
125 andcc %i0,1,%g0 ! test for short alignment
126 be,a 2f ! short aligned case: 4 loads, 4 stores
127 lduh [%i0],%o0
129 ldub [%i0],%o0 ! worst case: byte alignment
130 ldub [%i0+1],%o1 ! 8 loads, 8 stores
131 ldub [%i0+2],%o2
132 ldub [%i0+3],%o3
133 stb %o0,[%fp-8]
134 stb %o1,[%fp-7]
135 stb %o2,[%fp-6]
136 stb %o3,[%fp-5]
137 ldub [%i0+4],%o0
138 ldub [%i0+5],%o1
139 ldub [%i0+6],%o2
140 ldub [%i0+7],%o3
141 stb %o0,[%fp-4]
142 stb %o1,[%fp-3]
143 stb %o2,[%fp-2]
144 stb %o3,[%fp-1]
145 ldd [%fp-8],%f0 ! load f0-f1, done
147 restore
149 lduh [%i0+2],%o1 ! rest of short aligned case
150 lduh [%i0+4],%o2
151 lduh [%i0+6],%o3
152 sth %o0,[%fp-8]
153 sth %o1,[%fp-6]
154 sth %o2,[%fp-4]
155 sth %o3,[%fp-2]
156 ldd [%fp-8],%f0 ! load f0-f1, done
158 restore
160 ld [%i0+4],%f1 ! rest of long aligned case
162 restore
163 SET_SIZE(.ld_double)
165 !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
168 ! int st_int(x,p)
169 ! int x;
170 ! char *p;
172 ! /* store 32-bit int from misaligned address;
173 ! return stored value */
176 RTENTRY(.st_int)
177 andcc %o1,1,%g0 ! test for short alignment
178 be,a 1f
179 srl %o0,16,%o4
181 srl %o0,24,%o5 ! byte aligned case
182 stb %o5,[%o1]
183 srl %o0,16,%o2
184 stb %o2,[%o1+1]
185 srl %o0,8,%o3
186 stb %o3,[%o1+2]
187 retl
188 stb %o0,[%o1+3]
190 sth %o4,[%o1] ! rest of short aligned case
191 retl
192 sth %o0,[%o1+2]
193 SET_SIZE(.st_int)
195 !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
198 ! float st_float(x,p)
199 ! float x;
200 ! char *p;
202 ! /* store 32-bit float from misaligned address;
203 ! return stored value */
206 RTENTRY(.st_float)
207 save %sp,-SA(MINFRAME+8),%sp
208 andcc %i1,1,%g0 ! test for short alignment
209 be,a 1f ! short aligned case
210 srl %i0,16,%o0
212 srl %i0,24,%o0 ! byte aligned case
213 srl %i0,16,%o1
214 srl %i0,8,%o2
215 stb %o0,[%i1]
216 stb %o1,[%i1+1]
217 stb %o2,[%i1+2]
218 stb %i0,[%i1+3]
219 st %i0,[%fp-4] ! store temp, load f0, done
220 ld [%fp-4],%f0
222 restore
224 sth %o0,[%i1] ! rest of short aligned case
225 sth %i0,[%i1+2]
226 st %i0,[%fp-4]
227 ld [%fp-4],%f0
229 restore
230 SET_SIZE(.st_float)
232 !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
235 ! double st_double(x,p)
236 ! double x;
237 ! char *p;
239 ! /* store 64-bit float from misaligned address;
240 ! return stored value */
243 RTENTRY(.st_double)
244 save %sp,-SA(MINFRAME+8),%sp
245 andcc %i2,3,%g0 ! test for long alignment
246 be,a 1f ! long aligned case: 2 stores, 2 loads
247 st %i0,[%i2]
249 andcc %i2,1,%g0 ! test for short alignment
250 be,a 2f ! short aligned case: 4 stores, 4 loads
251 srl %i0,16,%o0
252 ! ! byte aligned case: the pits
253 srl %i0,24,%o0
254 srl %i0,16,%o1
255 srl %i0,8,%o2
256 stb %o0,[%i2] ! store first word, a byte at a time
257 stb %o1,[%i2+1]
258 stb %o2,[%i2+2]
259 stb %i0,[%i2+3]
260 srl %i1,24,%o0
261 srl %i1,16,%o1
262 srl %i1,8,%o2
263 stb %o0,[%i2+4] ! store second word, a byte at a time
264 stb %o1,[%i2+5]
265 stb %o2,[%i2+6]
266 stb %i1,[%i2+7]
267 std %i0,[%fp-8] ! since dest is misaligned, must use temp
268 ldd [%fp-8],%f0 ! load f0,f1 from double-aligned temp, done
270 restore
271 2: ! rest of short aligned case
272 srl %i1,16,%o1
273 sth %o0,[%i2] ! store two words, a half word at a time
274 sth %i0,[%i2+2]
275 sth %o1,[%i2+4]
276 sth %i1,[%i2+6]
277 std %i0,[%fp-8] ! since dest is misaligned, must use temp
278 ldd [%fp-8],%f0 ! load f0,f1 from double-aligned temp, done
280 restore
281 1: ! rest of long aligned case
282 st %i1,[%i2+4]
283 ld [%i2],%f0 ! load f0,f1 from long-aligned memory, done
284 ld [%i2+4],%f1
286 restore
287 SET_SIZE(.st_double)
289 !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
292 ! void st_float_foreff(x,p)
293 ! float x;
294 ! char *p;
296 ! /* store 32-bit float from misaligned address */
299 RTENTRY(.st_float_foreff)
300 andcc %o1,1,%g0 ! test for short alignment
301 be,a 1f
302 srl %o0,16,%o2
304 srl %o0,24,%o2 ! byte aligned case
305 srl %o0,16,%o3
306 srl %o0,8,%o4
307 stb %o2,[%o1]
308 stb %o3,[%o1+1]
309 stb %o4,[%o1+2]
310 retl
311 stb %o0,[%o1+3]
312 1: ! rest of short aligned case
313 sth %o2,[%o1]
314 retl
315 sth %o0,[%o1+2]
316 SET_SIZE(.st_float_foreff)
318 !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
321 ! void st_double_foreff(x,p)
322 ! double x;
323 ! char *p;
325 ! /* store 64-bit float from misaligned address;
326 ! return stored value */
329 RTENTRY(.st_double_foreff)
330 andcc %o2,3,%g0 ! test for long alignment
331 be,a 1f ! long aligned case: 2 stores
332 st %o0,[%o2]
334 andcc %o2,1,%g0 ! test for short alignment
335 be,a 2f ! short aligned case: 4 stores
336 srl %o0,16,%o3
338 srl %o0,24,%o3 ! byte aligned case: 8 stores
339 srl %o0,16,%o4
340 srl %o0,8,%o5
341 stb %o3,[%o2]
342 stb %o4,[%o2+1]
343 stb %o5,[%o2+2]
344 stb %o0,[%o2+3]
345 srl %o1,24,%o3
346 srl %o1,16,%o4
347 srl %o1,8,%o5
348 stb %o3,[%o2+4]
349 stb %o4,[%o2+5]
350 stb %o5,[%o2+6]
351 retl
352 stb %o1,[%o2+7]
353 2: ! rest of short aligned case
354 srl %o1,16,%o4
355 sth %o3,[%o2]
356 sth %o0,[%o2+2]
357 sth %o4,[%o2+4]
358 retl
359 sth %o1,[%o2+6]
360 1: ! rest of long aligned case
361 retl
362 st %o1,[%o2+4]
363 SET_SIZE(.st_double_foreff)