diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index d7c8ed4f1b..12ce7eeada 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -287,7 +287,10 @@ IntLogicOp::generateDisassembly( } else if (myMnemonic == "extsb" || myMnemonic == "extsh" || myMnemonic == "extsw" || - myMnemonic == "cntlzw") { + myMnemonic == "cntlzw" || + myMnemonic == "cntlzd" || + myMnemonic == "cnttzw" || + myMnemonic == "cnttzd") { printSecondSrc = false; } diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh index 53e8a4a597..481b11b27e 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -484,6 +484,8 @@ class IntLogicOp : public IntOp { } + /* Compute the number of consecutive zero bits starting from the + leftmost bit and moving right in a 32-bit integer */ inline int findLeadingZeros(uint32_t rs) const { @@ -499,6 +501,57 @@ class IntLogicOp : public IntOp } } + /* Compute the number of consecutive zero bits starting from the + leftmost bit and moving right in a 64-bit integer */ + inline int + findLeadingZeros(uint64_t rs) const + { + if (rs) { + #if defined(__GNUC__) || (defined(__clang__) && \ + __has_builtin(__builtin_clzll)) + return __builtin_clzll(rs); + #else + return 63 - findMsbSet(rs); + #endif + } else { + return 64; + } + } + + /* Compute the number of consecutive zero bits starting from the + rightmost bit and moving left in a 32-bit integer */ + inline int + findTrailingZeros(uint32_t rs) const + { + if (rs) { + #if defined(__GNUC__) || (defined(__clang__) && \ + __has_builtin(__builtin_ctz)) + return __builtin_ctz(rs); + #else + return findLsbSet(rs); + #endif + } else { + return 32; + } + } + + /* Compute the number of consecutive zero bits starting from the + rightmost bit and moving left in a 64-bit integer */ + inline int + findTrailingZeros(uint64_t rs) const + { + if (rs) { + #if defined(__GNUC__) || (defined(__clang__) && \ + __has_builtin(__builtin_ctzll)) + return __builtin_ctzll(rs); + #else + return findLsbSet(rs); + #endif + } else { + return 64; + } + } + std::string generateDisassembly( Addr pc, const Loader::SymbolTable *symtab) const override; }; diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index 0ec249e78e..15ad7ad919 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -267,7 +267,11 @@ decode PO default Unknown::unknown() { 53: LoadIndexUpdateOp::ldux({{ Rt = Mem; }}); 55: LoadIndexUpdateOp::lwzux({{ Rt = Mem_uw; }}); - 60: IntLogicOp::andc({{ Ra = Rs & ~Rb; }}, true); + + format IntLogicOp { + 58: cntlzd({{ Ra = findLeadingZeros(Rs); }}, true); + 60: andc({{ Ra = Rs & ~Rb; }}, true); + } format LoadIndexOp { 84: ldarx({{ @@ -434,7 +438,9 @@ decode PO default Unknown::unknown() { } }}); + 538: IntLogicOp::cnttzw({{ Ra = findTrailingZeros(Rs_uw); }}, true); 567: LoadIndexUpdateOp::lfsux({{ Ft_sf = Mem_sf; }}); + 570: IntLogicOp::cnttzd({{ Ra = findTrailingZeros(Rs); }}, true); 598: MiscOp::sync({{ }}, [ IsReadBarrier, IsWriteBarrier ]); 599: LoadIndexOp::lfdx({{ Ft = Mem_df; }}); 631: LoadIndexUpdateOp::lfdux({{ Ft = Mem_df; }});