From 0a7e5b59984be7e2370d8096bbcc808abfc0c7d6 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 f87afa282..6f190d331 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -293,7 +293,10 @@ IntLogicOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const } 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 6658760f5..afbdc4341 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -494,6 +494,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 { @@ -509,6 +511,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 6390017af..01ca336b8 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -515,6 +515,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