OSDN Git Service

* config/i386/mmx.md (mmx_nand<mode>3): Rename to mmx_andnot<mode>3.
[pf3gnuchains/gcc-fork.git] / gcc / config / spu / divmodti4.c
1 /* Copyright (C) 2008 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 2 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    You should have received a copy of the GNU General Public License
14    along with this file; see the file COPYING.  If not, write to the Free
15    Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
16    02110-1301, USA.  */
17
18 /* As a special exception, if you link this library with files compiled with
19    GCC to produce an executable, this does not cause the resulting executable
20    to be covered by the GNU General Public License.  The exception does not
21    however invalidate any other reasons why the executable file might be covered
22    by the GNU General Public License. */
23
24 #include <spu_intrinsics.h>
25
26 typedef unsigned int UTItype __attribute__ ((mode (TI)));
27 typedef int TItype __attribute__ ((mode (TI)));
28 TItype __divti3 (TItype u, TItype v);
29 TItype __modti3 (TItype u, TItype v);
30 UTItype __udivti3 (UTItype u, UTItype v);
31 UTItype __umodti3 (UTItype u, UTItype v);
32 UTItype __udivmodti4 (UTItype u, UTItype v, UTItype *w);
33
34 inline static unsigned int
35 count_leading_zeros (UTItype x)
36 {
37   qword c = si_clz (*(qword *) & x);
38   qword cmp0 = si_cgti (c, 31);
39   qword cmp1 = si_and (cmp0, si_shlqbyi (cmp0, 4));
40   qword cmp2 = si_and (cmp1, si_shlqbyi (cmp0, 8));
41   qword s = si_a (c, si_and (cmp0, si_shlqbyi (c, 4)));
42   s = si_a (s, si_and (cmp1, si_shlqbyi (c, 8)));
43   s = si_a (s, si_and (cmp2, si_shlqbyi (c, 12)));
44   return si_to_uint (s);
45 }
46
47 /* Based on implementation of udivmodsi4, which is essentially
48  * an optimized version of gcc/config/udivmodsi4.c
49         clz      %7,%2
50         clz      %4,%1
51         il       %5,1
52         fsmbi    %0,0
53         sf       %7,%4,%7
54         ori      %3,%1,0
55         shl      %5,%5,%7
56         shl      %4,%2,%7
57 1:      or       %8,%0,%5
58         rotmi    %5,%5,-1
59         clgt     %6,%4,%3
60         sf       %7,%4,%3
61         rotmi    %4,%4,-1
62         selb     %0,%8,%0,%6
63         selb     %3,%7,%3,%6
64 3:      brnz     %5,1b
65  */
66
67 UTItype
68 __udivmodti4 (UTItype num, UTItype den, UTItype * rp)
69 {
70   qword shift =
71     si_from_uint (count_leading_zeros (den) - count_leading_zeros (num));
72   qword n0 = *(qword *) & num;
73   qword d0 = *(qword *) & den;
74   qword bit = si_andi (si_fsmbi (1), 1);
75   qword r0 = si_il (0);
76   qword m1 = si_fsmbi (0x000f);
77   qword mask, r1, n1;
78
79   d0 = si_shlqbybi (si_shlqbi (d0, shift), shift);
80   bit = si_shlqbybi (si_shlqbi (bit, shift), shift);
81
82   do
83     {
84       r1 = si_or (r0, bit);
85
86       // n1 = n0 - d0 in TImode
87       n1 = si_bg (d0, n0);
88       n1 = si_shlqbyi (n1, 4);
89       n1 = si_sf (m1, n1);
90       n1 = si_bgx (d0, n0, n1);
91       n1 = si_shlqbyi (n1, 4);
92       n1 = si_sf (m1, n1);
93       n1 = si_bgx (d0, n0, n1);
94       n1 = si_shlqbyi (n1, 4);
95       n1 = si_sf (m1, n1);
96       n1 = si_sfx (d0, n0, n1);
97
98       mask = si_fsm (si_cgti (n1, -1));
99       r0 = si_selb (r0, r1, mask);
100       n0 = si_selb (n0, n1, mask);
101       bit = si_rotqmbii (bit, -1);
102       d0 = si_rotqmbii (d0, -1);
103     }
104   while (si_to_uint (si_orx (bit)));
105   if (rp)
106     *rp = *(UTItype *) & n0;
107   return *(UTItype *) & r0;
108 }
109
110 UTItype
111 __udivti3 (UTItype n, UTItype d)
112 {
113   return __udivmodti4 (n, d, (UTItype *)0);
114 }
115
116 UTItype
117 __umodti3 (UTItype n, UTItype d)
118 {
119   UTItype w;
120   __udivmodti4 (n, d, &w);
121   return w;
122 }
123
124 TItype
125 __divti3 (TItype n, TItype d)
126 {
127   int c = 0;
128   TItype w;
129
130   if (n < 0)
131     {
132         c = ~c;
133         n = -n;
134     }
135   if (d < 0)
136     {
137         c = ~c;
138         d = -d;
139     }
140
141   w = __udivmodti4 (n, d, (UTItype *)0);
142   if (c)
143     w = -w;
144   return w;
145 }
146
147 TItype
148 __modti3 (TItype n, TItype d)
149 {
150   int c = 0;
151   TItype w;
152
153   if (n < 0)
154     {
155         c = ~c;
156         n = -n;
157     }
158   if (d < 0)
159     {
160         c = ~c;
161         d = -d;
162     }
163
164   __udivmodti4 (n, d, (UTItype *) &w);
165   if (c)
166     w = -w;
167   return w;
168 }