Revision 9d901a20 target-ppc/op_helper.c
b/target-ppc/op_helper.c | ||
---|---|---|
199 | 199 |
|
200 | 200 |
/*****************************************************************************/ |
201 | 201 |
/* Fixed point operations helpers */ |
202 |
#if defined(TARGET_PPC64) |
|
203 |
static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) |
|
204 |
{ |
|
205 |
*plow += a; |
|
206 |
/* carry test */ |
|
207 |
if (*plow < a) |
|
208 |
(*phigh)++; |
|
209 |
*phigh += b; |
|
210 |
} |
|
211 |
|
|
212 |
static void neg128 (uint64_t *plow, uint64_t *phigh) |
|
213 |
{ |
|
214 |
*plow = ~*plow; |
|
215 |
*phigh = ~*phigh; |
|
216 |
add128(plow, phigh, 1, 0); |
|
217 |
} |
|
218 |
|
|
219 |
static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) |
|
220 |
{ |
|
221 |
uint32_t a0, a1, b0, b1; |
|
222 |
uint64_t v; |
|
223 |
|
|
224 |
a0 = a; |
|
225 |
a1 = a >> 32; |
|
226 |
|
|
227 |
b0 = b; |
|
228 |
b1 = b >> 32; |
|
229 |
|
|
230 |
v = (uint64_t)a0 * (uint64_t)b0; |
|
231 |
*plow = v; |
|
232 |
*phigh = 0; |
|
233 |
|
|
234 |
v = (uint64_t)a0 * (uint64_t)b1; |
|
235 |
add128(plow, phigh, v << 32, v >> 32); |
|
236 |
|
|
237 |
v = (uint64_t)a1 * (uint64_t)b0; |
|
238 |
add128(plow, phigh, v << 32, v >> 32); |
|
239 |
|
|
240 |
v = (uint64_t)a1 * (uint64_t)b1; |
|
241 |
*phigh += v; |
|
242 |
#if defined(DEBUG_MULDIV) |
|
243 |
printf("mul: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n", |
|
244 |
a, b, *phigh, *plow); |
|
245 |
#endif |
|
246 |
} |
|
247 |
|
|
248 |
void do_mul64 (uint64_t *plow, uint64_t *phigh) |
|
249 |
{ |
|
250 |
mul64(plow, phigh, T0, T1); |
|
251 |
} |
|
252 |
|
|
253 |
static void imul64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b) |
|
254 |
{ |
|
255 |
int sa, sb; |
|
256 |
|
|
257 |
sa = (a < 0); |
|
258 |
if (sa) |
|
259 |
a = -a; |
|
260 |
sb = (b < 0); |
|
261 |
if (sb) |
|
262 |
b = -b; |
|
263 |
mul64(plow, phigh, a, b); |
|
264 |
if (sa ^ sb) { |
|
265 |
neg128(plow, phigh); |
|
266 |
} |
|
267 |
} |
|
268 |
|
|
269 |
void do_imul64 (uint64_t *plow, uint64_t *phigh) |
|
270 |
{ |
|
271 |
imul64(plow, phigh, T0, T1); |
|
272 |
} |
|
273 |
#endif |
|
274 |
|
|
275 | 202 |
void do_adde (void) |
276 | 203 |
{ |
277 | 204 |
T2 = T0; |
... | ... | |
403 | 330 |
int64_t th; |
404 | 331 |
uint64_t tl; |
405 | 332 |
|
406 |
do_imul64(&tl, &th);
|
|
333 |
muls64(&tl, &th, T0, T1);
|
|
407 | 334 |
if (likely(th == 0)) { |
408 | 335 |
xer_ov = 0; |
409 | 336 |
} else { |
Also available in: Unified diff