44#include <stdint.h>
55#include <stdio.h>
66#include <stdlib.h>
7+ #include <string.h>
78
89#ifdef _MSC_VER
910# define const_inline force_inline
@@ -88,8 +89,8 @@ _Static_assert(sizeof(b25_loc) == sizeof(uint16_t), "b25_loc is 16 bits");
8889
8990struct b25_info {
9091 b25_div div ;
91- u10x3 loc [4 ];
92- uint32_t mask [12 ];
92+ u10x3 loc [3 ];
93+ uint32_t mask [9 ];
9394};
9495
9596static const_inline unsigned
@@ -134,6 +135,19 @@ u10x3_append (u10x3 *dst,
134135 }
135136}
136137
138+ static force_inline unsigned
139+ b25_div_get (b25_div const * div ,
140+ uint5 i )
141+ {
142+ return (unsigned )(div -> bits >> b25_div_offset (i ) & b25_div_mask (i ));
143+ }
144+
145+ static force_inline unsigned
146+ b25_info_get_num_cycles (struct b25_info const * const src )
147+ {
148+ return src -> div .total - b25_div_get (& src -> div , 0 );
149+ }
150+
137151static force_inline void
138152b25_info_add_cycle (struct b25_info * dst ,
139153 unsigned off ,
@@ -143,28 +157,24 @@ b25_info_add_cycle (struct b25_info *dst,
143157 if (off > 31U || !prd || prd > 32U )
144158 return ;
145159
146- const unsigned i = dst -> div . total ;
147- if (i >= 12U )
160+ const unsigned i = b25_info_get_num_cycles ( dst ) ;
161+ if (i >= 9U )
148162 return ;
149163
150164 uint5 n = (uint5 )(prd - 1U );
151- u10x3_append (& dst -> loc [i / 3U ], (uint5 )off , n );
152165 b25_div_add (& dst -> div , n );
153- dst -> mask [i ] = msk ;
166+ if (prd > 1U ) {
167+ u10x3_append (& dst -> loc [i / 3U ], (uint5 )off , n );
168+ dst -> mask [i ] = msk ;
169+ }
154170 assert (dst -> div .unique < 8U );
155171}
156172
157- static force_inline unsigned
158- b25_info_get_num_cycles (struct b25_info const * const src )
159- {
160- return src -> div .total ;
161- }
162-
163173static force_inline b25_loc
164174b25_info_get_cycle (struct b25_info const * src ,
165175 unsigned i )
166176{
167- if (i < src -> div . total ) {
177+ if (i < b25_info_get_num_cycles ( src ) ) {
168178 const unsigned n = i % 3U ;
169179 u10x3 x = src -> loc [i / 3U ];
170180 if (n < x .count ) {
@@ -178,13 +188,6 @@ b25_info_get_cycle (struct b25_info const *src,
178188 return (b25_loc ){0 };
179189}
180190
181- static force_inline unsigned
182- b25_div_get (b25_div const * div ,
183- uint5 i )
184- {
185- return (unsigned )(div -> bits >> b25_div_offset (i ) & b25_div_mask (i ));
186- }
187-
188191static force_inline unsigned
189192b25_info_get_num_period_cycles (struct b25_info const * const src ,
190193 unsigned const prd )
@@ -462,7 +465,7 @@ b25_info_print (struct b25_info const *const b25,
462465 printf ("{0x%08" PRIx32 ", 0x%016" PRIx64 ", {%"
463466 PRIu16 ",%" PRIu16 ",%" PRIu16 "}, {%u" ,
464467 seq , b25 -> div .bits , id , idx , rot , num );
465- for (unsigned n = 0 ; ++ n < 33U ; ) {
468+ for (unsigned n = 1 ; ++ n < 33U ; ) {
466469 unsigned c = b25_info_get_num_period_cycles (b25 , n );
467470 if (c )
468471 printf (",[%u]=%u" , n , c );
@@ -479,18 +482,6 @@ b25_info_print (struct b25_info const *const b25,
479482 puts ("}}," );
480483}
481484
482- static int
483- alt_main (int c ,
484- char * * v )
485- {
486- for (int i = 0 ; ++ i < c ;) {
487- uint16_t id = (uint16_t )strtoul (v [i ], NULL , 0 );
488- struct b25_info b25 = b25_info (id );
489- b25_info_print (& b25 , id );
490- }
491- return 0 ;
492- }
493-
494485static const struct perm four8 [1 ] = {
495486 { 6 ,1439 },
496487};
@@ -757,3 +748,93 @@ static const struct perm one32[1936] = {
757748 { 7 ,2031 }, { 6 ,2032 }, { 4 ,2034 }, { 6 ,2037 }, {14 ,2037 }, {28 ,2037 }, {19 ,2040 }, {14 ,2041 },
758749 { 6 ,2042 }, {30 ,2042 }, { 4 ,2043 }, {13 ,2044 }, {19 ,2044 }, { 1 ,2045 }, {19 ,2045 }, { 5 ,2047 },
759750};
751+
752+ struct bag {
753+ uint32_t seq ;
754+ uint8_t head [2 ];
755+ uint8_t iter [2 ];
756+ char * ptr [32 ];
757+ };
758+
759+ static const uint64_t BAG_DBSEQ [56 ] = {
760+ 0xb1aeca7cc653ed7d , 0xab1be9cacc6e53ea , 0x66f2b3e8dfca39be , 0xf46a31f2bb34bea3 ,
761+ 0xdf2a232f8ed10cad , 0x8f95df35ca3eacd1 , 0xe57da3e3728faa8d , 0x4fb946bc3be5a8b4 ,
762+ 0x4538df5884d6477a , 0x18d64dd1fc4ec6be , 0x48b968fb9365937d , 0x1da4971f64cb5be7 ,
763+ 0x33ea2593a8df45f3 , 0xd4d8e09b98fa896e , 0x89daf97df6a723e7 , 0xd94eb7c524e2df4e ,
764+ 0x459d6f890e5769f0 , 0x2a6a7dc567a7dae2 , 0x2fa1a89767b69f72 , 0xfae5ea8bec99ea27 ,
765+ 0xebe25cb2717d3ac4 , 0xeb14f9db8967d0ac , 0x326c5f5fbeb13936 , 0x134c8adf4cd897d5 ,
766+ 0xd376be5307d8be6a , 0x13077c9a2addf12c , 0x9371fc4d9752df2b , 0xadcc43c9bac5df15 ,
767+ 0x62e6a27d4d9713f4 , 0xf6695c7fd8b9a93f , 0xe1a9d97c7dc4b35c , 0x7e1beb299c6beca7 ,
768+ 0x1a137594798ca3ed , 0xe9e43ee568b4f95d , 0x691e85cfb48ad646 , 0x6393485f3b48a176 ,
769+ 0x7c4bb4589f2bb35f , 0xec8a7d73a89767c6 , 0x12e2b27c8b2e27d4 , 0xc17c9a8ba1cd8afa ,
770+ 0x2d77dc98adef5365 , 0xa35f4c72b7dff731 , 0xb517bd235d9fd3ec , 0xc4ef9525a89dea93 ,
771+ 0xb93ea2a2ca75f04a , 0x7be589d72ea27cab , 0x90d48b7c934d95f0 , 0x2b3f289bacfc574d ,
772+ 0xea7df5365c2fd137 , 0xcaedf1ba567f465b , 0x2b37df32dc7d70c7 , 0xeb28dedd322b7e31 ,
773+ 0x2a277cb764d47df8 , 0x074cadf1ec4cb7d4 , 0x6d4df2c756f6b931 , 0x0001c9f51b52ea3e ,
774+ };
775+
776+ static const_inline uint32_t
777+ bag_seq (unsigned i )
778+ {
779+ if (i > 118U )
780+ return 0U ;
781+
782+ unsigned y = (i *= 30U ) >> 6U , x = i & 63U ;
783+ uint32_t s = (uint32_t )(BAG_DBSEQ [y ] >> x );
784+
785+ if (x > 34U )
786+ s |= (uint32_t )(BAG_DBSEQ [y + 1U ] << (64U - x ));
787+
788+ return ror32 ((s >> 4U & 0x3fffffeU ) | 0x4000001U , s & 0x1fU );
789+ }
790+
791+ static const_inline struct bag
792+ bag (unsigned i )
793+ {
794+ if (i > 118U )
795+ return (struct bag ){0 };
796+ uint32_t seq = bag_seq (i );
797+ uint8_t h2 = i < 65U ? 1U
798+ : (i < 104U ? (2U + (i >= 88U ))
799+ : (i < 116U ? (4U + (i >= 110U ))
800+ : (6U + (i >= 117U ))));
801+ return (struct bag ){
802+ .seq = seq ,
803+ .head = {0 , h2 },
804+ .iter = {0 , h2 },
805+ };
806+ }
807+
808+ static int
809+ alt_main (int c ,
810+ char * * v )
811+ {
812+ for (int i = 0 ; ++ i < c ;) {
813+ uint16_t id = (uint16_t )strtoul (v [i ], NULL , 0 );
814+ struct b25_info b25 = b25_info (id );
815+ b25_info_print (& b25 , id );
816+ }
817+
818+ if (c > 1 )
819+ return 0 ;
820+
821+ struct b25_info info [array_size (two16 )] = {0 };
822+ for (size_t i = 0 ; i < array_size (two16 ); ++ i )
823+ info [i ] = b25_info (two16 [i ].seq << 5U | two16 [i ].rot );
824+ for (size_t i = 0 ; i < array_size (two16 ); ++ i )
825+ b25_info_print (& info [i ], two16 [i ].seq << 5U | two16 [i ].rot );
826+
827+ char const * const ptr [] = {
828+ "\n" ," " , "!" , "," , "." , "?" , "a" , "b" ,
829+ "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" ,
830+ "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" ,
831+ "s" , "t" , "u" , "v" , "w" , "x" , "y" , "z" ,
832+ };
833+
834+ for (unsigned i = 0 ; i < array_size (two16 ); ++ i ) {
835+ struct bag b = bag (i );
836+ memcpy (& b .ptr [0 ], ptr , sizeof (ptr ));
837+ }
838+
839+ return 0 ;
840+ }
0 commit comments