math64.h
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:21k
源码类别:

Symbian

开发平台:

Visual C++

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