From 260323d70d860252b86ed61b729e856505fde169 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:21:19 +0530 Subject: [PATCH] arch-power: Add zero count instructions This introduces new helpers for finding the count of leading and trailing zero bits in a given value and adds the following instructions. * Count Trailing Zeros Word (cnttzw[.]) * Count Leading Zeros Doubleword (cntlzd[.]) * Count Trailing Zeros Doubleword (cnttzd[.]) Change-Id: I69dad34bc2cffb2ac70ecd3dba7301fa1cdcb340 Signed-off-by: Sandipan Das --- src/arch/power/insts/integer.cc | 5 +++- src/arch/power/insts/integer.hh | 53 +++++++++++++++++++++++++++++++++ src/arch/power/isa/decoder.isa | 3 ++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index 408ca8e08..4c62f37ba 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -302,7 +302,10 @@ IntLogicOp::generateDisassembly( } else if (!myMnemonic.compare("extsb") || !myMnemonic.compare("extsh") || !myMnemonic.compare("extsw") || - !myMnemonic.compare("cntlzw")) { + !myMnemonic.compare("cntlzw") || + !myMnemonic.compare("cntlzd") || + !myMnemonic.compare("cnttzw") || + !myMnemonic.compare("cnttzd")) { printSecondSrc = false; } diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh index a3d99ff33..1e4ce368b 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -504,6 +504,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 { @@ -519,6 +521,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 681358234..dfad97874 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -499,6 +499,9 @@ decode PO default Unknown::unknown() { 922: extsh({{ Ra = Rs_sh; }}, true); 986: extsw({{ Ra = Rs_sw; }}, true); 26: cntlzw({{ Ra = findLeadingZeros(Rs_uw); }}, true); + 58: cntlzd({{ Ra = findLeadingZeros(Rs); }}, true); + 538: cnttzw({{ Ra = findTrailingZeros(Rs_uw); }}, true); + 570: cnttzd({{ Ra = findTrailingZeros(Rs); }}, true); 508: cmpb({{ uint64_t mask = 0xff; -- 2.30.2