]>
Commit | Line | Data |
---|---|---|
69d35728 TS |
1 | /* |
2 | * Utility compute operations used by translated code. | |
3 | * | |
e494ead5 | 4 | * Copyright (c) 2003 Fabrice Bellard |
69d35728 TS |
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 | ||
facd2857 BS |
26 | #include <stdlib.h> |
27 | #include <stdint.h> | |
1de7afc9 | 28 | #include "qemu/host-utils.h" |
69d35728 | 29 | |
e494ead5 | 30 | /* Long integer helpers */ |
f540166b | 31 | #ifndef CONFIG_INT128 |
ff7a1eb0 RH |
32 | static inline void mul64(uint64_t *plow, uint64_t *phigh, |
33 | uint64_t a, uint64_t b) | |
69d35728 | 34 | { |
ff7a1eb0 RH |
35 | typedef union { |
36 | uint64_t ll; | |
37 | struct { | |
38 | #ifdef HOST_WORDS_BIGENDIAN | |
39 | uint32_t high, low; | |
40 | #else | |
41 | uint32_t low, high; | |
42 | #endif | |
43 | } l; | |
44 | } LL; | |
45 | LL rl, rm, rn, rh, a0, b0; | |
46 | uint64_t c; | |
e494ead5 | 47 | |
ff7a1eb0 RH |
48 | a0.ll = a; |
49 | b0.ll = b; | |
e494ead5 | 50 | |
ff7a1eb0 RH |
51 | rl.ll = (uint64_t)a0.l.low * b0.l.low; |
52 | rm.ll = (uint64_t)a0.l.low * b0.l.high; | |
53 | rn.ll = (uint64_t)a0.l.high * b0.l.low; | |
54 | rh.ll = (uint64_t)a0.l.high * b0.l.high; | |
e494ead5 | 55 | |
ff7a1eb0 RH |
56 | c = (uint64_t)rl.l.high + rm.l.low + rn.l.low; |
57 | rl.l.high = c; | |
58 | c >>= 32; | |
59 | c = c + rm.l.high + rn.l.high + rh.l.low; | |
60 | rh.l.low = c; | |
61 | rh.l.high += (uint32_t)(c >> 32); | |
e494ead5 | 62 | |
ff7a1eb0 RH |
63 | *plow = rl.ll; |
64 | *phigh = rh.ll; | |
69d35728 TS |
65 | } |
66 | ||
67 | /* Unsigned 64x64 -> 128 multiplication */ | |
e494ead5 | 68 | void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) |
69d35728 | 69 | { |
e494ead5 | 70 | mul64(plow, phigh, a, b); |
e494ead5 | 71 | } |
69d35728 | 72 | |
e494ead5 TS |
73 | /* Signed 64x64 -> 128 multiplication */ |
74 | void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b) | |
75 | { | |
ff7a1eb0 | 76 | uint64_t rh; |
69d35728 | 77 | |
ff7a1eb0 RH |
78 | mul64(plow, &rh, a, b); |
79 | ||
80 | /* Adjust for signs. */ | |
81 | if (b < 0) { | |
82 | rh -= a; | |
e494ead5 | 83 | } |
ff7a1eb0 RH |
84 | if (a < 0) { |
85 | rh -= b; | |
86 | } | |
87 | *phigh = rh; | |
69d35728 | 88 | } |
f540166b | 89 | #endif /* !CONFIG_INT128 */ |