30 #ifndef __ARCH_POWER_INSTS_INTEGER_HH__
31 #define __ARCH_POWER_INSTS_INTEGER_HH__
78 if (
a <
b) { cr.cr0.lt = 1; }
79 else if (
a >
b) { cr.cr0.gt = 1; }
80 else { cr.cr0.eq = 1; }
81 if (
so) { cr.cr0.so = 1; }
92 if (
a <
b) { cr.cr0.lt = 1; }
93 else if (
a >
b) { cr.cr0.gt = 1; }
94 else { cr.cr0.eq = 1; }
95 if (
so) { cr.cr0.so = 1; }
117 :
IntOp(mnem, _machInst, __opClass),
137 :
IntOp(mnem, _machInst, __opClass)
142 inline std::tuple<uint64_t, uint64_t>
143 add(uint64_t ralo, uint64_t rahi, uint64_t rb)
const
146 #if defined(__SIZEOF_INT128__)
147 __uint128_t
ra = ((__uint128_t)rahi << 64) | ralo;
148 __uint128_t
sum =
ra + rb;
152 shi = rahi + ((ralo + rb) < ralo);
155 return std::make_tuple(slo, shi);
159 inline std::tuple<uint64_t, int64_t>
160 add(uint64_t ralo, int64_t rahi, int64_t rb)
const
164 #if defined(__SIZEOF_INT128__)
165 __int128_t
ra = ((__int128_t)rahi << 64) | ralo;
166 __int128_t
sum = (__int128_t)
ra + rb;
184 return std::make_tuple(slo, shi);
191 inline std::tuple<uint64_t, uint64_t>
195 #if defined(__SIZEOF_INT128__)
196 __uint128_t prod = (__uint128_t)
ra * rb;
200 uint64_t ralo = (uint32_t)
ra, rahi =
ra >> 32;
201 uint64_t rblo = (uint32_t)rb, rbhi = rb >> 32;
202 uint64_t pp0 = ralo * rblo;
203 uint64_t pp1 = rahi * rblo;
204 uint64_t pp2 = ralo * rbhi;
205 uint64_t pp3 = rahi * rbhi;
206 uint64_t
c = ((uint32_t)pp1) + ((uint32_t)pp2) + (pp0 >> 32);
207 phi = pp3 + (pp2 >> 32) + (pp1 >> 32) + (
c >> 32);
208 plo = (
c << 32) | ((uint32_t)pp0);
210 return std::make_tuple(plo, phi);
214 inline std::tuple<uint64_t, int64_t>
218 #if defined(__SIZEOF_INT128__)
219 __int128_t prod = (__int128_t)
ra * rb;
223 std::tie(plo, phi) =
multiply((uint64_t)
ra, (uint64_t)rb);
224 if (rb < 0) phi -= (uint64_t)
ra;
225 if (
ra < 0) phi -= (uint64_t)rb;
227 return std::make_tuple(plo, (int64_t)phi);
234 inline std::tuple<uint64_t, uint64_t>
238 #if defined(__SIZEOF_INT128__)
239 __uint128_t res = ((__uint128_t)
ra * rb) +
rc;
245 std::tie(rlo, rhi) =
add(plo, phi,
rc);
247 return std::make_tuple(rlo, rhi);
254 inline std::tuple<uint64_t, int64_t>
259 #if defined(__SIZEOF_INT128__)
260 __int128_t res = (__int128_t)
ra * rb +
rc;
267 std::tie(rlo, rhi) =
add(plo, phi,
rc);
269 return std::make_tuple(rlo, rhi);
277 inline std::tuple<bool, uint64_t, uint64_t>
278 divide(uint64_t ralo, uint64_t rahi, uint64_t rb)
const
282 #if defined(__SIZEOF_INT128__)
286 __uint128_t
ra = ((__uint128_t)rahi << 64) | ralo;
287 __uint128_t res =
ra / rb;
290 ov = res > UINT64_MAX;
297 }
else if (rahi == 0) {
301 }
else if (rahi >= rb) {
304 for (
int i = 0;
i < 64; ++
i) {
306 rahi = (rahi << 1) | (ralo >> 63);
307 if (
c || (rahi >= rb)) {
313 ralo = (ralo << 1) |
c;
320 return std::make_tuple(
ov,
q,
r);
327 inline std::tuple<bool, int64_t, int64_t>
328 divide(uint64_t ralo, int64_t rahi, int64_t rb)
const
332 #if defined(__SIZEOF_INT128__)
336 __int128_t
ra = ((__int128_t)rahi << 64) | ralo;
337 __int128_t res =
ra / rb;
343 bool raneg = rahi < 0;
358 std::tie(
ov,
q,
r) =
divide(ralo, (uint64_t)rahi, (uint64_t)rb);
359 if (raneg ^ rbneg)
q = -
q;
361 if (!
ov)
ov = ((
q < 0) ^ (raneg ^ rbneg));
363 return std::make_tuple(
ov,
q,
r);
367 Addr pc,
const Loader::SymbolTable *symtab)
const override;
388 Addr pc,
const Loader::SymbolTable *symtab)
const override;
409 Addr pc,
const Loader::SymbolTable *symtab)
const override;
425 :
IntOp(mnem, _machInst, __opClass),
432 Addr pc,
const Loader::SymbolTable *symtab)
const override;
453 Addr pc,
const Loader::SymbolTable *symtab)
const override;
474 Addr pc,
const Loader::SymbolTable *symtab)
const override;
487 :
IntOp(mnem, _machInst, __opClass)
497 #if defined(__GNUC__) || (defined(__clang__) && \
498 __has_builtin(__builtin_clz))
499 return __builtin_clz(
rs);
514 #if defined(__GNUC__) || (defined(__clang__) && \
515 __has_builtin(__builtin_clzll))
516 return __builtin_clzll(
rs);
531 #if defined(__GNUC__) || (defined(__clang__) && \
532 __has_builtin(__builtin_ctz))
533 return __builtin_ctz(
rs);
548 #if defined(__GNUC__) || (defined(__clang__) && \
549 __has_builtin(__builtin_ctzll))
550 return __builtin_ctzll(
rs);
560 Addr pc,
const Loader::SymbolTable *symtab)
const override;
581 Addr pc,
const Loader::SymbolTable *symtab)
const override;
597 :
IntOp(mnem, _machInst, __opClass),
619 :
IntOp(mnem, _machInst, __opClass),
625 Addr pc,
const Loader::SymbolTable *symtab)
const override;
655 res = (res << 32) | res;
663 begin = begin & 0x1f;
666 return mask(31 - begin, 31 - end);
668 return ~
mask(31 - (end + 1), 31 - (begin - 1));
701 return (value <<
shift) | (value >> (64 -
shift));
707 begin = begin & 0x3f;
710 return mask(63 - begin, 63 - end);
712 return ~
mask(63 - (end + 1), 63 - (begin - 1));
717 Addr pc,
const Loader::SymbolTable *symtab)
const override;
731 :
IntOp(mnem, _machInst, __opClass),
739 if (((
to & 0x10) && (
a <
b)) ||
740 ((
to & 0x08) && (
a >
b)) ||
741 ((
to & 0x04) && (
a ==
b)) ||
742 ((
to & 0x02) && ((uint64_t)
a < (uint64_t)
b)) ||
743 ((
to & 0x01) && ((uint64_t)
a > (uint64_t)
b))) {
756 case 1: str =
"lgt";
break;
757 case 2: str =
"llt";
break;
758 case 4: str =
"eq";
break;
759 case 5: str =
"lge";
break;
760 case 6: str =
"lle";
break;
761 case 8: str =
"gt";
break;
762 case 12: str =
"ge";
break;
763 case 16: str =
"lt";
break;
764 case 20: str =
"le";
break;
765 case 24: str =
"ne";
break;
766 case 31: str =
"u";
break;
773 Addr pc,
const Loader::SymbolTable *symtab)
const override;
793 Addr pc,
const Loader::SymbolTable *symtab)
const override;
799 #endif //__ARCH_POWER_INSTS_INTEGER_HH__