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);
425 :
IntOp(mnem, _machInst, __opClass),
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);
597 :
IntOp(mnem, _machInst, __opClass),
619 :
IntOp(mnem, _machInst, __opClass),
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));
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;
Class for integer arithmetic operations.
std::tuple< uint64_t, int64_t > multiplyAdd(int64_t ra, int64_t rb, int64_t rc) const
Compute 128-bit result of 64-bit signed integer multiplication followed by addition.
std::tuple< bool, uint64_t, uint64_t > divide(uint64_t ralo, uint64_t rahi, uint64_t rb) const
Compute overflow, 64-bit quotient and 64-bit remainder of 128-bit by 64-bit unsigned integer division...
IntArithOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
std::tuple< uint64_t, uint64_t > multiplyAdd(uint64_t ra, uint64_t rb, uint64_t rc) const
Compute 128-bit result of 64-bit unsigned integer multiplication followed by addition.
std::tuple< uint64_t, uint64_t > add(uint64_t ralo, uint64_t rahi, uint64_t rb) const
std::tuple< bool, int64_t, int64_t > divide(uint64_t ralo, int64_t rahi, int64_t rb) const
Compute overflow, 64-bit quotient and 64-bit remainder of 128-bit by 64-bit signed integer division.
std::tuple< uint64_t, int64_t > add(uint64_t ralo, int64_t rahi, int64_t rb) const
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
std::tuple< uint64_t, int64_t > multiply(int64_t ra, int64_t rb) const
std::tuple< uint64_t, uint64_t > multiply(uint64_t ra, uint64_t rb) const
Compute 128-bit product of 64-bit unsigned integer multiplication based on https://stackoverflow....
Class for integer compare operations.
IntCompOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Class for integer rotate operations with a shift amount obtained from a register or by concatenating ...
IntConcatRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
uint64_t bitmask(uint32_t begin, uint32_t end) const
uint64_t rotate(uint64_t value, uint32_t shift) const
Class for integer shift operations with a shift value obtained from a register or by concatenating im...
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
IntConcatShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
Class for integer arithmetic operations with displacement.
IntDispArithOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Class for integer immediate arithmetic operations.
IntImmArithOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Class for integer immediate compare logical operations.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
IntImmCompLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
Class for integer immediate compare operations.
IntImmCompOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Class for integer immediate logical operations.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
IntImmLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
Class for integer immediate (signed and unsigned) operations.
IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Class for integer immediate trap operations.
IntImmTrapOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Class for integer logical operations.
int findLeadingZeros(uint64_t rs) const
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
IntLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
int findTrailingZeros(uint64_t rs) const
int findLeadingZeros(uint32_t rs) const
int findTrailingZeros(uint32_t rs) const
We provide a base class for integer operations and then inherit for several other classes.
uint32_t makeCRFieldUnsigned(uint64_t a, uint64_t b, bool so) const
uint32_t makeCRFieldSigned(int64_t a, int64_t b, bool so) const
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
IntOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
Class for integer rotate operations with a shift amount obtained from a register or an immediate and ...
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
uint64_t bitmask(uint32_t begin, uint32_t end) const
uint64_t rotate(uint32_t value, uint32_t shift) const
IntRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
Class for integer operations with a shift value obtained from a register or an instruction field.
IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Class for integer trap operations.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
std::string suffix() const
bool checkTrap(int64_t a, int64_t b) const
IntTrapOp(const char *mnem, MachInst _machInst, OpClass __opClass)
Constructor.
constexpr int findMsbSet(uint64_t val)
Returns the bit position of the MSB that is set in the input.
constexpr uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input That function will either use a builtin ...
Bitfield< 19, 16 > divide
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.