From f48fa0c1d5b95d8df1b56d82166cd336eb69b52d Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 16 May 2017 13:37:08 +0000 Subject: [PATCH] Core: Bits::Get(pos, count), Get64 git-svn-id: svn://ultimatepp.org/upp/trunk@11096 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/Other.h | 7 ++++-- uppsrc/Core/Vcont.hpp | 37 +++++++++++++++++++++++++++--- uppsrc/Core/src.tpp/Bits$en-us.tpp | 15 +++++++++++- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/uppsrc/Core/Other.h b/uppsrc/Core/Other.h index 108f3f694..3387173b5 100644 --- a/uppsrc/Core/Other.h +++ b/uppsrc/Core/Other.h @@ -131,8 +131,12 @@ public: bool operator[](int i) const { return Get(i); } void Set(int i, dword bits, int count); + dword Get(int i, int count); void Set64(int i, uint64 bits, int count); - void SetN(int i, int count, bool b = true); + uint64 Get64(int i, int count); + + void SetN(int i, bool b, int count); + void SetN(int i, int count) { SetN(i, count); } void Reserve(int nbits); void Shrink(); @@ -150,7 +154,6 @@ public: Bits(Bits&& b) { alloc = b.alloc; bp = b.bp; b.bp = NULL; } void operator=(Bits&& b) { if(this != &b) { Clear(); alloc = b.alloc; bp = b.bp; b.bp = NULL; } } - }; //# System dependent diff --git a/uppsrc/Core/Vcont.hpp b/uppsrc/Core/Vcont.hpp index 1fe0ef673..28252ea4c 100644 --- a/uppsrc/Core/Vcont.hpp +++ b/uppsrc/Core/Vcont.hpp @@ -786,7 +786,7 @@ BiArray::BiArray(std::initializer_list init) inline void Bits::Set(int i, dword bits, int count) { - ASSERT(i >= 0 && alloc >= 0 && count >= 0 && count <= 32); + ASSERT(i >= 0 && count >= 0 && count <= 32); if(!count) // note: this also avoids problem with (dword)-1 >> 32 being undefined return; int q = i >> 5; @@ -808,6 +808,26 @@ void Bits::Set(int i, dword bits, int count) bp[q] = (bp[q] & ~(mask >> i)) | (bits >> i); } +inline +dword Bits::Get(int i, int count) +{ + ASSERT(i >= 0 && count >= 0 && count <= 32); + if(!count) // note: this also avoids problem with (dword)-1 >> 32 being undefined + return 0; + int q = i >> 5; + i &= 31; + if(q >= alloc) + return 0; + if(i == 0 && count == 32) + return bp[q]; + dword mask = (dword)-1 >> (32 - count); // does not work for count == 0 + dword ret = (bp[q] & (mask << i)) >> i; + if(i + count <= 32 || ++q >= alloc) + return ret; + i = 32 - i; + return ret | ((bp[q] & (mask >> i)) << i); +} + inline void Bits::Set64(int i, uint64 bits, int count) { @@ -820,9 +840,20 @@ void Bits::Set64(int i, uint64 bits, int count) } inline -void Bits::SetN(int i, int count, bool b) +uint64 Bits::Get64(int i, int count) { - ASSERT(i >= 0 && alloc >= 0); + if(count > 32) { + dword l = Get(i, 32); + return MAKEQWORD(l, Get(i + 32, count - 32)); + } + else + return Get(i, count); +} + +inline +void Bits::SetN(int i, bool b, int count) +{ + ASSERT(i >= 0); if(!count) // note: this also avoids problem with (dword)-1 >> 32 being undefined return; diff --git a/uppsrc/Core/src.tpp/Bits$en-us.tpp b/uppsrc/Core/src.tpp/Bits$en-us.tpp index f90382e5d..f5d2bf0da 100644 --- a/uppsrc/Core/src.tpp/Bits$en-us.tpp +++ b/uppsrc/Core/src.tpp/Bits$en-us.tpp @@ -35,11 +35,18 @@ onst]&] [s5;:Bits`:`:operator`[`]`(int`)const: [@(0.0.255) bool]_[* operator`[`]]([@(0.0.255) int]_ [*@3 i])_[@(0.0.255) const]&] [s2;%% Returns the value of bool [%-*@3 i].&] +[s3;%% &] [s4; &] [s5;:Upp`:`:Bits`:`:Set`(int`,Upp`:`:dword`,int`): [@(0.0.255) void]_[* Set]([@(0.0.255) in t]_[*@3 i], [_^Upp`:`:dword^ dword]_[*@3 bits], [@(0.0.255) int]_[*@3 count])&] [s2;%% Sets [%-*@3 count] [%-*@3 bits] ([%-*@3 bits ]LSB is first) starting -from [%-*@3 i].&] +at[%-*@3 i].&] +[s3;%% &] +[s4; &] +[s5;:Upp`:`:Bits`:`:Get`(int`,int`): [_^Upp`:`:dword^ dword]_[* Get]([@(0.0.255) int]_[*@3 i], + [@(0.0.255) int]_[*@3 count])&] +[s2;%% Returns a set of [%-*@3 count ]bits (at most 32) starting at +[%-*@3 i], as binary number. First bit is returned as LSB.&] [s3;%% &] [s4; &] [s5;:Upp`:`:Bits`:`:Set64`(int`,Upp`:`:uint64`,int`): [@(0.0.255) void]_[* Set64]([@(0.0.255) i @@ -48,6 +55,12 @@ nt]_[*@3 i], [_^Upp`:`:uint64^ uint64]_[*@3 bits], [@(0.0.255) int]_[*@3 count]) from [%-*@3 i].&] [s3;%% &] [s4; &] +[s5;:Upp`:`:Bits`:`:Get64`(int`,int`): [_^Upp`:`:uint64^ uint64]_[* Get64]([@(0.0.255) int]_ +[*@3 i], [@(0.0.255) int]_[*@3 count])&] +[s2;%% Returns a set of [%-*@3 count ]bits (at most 64) starting at +[%-*@3 i], as binary number. First bit is returned as LSB.&] +[s3;%% &] +[s4; &] [s5;:Upp`:`:Bits`:`:SetN`(int`,int`,bool`): [@(0.0.255) void]_[* SetN]([@(0.0.255) int]_[*@3 i ], [@(0.0.255) int]_[*@3 count], [@(0.0.255) bool]_[*@3 b]_`=_[@(0.0.255) true])&] [s2;%% Sets [%-*@3 count] bits, starting from [%-*@3 i], to [%-*@3 b].&]