{
stringstream ss;
bool printSecondSrc = true;
+ bool printThirdSrc = false;
// Generate the correct mnemonic
string myMnemonic(mnemonic);
!myMnemonic.compare("subfze") ||
!myMnemonic.compare("neg")){
printSecondSrc = false;
+ } else if (!myMnemonic.compare("maddhd") ||
+ !myMnemonic.compare("maddhdu") ||
+ !myMnemonic.compare("maddld")) {
+ printThirdSrc = true;
}
// Additional characters depending on isa bits being set
if (_numSrcRegs > 1 && printSecondSrc) {
ss << ", ";
printReg(ss, _srcRegIdx[1]);
+
+ // Print the third source register
+ if (_numSrcRegs > 2 && printThirdSrc) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[2]);
+ }
}
}
{
}
+ /* Compute 128-bit sum of 128-bit to 64-bit unsigned integer addition */
+ inline std::tuple<uint64_t, uint64_t>
+ add(uint64_t ralo, uint64_t rahi, uint64_t rb) const
+ {
+ uint64_t slo, shi;
+ #if defined(__SIZEOF_INT128__)
+ __uint128_t ra = ((__uint128_t)rahi << 64) | ralo;
+ __uint128_t sum = ra + rb;
+ slo = sum;
+ shi = sum >> 64;
+ #else
+ shi = rahi + ((ralo + rb) < ralo);
+ slo = ralo + rb;
+ #endif
+ return std::make_tuple(slo, shi);
+ }
+
+ /* Compute 128-bit sum of 128-bit to 64-bit signed integer addition */
+ inline std::tuple<uint64_t, int64_t>
+ add(uint64_t ralo, int64_t rahi, int64_t rb) const
+ {
+ uint64_t slo;
+ int64_t shi;
+ #if defined(__SIZEOF_INT128__)
+ __int128_t ra = ((__int128_t)rahi << 64) | ralo;
+ __int128_t sum = (__int128_t)ra + rb;
+ slo = sum;
+ shi = sum >> 64;
+ #else
+ if (rb < 0) {
+ shi = rahi - 1;
+ slo = ralo + rb;
+ if (slo < rb) {
+ shi++;
+ }
+ } else {
+ shi = rahi;
+ slo = ralo + rb;
+ if (slo < rb) {
+ shi++;
+ }
+ }
+ #endif
+ return std::make_tuple(slo, shi);
+ }
+
/* Compute 128-bit product of 64-bit unsigned integer multiplication */
inline std::tuple<uint64_t, uint64_t>
multiply(uint64_t ra, uint64_t rb) const
return std::make_tuple(plo, (int64_t)phi);
}
+ /* Compute 128-bit result of 64-bit unsigned integer multiplication
+ followed by addition */
+ inline std::tuple<uint64_t, uint64_t>
+ multiplyAdd(uint64_t ra, uint64_t rb, uint64_t rc) const
+ {
+ uint64_t rlo, rhi;
+ #if defined(__SIZEOF_INT128__)
+ __uint128_t res = ((__uint128_t)ra * rb) + rc;
+ rlo = res;
+ rhi = res >> 64;
+ #else
+ uint64_t plo, phi;
+ std::tie(plo, phi) = multiply(ra, rb);
+ std::tie(rlo, rhi) = add(plo, phi, rc);
+ #endif
+ return std::make_tuple(rlo, rhi);
+ }
+
+ /* Compute 128-bit result of 64-bit signed integer multiplication
+ followed by addition */
+ inline std::tuple<uint64_t, int64_t>
+ multiplyAdd(int64_t ra, int64_t rb, int64_t rc) const
+ {
+ uint64_t rlo;
+ int64_t rhi;
+ #if defined(__SIZEOF_INT128__)
+ __int128_t res = (__int128_t)ra * rb + rc;
+ rlo = res;
+ rhi = res >> 64;
+ #else
+ uint64_t plo;
+ int64_t phi;
+ std::tie(plo, phi) = multiply(ra, rb);
+ std::tie(rlo, rhi) = add(plo, phi, rc);
+ #endif
+ return std::make_tuple(rlo, rhi);
+ }
+
std::string generateDisassembly(
Addr pc, const SymbolTable *symtab) const override;
};
}});
}
+ 4: decode VA_XO {
+
+ // Arithmetic instructions that use source registers Ra, Rb and Rc,
+ // with destination register Rt.
+ format IntArithOp {
+ 48: maddhd({{
+ int64_t res;
+ std::tie(std::ignore, res) = multiplyAdd(Ra_sd, Rb_sd, Rc_sd);
+ Rt = res;
+ }});
+
+ 49: maddhdu({{
+ uint64_t res;
+ std::tie(std::ignore, res) = multiplyAdd(Ra, Rb, Rc);
+ Rt = res;
+ }});
+
+ 51: maddld({{
+ uint64_t res;
+ std::tie(res, std::ignore) = multiplyAdd(Ra_sd, Rb_sd, Rc_sd);
+ Rt = res;
+ }});
+ }
+ }
+
format IntImmOp {
10: cmpli({{
Xer xer = XER;