From 99495afb209db57a8f1b3ce0abe60c3f8ff11270 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40920 Reviewed-by: Boris Shingarov Maintainer: Boris Shingarov Tested-by: kokoro --- src/arch/power/insts/integer.cc | 5 +++- src/arch/power/insts/integer.hh | 53 +++++++++++++++++++++++++++++++++ src/arch/power/isa/decoder.isa | 8 ++++- 3 files changed, 64 insertions(+), 2 deletions(-) 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; }});