1
/***************************************************************************
5
Definitions for inline functions that can be overriden by OSD-
8
Copyright Nicola Salmoria and the MAME Team.
9
Visit http://mamedev.org for licensing and usage restrictions.
11
***************************************************************************/
16
/* we come with implementations for GCC x86 and PPC */
19
#if defined(__i386__) || defined(__x86_64__)
21
#elif defined(__ppc__) || defined (__PPC__) || defined(__ppc64__) || defined(__PPC64__)
34
/***************************************************************************
36
***************************************************************************/
38
/*-------------------------------------------------
39
mul_32x32 - perform a signed 32 bit x 32 bit
40
multiply and return the full 64 bit result
41
-------------------------------------------------*/
44
INLINE INT64 mul_32x32(INT32 a, INT32 b)
46
return (INT64)a * (INT64)b;
51
/*-------------------------------------------------
52
mulu_32x32 - perform an unsigned 32 bit x
53
32 bit multiply and return the full 64 bit
55
-------------------------------------------------*/
58
INLINE UINT64 mulu_32x32(UINT32 a, UINT32 b)
60
return (UINT64)a * (UINT64)b;
65
/*-------------------------------------------------
66
mul_32x32_hi - perform a signed 32 bit x 32 bit
67
multiply and return the upper 32 bits of the
69
-------------------------------------------------*/
72
INLINE INT32 mul_32x32_hi(INT32 a, INT32 b)
74
return (UINT32)(((INT64)a * (INT64)b) >> 32);
79
/*-------------------------------------------------
80
mulu_32x32_hi - perform an unsigned 32 bit x
81
32 bit multiply and return the upper 32 bits
83
-------------------------------------------------*/
86
INLINE UINT32 mulu_32x32_hi(UINT32 a, UINT32 b)
88
return (UINT32)(((UINT64)a * (UINT64)b) >> 32);
93
/*-------------------------------------------------
94
mul_32x32_shift - perform a signed 32 bit x
95
32 bit multiply and shift the result by the
96
given number of bits before truncating the
98
-------------------------------------------------*/
100
#ifndef mul_32x32_shift
101
INLINE INT32 mul_32x32_shift(INT32 a, INT32 b, UINT8 shift)
103
return (INT32)(((INT64)a * (INT64)b) >> shift);
108
/*-------------------------------------------------
109
mulu_32x32_shift - perform an unsigned 32 bit x
110
32 bit multiply and shift the result by the
111
given number of bits before truncating the
113
-------------------------------------------------*/
115
#ifndef mulu_32x32_shift
116
INLINE UINT32 mulu_32x32_shift(UINT32 a, UINT32 b, UINT8 shift)
118
return (UINT32)(((UINT64)a * (UINT64)b) >> shift);
123
/*-------------------------------------------------
124
div_64x32 - perform a signed 64 bit x 32 bit
125
divide and return the 32 bit quotient
126
-------------------------------------------------*/
129
INLINE INT32 div_64x32(INT64 a, INT32 b)
136
/*-------------------------------------------------
137
divu_64x32 - perform an unsigned 64 bit x 32 bit
138
divide and return the 32 bit quotient
139
-------------------------------------------------*/
142
INLINE UINT32 divu_64x32(UINT64 a, UINT32 b)
144
return a / (UINT64)b;
149
/*-------------------------------------------------
150
div_64x32_rem - perform a signed 64 bit x 32
151
bit divide and return the 32 bit quotient and
153
-------------------------------------------------*/
155
#ifndef div_64x32_rem
156
INLINE INT32 div_64x32_rem(INT64 a, INT32 b, INT32 *remainder)
158
*remainder = a % (INT64)b;
164
/*-------------------------------------------------
165
divu_64x32_rem - perform an unsigned 64 bit x
166
32 bit divide and return the 32 bit quotient
168
-------------------------------------------------*/
170
#ifndef divu_64x32_rem
171
INLINE UINT32 divu_64x32_rem(UINT64 a, UINT32 b, UINT32 *remainder)
173
*remainder = a % (UINT64)b;
174
return a / (UINT64)b;
179
/*-------------------------------------------------
180
div_32x32_shift - perform a signed divide of
181
two 32 bit values, shifting the first before
182
division, and returning the 32 bit quotient
183
-------------------------------------------------*/
185
#ifndef div_32x32_shift
186
INLINE INT32 div_32x32_shift(INT32 a, INT32 b, UINT8 shift)
188
return ((INT64)a << shift) / (INT64)b;
193
/*-------------------------------------------------
194
divu_32x32_shift - perform an unsigned divide of
195
two 32 bit values, shifting the first before
196
division, and returning the 32 bit quotient
197
-------------------------------------------------*/
199
#ifndef divu_32x32_shift
200
INLINE UINT32 divu_32x32_shift(UINT32 a, UINT32 b, UINT8 shift)
202
return ((UINT64)a << shift) / (UINT64)b;
207
/*-------------------------------------------------
208
mod_64x32 - perform a signed 64 bit x 32 bit
209
divide and return the 32 bit remainder
210
-------------------------------------------------*/
213
INLINE INT32 mod_64x32(INT64 a, INT32 b)
220
/*-------------------------------------------------
221
modu_64x32 - perform an unsigned 64 bit x 32 bit
222
divide and return the 32 bit remainder
223
-------------------------------------------------*/
226
INLINE UINT32 modu_64x32(UINT64 a, UINT32 b)
228
return a % (UINT64)b;
233
/*-------------------------------------------------
234
recip_approx - compute an approximate floating
236
-------------------------------------------------*/
239
INLINE float recip_approx(float value)
247
/***************************************************************************
248
INLINE BIT MANIPULATION FUNCTIONS
249
***************************************************************************/
251
/*-------------------------------------------------
252
count_leading_zeros - return the number of
253
leading zero bits in a 32-bit value
254
-------------------------------------------------*/
256
#ifndef count_leading_zeros
257
INLINE UINT8 count_leading_zeros(UINT32 val)
260
for (count = 0; (INT32)val >= 0; count++) val <<= 1;
266
/*-------------------------------------------------
267
count_leading_ones - return the number of
268
leading one bits in a 32-bit value
269
-------------------------------------------------*/
271
#ifndef count_leading_ones
272
INLINE UINT8 count_leading_ones(UINT32 val)
275
for (count = 0; (INT32)val < 0; count++) val <<= 1;
282
/***************************************************************************
283
INLINE SYNCHRONIZATION FUNCTIONS
284
***************************************************************************/
286
/*-------------------------------------------------
287
compare_exchange32 - compare the 'compare'
288
value against the memory at 'ptr'; if equal,
289
swap in the 'exchange' value. Regardless,
290
return the previous value at 'ptr'.
292
Note that the default implementation does
293
no synchronization. You MUST override this
294
in osinline.h for it to be useful in a
295
multithreaded environment!
296
-------------------------------------------------*/
298
#ifndef compare_exchange32
299
INLINE INT32 compare_exchange32(INT32 volatile *ptr, INT32 compare, INT32 exchange)
309
/*-------------------------------------------------
310
compare_exchange64 - compare the 'compare'
311
value against the memory at 'ptr'; if equal,
312
swap in the 'exchange' value. Regardless,
313
return the previous value at 'ptr'.
315
Note that the default implementation does
316
no synchronization. You MUST override this
317
in osinline.h for it to be useful in a
318
multithreaded environment!
319
-------------------------------------------------*/
322
#ifndef compare_exchange64
323
INLINE INT64 compare_exchange64(INT64 volatile *ptr, INT64 compare, INT64 exchange)
334
/*-------------------------------------------------
335
compare_exchange_ptr - compare the 'compare'
336
value against the memory at 'ptr'; if equal,
337
swap in the 'exchange' value. Regardless,
338
return the previous value at 'ptr'.
339
-------------------------------------------------*/
341
#ifndef compare_exchange_ptr
342
INLINE void *compare_exchange_ptr(void * volatile *ptr, void *compare, void *exchange)
346
result = compare_exchange64((INT64 volatile *)ptr, (INT64)compare, (INT64)exchange);
349
result = compare_exchange32((INT32 volatile *)ptr, (INT32)compare, (INT32)exchange);
351
return (void *)result;
356
/*-------------------------------------------------
357
atomic_exchange32 - atomically exchange the
358
exchange value with the memory at 'ptr',
359
returning the original value.
361
Note that the default implementation does
362
no synchronization. You MUST override this
363
in osinline.h for it to be useful in a
364
multithreaded environment!
365
-------------------------------------------------*/
367
#ifndef atomic_exchange32
368
INLINE INT32 atomic_exchange32(INT32 volatile *ptr, INT32 exchange)
377
/*-------------------------------------------------
378
atomic_add32 - atomically add the delta value
379
to the memory at 'ptr', returning the final
382
Note that the default implementation does
383
no synchronization. You MUST override this
384
in osinline.h for it to be useful in a
385
multithreaded environment!
386
-------------------------------------------------*/
389
INLINE INT32 atomic_add32(INT32 volatile *ptr, INT32 delta)
391
return (*ptr += delta);
396
/*-------------------------------------------------
397
atomic_increment32 - atomically increment the
398
32-bit value in memory at 'ptr', returning the
401
Note that the default implementation does
402
no synchronization. You MUST override this
403
in osinline.h for it to be useful in a
404
multithreaded environment!
405
-------------------------------------------------*/
407
#ifndef atomic_increment32
408
INLINE INT32 atomic_increment32(INT32 volatile *ptr)
410
return atomic_add32(ptr, 1);
415
/*-------------------------------------------------
416
atomic_decrement32 - atomically decrement the
417
32-bit value in memory at 'ptr', returning the
420
Note that the default implementation does
421
no synchronization. You MUST override this
422
in osinline.h for it to be useful in a
423
multithreaded environment!
424
-------------------------------------------------*/
426
#ifndef atomic_decrement32
427
INLINE INT32 atomic_decrement32(INT32 volatile *ptr)
429
return atomic_add32(ptr, -1);
435
/***************************************************************************
436
INLINE TIMING FUNCTIONS
437
***************************************************************************/
439
/*-------------------------------------------------
440
get_profile_ticks - return a tick counter
441
from the processor that can be used for
442
profiling. It does not need to run at any
444
-------------------------------------------------*/
446
#ifndef get_profile_ticks
447
INLINE INT64 get_profile_ticks(void)
453
#endif /* __EMINLINE__ */