Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/spu/divmodti4.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
2 | |
3 This file is free software; you can redistribute it and/or modify it under | |
4 the terms of the GNU General Public License as published by the Free | |
5 Software Foundation; either version 3 of the License, or (at your option) | |
6 any later version. | |
7 | |
8 This file is distributed in the hope that it will be useful, but WITHOUT | |
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
11 for more details. | |
12 | |
13 Under Section 7 of GPL version 3, you are granted additional | |
14 permissions described in the GCC Runtime Library Exception, version | |
15 3.1, as published by the Free Software Foundation. | |
16 | |
17 You should have received a copy of the GNU General Public License and | |
18 a copy of the GCC Runtime Library Exception along with this program; | |
19 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 #include <spu_intrinsics.h> | |
23 | |
24 typedef unsigned int UTItype __attribute__ ((mode (TI))); | |
25 typedef int TItype __attribute__ ((mode (TI))); | |
26 TItype __divti3 (TItype u, TItype v); | |
27 TItype __modti3 (TItype u, TItype v); | |
28 UTItype __udivti3 (UTItype u, UTItype v); | |
29 UTItype __umodti3 (UTItype u, UTItype v); | |
30 UTItype __udivmodti4 (UTItype u, UTItype v, UTItype *w); | |
31 | |
32 inline static unsigned int | |
33 count_leading_zeros (UTItype x) | |
34 { | |
35 qword c = si_clz (*(qword *) & x); | |
36 qword cmp0 = si_cgti (c, 31); | |
37 qword cmp1 = si_and (cmp0, si_shlqbyi (cmp0, 4)); | |
38 qword cmp2 = si_and (cmp1, si_shlqbyi (cmp0, 8)); | |
39 qword s = si_a (c, si_and (cmp0, si_shlqbyi (c, 4))); | |
40 s = si_a (s, si_and (cmp1, si_shlqbyi (c, 8))); | |
41 s = si_a (s, si_and (cmp2, si_shlqbyi (c, 12))); | |
42 return si_to_uint (s); | |
43 } | |
44 | |
45 /* Based on implementation of udivmodsi4, which is essentially | |
46 * an optimized version of gcc/config/udivmodsi4.c | |
47 clz %7,%2 | |
48 clz %4,%1 | |
49 il %5,1 | |
50 fsmbi %0,0 | |
51 sf %7,%4,%7 | |
52 ori %3,%1,0 | |
53 shl %5,%5,%7 | |
54 shl %4,%2,%7 | |
55 1: or %8,%0,%5 | |
56 rotmi %5,%5,-1 | |
57 clgt %6,%4,%3 | |
58 sf %7,%4,%3 | |
59 rotmi %4,%4,-1 | |
60 selb %0,%8,%0,%6 | |
61 selb %3,%7,%3,%6 | |
62 3: brnz %5,1b | |
63 */ | |
64 | |
65 UTItype | |
66 __udivmodti4 (UTItype num, UTItype den, UTItype * rp) | |
67 { | |
68 qword shift = | |
69 si_from_uint (count_leading_zeros (den) - count_leading_zeros (num)); | |
70 qword n0 = *(qword *) & num; | |
71 qword d0 = *(qword *) & den; | |
72 qword bit = si_andi (si_fsmbi (1), 1); | |
73 qword r0 = si_il (0); | |
74 qword m1 = si_fsmbi (0x000f); | |
75 qword mask, r1, n1; | |
76 | |
77 d0 = si_shlqbybi (si_shlqbi (d0, shift), shift); | |
78 bit = si_shlqbybi (si_shlqbi (bit, shift), shift); | |
79 | |
80 do | |
81 { | |
82 r1 = si_or (r0, bit); | |
83 | |
84 // n1 = n0 - d0 in TImode | |
85 n1 = si_bg (d0, n0); | |
86 n1 = si_shlqbyi (n1, 4); | |
87 n1 = si_sf (m1, n1); | |
88 n1 = si_bgx (d0, n0, n1); | |
89 n1 = si_shlqbyi (n1, 4); | |
90 n1 = si_sf (m1, n1); | |
91 n1 = si_bgx (d0, n0, n1); | |
92 n1 = si_shlqbyi (n1, 4); | |
93 n1 = si_sf (m1, n1); | |
94 n1 = si_sfx (d0, n0, n1); | |
95 | |
96 mask = si_fsm (si_cgti (n1, -1)); | |
97 r0 = si_selb (r0, r1, mask); | |
98 n0 = si_selb (n0, n1, mask); | |
99 bit = si_rotqmbii (bit, -1); | |
100 d0 = si_rotqmbii (d0, -1); | |
101 } | |
102 while (si_to_uint (si_orx (bit))); | |
103 if (rp) | |
104 *rp = *(UTItype *) & n0; | |
105 return *(UTItype *) & r0; | |
106 } | |
107 | |
108 UTItype | |
109 __udivti3 (UTItype n, UTItype d) | |
110 { | |
111 return __udivmodti4 (n, d, (UTItype *)0); | |
112 } | |
113 | |
114 UTItype | |
115 __umodti3 (UTItype n, UTItype d) | |
116 { | |
117 UTItype w; | |
118 __udivmodti4 (n, d, &w); | |
119 return w; | |
120 } | |
121 | |
122 TItype | |
123 __divti3 (TItype n, TItype d) | |
124 { | |
125 int c = 0; | |
126 TItype w; | |
127 | |
128 if (n < 0) | |
129 { | |
130 c = ~c; | |
131 n = -n; | |
132 } | |
133 if (d < 0) | |
134 { | |
135 c = ~c; | |
136 d = -d; | |
137 } | |
138 | |
139 w = __udivmodti4 (n, d, (UTItype *)0); | |
140 if (c) | |
141 w = -w; | |
142 return w; | |
143 } | |
144 | |
145 TItype | |
146 __modti3 (TItype n, TItype d) | |
147 { | |
148 int c = 0; | |
149 TItype w; | |
150 | |
151 if (n < 0) | |
152 { | |
153 c = ~c; | |
154 n = -n; | |
155 } | |
156 if (d < 0) | |
157 { | |
158 c = ~c; | |
159 d = -d; | |
160 } | |
161 | |
162 __udivmodti4 (n, d, (UTItype *) &w); | |
163 if (c) | |
164 w = -w; | |
165 return w; | |
166 } |