xref: /openbmc/u-boot/arch/sh/lib/udivsi3_i4i.S (revision ed09a554)
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2   2004, 2005, 2006
3   Free Software Foundation, Inc.
4
5 * SPDX-License-Identifier:	GPL-2.0+
6 */
7
8!! libgcc routines for the Renesas / SuperH SH CPUs.
9!! Contributed by Steve Chamberlain.
10!! sac@cygnus.com
11
12!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
13!! recoded in assembly by Toshiyasu Morita
14!! tm@netcom.com
15
16/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
17   ELF local label prefixes by J"orn Rennecke
18   amylaar@cygnus.com  */
19
20/* This code used shld, thus is not suitable for SH1 / SH2.  */
21
22/* Signed / unsigned division without use of FPU, optimized for SH4.
23   Uses a lookup table for divisors in the range -128 .. +128, and
24   div1 with case distinction for larger divisors in three more ranges.
25   The code is lumped together with the table to allow the use of mova.  */
26#ifdef CONFIG_CPU_LITTLE_ENDIAN
27#define L_LSB 0
28#define L_LSWMSB 1
29#define L_MSWLSB 2
30#else
31#define L_LSB 3
32#define L_LSWMSB 2
33#define L_MSWLSB 1
34#endif
35
36	.balign 4
37	.global	__udivsi3_i4i
38	.global	__udivsi3_i4
39	.set	__udivsi3_i4, __udivsi3_i4i
40	.type	__udivsi3_i4i, @function
41__udivsi3_i4i:
42	mov.w c128_w, r1
43	div0u
44	mov r4,r0
45	shlr8 r0
46	cmp/hi r1,r5
47	extu.w r5,r1
48	bf udiv_le128
49	cmp/eq r5,r1
50	bf udiv_ge64k
51	shlr r0
52	mov r5,r1
53	shll16 r5
54	mov.l r4,@-r15
55	div1 r5,r0
56	mov.l r1,@-r15
57	div1 r5,r0
58	div1 r5,r0
59	bra udiv_25
60	div1 r5,r0
61
62div_le128:
63	mova div_table_ix,r0
64	bra div_le128_2
65	mov.b @(r0,r5),r1
66udiv_le128:
67	mov.l r4,@-r15
68	mova div_table_ix,r0
69	mov.b @(r0,r5),r1
70	mov.l r5,@-r15
71div_le128_2:
72	mova div_table_inv,r0
73	mov.l @(r0,r1),r1
74	mov r5,r0
75	tst #0xfe,r0
76	mova div_table_clz,r0
77	dmulu.l r1,r4
78	mov.b @(r0,r5),r1
79	bt/s div_by_1
80	mov r4,r0
81	mov.l @r15+,r5
82	sts mach,r0
83	/* clrt */
84	addc r4,r0
85	mov.l @r15+,r4
86	rotcr r0
87	rts
88	shld r1,r0
89
90div_by_1_neg:
91	neg r4,r0
92div_by_1:
93	mov.l @r15+,r5
94	rts
95	mov.l @r15+,r4
96
97div_ge64k:
98	bt/s div_r8
99	div0u
100	shll8 r5
101	bra div_ge64k_2
102	div1 r5,r0
103udiv_ge64k:
104	cmp/hi r0,r5
105	mov r5,r1
106	bt udiv_r8
107	shll8 r5
108	mov.l r4,@-r15
109	div1 r5,r0
110	mov.l r1,@-r15
111div_ge64k_2:
112	div1 r5,r0
113	mov.l zero_l,r1
114	.rept 4
115	div1 r5,r0
116	.endr
117	mov.l r1,@-r15
118	div1 r5,r0
119	mov.w m256_w,r1
120	div1 r5,r0
121	mov.b r0,@(L_LSWMSB,r15)
122	xor r4,r0
123	and r1,r0
124	bra div_ge64k_end
125	xor r4,r0
126div_r8:
127	shll16 r4
128	bra div_r8_2
129	shll8 r4
130udiv_r8:
131	mov.l r4,@-r15
132	shll16 r4
133	clrt
134	shll8 r4
135	mov.l r5,@-r15
136div_r8_2:
137	rotcl r4
138	mov r0,r1
139	div1 r5,r1
140	mov r4,r0
141	rotcl r0
142	mov r5,r4
143	div1 r5,r1
144	.rept 5
145	rotcl r0; div1 r5,r1
146	.endr
147	rotcl r0
148	mov.l @r15+,r5
149	div1 r4,r1
150	mov.l @r15+,r4
151	rts
152	rotcl r0
153
154	.global	__sdivsi3_i4i
155	.global __sdivsi3_i4
156	.global	__sdivsi3
157	.set	__sdivsi3_i4, __sdivsi3_i4i
158	.set	__sdivsi3, __sdivsi3_i4i
159	.type	__sdivsi3_i4i, @function
160	/* This is link-compatible with a __sdivsi3 call,
161	   but we effectively clobber only r1.  */
162__sdivsi3_i4i:
163	mov.l r4,@-r15
164	cmp/pz r5
165	mov.w c128_w, r1
166	bt/s pos_divisor
167	cmp/pz r4
168	mov.l r5,@-r15
169	neg r5,r5
170	bt/s neg_result
171	cmp/hi r1,r5
172	neg r4,r4
173pos_result:
174	extu.w r5,r0
175	bf div_le128
176	cmp/eq r5,r0
177	mov r4,r0
178	shlr8 r0
179	bf/s div_ge64k
180	cmp/hi r0,r5
181	div0u
182	shll16 r5
183	div1 r5,r0
184	div1 r5,r0
185	div1 r5,r0
186udiv_25:
187	mov.l zero_l,r1
188	div1 r5,r0
189	div1 r5,r0
190	mov.l r1,@-r15
191	.rept 3
192	div1 r5,r0
193	.endr
194	mov.b r0,@(L_MSWLSB,r15)
195	xtrct r4,r0
196	swap.w r0,r0
197	.rept 8
198	div1 r5,r0
199	.endr
200	mov.b r0,@(L_LSWMSB,r15)
201div_ge64k_end:
202	.rept 8
203	div1 r5,r0
204	.endr
205	mov.l @r15+,r4 ! zero-extension and swap using LS unit.
206	extu.b r0,r0
207	mov.l @r15+,r5
208	or r4,r0
209	mov.l @r15+,r4
210	rts
211	rotcl r0
212
213div_le128_neg:
214	tst #0xfe,r0
215	mova div_table_ix,r0
216	mov.b @(r0,r5),r1
217	mova div_table_inv,r0
218	bt/s div_by_1_neg
219	mov.l @(r0,r1),r1
220	mova div_table_clz,r0
221	dmulu.l r1,r4
222	mov.b @(r0,r5),r1
223	mov.l @r15+,r5
224	sts mach,r0
225	/* clrt */
226	addc r4,r0
227	mov.l @r15+,r4
228	rotcr r0
229	shld r1,r0
230	rts
231	neg r0,r0
232
233pos_divisor:
234	mov.l r5,@-r15
235	bt/s pos_result
236	cmp/hi r1,r5
237	neg r4,r4
238neg_result:
239	extu.w r5,r0
240	bf div_le128_neg
241	cmp/eq r5,r0
242	mov r4,r0
243	shlr8 r0
244	bf/s div_ge64k_neg
245	cmp/hi r0,r5
246	div0u
247	mov.l zero_l,r1
248	shll16 r5
249	div1 r5,r0
250	mov.l r1,@-r15
251	.rept 7
252	div1 r5,r0
253	.endr
254	mov.b r0,@(L_MSWLSB,r15)
255	xtrct r4,r0
256	swap.w r0,r0
257	.rept 8
258	div1 r5,r0
259	.endr
260	mov.b r0,@(L_LSWMSB,r15)
261div_ge64k_neg_end:
262	.rept 8
263	div1 r5,r0
264	.endr
265	mov.l @r15+,r4 ! zero-extension and swap using LS unit.
266	extu.b r0,r1
267	mov.l @r15+,r5
268	or r4,r1
269div_r8_neg_end:
270	mov.l @r15+,r4
271	rotcl r1
272	rts
273	neg r1,r0
274
275div_ge64k_neg:
276	bt/s div_r8_neg
277	div0u
278	shll8 r5
279	mov.l zero_l,r1
280	.rept 6
281	div1 r5,r0
282	.endr
283	mov.l r1,@-r15
284	div1 r5,r0
285	mov.w m256_w,r1
286	div1 r5,r0
287	mov.b r0,@(L_LSWMSB,r15)
288	xor r4,r0
289	and r1,r0
290	bra div_ge64k_neg_end
291	xor r4,r0
292
293c128_w:
294	.word 128
295
296div_r8_neg:
297	clrt
298	shll16 r4
299	mov r4,r1
300	shll8 r1
301	mov r5,r4
302	.rept 7
303	rotcl r1; div1 r5,r0
304	.endr
305	mov.l @r15+,r5
306	rotcl r1
307	bra div_r8_neg_end
308	div1 r4,r0
309
310m256_w:
311	.word 0xff00
312/* This table has been generated by divtab-sh4.c.  */
313	.balign 4
314div_table_clz:
315	.byte	0
316	.byte	1
317	.byte	0
318	.byte	-1
319	.byte	-1
320	.byte	-2
321	.byte	-2
322	.byte	-2
323	.byte	-2
324	.byte	-3
325	.byte	-3
326	.byte	-3
327	.byte	-3
328	.byte	-3
329	.byte	-3
330	.byte	-3
331	.byte	-3
332	.byte	-4
333	.byte	-4
334	.byte	-4
335	.byte	-4
336	.byte	-4
337	.byte	-4
338	.byte	-4
339	.byte	-4
340	.byte	-4
341	.byte	-4
342	.byte	-4
343	.byte	-4
344	.byte	-4
345	.byte	-4
346	.byte	-4
347	.byte	-4
348	.byte	-5
349	.byte	-5
350	.byte	-5
351	.byte	-5
352	.byte	-5
353	.byte	-5
354	.byte	-5
355	.byte	-5
356	.byte	-5
357	.byte	-5
358	.byte	-5
359	.byte	-5
360	.byte	-5
361	.byte	-5
362	.byte	-5
363	.byte	-5
364	.byte	-5
365	.byte	-5
366	.byte	-5
367	.byte	-5
368	.byte	-5
369	.byte	-5
370	.byte	-5
371	.byte	-5
372	.byte	-5
373	.byte	-5
374	.byte	-5
375	.byte	-5
376	.byte	-5
377	.byte	-5
378	.byte	-5
379	.byte	-5
380	.byte	-6
381	.byte	-6
382	.byte	-6
383	.byte	-6
384	.byte	-6
385	.byte	-6
386	.byte	-6
387	.byte	-6
388	.byte	-6
389	.byte	-6
390	.byte	-6
391	.byte	-6
392	.byte	-6
393	.byte	-6
394	.byte	-6
395	.byte	-6
396	.byte	-6
397	.byte	-6
398	.byte	-6
399	.byte	-6
400	.byte	-6
401	.byte	-6
402	.byte	-6
403	.byte	-6
404	.byte	-6
405	.byte	-6
406	.byte	-6
407	.byte	-6
408	.byte	-6
409	.byte	-6
410	.byte	-6
411	.byte	-6
412	.byte	-6
413	.byte	-6
414	.byte	-6
415	.byte	-6
416	.byte	-6
417	.byte	-6
418	.byte	-6
419	.byte	-6
420	.byte	-6
421	.byte	-6
422	.byte	-6
423	.byte	-6
424	.byte	-6
425	.byte	-6
426	.byte	-6
427	.byte	-6
428	.byte	-6
429	.byte	-6
430	.byte	-6
431	.byte	-6
432	.byte	-6
433	.byte	-6
434	.byte	-6
435	.byte	-6
436	.byte	-6
437	.byte	-6
438	.byte	-6
439	.byte	-6
440	.byte	-6
441	.byte	-6
442	.byte	-6
443/* Lookup table translating positive divisor to index into table of
444   normalized inverse.  N.B. the '0' entry is also the last entry of the
445 previous table, and causes an unaligned access for division by zero.  */
446div_table_ix:
447	.byte	-6
448	.byte	-128
449	.byte	-128
450	.byte	0
451	.byte	-128
452	.byte	-64
453	.byte	0
454	.byte	64
455	.byte	-128
456	.byte	-96
457	.byte	-64
458	.byte	-32
459	.byte	0
460	.byte	32
461	.byte	64
462	.byte	96
463	.byte	-128
464	.byte	-112
465	.byte	-96
466	.byte	-80
467	.byte	-64
468	.byte	-48
469	.byte	-32
470	.byte	-16
471	.byte	0
472	.byte	16
473	.byte	32
474	.byte	48
475	.byte	64
476	.byte	80
477	.byte	96
478	.byte	112
479	.byte	-128
480	.byte	-120
481	.byte	-112
482	.byte	-104
483	.byte	-96
484	.byte	-88
485	.byte	-80
486	.byte	-72
487	.byte	-64
488	.byte	-56
489	.byte	-48
490	.byte	-40
491	.byte	-32
492	.byte	-24
493	.byte	-16
494	.byte	-8
495	.byte	0
496	.byte	8
497	.byte	16
498	.byte	24
499	.byte	32
500	.byte	40
501	.byte	48
502	.byte	56
503	.byte	64
504	.byte	72
505	.byte	80
506	.byte	88
507	.byte	96
508	.byte	104
509	.byte	112
510	.byte	120
511	.byte	-128
512	.byte	-124
513	.byte	-120
514	.byte	-116
515	.byte	-112
516	.byte	-108
517	.byte	-104
518	.byte	-100
519	.byte	-96
520	.byte	-92
521	.byte	-88
522	.byte	-84
523	.byte	-80
524	.byte	-76
525	.byte	-72
526	.byte	-68
527	.byte	-64
528	.byte	-60
529	.byte	-56
530	.byte	-52
531	.byte	-48
532	.byte	-44
533	.byte	-40
534	.byte	-36
535	.byte	-32
536	.byte	-28
537	.byte	-24
538	.byte	-20
539	.byte	-16
540	.byte	-12
541	.byte	-8
542	.byte	-4
543	.byte	0
544	.byte	4
545	.byte	8
546	.byte	12
547	.byte	16
548	.byte	20
549	.byte	24
550	.byte	28
551	.byte	32
552	.byte	36
553	.byte	40
554	.byte	44
555	.byte	48
556	.byte	52
557	.byte	56
558	.byte	60
559	.byte	64
560	.byte	68
561	.byte	72
562	.byte	76
563	.byte	80
564	.byte	84
565	.byte	88
566	.byte	92
567	.byte	96
568	.byte	100
569	.byte	104
570	.byte	108
571	.byte	112
572	.byte	116
573	.byte	120
574	.byte	124
575	.byte	-128
576/* 1/64 .. 1/127, normalized.  There is an implicit leading 1 in bit 32.  */
577	.balign 4
578zero_l:
579	.long	0x0
580	.long	0xF81F81F9
581	.long	0xF07C1F08
582	.long	0xE9131AC0
583	.long	0xE1E1E1E2
584	.long	0xDAE6076C
585	.long	0xD41D41D5
586	.long	0xCD856891
587	.long	0xC71C71C8
588	.long	0xC0E07039
589	.long	0xBACF914D
590	.long	0xB4E81B4F
591	.long	0xAF286BCB
592	.long	0xA98EF607
593	.long	0xA41A41A5
594	.long	0x9EC8E952
595	.long	0x9999999A
596	.long	0x948B0FCE
597	.long	0x8F9C18FA
598	.long	0x8ACB90F7
599	.long	0x86186187
600	.long	0x81818182
601	.long	0x7D05F418
602	.long	0x78A4C818
603	.long	0x745D1746
604	.long	0x702E05C1
605	.long	0x6C16C16D
606	.long	0x68168169
607	.long	0x642C8591
608	.long	0x60581606
609	.long	0x5C9882BA
610	.long	0x58ED2309
611div_table_inv:
612	.long	0x55555556
613	.long	0x51D07EAF
614	.long	0x4E5E0A73
615	.long	0x4AFD6A06
616	.long	0x47AE147B
617	.long	0x446F8657
618	.long	0x41414142
619	.long	0x3E22CBCF
620	.long	0x3B13B13C
621	.long	0x38138139
622	.long	0x3521CFB3
623	.long	0x323E34A3
624	.long	0x2F684BDB
625	.long	0x2C9FB4D9
626	.long	0x29E4129F
627	.long	0x27350B89
628	.long	0x24924925
629	.long	0x21FB7813
630	.long	0x1F7047DD
631	.long	0x1CF06ADB
632	.long	0x1A7B9612
633	.long	0x18118119
634	.long	0x15B1E5F8
635	.long	0x135C8114
636	.long	0x11111112
637	.long	0xECF56BF
638	.long	0xC9714FC
639	.long	0xA6810A7
640	.long	0x8421085
641	.long	0x624DD30
642	.long	0x4104105
643	.long	0x2040811
644	/* maximum error: 0.987342 scaled: 0.921875*/
645