math64.h
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:19k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /* platform-specific routines and macros. */
  36. ///////////////////////////////////////////////////////////////////////////////////////
  37. // MSVC / i386
  38. ///////////////////////////////////////////////////////////////////////////////////////
  39. #if (defined(_M_IX86) && defined(_MSC_VER)) || (defined(__WINS__) && defined(_SYMBIAN)) || (defined(__WINS__) && defined(WINCE_EMULATOR)) || (defined(_OPENWAVE_SIMULATOR))
  40. #define HAVE_PLATFORM_MACROS
  41. #pragma warning(disable:4035)
  42. /* Compute a * b / c, using 64-bit intermediate result */
  43. static __inline int MulDiv64(int a, int b, int c)
  44. {
  45. __asm mov eax, a
  46. __asm imul b
  47. __asm idiv c
  48. }
  49. /* Compute (a * b) >> 32, using 64-bit intermediate result */
  50. static __inline int MulShift32(int a, int b)
  51. {
  52. __asm mov eax, a
  53. __asm imul b
  54.   __asm mov eax, edx
  55. }
  56. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  57. static __inline int MulShift31(int a, int b)
  58. {
  59. __asm mov eax, a
  60. __asm imul b
  61. __asm shrd eax, edx, 31
  62. }
  63. /* Compute (a * b) >> 30, using 64-bit intermediate result */
  64. static __inline int MulShift30(int a, int b)
  65. {
  66. __asm mov eax, a
  67. __asm imul b
  68. __asm shrd eax, edx, 30
  69. }
  70. /* Compute (a * b) >> n, using 64-bit intermediate result */
  71. static __inline int MulShiftN(int a, int b, int n)
  72. {
  73. __asm mov eax, a
  74. __asm imul b
  75. __asm mov ecx, n
  76. __asm shrd eax, edx, cl
  77. }
  78. #ifdef DEBUG
  79. #ifdef ASSERT
  80. #undef ASSERT
  81. #endif
  82. #define ASSERT(x) if (!(x)) __asm int 3;
  83. #endif
  84. #ifdef TIMING
  85. __int64 _timestamp;
  86. __inline __int64 rdtsc() {
  87. //    __asm   rdtsc  /* timestamp in edx:eax */
  88.     __asm _emit 0x0f __asm _emit 0x31 // MSVC5 does not know rdtsc
  89. }
  90. #define TICK() _timestamp = rdtsc();
  91. #define TOCK(nsamples) (_timestamp = rdtsc() - _timestamp, 
  92. printf("cycles =%4.0fn", _timestamp / (double)(nsamples)) , _timestamp)
  93. #endif // TIMING
  94. #pragma warning(default:4035)
  95. #endif // (defined(_M_IX86) && defined(_MSC_VER)) || (defined(__WINS__) && defined(_SYMBIAN))
  96. ///////////////////////////////////////////////////////////////////////////////////////
  97. // GCC / i386
  98. ///////////////////////////////////////////////////////////////////////////////////////
  99. #if defined(__GNUC__) && defined(__i386__)
  100. #define HAVE_PLATFORM_MACROS
  101. /* Compute a * b / c, using 64-bit intermediate result */
  102. static __inline__ int MulDiv64(register int x, register int y, register int z)
  103. {
  104.     int zhi ;
  105.     /* we specify four alternatives here, one for each permutation of memory or
  106.        register operand in the multiplier and the divisor. All are commutative in
  107.        the multiplication arguments, one of which needs to be in eax when we
  108.        start. */
  109.     __asm__ volatile ("imull %3nt"
  110.                       "idivl %4"
  111.                       : "=&d,&d,&d,&d" (zhi), "+a,a,a,a" (x)
  112.                       : "%1,%1,%1,%1" (x), "m,r,m,r" (y), "m,m,r,r" (z)) ;
  113.     return x ;
  114. }
  115. /* Compute (a * b) >> 32, using 64-bit intermediate result */
  116. static __inline__ int MulShift32(int x, int y)
  117. {
  118.     int z ;
  119.     /* we specify two alternatives here. The first one can read the multiplier from
  120.        memory, the second from from a register. Both return the result in eax,edx
  121.        and are commutative in the arguments, one of which needs to be in eax when we
  122.        start. */
  123.     __asm__ volatile ("imull %3" : "=d,d" (z), "+a,a" (x): "%1,1" (x), "m,r" (y)) ;
  124.     return z ;
  125. }
  126. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  127. static __inline__ int MulShift31(int x, int y)
  128. {
  129.     int zhi ;
  130.     __asm__ volatile ("imull %3nt"
  131.                       "shrdl $31,%1,%0": "+a,a" (x), "=d,d" (zhi) : "%0,%0" (x), "m,r" (y)) ;
  132.     return x ;
  133. }
  134. /* Compute (a * b) >> 30, using 64-bit intermediate result */
  135. static __inline__ int MulShift30(int x, int y)
  136. {
  137.     int zhi ;
  138.     __asm__ volatile ("imull %3nt"
  139.                       "shrdl $30,%1,%0" : "+a,a" (x), "=d,d" (zhi) : "%0,%0" (x), "m,r" (y)) ;
  140.     return x ;
  141. }
  142. /* Compute (a * b) >> n, using 64-bit intermediate result */
  143. static __inline__ int MulShiftN(register int x, register int y, register int n)
  144. {
  145.     int zhi ;
  146.     __asm__ volatile ("imull %3nt"
  147.                       "shrdl %%cl,%1,%0" : "+a,a" (x), "=d,d" (zhi) : "%0,%0" (x), "m,r" (y), "c,c" (n)) ;
  148.     return x ;
  149. }
  150. #ifdef TIMING
  151. long long _timestamp;
  152. static __inline__ long long rdtsc() {
  153.     long long r ;
  154.     __asm__ __volatile ("rdtsc" : "=A" (r)) ;
  155.     return r ;    
  156. }
  157. #define TICK() _timestamp = rdtsc();
  158. #define TOCK(nsamples) (_timestamp = rdtsc() - _timestamp, 
  159. printf("cycles =%4.0fn", _timestamp / (double)(nsamples)), _timestamp)
  160. #endif
  161. #ifdef DEBUG
  162. #define ASSERT(x) if (!(x)) __asm__ __volatile ("int $3" :: )
  163. #endif
  164. #endif // defined(__GNUC__) && defined(__i386__)
  165. ///////////////////////////////////////////////////////////////////////////////////////
  166. // Sun native compiler / Sparc
  167. ///////////////////////////////////////////////////////////////////////////////////////
  168. #if defined(__sparc)
  169. // the macros definitions come from an il file here.
  170. #define HAVE_PLATFORM_MACROS
  171. /* Compute a * b / c, using 64-bit intermediate result */
  172. signed int MulDiv64(signed int a, signed int b, signed int c) ;
  173. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  174. signed int MulShift31(signed int a, signed int b) ;
  175. /* Compute (a * b) >> 32, using 64-bit intermediate result */
  176. signed int MulShift32(signed int a, signed int b) ;
  177. /* Compute (a * b) >> n, using 64-bit intermediate result */
  178. signed int MulShiftN(signed int a, signed int b, signed int n) ;
  179. #ifdef TIMING
  180. int _t1 ;
  181. int rdtsc() ;
  182. #define TICK() _t1 = rdtsc()
  183. #define TOCK(nsamples) (_t1 = rdtsc()-_t1 , printf("cycles = %4.1fn", 
  184.   _t1 / (double)(nsamples)), _t1 )
  185. #endif
  186. #define HAVE_FASTABS
  187. static inline int FASTABS(int x) 
  188. {
  189. int sign;
  190. sign = x >> 31;
  191. x ^= sign;
  192. x -= sign;
  193. return x;
  194. }
  195. #ifdef DEBUG
  196. #include <assert.h>
  197. #define ASSERT(x)  assert(x)
  198. #endif
  199. #endif // defined(__sparc)
  200. ///////////////////////////////////////////////////////////////////////////////////////
  201. // Codewarrior / PowerPC
  202. ///////////////////////////////////////////////////////////////////////////////////////
  203. #if defined(__MWERKS__) && defined(__POWERPC__)
  204. /*if your compiler can compile 64-bit instructions, define this. CW 8 cannot */
  205. /* #define USE_64BIT_INSNS */
  206. #define HAVE_PLATFORM_MACROS
  207. /* Compute a * b / c, using 64-bit intermediate result */
  208. #ifdef USE_64BIT_INSNS
  209. inline int MulDiv64(register int a, register int b, register int c)
  210. {
  211. asm {
  212. mulhd r0,a,b
  213. divd r0,r0,c
  214. }
  215. }
  216. #else
  217. inline int MulDiv64(double a, double b, double c)
  218. {
  219. return (int)( (a/c) * b ) ;
  220. }
  221. #endif
  222. /* Compute (a * b) >> 30, using 64-bit intermediate result */
  223. inline int MulShift30(register int a, register int b)
  224. {
  225. register int res ;
  226. #ifdef USE_64BIT_INSNS
  227. asm {
  228. mulhd res,a,b
  229. srd res,30
  230. }
  231. #else
  232. asm {
  233. mulhw res,a,b
  234. slwi res,res,2 // not exact; last two bits are wrong
  235. }
  236. #endif
  237. return res ;
  238. }
  239. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  240. inline int MulShift31(register int a, register int b)
  241. {
  242. register int res ;
  243. #ifdef USE_64BIT_INSNS
  244. asm {
  245. mulhd res,a,b
  246. srd res,31
  247. }
  248. #else
  249. asm {
  250. mulhw res,a,b
  251. slwi res,res,1 // not exact; last bit is wrong half the time
  252. }
  253. #endif
  254. return res ;
  255. }
  256. /* Compute (a * b) >> 32, using 64-bit intermediate result */
  257. inline int MulShift32(register int a, register int b)
  258. {
  259. register int res ;
  260. asm {
  261. mulhw res,a,b
  262. }
  263. return res ;
  264. }
  265. /* Compute (a * b) >> n, using 64-bit intermediate result */
  266. //inline int MulShiftN(register int a, register int b, register int n)
  267. static int MulShiftN(register int a, register int b, int n)
  268. {
  269. #ifdef USE_64BIT_INSNS
  270. register int res ;
  271. asm {
  272. mulhd res,a,b
  273. srd res,n
  274. }
  275. return res ;
  276. #else
  277. register unsigned int temp ;
  278. int result ;
  279. asm {
  280. mullw  temp,a,b
  281. }
  282. result = temp >> n ;
  283. asm {
  284. mulhw  temp,a,b
  285. }
  286. result |= (temp << (32-n)) ;
  287. return result ;
  288. #endif
  289. }
  290. #ifdef TIMING
  291. static unsigned int tick,tock ;
  292. inline void fTICK()
  293. { register int t ; asm { mftb t } ; tick = t ; }
  294. inline void fTOCK()
  295. { register int t ; asm { mftb t } ; tock = t ;
  296.   if (tock < tick) {
  297.    tock += 65536 ; tick -= 65536 ; 
  298.   }
  299. }
  300. #define TICK() fTICK()
  301. #define TOCK(nsamples) ( fTOCK() , printf("cycles = %4.1fn",4.0f*(tock-tick)/(float)(nsamples)), 
  302. tock-tick )
  303. #endif // TIMING
  304. #endif //  defined(__MWERKS__) && defined(__POWERPC__)
  305. ///////////////////////////////////////////////////////////////////////////////////////
  306. // GCC / PowerPC
  307. ///////////////////////////////////////////////////////////////////////////////////////
  308. #if defined(__GNUC__) && (defined(__POWERPC__) || defined(__powerpc__))
  309. /*if your compiler can compile 64-bit instructions, and your CPU has them,
  310.  define this. */
  311. // #define USE_64BIT_INSNS
  312. #define HAVE_PLATFORM_MACROS
  313. /* Compute a * b / c, using 64-bit intermediate result */
  314. static __inline__ int MulDiv64(int a, int b, int c)
  315. {
  316. int res ;
  317. #ifdef USE_64BIT_INSNS
  318. __asm__ volatile ("mulhd %0,%2,%3nt"
  319.   "divd %0,%0,%1"
  320.   : "=&r" (res) : "r" (c), "%r" (a), "r" (b) ) ;
  321. #else
  322. res = (int)(((double)a*(double)b - (double)(c>>1)) / (double)c) ;
  323. #endif
  324. return res ;
  325. }
  326. /* Compute (a * b) >> 32, using 64-bit intermediate result */
  327. static __inline__ int MulShift32(int a, int b)
  328. {
  329. int res ;
  330. __asm__ ("mulhw %0,%1,%2" : "=r" (res) : "%r" (a) , "r" (b) ) ;
  331. return res ;
  332. }
  333. /* Compute (a * b) >> 30, using 64-bit intermediate result */
  334. static __inline__ int MulShift30(int a, int b)
  335. {
  336. int res ;
  337. #ifdef USE_64BIT_INSNS
  338. __asm__ ("mulhd %0,%1,%2nt"
  339.  "srd %0,30" : "=r" (res) : "%r" (a), "r" (b) ) ;
  340. #else
  341. res = MulShift32(a,b) << 2 ;
  342. #endif
  343. return res ;
  344. }
  345. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  346. static __inline__ int MulShift31(int a, int b)
  347. {
  348. int res ;
  349. #ifdef USE_64BIT_INSNS
  350. __asm__ ("mulhd %0,%1,%2nt"
  351.  "srd %0,31" : "=r" (res) : "%r" (a), "r" (b) ) ;
  352. #else
  353. res = MulShift32(a,b) << 1 ;
  354. #endif
  355. return res ;
  356. }
  357. /* Compute (a * b) >> n, using 64-bit intermediate result */
  358. static __inline__ int MulShiftN(int a, int b, int n)
  359. {
  360. int res ;
  361. #ifdef USE_64BIT_INSNS
  362. __asm__ ("mulhd %0,%1,%2nt"
  363.  "srd %0,%3" : "=&r" (res) : "%r" (a), "r" (b), "r" (n) ) ;
  364. #else
  365. unsigned int temp ;
  366. __asm__ ("mullw %0,%1,%2" : "=r" (temp) : "%r" (a) , "r" (b) ) ;
  367. res = temp >> n ;
  368. __asm__ ("mulhw %0,%1,%2" : "=r" (temp) : "%r" (a) , "r" (b) ) ;
  369. res |= (temp << (32-n)) ;
  370. #endif
  371. return res ;
  372. }
  373. #ifdef TIMING
  374. static unsigned int tick,tock ;
  375. inline void fTICK()
  376. { register int t ; __asm__ ( "mftb %0" : "=r" (t) ) ; tick = t ; }
  377. inline void fTOCK()
  378. { register int t ; __asm__ ( "mftb %0" : "=r" (t) ) ; tock = t ;
  379.   if (tock < tick) {
  380.    tock += 65536 ; tick -= 65536 ; 
  381.   }
  382. }
  383. #define TICK() fTICK()
  384. #define TOCK(nsamples) ( fTOCK() , printf("cycles = %4.1fn",4.0f*(tock-tick)/(float)(nsamples)), 
  385. tock-tick )
  386. #endif // TIMING
  387. #endif //  defined(__GNUC__) && defined(__POWERPC__)
  388. ///////////////////////////////////////////////////////////////////////////////////////
  389. // EVC3.0 / ARM
  390. ///////////////////////////////////////////////////////////////////////////////////////
  391. #if (defined(_ARM) && defined(_MSC_VER))
  392. /* EVC does not allow us to use inline assembly. Thus, you'll only see prototypes here.
  393.  */
  394. #define HAVE_PLATFORM_MACROS
  395. /* Compute a * b / c, using 64-bit intermediate result. Since the ARM does not have
  396.    a division instruction, we code a totally lame C version here. TODO wschildbach
  397.  */
  398. static __inline int MulDiv64(int a, int b, int c)
  399. {
  400.   __int64 t = (__int64)a * (__int64)b ;
  401.   return (int)(t / c) ;
  402. }
  403. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  404. #ifdef __cplusplus
  405. extern "C" {
  406. #endif // __cplusplus
  407. int MulShift32(int a, int b);
  408. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  409. int MulShift31(int a, int b);
  410. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  411. int MulShift30(int a, int b);
  412. /* Compute (a * b) >> n, using 64-bit intermediate result */
  413. int MulShiftN(int a, int b, int n);
  414. #ifdef __cplusplus
  415. }
  416. #endif // __cplusplus
  417. #endif // (defined(_ARM) && defined(_MSC_VER))
  418. ///////////////////////////////////////////////////////////////////////////////////////
  419. // GNUC / ARM
  420. ///////////////////////////////////////////////////////////////////////////////////////
  421. #if (defined(_ARM) && defined(__GNUC__))
  422. #define HAVE_PLATFORM_MACROS
  423. #if defined(__MARM_THUMB__)
  424. /* Compute a * b / c, using 64-bit intermediate result. Since the ARM does not have
  425.    a division instruction, we code a totally lame C version here. TODO wschildbach
  426.  */
  427. static __inline int MulDiv64(int a, int b, int c)
  428. {
  429.   long long t = (long long)a * (long long)b ;
  430.   return (int)(t / c) ;
  431. }
  432. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  433. static __inline__ int MulShift32(int x, int y)
  434. {
  435.     SymInt64 a = x;
  436.     SymInt64 b = y;
  437.     a *= b;
  438.     a >>= 32;
  439.     return a.Low();
  440. }
  441. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  442. static __inline__ int MulShift31(int x, int y)
  443. {
  444.     SymInt64 a = x;
  445.     SymInt64 b = y;
  446.     a *= b;
  447.     a >>= 31;
  448.     return a.Low();
  449. }
  450. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  451. static __inline__ int MulShift30(int x, int y)
  452. {
  453.     SymInt64 a = x;
  454.     SymInt64 b = y;
  455.     a *= b;
  456.     a >>= 30;
  457.     return a.Low();
  458. }
  459. /* Compute (a * b) >> n, using 64-bit intermediate result */
  460. static __inline__ int MulShiftN(int x, int y, int n)
  461. {
  462.     SymInt64 a = x;
  463.     SymInt64 b = y;
  464.     a *= b;
  465.     a >>= n;
  466.     return a.Low();
  467. }
  468. #define HAVE_FASTABS
  469. static __inline int FASTABS(int x)
  470. {
  471.     if (x >= 0)
  472. return x;
  473.     return -x;
  474. }
  475. #else
  476. /* Compute a * b / c, using 64-bit intermediate result. Since the ARM does not have
  477.    a division instruction, we code a totally lame C version here. TODO wschildbach
  478.  */
  479. static __inline int MulDiv64(int a, int b, int c)
  480. {
  481.   long long t = (long long)a * (long long)b ;
  482.   return (int)(t / c) ;
  483. }
  484. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  485. static __inline__ int MulShift32(int x, int y)
  486. {
  487.   int zlow ;
  488.   __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (x) : "%r" (y), "1" (x)) ;
  489.   return x ;
  490. }
  491. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  492. static __inline__ int MulShift31(int x, int y)
  493. {
  494.   int zlow ;
  495.   __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (x) : "%r" (y), "1" (x)) ;
  496.   __asm__ volatile ("mov %0,%1, lsr #31" : "=r" (zlow) : "r" (zlow)) ;
  497.   __asm__ volatile ("orr %0,%1,%2, lsl #1" : "=r" (x) : "r" (zlow), "r" (x)) ;
  498.   return x ;
  499. }
  500. /* Compute (a * b) >> 31, using 64-bit intermediate result */
  501. static __inline__ int MulShift30(int x, int y)
  502. {
  503.   int zlow ;
  504.   __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (x) : "%r" (y), "1" (x)) ;
  505.   __asm__ volatile ("mov %0,%1, lsr #30" : "=r" (zlow) : "r" (zlow)) ;
  506.   __asm__ volatile ("orr %0,%1,%2, lsl #2" : "=r" (x) : "r" (zlow), "r" (x)) ;
  507.   return x ;
  508. }
  509. /* Compute (a * b) >> n, using 64-bit intermediate result */
  510. static __inline__ int MulShiftN(int x, int y, int n)
  511. {
  512.   int zlow ;
  513.   __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (x) : "%r" (y), "1" (x)) ;
  514.   __asm__ volatile ("mov %0,%1, lsr %2" : "=r" (zlow) : "r" (zlow), "r" (n)) ;
  515.   __asm__ volatile ("orr %0,%1,%2, lsl %3" : "=r" (x) : "r" (zlow), "r" (x), "r" (32-n)) ;
  516.   return x ;
  517. }
  518. #define HAVE_FASTABS
  519. static __inline int FASTABS(int x)
  520. {
  521. int s;
  522.   // s = x ^ (x >> 31)
  523.   __asm__ volatile ("eor %0, %1, %1, asr #31" : "=r" (s) : "r" (x)) ;
  524.   // x = s - (x >> 31)
  525.   __asm__ volatile ("sub %0, %1, %2, asr #31" : "=r" (x) : "r" (s), "r" (x)) ;
  526. return x;
  527. }
  528. #endif // defined(__MARM_THUMB__)
  529. #endif // (defined(_ARM) && defined(__GNUC__))
  530. ///////////////////////////////////////////////////////////////////////////////////////
  531. // ARM_ADS / ARM
  532. ///////////////////////////////////////////////////////////////////////////////////////
  533. #if defined(ARM_ADS)
  534. static __inline int MulShift32(int x, int y)
  535. {
  536.     /* JR - important rules for smull RdLo, RdHi, Rm, Rs:
  537.      *        RdHi and Rm can't be the same register
  538.      *        RdLo and Rm can't be the same register
  539.      *        RdHi and RdLo can't be the same register
  540.      *      for MULSHIFT0(x,y), x = R0 and y = R1
  541.      *      therefore we do y*x instead of x*y so that top 32 can go in R0 (the return register)
  542.      */
  543.     int zlow;
  544.     __asm {
  545.      smull zlow,x,y,x
  546.     }
  547.     return x;
  548. }
  549. static __inline int MulShift31(int x, int y)
  550. {
  551.     /* JR - store result in z (instead of reusing zlow) so that gcc optimizes properly */
  552.     int zlow, z;
  553.     __asm {
  554.      smull  zlow, x, y, x
  555. mov  zlow, zlow, lsr #31
  556.      orr  z, zlow, x, lsl #1
  557.     }
  558.     return z;
  559. }
  560. static __inline int MulShift30(int x, int y)
  561. {
  562.     /* JR - store result in z (instead of reusing zlow) so that gcc optimizes properly */
  563.     int zlow, z;
  564.     
  565.     __asm {
  566.      smull  zlow, x, y, x
  567. mov  zlow, zlow, lsr #30
  568.      orr  z, zlow, x, lsl #2
  569.     }
  570.     return z;
  571. }
  572. #define HAVE_FASTABS
  573. static __inline int FASTABS(int x) 
  574. {
  575. int s;
  576. __asm {
  577.  eor s, x, x, asr #31
  578.  sub x, s, x, asr #31 
  579. }
  580. return x;
  581. }
  582. #endif // defined(ARM_ADS)
  583. ///////////////////////////////////////////////////////////////////////////////////////
  584. // platform independent implementations
  585. ///////////////////////////////////////////////////////////////////////////////////////
  586. #ifndef ASSERT
  587. #define ASSERT(x)
  588. #endif
  589. #ifndef TICK
  590. #define TICK()
  591. #endif
  592. #ifndef TOCK
  593. #define TOCK(nsamples) 1
  594. #endif
  595. #ifndef HAVE_FASTABS
  596. static __inline int FASTABS(int x) 
  597. {
  598. int sign;
  599. sign = x >> 31;
  600. x ^= sign;
  601. x -= sign;
  602. return x;
  603. }
  604. #endif