1 #include "xc88x.h"
2 
3 #include "mdu88x.h"
4 
5 static uint16_t v;
6 static uint32_t d;
7 
8 /* unsigned OPs */
9 
10 uint8_t
mdu_32udiv16(uint32_t op1,uint16_t op2,uint32_t * res,uint16_t * rem)11 mdu_32udiv16(uint32_t op1, uint16_t op2, uint32_t *res, uint16_t *rem)
12   __reentrant
13 {
14   MD0= op1 & 0xff;
15   MD1= (op1 >> 8) & 0xff;
16   MD2= (op1 >> 16) & 0xff;
17   MD3= (op1 >> 24) & 0xff;
18 
19   MD4= op2 & 0xff;
20   MD5= (op2 >> 8) & 0xff;
21 
22   MDUCON= 0x10 + 0x02;
23   while (MDUSTAT & 0x04) ;
24 
25   d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
26   if (res)
27     *res= d;
28   v= MD5*256 + MD4;
29   if (rem)
30     *rem= v;
31 
32   return MDUSTAT & 0x02;
33 }
34 
35 uint8_t
mdu_16udiv16(uint16_t op1,uint16_t op2,uint16_t * res,uint16_t * rem)36 mdu_16udiv16(uint16_t op1, uint16_t op2, uint16_t *res, uint16_t *rem)
37   __reentrant
38 {
39   MD0= op1 & 0xff;
40   MD1= (op1 >> 8) & 0xff;
41   MD4= op2 & 0xff;
42   MD5= (op2 >> 8) & 0xff;
43 
44   MDUCON= 0x10 + 0x01;
45   while (MDUSTAT & 0x04) ;
46 
47   v= MD1*256 + MD0;
48   if (res)
49     *res= v;
50   v= MD5*256 + MD4;
51   if (rem)
52     *rem= v;
53 
54   return MDUSTAT & 0x02;
55 }
56 
57 uint8_t
mdu_16umul16(uint16_t op1,uint16_t op2,uint32_t * res)58 mdu_16umul16(uint16_t op1, uint16_t op2, uint32_t *res)
59   __reentrant
60 {
61   MD0= op1 & 0xff;
62   MD4= op2 & 0xff;
63   MD1= (op1 >> 8) & 0xff;
64   MD5= (op2 >> 8) & 0xff;
65 
66   MDUCON= 0x10 + 0x00;
67   while (MDUSTAT & 0x04) ;
68 
69   d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
70   if (res)
71     *res= d;
72 
73   return MDUSTAT & 0x02;
74 }
75 
76 /* signed OPs */
77 
78 uint8_t
mdu_32sdiv16(int32_t op1,int16_t op2,int32_t * res,int16_t * rem)79 mdu_32sdiv16(int32_t op1, int16_t op2, int32_t *res, int16_t *rem)
80   __reentrant
81 {
82   MD0= op1 & 0xff;
83   MD1= (op1 >> 8) & 0xff;
84   MD2= (op1 >> 16) & 0xff;
85   MD3= (op1 >> 24) & 0xff;
86 
87   MD4= op2 & 0xff;
88   MD5= (op2 >> 8) & 0xff;
89 
90   MDUCON= 0x10 + 0x06;
91   while (MDUSTAT & 0x04) ;
92 
93   d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
94   if (res)
95     *res= d;
96   v= MD5*256 + MD4;
97   if (rem)
98     *rem= v;
99 
100   return MDUSTAT & 0x02;
101 }
102 
103 uint8_t
mdu_16sdiv16(int16_t op1,int16_t op2,int16_t * res,int16_t * rem)104 mdu_16sdiv16(int16_t op1, int16_t op2, int16_t *res, int16_t *rem)
105   __reentrant
106 {
107   MD0= op1 & 0xff;
108   MD1= (op1 >> 8) & 0xff;
109   MD4= op2 & 0xff;
110   MD5= (op2 >> 8) & 0xff;
111 
112   MDUCON= 0x10 + 0x05;
113   while (MDUSTAT & 0x04) ;
114 
115   v= MD1*256 + MD0;
116   if (res)
117     *res= v;
118   v= MD5*256 + MD4;
119   if (rem)
120     *rem= v;
121 
122   return MDUSTAT & 0x02;
123 }
124 
125 uint8_t
mdu_16smul16(int16_t op1,int16_t op2,int32_t * res)126 mdu_16smul16(int16_t op1, int16_t op2, int32_t *res)
127   __reentrant
128 {
129   MD0= op1 & 0xff;
130   MD4= op2 & 0xff;
131   MD1= (op1 >> 8) & 0xff;
132   MD5= (op2 >> 8) & 0xff;
133 
134   MDUCON= 0x10 + 0x04;
135   while (MDUSTAT & 0x04) ;
136 
137   d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
138   if (res)
139     *res= d;
140 
141   return MDUSTAT & 0x02;
142 }
143 
144 /* normalize */
145 
146 uint8_t
mdu_norm(uint32_t op,uint32_t * res,uint8_t * nuof_shifts)147 mdu_norm(uint32_t op, uint32_t *res, uint8_t *nuof_shifts)
148   __reentrant
149 {
150   MD0= op & 0xff;
151   MD1= (op >> 8) & 0xff;
152   MD2= (op >> 16) & 0xff;
153   MD3= (op >> 24) & 0xff;
154 
155   MDUCON= 0x10 + 0x08;
156   while (MDUSTAT & 0x04) ;
157 
158   d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
159   if (res)
160     *res= d;
161   if (nuof_shifts)
162     *nuof_shifts= MD4 & 0x1f;
163   return MDUSTAT & 0x02;
164 }
165 
166 /* logical shifts */
167 
168 uint8_t
mdu_lshift(uint32_t op,uint8_t shifts,uint8_t right,uint32_t * res)169 mdu_lshift(uint32_t op, uint8_t shifts, uint8_t right, uint32_t *res)
170   __reentrant
171 {
172   MD0= op & 0xff;
173   MD1= (op >> 8) & 0xff;
174   MD2= (op >> 16) & 0xff;
175   MD3= (op >> 24) & 0xff;
176   MD4= (right?0x20:0) + (shifts&0x1f);
177 
178   MDUCON= 0x10 + 0x03;
179   while (MDUSTAT & 0x04) ;
180 
181   d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
182   if (res)
183     *res= d;
184   return MDUSTAT & 0x02;
185 }
186 
187 uint8_t
mdu_lshift_left(uint32_t op,uint8_t shifts,uint32_t * res)188 mdu_lshift_left(uint32_t op, uint8_t shifts, uint32_t *res)
189   __reentrant
190 {
191   return mdu_lshift(op, shifts, 0, res);
192 }
193 
194 uint8_t
mdu_lshift_right(uint32_t op,uint8_t shifts,uint32_t * res)195 mdu_lshift_right(uint32_t op, uint8_t shifts, uint32_t *res)
196   __reentrant
197 {
198   return mdu_lshift(op, shifts, 1, res);
199 }
200 
201 /* arithmetic shifts */
202 
203 uint8_t
mdu_ashift(int32_t op,int8_t shifts,int8_t right,int32_t * res)204 mdu_ashift(int32_t op, int8_t shifts, int8_t right, int32_t *res)
205   __reentrant
206 {
207   MD0= op & 0xff;
208   MD1= (op >> 8) & 0xff;
209   MD2= (op >> 16) & 0xff;
210   MD3= (op >> 24) & 0xff;
211   MD4= (right?0x20:0) + (shifts&0x1f);
212 
213   MDUCON= 0x10 + 0x07;
214   while (MDUSTAT & 0x04) ;
215 
216   d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
217   if (res)
218     *res= d;
219   return MDUSTAT & 0x02;
220 }
221 
222 uint8_t
mdu_ashift_left(int32_t op,int8_t shifts,int32_t * res)223 mdu_ashift_left(int32_t op, int8_t shifts, int32_t *res)
224   __reentrant
225 {
226   return mdu_lshift(op, shifts, 0, res);
227 }
228 
229 uint8_t
mdu_ashift_right(int32_t op,int8_t shifts,int32_t * res)230 mdu_ashift_right(int32_t op, int8_t shifts, int32_t *res)
231   __reentrant
232 {
233   return mdu_lshift(op, shifts, 1, res);
234 }
235