root / hostutils.c @ 7a51ad82
History  View  Annotate  Download (2.8 kB)
1 
/*


2 
* Utility compute operations used by translated code.

3 
*

4 
* Copyright (c) 2003 Fabrice Bellard

5 
* Copyright (c) 2007 Aurelien Jarno

6 
*

7 
* Permission is hereby granted, free of charge, to any person obtaining a copy

8 
* of this software and associated documentation files (the "Software"), to deal

9 
* in the Software without restriction, including without limitation the rights

10 
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

11 
* copies of the Software, and to permit persons to whom the Software is

12 
* furnished to do so, subject to the following conditions:

13 
*

14 
* The above copyright notice and this permission notice shall be included in

15 
* all copies or substantial portions of the Software.

16 
*

17 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

18 
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

19 
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL

20 
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

21 
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

22 
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN

23 
* THE SOFTWARE.

24 
*/

25  
26 
#include "vl.h" 
27  
28 
//#define DEBUG_MULDIV

29  
30 
/* Long integer helpers */

31 
#if !defined(__x86_64__)

32 
static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) 
33 
{ 
34 
*plow += a; 
35 
/* carry test */

36 
if (*plow < a)

37 
(*phigh)++; 
38 
*phigh += b; 
39 
} 
40  
41 
static void neg128 (uint64_t *plow, uint64_t *phigh) 
42 
{ 
43 
*plow = ~*plow; 
44 
*phigh = ~*phigh; 
45 
add128(plow, phigh, 1, 0); 
46 
} 
47  
48 
static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) 
49 
{ 
50 
uint32_t a0, a1, b0, b1; 
51 
uint64_t v; 
52  
53 
a0 = a; 
54 
a1 = a >> 32;

55  
56 
b0 = b; 
57 
b1 = b >> 32;

58  
59 
v = (uint64_t)a0 * (uint64_t)b0; 
60 
*plow = v; 
61 
*phigh = 0;

62  
63 
v = (uint64_t)a0 * (uint64_t)b1; 
64 
add128(plow, phigh, v << 32, v >> 32); 
65  
66 
v = (uint64_t)a1 * (uint64_t)b0; 
67 
add128(plow, phigh, v << 32, v >> 32); 
68  
69 
v = (uint64_t)a1 * (uint64_t)b1; 
70 
*phigh += v; 
71 
} 
72  
73 
/* Unsigned 64x64 > 128 multiplication */

74 
void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)

75 
{ 
76 
mul64(plow, phigh, a, b); 
77 
#if defined(DEBUG_MULDIV)

78 
printf("mulu64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",

79 
a, b, *phigh, *plow); 
80 
#endif

81 
} 
82  
83 
/* Signed 64x64 > 128 multiplication */

84 
void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)

85 
{ 
86 
int sa, sb;

87  
88 
sa = (a < 0);

89 
if (sa)

90 
a = a; 
91 
sb = (b < 0);

92 
if (sb)

93 
b = b; 
94 
mul64(plow, phigh, a, b); 
95 
if (sa ^ sb) {

96 
neg128(plow, phigh); 
97 
} 
98 
#if defined(DEBUG_MULDIV)

99 
printf("muls64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",

100 
a, b, *phigh, *plow); 
101 
#endif

102 
} 
103 
#endif /* !defined(__x86_64__) */ 