7676 * Max 0x7f 0111 1111 127 1.984375
7777 * Min 0x80 1000 0000 -128 -2
7878 *
79+ * twin_xfixed_t - A fixed-point type in the Q31.32 format.
80+ *
81+ * Hex Binary
82+ * Max 0x7fffffff 0111 1111 1111 1111 1111 1111 1111 1111
83+ * Min 0x80000000 1000 0000 0000 0000 0000 0000 0000 0000
84+ * Decimal Actual
85+ * Max 9,223,372,036,854,775,807 1,073,741,823.9999999997
86+ * Min -9,223,372,036,854,775,808 -1,073,741,824
87+ *
7988 * All of the above tables are based on two's complement representation.
8089 */
8190typedef int16_t twin_sfixed_t ;
8291typedef int32_t twin_dfixed_t ;
8392typedef int8_t twin_gfixed_t ;
93+ typedef int64_t twin_xfixed_t ;
8494
8595#define twin_sfixed_floor (f ) ((f) & ~0xf)
8696#define twin_sfixed_trunc (f ) ((f) >> 4)
@@ -95,6 +105,9 @@ typedef int8_t twin_gfixed_t;
95105#define twin_sfixed_to_dfixed (s ) (((twin_dfixed_t) (s)) << 4)
96106#define twin_dfixed_to_sfixed (d ) ((twin_sfixed_t) ((d) >> 4))
97107
108+ #define twin_xfixed_to_fixed (x ) ((twin_fixed_t) ((x) >> 16))
109+ #define twin_fixed_to_xfixed (f ) (((twin_xfixed_t) (f)) << 16)
110+
98111/*
99112 * twin_sfixed_t a = b'10100;
100113 * twin_sfixed_t b = b'10000;
@@ -116,14 +129,19 @@ typedef int8_t twin_gfixed_t;
116129 */
117130
118131#define twin_sfixed_mul (a , b ) \
119- ((((twin_sfixed_t ) (a)) * ((twin_sfixed_t ) (b))) >> 4)
132+ (twin_sfixed_t) ((((int32_t ) (a)) * ((int32_t ) (b))) >> 4)
120133#define twin_sfixed_div (a , b ) \
121- ((((twin_sfixed_t ) (a)) << 4) / ((twin_sfixed_t ) (b)))
134+ (twin_sfixed_t) ((((int32_t ) (a)) << 4) / ((int32_t ) (b)))
122135
123136#define twin_dfixed_mul (a , b ) \
124- ((((twin_dfixed_t ) (a)) * ((twin_dfixed_t ) (b))) >> 8)
137+ (twin_dfixed_t) ((((int64_t ) (a)) * ((int64_t ) (b))) >> 8)
125138#define twin_dfixed_div (a , b ) \
126- ((((twin_dfixed_t) (a)) << 8) / ((twin_dfixed_t) (b)))
139+ (twin_dfixed_t)((((int64_t) (a)) << 8) / ((int64_t) (b)))
140+
141+ #define twin_xfixed_mul (a , b ) \
142+ (twin_xfixed_t)((((__int128_t) (a)) * ((__int128_t) (b))) >> 32)
143+ #define twin_xfixed_div (a , b ) \
144+ (twin_xfixed_t)((((__int128_t) (a)) << 32) / ((__int128_t) (b)))
127145
128146/*
129147 * 'double' is a no-no in any shipping code, but useful during
@@ -141,6 +159,7 @@ typedef int8_t twin_gfixed_t;
141159
142160#define TWIN_GFIXED_ONE (0x40)
143161
162+ #define TWIN_XFIXED_ONE (0x100000000)
144163/*
145164 * Compositing stuff
146165 */
@@ -375,7 +394,7 @@ twin_dfixed_t _twin_distance_to_line_squared(twin_spoint_t *p,
375394 * Fixed point helper functions
376395 */
377396twin_sfixed_t _twin_sfixed_sqrt (twin_sfixed_t as );
378-
397+ twin_xfixed_t _twin_xfixed_sqrt ( twin_xfixed_t a );
379398/*
380399 * Matrix stuff
381400 */
@@ -595,11 +614,22 @@ static inline int twin_clz(uint32_t v)
595614 return 31 - leading_zero ;
596615 return 32 ; /* undefined behavior */
597616}
617+ static inline int twin_clzll (uint64_t v )
618+ {
619+ uint32_t leading_zero = 0 ;
620+ if (_BitScanReverse64 (& leading_zero , v ))
621+ return 63 - leading_zero ;
622+ return 64 ; /* undefined behavior */
623+ }
598624#elif defined(__GNUC__ ) || defined(__clang__ )
599625static inline int twin_clz (uint32_t v )
600626{
601627 return __builtin_clz (v );
602628}
629+ static inline int twin_clzll (uint64_t v )
630+ {
631+ return __builtin_clzll (v );
632+ }
603633#else /* generic implementation */
604634static inline int twin_clz (uint32_t v )
605635{
@@ -617,6 +647,26 @@ static inline int twin_clz(uint32_t v)
617647
618648 return mul_debruijn [(uint32_t ) (v * 0x07C4ACDDU ) >> 27 ];
619649}
650+ static inline int twin_clzll (uint64_t v )
651+ {
652+ /* https://stackoverflow.com/questions/21888140/de-bruijn-algorithm-binary-digit-count-64bits-c-sharp
653+ */
654+ static const uint8_t mul_debruijn [] = {
655+ 0 , 1 , 2 , 53 , 3 , 7 , 54 , 27 , 4 , 38 , 41 , 8 , 34 , 55 , 48 , 28 ,
656+ 62 , 5 , 39 , 46 , 44 , 42 , 22 , 9 , 24 , 35 , 59 , 56 , 49 , 18 , 29 , 11 ,
657+ 63 , 52 , 6 , 26 , 37 , 40 , 33 , 47 , 61 , 45 , 43 , 21 , 23 , 58 , 17 , 10 ,
658+ 51 , 25 , 36 , 32 , 60 , 20 , 57 , 16 , 50 , 31 , 19 , 15 , 30 , 14 , 13 , 12 ,
659+ };
660+
661+ v |= v >> 1 ;
662+ v |= v >> 2 ;
663+ v |= v >> 4 ;
664+ v |= v >> 8 ;
665+ v |= v >> 16 ;
666+ v |= v >> 32 ;
667+
668+ return mul_debruijn [(uint64_t ) (v * 0x022fdd63cc95386dUL ) >> 58 ];
669+ }
620670#endif
621671
622672extern const uint8_t _twin_cursor_default [];
0 commit comments