From 32199d744ecc2343a6b798baf60e877323efbdac Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Thu, 7 Jun 2018 15:09:04 +0530 Subject: [PATCH] arch-power: Add fixed-point logical count zeros instructions This adds the following logical instructions: * Count Trailing Zeros Word (cnttzw[.]) * Count Leading Zeros Doubleword (cntlzd[.]) * Count Trailing Zeros Doubleword (cnttzd[.]) Change-Id: I4bcf090178d9241f230509ba55e8e58f5e7794ac 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 b49da47e1..2f7e15909 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -295,7 +295,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 0cdd2b457..4129a3482 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -492,6 +492,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 { @@ -507,6 +509,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 SymbolTable *symtab) const override; }; diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index 6575f4f54..c605b697d 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -513,6 +513,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