picox  0.1
xutils.h
[詳解]
1 
14 /*
15  * License: MIT license
16  * Copyright (c) <2015> <MaskedW [maskedw00@gmail.com]>
17  *
18  * Permission is hereby granted, free of charge, to any person
19  * obtaining a copy of this software and associated documentation
20  * files (the "Software"), to deal in the Software without
21  * restriction, including without limitation the rights to use, copy,
22  * modify, merge, publish, distribute, sublicense, and/or sell copies
23  * of the Software, and to permit persons to whom the Software is
24  * furnished to do so, subject to the following conditions:
25  *
26  * The above copyright notice and this permission notice shall be
27  * included in all copies or substantial portions of the Software.
28  *
29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
33  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
34  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
35  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36  * SOFTWARE.
37  */
38 
39 #ifndef picox_core_xutils_h_
40 #define picox_core_xutils_h_
41 
42 
58 #ifdef __cplusplus
59 extern "C" {
60 #endif
61 
62 
63 #if (X_CONF_BYTE_ORDER != X_BYTE_ORDER_LITTLE) && \
64  (X_CONF_BYTE_ORDER != X_BYTE_ORDER_BIG) && \
65  (X_CONF_BYTE_ORDER != X_BYTE_ORDER_UNKNOWN)
66  #error Invalid byte order
67 #endif
68 
69 
70 #define X_BYTE_ORDER X_CONF_BYTE_ORDER
71 
72 
75 #define X_BIT(x) (1UL << (x))
76 
77 
80 #define X_BIT64(x) (1ULL << (x))
81 
82 
85 #define X_BIT_MASK(n) ((1UL << (n)) - 1)
86 
87 
90 #define X_SWAP(x, y, T) do { T tmp = x; x = y; y = tmp; } while (0)
91 
92 
95 #define X_MIN(a,b) (((a)<(b))?(a):(b))
96 
97 
100 #define X_MAX(a,b) (((a)>(b))?(a):(b))
101 
102 
111 #define X_CONSTRAIN(x, a, b) (((x) < (a)) ? (a) : ((b) < (x)) ? (b) : (x))
112 
113 
116 #define X_BREAK_IF(cond) if(cond) break
117 
118 
121 #define X_CONTINUE_IF(cond) if(cond) continue
122 
123 
126 #define X_EXPR_IF(cond, expr) if(cond) expr
127 
128 
131 #define X_GOTO_IF(cond, label) if(cond) goto label
132 
133 
136 #define X_ASSIGN_IF(cond, x, v) if(cond) x = (v)
137 
138 
141 #define X_ASSIGN_AND_GOTO_IF(cond, x, v, label) if(cond) { (x) = (v); goto label; }
142 
143 
146 #define X_ASSIGN_NOT_NULL(x, v) if (x) *(x) = (v)
147 
148 
151 #define X_RETURN_IF(cond) if(cond) return
152 
153 
156 #define X_RETURN_VALUE_IF(cond, x) if(cond) return x
157 
158 
161 #define X_UNUSED(x) (void)(x)
162 
163 
166 #define X_FOREVER() for (;;)
167 
168 
171 #define X_DIV_ROUNDUP(dividend, divisor) (((dividend) + (divisor) - 1) / (divisor))
172 
173 
176 #define X_ROUNDUP_MULTIPLE(x, m) (((m) == 0) ? (x) : (((uint32_t)(x) + (m) - 1) / (m)) * (m))
177 
178 
181 static inline uint32_t x_roundup_multiple(uint32_t x, uint32_t m)
182 {
183  return X_ROUNDUP_MULTIPLE(x, m);
184 }
185 
186 
189 #define X_ROUNDUP_MULTIPLE_PTR(x, m) (((m) == 0) ? (void*)(x) : (void*)((((uintptr_t)(x) + (m) - 1) / (m)) * (m)))
190 
191 
194 static inline void* x_roundup_multiple_ptr(const void* x, uint32_t m)
195 {
196  return (void*)X_ROUNDUP_MULTIPLE_PTR(x, m);
197 }
198 
199 
202 #define X_ROUNDDOWN_MULTIPLE(x, m) (((m) == 0) ? (x) : ((uint32_t)(x) - ((x) % (m))))
203 
204 
207 static inline uint32_t x_rounddown_multiple(uint32_t x, uint32_t m)
208 {
209  return X_ROUNDDOWN_MULTIPLE(x, m);
210 }
211 
212 
215 #define X_ROUNDDOWN_MULTIPLE_PTR(x, m) (((m) == 0) ? (void*)(x) : (void*)((uintptr_t)(x) - (((uintptr_t)(x)) % (m))))
216 
217 
220 static inline void* x_rounddown_multiple_ptr(const void* x, uintptr_t m)
221 {
222  return (void*)X_ROUNDDOWN_MULTIPLE_PTR(x, m);
223 }
224 
225 
227 #define X_ROUNDUP_POWER_OF_TWO_5(x) (((x) | (x) >> 16) + 1)
228 #define X_ROUNDUP_POWER_OF_TWO_4(x) X_ROUNDUP_POWER_OF_TWO_5((x) | ((x) >> 8))
229 #define X_ROUNDUP_POWER_OF_TWO_3(x) X_ROUNDUP_POWER_OF_TWO_4((x) | ((x) >> 4))
230 #define X_ROUNDUP_POWER_OF_TWO_2(x) X_ROUNDUP_POWER_OF_TWO_3((x) | ((x) >> 2))
231 #define X_ROUNDUP_POWER_OF_TWO_1(x) X_ROUNDUP_POWER_OF_TWO_2((x) | ((x) >> 1))
232 
234 
237 #define X_ROUNDUP_POWER_OF_TWO(x) X_ROUNDUP_POWER_OF_TWO_1((uint32_t)(x) - 1)
238 
239 
242 static inline uint32_t x_roundup_power_of_two(uint32_t x)
243 {
244  return X_ROUNDUP_POWER_OF_TWO(x);
245 }
246 
247 
250 #define X_ROUNDUP_POWER_OF_TWO_PTR(x) ((void*)X_ROUNDUP_POWER_OF_TWO_1((uintptr_t)(x) - 1))
251 
252 
255 static inline void* x_roundup_power_of_two_ptr(const void* x)
256 {
257  return (void*)X_ROUNDUP_POWER_OF_TWO_PTR(x);
258 }
259 
260 
262 #define X_ROUNDDOWN_POWER_OF_TWO_5(x) ((x) - ((x) >> 1))
263 #define X_ROUNDDOWN_POWER_OF_TWO_4(x) X_ROUNDDOWN_POWER_OF_TWO_5((x) | ((x) >> 16))
264 #define X_ROUNDDOWN_POWER_OF_TWO_3(x) X_ROUNDDOWN_POWER_OF_TWO_4((x) | ((x) >> 8))
265 #define X_ROUNDDOWN_POWER_OF_TWO_2(x) X_ROUNDDOWN_POWER_OF_TWO_3((x) | ((x) >> 4))
266 #define X_ROUNDDOWN_POWER_OF_TWO_1(x) X_ROUNDDOWN_POWER_OF_TWO_2((x) | ((x) >> 2))
267 
269 
272 #define X_ROUNDDOWN_POWER_OF_TWO(x) X_ROUNDDOWN_POWER_OF_TWO_1(((uint32_t)(x)) | (((uint32_t)(x)) >> 1))
273 
274 
277 static inline uint32_t x_rounddown_power_of_two(uint32_t x)
278 {
279  return X_ROUNDDOWN_POWER_OF_TWO(x);
280 }
281 
282 
285 #define X_ROUNDDOWN_POWER_OF_TWO_PTR(x) ((void*)X_ROUNDDOWN_POWER_OF_TWO_1(((uintptr_t)(x)) | (((uintptr_t)(x)) >> 1)))
286 
287 
290 static inline void* x_rounddown_power_of_two_ptr(const void* x)
291 {
293 }
294 
295 
298 #define X_IS_MULTIPLE(x, m) (X_ROUNDUP_MULTIPLE(x, m) == (x))
299 
300 
303 static inline bool x_is_multiple(uint32_t x, uint32_t m)
304 {
305  return X_IS_MULTIPLE(x, m);
306 }
307 
308 
311 #define X_IS_MULTIPLE_PTR(x, m) (X_ROUNDUP_MULTIPLE_PTR(x, m) == (x))
312 
313 
316 static inline bool x_is_multiple_ptr(const void* x, uint32_t m)
317 {
318  return X_IS_MULTIPLE_PTR(x, m);
319 }
320 
321 
324 #define X_IS_POWER_OF_TWO(x) (((x) & -(x)) == (x))
325 
326 
329 static inline bool x_is_power_of_two(uint32_t x)
330 {
331  return X_IS_POWER_OF_TWO(x);
332 }
333 
334 
337 #define X_IS_POWER_OF_TWO_PTR(x) ((((intptr_t)(x)) & -((intptr_t)(x))) == ((intptr_t)(x)))
338 
339 
342 static inline bool x_is_power_of_two_ptr(const void* x)
343 {
344  return X_IS_POWER_OF_TWO_PTR(x);
345 }
346 
347 
352 #define X_ROUNDUP_ALIGNMENT(x, a) ((((uint32_t)(x)) + (a) - 1) & ((uint32_t)0 - (a)))
353 
354 
357 static inline uint32_t x_roundup_alignment(uint32_t x, uint32_t a)
358 {
359  X_ASSERT(X_IS_POWER_OF_TWO(a));
360  return X_ROUNDUP_ALIGNMENT(x, a);
361 }
362 
363 
366 #define X_ROUNDUP_ALIGNMENT_PTR(x, a) ((void*)((((uintptr_t)(x)) + (a) - 1) & ((uintptr_t)0 - (a))))
367 
368 
371 static inline void* x_roundup_alignment_ptr(const void* x, size_t a)
372 {
373  X_ASSERT(X_IS_POWER_OF_TWO(a));
374  return X_ROUNDUP_ALIGNMENT_PTR(x, a);
375 }
376 
377 
382 #define X_ROUNDDOWN_ALIGNMENT(x, a) (X_ROUNDUP_ALIGNMENT((x) - (a) + 1, a))
383 
384 
387 static inline uint32_t x_rounddown_alignment(uint32_t x, uint32_t a)
388 {
389  X_ASSERT(X_IS_POWER_OF_TWO(a));
390  return X_ROUNDDOWN_ALIGNMENT(x, a);
391 }
392 
393 
396 #define X_ROUNDDOWN_ALIGNMENT_PTR(x, a) (X_ROUNDUP_ALIGNMENT_PTR(((uintptr_t)(x)) - (a) + 1, a))
397 
398 
401 static inline void* x_rounddown_alignment_ptr(const void* x, uint32_t a)
402 {
403  X_ASSERT(X_IS_POWER_OF_TWO(a));
404  return X_ROUNDDOWN_ALIGNMENT_PTR(x, a);
405 }
406 
407 
410 #define X_IS_ALIGNMENT(x) (((uint32_t)(x) > 0) && (((uint32_t)(x) & ((uint32_t)(x) - 1)) == 0))
411 
412 
415 static inline bool x_is_alignment(uint32_t x)
416 {
417  return X_IS_ALIGNMENT(x);
418 }
419 
420 
423 #define X_IS_ALIGNED(x, a) (X_ROUNDUP_ALIGNMENT_PTR((x), (a)) == (x))
424 
425 
428 static inline bool x_is_aligned(const void* ptr, size_t alignment)
429 {
430  X_ASSERT(X_IS_POWER_OF_TWO(alignment));
431 
432  const bool ok = (X_ROUNDUP_ALIGNMENT_PTR(ptr, alignment) == ptr);
433  return ok;
434 }
435 
436 
439 #define X_HIGH_WORD(x) ((uint16_t)((x) >> 16))
440 
441 
444 #define X_LOW_WORD(x) ((uint16_t)(x))
445 
446 
449 #define X_HIGH_BYTE(x) ((uint8_t)((x) >> 8))
450 
451 
454 #define X_LOW_BYTE(x) ((uint8_t)(x))
455 
456 
459 #define X_HIGH_NIBBLE(x) (((uint8_t)(x)) >> 4)
460 
461 
464 #define X_LOW_NIBBLE(x) (((uint8_t)(x)) & 0x0f)
465 
466 
469 #define X_REVERSE_BITS8(x) (((x) >> 7) & 0x01) | (((x) >> 5) & 0x02) | \
470  (((x) >> 3) & 0x04) | (((x) >> 1) & 0x08) | \
471  (((x) << 7) & 0x80) | (((x) << 5) & 0x40) | \
472  (((x) << 3) & 0x20) | (((x) << 1) & 0x10)
473 
474 
476 #define X_DECLARE_BIT_REVERSE_TABLE \
477  const uint8_t bit_reverse_table[16] = \
478  { \
479  0, /* 0000 -> 0000 */ \
480  8, /* 0001 -> 1000 */ \
481  4, /* 0010 -> 0100 */ \
482  12, /* 0011 -> 1100 */ \
483  2, /* 0100 -> 0010 */ \
484  10, /* 0101 -> 1010 */ \
485  6, /* 0110 -> 0110 */ \
486  14, /* 0111 -> 1110 */ \
487  1, /* 1000 -> 0001 */ \
488  9, /* 1001 -> 1001 */ \
489  5, /* 1010 -> 0101 */ \
490  13, /* 1011 -> 1101 */ \
491  3, /* 1100 -> 0011 */ \
492  11, /* 1101 -> 1011 */ \
493  7, /* 1110 -> 0111 */ \
494  15, /* 1111 -> 1111 */ \
495  }
496 
498 
501 static inline uint8_t x_reverse_bits8(uint8_t x)
502 {
503 #if 0
504  x = (x & 0xF0) >> 4 | (x & 0x0F) << 4;
505  x = (x & 0xCC) >> 2 | (x & 0x33) << 2;
506  x = (x & 0xAA) >> 1 | (x & 0x55) << 1;
507  return x;
508 #endif
509  X_DECLARE_BIT_REVERSE_TABLE;
510  const uint8_t a = bit_reverse_table[(x >> 4)];
511  const uint8_t b = bit_reverse_table[(x & 0xf)] << 4;
512  return a | b;
513 }
514 
517 #define X_REVERSE_BITS16(x) (((uint16_t)(X_REVERSE_BITS8(X_HIGH_BYTE(x)))) | \
518  (((uint16_t) X_REVERSE_BITS8(X_LOW_BYTE(x))) << 8))
519 
520 
523 static inline uint16_t x_reverse_bits16(uint16_t x)
524 {
525 #if 0
526  x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1);
527  x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2);
528  x = ((x >> 4) & 0x0F0F) | ((x & 0x0F0F) << 4);
529  x = ((x >> 8) & 0x00FF) | ((x & 0x00FF) << 8);
530  return x;
531 #endif
532  const uint16_t a = x_reverse_bits8(x >> 8);
533  const uint16_t b = x_reverse_bits8(x) << 8;
534  return a | b;
535 }
536 
537 
540 #define X_REVERSE_BITS32(x) (((uint32_t)(X_REVERSE_BITS16(X_HIGH_WORD(x)))) | \
541  (((uint32_t)(X_REVERSE_BITS16(X_LOW_WORD(x)))) << 16))
542 
543 
546 static inline uint32_t x_reverse_bits32(register uint32_t x)
547 {
548 #if 0
549  x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
550  x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
551  x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
552  x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
553  return ((x >> 16) | (x << 16));
554 #endif
555  const uint32_t a = x_reverse_bits16(x >> 16);
556  const uint32_t b = ((uint32_t)x_reverse_bits16(x)) << 16;
557  return a | b;
558 }
559 
560 
563 #define X_REVERSE_ENDIAN16(x) ((((uint16_t)(x)) << 8) | (((uint16_t)(x) >> 8) & 0x00ff))
564 
565 
568 static inline uint16_t x_reverse_endian16(register uint16_t x)
569 {
570  return X_REVERSE_ENDIAN16(x);
571 }
572 
573 
576 #define X_REVERSE_ENDIAN32(x) (((((uint32_t)(x)) << 24) | \
577  (((x) << 8) & 0x00ff0000) | \
578  (((x) >> 8) & 0x0000ff00) | \
579  (((x) >> 24) & 0x000000ff)))
580 
581 
584 static inline uint32_t x_reverse_endian32(uint32_t x)
585 {
586  return X_REVERSE_ENDIAN32(x);
587 }
588 
589 
592 #define X_ODD_BITS8(x) (((uint8_t)(x)) & 0x55)
593 
594 
597 #define X_ODD_BITS16(x) (((uint16_t)(x)) & 0x5555)
598 
599 
602 #define X_ODD_BITS32(x) (((uint32_t)(x)) & 0x55555555)
603 
604 
607 #define X_EVEN_BITS8(x) (((uint8_t)(x)) & 0xaa)
608 
609 
612 #define X_EVEN_BITS16(x) (((uint16_t)(x)) & 0xaaaa)
613 
614 
617 #define X_EVEN_BITS32(x) (((uint32_t)(x)) & 0xaaaaaaaa)
618 
619 
622 #define X_SWAP_ADJACENT_BITS8(x) ((X_ODD_BITS8(x) << 1) | ((X_EVEN_BITS8(x)) >> 1))
623 
624 
627 #define X_SWAP_ADJACENT_BITS16(x) ((X_ODD_BITS16(x) << 1) | ((X_EVEN_BITS16(x)) >> 1))
628 
629 
632 #define X_SWAP_ADJACENT_BITS32(x) ((X_ODD_BITS32(x) << 1) | ((X_EVEN_BITS32(x)) >> 1))
633 
634 
637 #define X_LOAD_U8(ptr) (*(uint8_t*)(ptr))
638 
639 
642 #define X_LOAD_U16_LIT(ptr) ((uint16_t)(((uint16_t)*((uint8_t*)(ptr)+1)<<8)|(uint16_t)*(uint8_t*)(ptr)))
643 
644 
647 #define X_LOAD_U32_LIT(ptr) \
648  ((uint32_t)((((uint32_t)*((uint8_t*)(ptr) + 3)) << 24) | \
649  (((uint32_t)*((uint8_t*)(ptr) + 2)) << 16) | \
650  (((uint16_t)*((uint8_t*)(ptr) + 1)) << 8) | \
651  *(uint8_t*)(ptr)))
652 
653 
656 #define X_LOAD_U16_BIG(ptr) (uint16_t)(((uint16_t)(*((uint8_t*)(ptr)))<<8)|(uint16_t)*((uint8_t*)(ptr) + 1))
657 
658 
661 #define X_LOAD_U32_BIG(ptr) \
662  ((uint32_t)((((uint32_t)*(((uint8_t*)(ptr)) + 0)) << 24) | \
663  (((uint32_t)*(((uint8_t*)(ptr)) + 1)) << 16) | \
664  (((uint16_t)*(((uint8_t*)(ptr)) + 2)) << 8) | \
665  *(((uint8_t*)(ptr)) + 3)))
666 
667 
670 #define X_STORE_U8(ptr, val) (*(uint8_t*)(ptr)=(uint8_t)(val))
671 
672 
675 #define X_STORE_U16_LIT(ptr, val) \
676  (*(uint8_t*)(ptr)=(uint8_t)(val), \
677  *((uint8_t*)(ptr)+1)=(uint8_t)((uint16_t)(val)>>8)) \
678 
679 
682 #define X_STORE_U32_LIT(ptr, val) \
683  (*(uint8_t*)(ptr)=(uint8_t)(val), \
684  *((uint8_t*)(ptr)+1)=(uint8_t)((uint16_t)(val)>>8), \
685  *((uint8_t*)(ptr)+2)=(uint8_t)((uint32_t)(val)>>16), \
686  *((uint8_t*)(ptr)+3)=(uint8_t)((uint32_t)(val)>>24))
687 
688 
691 #define X_STORE_U16_BIG(ptr, val) \
692  (*((uint8_t*)(ptr)+1)=(uint8_t)(val), \
693  *((uint8_t*)(ptr))=(uint8_t)((uint16_t)(val)>>8)) \
694 
695 
698 #define X_STORE_U32_BIG(ptr, val) \
699  (*((uint8_t*)(ptr)+3)=(uint8_t)(val), \
700  *((uint8_t*)(ptr)+2)=(uint8_t)((uint16_t)(val)>>8), \
701  *((uint8_t*)(ptr)+1)=(uint8_t)((uint32_t)(val)>>16), \
702  *((uint8_t*)(ptr)+0)=(uint8_t)((uint32_t)(val)>>24))
703 
704 
707 static inline ptrdiff_t x_distance_ptr(const void* begin, const void* end)
708 {
709  return (const char*)(end) - (const char*)(begin);
710 }
711 
712 
715 static inline bool x_is_within(int32_t x, int32_t begin, int32_t end)
716 {
717  return ((begin <= x) && (x < end));
718 }
719 
720 
723 static inline bool x_is_uwithin(uint32_t x, uint32_t begin, uint32_t end)
724 {
725  return ((begin <= x) && (x < end));
726 }
727 
728 
731 static inline bool x_is_within_uptr(uintptr_t x, uintptr_t begin, uintptr_t end)
732 {
733  return ((begin <= x) && (x < end));
734 }
735 
736 
739 static inline bool x_is_within_ptr(const void* ptr, const void* begin, const void* end)
740 {
741  const char* const p = (const char*)(ptr);
742  const char* const b = (const char*)(begin);
743  const char* const e = (const char*)(end);
744 
745  return ((b <= p) && (p < e));
746 }
747 
748 
750 #define X_DECLARE_LSB_POS_TABLE \
751  const uint8_t lsb_pos_table[15] = \
752  { \
753  0, /* (0001 & 1 << 0) != 0 */ \
754  1, /* (0010 & 1 << 1) != 0 */ \
755  0, /* (0011 & 1 << 0) != 0 */ \
756  2, /* (0100 & 1 << 2) != 0 */ \
757  0, /* (0101 & 1 << 0) != 0 */ \
758  1, /* (0110 & 1 << 1) != 0 */ \
759  0, /* (0111 & 1 << 0) != 0 */ \
760  3, /* (1000 & 1 << 3) != 0 */ \
761  0, /* (1001 & 1 << 0) != 0 */ \
762  1, /* (1010 & 1 << 1) != 0 */ \
763  0, /* (1011 & 1 << 0) != 0 */ \
764  2, /* (1100 & 1 << 2) != 0 */ \
765  0, /* (1101 & 1 << 0) != 0 */ \
766  1, /* (1110 & 1 << 1) != 0 */ \
767  0, /* (1111 & 1 << 0) != 0 */ \
768  };
769 
771 
776 static inline int x_find_lsb_pos8(uint8_t x)
777 {
778  X_DECLARE_LSB_POS_TABLE;
779  int n = 0;
780  if (!(x & 0x0f)) { x >>= 4; n += 4;}
781  return n + lsb_pos_table[(x &0x0f) - 1];
782 }
783 
784 
787 static inline int x_find_lsb_pos16(uint16_t x)
788 {
789  X_DECLARE_LSB_POS_TABLE;
790  int n = 0;
791  if (!(x & 0x00ff)) { x >>= 8; n += 8;}
792  if (!(x & 0x0f)) { x >>= 4; n += 4;}
793  return n + lsb_pos_table[(x &0x0f) - 1];
794 }
795 
796 
799 static inline int x_find_lsb_pos32(uint32_t x)
800 {
801  X_DECLARE_LSB_POS_TABLE;
802  int n = 0;
803  if (!(x & 0x0000ffff)) { x >>= 16; n += 16;}
804  if (!(x & 0x00ff)) { x >>= 8; n += 8;}
805  if (!(x & 0x0f)) { x >>= 4; n += 4;}
806  return n + lsb_pos_table[(x &0x0f) - 1];
807 }
808 
809 
814 static inline uint8_t x_find_lsb8(uint8_t x) { return x & ((~x) + 1); }
815 
816 
819 static inline uint16_t x_find_lsb16(uint16_t x) { return x & ((~x) + 1); }
820 
821 
824 static inline uint32_t x_find_lsb32(uint32_t x) { return x & ((~x) + 1); }
825 
826 
828 #define X_DECLARE_MSB_POS_TABLE \
829 const uint8_t msb_pos_table[15] = \
830  { \
831  0, /* (0001 & 1 << 0) != 0 */ \
832  1, /* (0010 & 1 << 1) != 0 */ \
833  1, /* (0011 & 1 << 1) != 0 */ \
834  2, /* (0100 & 1 << 2) != 0 */ \
835  2, /* (0101 & 1 << 2) != 0 */ \
836  2, /* (0110 & 1 << 2) != 0 */ \
837  2, /* (0111 & 1 << 2) != 0 */ \
838  3, /* (1000 & 1 << 3) != 0 */ \
839  3, /* (1001 & 1 << 3) != 0 */ \
840  3, /* (1010 & 1 << 3) != 0 */ \
841  3, /* (1011 & 1 << 3) != 0 */ \
842  3, /* (1100 & 1 << 3) != 0 */ \
843  3, /* (1101 & 1 << 3) != 0 */ \
844  3, /* (1110 & 1 << 3) != 0 */ \
845  3, /* (1111 & 1 << 3) != 0 */ \
846  };
847 
849 
854 static inline int x_find_msb_pos8(uint8_t x)
855 {
856  X_DECLARE_MSB_POS_TABLE;
857  int n = 0;
858  if (x & 0xf0) { x >>= 4; n += 4;}
859  return n + msb_pos_table[(x &0x0f) - 1];
860 }
861 
862 
865 static inline int x_find_msb_pos16(uint16_t x)
866 {
867  X_DECLARE_MSB_POS_TABLE;
868  int n = 0;
869  if (x & 0xff00) { x >>= 8; n += 8;}
870  if (x & 0xf0) { x >>= 4; n += 4;}
871  return n + msb_pos_table[(x &0x0f) - 1];
872 }
873 
874 
877 static inline int x_find_msb_pos32(uint32_t x)
878 {
879  X_DECLARE_MSB_POS_TABLE;
880  int n = 0;
881  if (x & 0xffff0000) { x >>= 16; n += 16;}
882  if (x & 0xff00) { x >>= 8; n += 8;}
883  if (x & 0xf0) { x >>= 4; n += 4;}
884  return n + msb_pos_table[(x &0x0f) - 1];
885 }
886 
887 
892 static inline uint8_t x_find_msb8(uint8_t x) { return 1U << x_find_msb_pos8(x); }
893 
894 
897 static inline uint16_t x_find_msb16(uint16_t x) { return 1U << x_find_msb_pos16(x); }
898 
899 
902 static inline uint32_t x_find_msb32(uint32_t x) { return 1UL << x_find_msb_pos32(x); }
903 
904 
906 #define X_COUNT_BITS_IMPL(x) int count = 0; while(x) { ++count; x = x & (x - 1); } return count;
907 
909 
912 static inline int x_count_bits8(uint8_t x) { X_COUNT_BITS_IMPL(x); }
913 
914 
917 static inline int x_count_bits16(uint16_t x) { X_COUNT_BITS_IMPL(x); }
918 
919 
922 static inline int x_count_bits32(uint32_t x) { X_COUNT_BITS_IMPL(x); }
923 
924 
929 static inline void x_reverse_2byte(void* x)
930 {
931  uint8_t* p = (uint8_t*)(x);
932  uint8_t tmp;
933  tmp = *p;
934  *p = *(p+1);
935  *(p+1) = tmp;
936 }
937 
938 
943 static inline void x_reverse_4byte(void* x)
944 {
945  uint8_t* p = (uint8_t*)(x);
946  uint8_t tmp;
947  tmp = *p;
948  *p = *(p+3);
949  *(p+3) = tmp;
950  tmp = *(p+1);
951  *(p+1) = *(p+2);
952  *(p+2) = tmp;
953 }
954 
955 
960 static inline int32_t x_map(
961  int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max)
962 {
963  return ((int64_t)(x - in_min)) * (out_max - out_min) / (in_max - in_min) + out_min;
964 }
965 
966 
969 static inline uint32_t x_umap(
970  uint32_t x, uint32_t in_min, uint32_t in_max, uint32_t out_min, uint32_t out_max)
971 {
972  return ((uint64_t)(x - in_min)) * (out_max - out_min) / (in_max - in_min) + out_min;
973 }
974 
975 
978 static inline bool x_is_big_endian(void)
979 {
980 #if X_BYTE_ORDER == X_BYTE_ORDER_BIG
981  return true;
982 #elif X_BYTE_ORDER == X_BYTE_ORDER_LITTLE
983  return false;
984 #else
985  union
986  {
987  uint32_t u;
988  uint8_t c[4];
989  } e = {0x01000000};
990  return e.c[0];
991 #endif
992 }
993 
994 
997 static inline bool x_is_little_endian(void)
998 {
999  return ! x_is_big_endian();
1000 }
1001 
1002 
1005 static inline uint16_t x_big_to_host16(uint16_t x)
1006 {
1007 #if X_BYTE_ORDER == X_BYTE_ORDER_BIG
1008  return x;
1009 #elif X_BYTE_ORDER == X_BYTE_ORDER_LITTLE
1010  return x_reverse_endian16(x);
1011 #else
1012  return x_is_big_endian() ? x : x_reverse_endian16(x);
1013 #endif
1014 }
1015 
1016 
1019 static inline uint32_t x_big_to_host32(uint32_t x)
1020 {
1021 #if X_BYTE_ORDER == X_BYTE_ORDER_BIG
1022  return x;
1023 #elif X_BYTE_ORDER == X_BYTE_ORDER_LITTLE
1024  return x_reverse_endian32(x);
1025 #else
1026  return x_is_big_endian() ? x : x_reverse_endian32(x);
1027 #endif
1028 }
1029 
1030 
1033 static inline uint16_t x_little_to_host16(uint16_t x)
1034 {
1035 #if X_BYTE_ORDER == X_BYTE_ORDER_LITTLE
1036  return x;
1037 #elif X_BYTE_ORDER == X_BYTE_ORDER_BIG
1038  return x_reverse_endian16(x);
1039 #else
1040  return x_is_little_endian() ? x : x_reverse_endian16(x);
1041 #endif
1042 }
1043 
1044 
1047 static inline uint32_t x_little_to_host32(uint32_t x)
1048 {
1049 #if X_BYTE_ORDER == X_BYTE_ORDER_LITTLE
1050  return x;
1051 #elif X_BYTE_ORDER == X_BYTE_ORDER_BIG
1052  return x_reverse_endian32(x);
1053 #else
1054  return x_is_little_endian() ? x : x_reverse_endian32(x);
1055 #endif
1056 }
1057 
1058 
1061 static inline uint16_t x_host_to_big16(uint16_t x)
1062 {
1063 #if X_BYTE_ORDER == X_BYTE_ORDER_BIG
1064  return x;
1065 #elif X_BYTE_ORDER == X_BYTE_ORDER_LITTLE
1066  return x_reverse_endian16(x);
1067 #else
1068  return x_is_big_endian() ? x : x_reverse_endian16(x);
1069 #endif
1070 }
1071 
1072 
1075 static inline uint32_t x_host_to_big32(uint32_t x)
1076 {
1077 #if X_BYTE_ORDER == X_BYTE_ORDER_BIG
1078  return x;
1079 #elif X_BYTE_ORDER == X_BYTE_ORDER_LITTLE
1080  return x_reverse_endian32(x);
1081 #else
1082  return x_is_big_endian() ? x : x_reverse_endian32(x);
1083 #endif
1084 }
1085 
1086 
1089 static inline uint16_t x_host_to_little16(uint16_t x)
1090 {
1091 #if X_BYTE_ORDER == X_BYTE_ORDER_LITTLE
1092  return x;
1093 #elif X_BYTE_ORDER == X_BYTE_ORDER_BIG
1094  return x_reverse_endian16(x);
1095 #else
1096  return x_is_little_endian() ? x : x_reverse_endian16(x);
1097 #endif
1098 }
1099 
1100 
1103 static inline uint32_t x_host_to_little32(uint32_t x)
1104 {
1105 #if X_BYTE_ORDER == X_BYTE_ORDER_LITTLE
1106  return x;
1107 #elif X_BYTE_ORDER == X_BYTE_ORDER_BIG
1108  return x_reverse_endian32(x);
1109 #else
1110  return x_is_little_endian() ? x : x_reverse_endian32(x);
1111 #endif
1112 }
1113 
1114 
1115 #ifdef __cplusplus
1116 }
1117 #endif
1118 
1119 
1125 #endif // picox_core_xutils_h_
static uint32_t x_roundup_power_of_two(uint32_t x)
X_ROUNDUP_POWER_OF_TWO()の関数版です。
Definition: xutils.h:242
static uint32_t x_roundup_multiple(uint32_t x, uint32_t m)
X_ROUNDUP_MULTIPLE()の関数版です。
Definition: xutils.h:181
#define X_ROUNDUP_POWER_OF_TWO(x)
xを最も近い2のべき乗に切り上げた値を返します。
Definition: xutils.h:237
#define X_IS_MULTIPLE_PTR(x, m)
X_IS_MULTIPLE()のポインタ版です。
Definition: xutils.h:311
static uint32_t x_roundup_alignment(uint32_t x, uint32_t a)
X_ROUNDUP_ALIGNMENT()の関数版です。
Definition: xutils.h:357
static IGNORE int x_find_lsb_pos8(uint8_t x)
8bit符号なし整数の下位から最も近くにセットされたビット位置を返します。
Definition: xutils.h:776
#define X_ROUNDUP_ALIGNMENT_PTR(x, a)
X_ROUNDUP_ALIGNMENT()のポインタ版です。
Definition: xutils.h:366
static int x_count_bits32(uint32_t x)
x_count_bits8()の32bit版です
Definition: xutils.h:922
static uint8_t x_find_msb8(uint8_t x)
8bit符号なし整数の上位から最も近くにセットされたビットを返します。
Definition: xutils.h:892
static bool x_is_aligned(const void *ptr, size_t alignment)
ptrが指すアドレスがalignmentの倍数かどうかをBool値で返します。
Definition: xutils.h:428
static void * x_roundup_multiple_ptr(const void *x, uint32_t m)
X_ROUNDUP_MULTIPLE_PTR()の関数版です。
Definition: xutils.h:194
#define X_ROUNDDOWN_ALIGNMENT(x, a)
xをアライメントの倍数に切り下げた値を返します。
Definition: xutils.h:382
#define X_ROUNDDOWN_ALIGNMENT_PTR(x, a)
X_ROUNDDOWN_ALIGNMENT()のポインタ版です。
Definition: xutils.h:396
static IGNORE int x_find_msb_pos8(uint8_t x)
8bit符号なし整数の上位から最も近くにセットされたビット位置を返します。
Definition: xutils.h:854
static bool x_is_multiple(uint32_t x, uint32_t m)
X_IS_MULTIPLE()の関数版です。
Definition: xutils.h:303
static ptrdiff_t x_distance_ptr(const void *begin, const void *end)
void*引数end, beginのバイト単位のアドレス差を返します。
Definition: xutils.h:707
static bool x_is_within(int32_t x, int32_t begin, int32_t end)
(begin <= x) && (x < end)を判定します。
Definition: xutils.h:715
static bool x_is_uwithin(uint32_t x, uint32_t begin, uint32_t end)
(begin <= x) && (x < end)を判定します。
Definition: xutils.h:723
#define X_REVERSE_ENDIAN16(x)
xの下位2バイトのバイトオーダーを逆転した値を返します。
Definition: xutils.h:563
static bool x_is_big_endian(void)
バイトオーダーがビッグエンディアンかどうかを返します。
Definition: xutils.h:978
#define X_REVERSE_ENDIAN32(x)
xの下位4バイトのバイトオーダーを逆転した値を返します。
Definition: xutils.h:576
static int x_find_msb_pos32(uint32_t x)
x_find_msb8()の32bit版です
Definition: xutils.h:877
static uint32_t x_host_to_big32(uint32_t x)
4Byteホストエンディアンデータをビッグエンディアンにして返します。
Definition: xutils.h:1075
static void * x_rounddown_multiple_ptr(const void *x, uintptr_t m)
X_ROUNDDOWN_MULTIPLE()の関数版です。
Definition: xutils.h:220
static int x_find_lsb_pos32(uint32_t x)
x_find_lsb8()の32bit版です
Definition: xutils.h:799
#define X_ROUNDUP_MULTIPLE(x, m)
xをmの倍数に切り上げた値を返します。
Definition: xutils.h:176
#define X_ROUNDDOWN_MULTIPLE_PTR(x, m)
xをmの倍数に切り下げた値を返します。
Definition: xutils.h:215
static void x_reverse_2byte(void *x)
xが指す先頭2バイトを逆転します
Definition: xutils.h:929
#define X_ROUNDDOWN_POWER_OF_TWO_PTR(x)
X_ROUNDDOWN_POWER_OF_TWO()のポインタ版です。
Definition: xutils.h:285
#define X_IS_POWER_OF_TWO(x)
xが2のべき乗かどうかをBool値で返します。
Definition: xutils.h:324
static uint16_t x_find_msb16(uint16_t x)
x_find_msb8()の16bit版です
Definition: xutils.h:897
static bool x_is_within_uptr(uintptr_t x, uintptr_t begin, uintptr_t end)
(begin <= x) && (x < end)を判定します。
Definition: xutils.h:731
static uint32_t x_umap(uint32_t x, uint32_t in_min, uint32_t in_max, uint32_t out_min, uint32_t out_max)
x_map()の符号なし版です。
Definition: xutils.h:969
static uint16_t x_big_to_host16(uint16_t x)
2Byteビッグエンディアンデータをホストのエンディアンにして返します。
Definition: xutils.h:1005
#define X_IS_POWER_OF_TWO_PTR(x)
X_IS_POWER_OF_TWO()のポインタ版です。
Definition: xutils.h:337
#define X_IS_ALIGNMENT(x)
xが1または2のべき乗かどうかをBool値で返します。
Definition: xutils.h:410
#define X_ROUNDDOWN_MULTIPLE(x, m)
xをmの倍数に切り下げた値を返します。
Definition: xutils.h:202
static uint16_t x_find_lsb16(uint16_t x)
x_find_lsb8()の16bit版です
Definition: xutils.h:819
static uint16_t x_host_to_little16(uint16_t x)
2Byteホストエンディアンデータをリトルエンディアンにして返します。
Definition: xutils.h:1089
static void x_reverse_4byte(void *x)
xが指す先頭4バイトを逆転します
Definition: xutils.h:943
static bool x_is_power_of_two_ptr(const void *x)
X_IS_POWER_OF_TWO_PTR()の関数版です。
Definition: xutils.h:342
static IGNORE uint8_t x_reverse_bits8(uint8_t x)
X_REVERSE_BITS8()の関数版です。
Definition: xutils.h:501
static uint16_t x_reverse_endian16(register uint16_t x)
X_REVERSE_ENDIAN16()の関数版です。
Definition: xutils.h:568
static uint32_t x_rounddown_power_of_two(uint32_t x)
X_ROUNDDOWN_POWER_OF_TWO()の関数版です。
Definition: xutils.h:277
static uint32_t x_host_to_little32(uint32_t x)
4Byteホストエンディアンデータをリトルエンディアンにして返します。
Definition: xutils.h:1103
static uint32_t x_rounddown_multiple(uint32_t x, uint32_t m)
X_ROUNDDOWN_MULTIPLE()の関数版です。
Definition: xutils.h:207
static bool x_is_power_of_two(uint32_t x)
X_IS_POWER_OF_TWO()の関数版です。
Definition: xutils.h:329
static uint32_t x_find_msb32(uint32_t x)
x_find_msb8()の32bit版です
Definition: xutils.h:902
static void * x_roundup_power_of_two_ptr(const void *x)
X_ROUNDUP_POWER_OF_TWO_PTR()の関数版です。
Definition: xutils.h:255
static int x_count_bits16(uint16_t x)
x_count_bits8()の16bit版です
Definition: xutils.h:917
static int32_t x_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max)
数値をある範囲から別の範囲に変換します
Definition: xutils.h:960
static uint32_t x_reverse_bits32(register uint32_t x)
X_REVERSE_BITS32()の関数版です。
Definition: xutils.h:546
static uint32_t x_reverse_endian32(uint32_t x)
X_REVERSE_ENDIAN32()の関数版です。
Definition: xutils.h:584
static bool x_is_alignment(uint32_t x)
X_IS_ALIGNMENT()の関数版です。
Definition: xutils.h:415
static uint16_t x_little_to_host16(uint16_t x)
2Byteリトルエンディアンデータをホストのエンディアンにして返します。
Definition: xutils.h:1033
static void * x_roundup_alignment_ptr(const void *x, size_t a)
X_ROUNDUP_ALIGNMENT_PTR()の関数版です。
Definition: xutils.h:371
static uint8_t x_find_lsb8(uint8_t x)
8bit符号なし整数の下位から最も近くにセットされたビットを返します。
Definition: xutils.h:814
static void * x_rounddown_power_of_two_ptr(const void *x)
X_ROUNDDOWN_POWER_OF_TWO_PTR()の関数版です。
Definition: xutils.h:290
#define X_ROUNDUP_ALIGNMENT(x, a)
xをアライメントの倍数に切り上げた値を返します。
Definition: xutils.h:352
#define X_IS_MULTIPLE(x, m)
xがmの倍数かどうかをBool値で返します。
Definition: xutils.h:298
static int x_find_lsb_pos16(uint16_t x)
x_find_lsb8()の16bit版です
Definition: xutils.h:787
static uint16_t x_reverse_bits16(uint16_t x)
X_REVERSE_BITS16()の関数版です。
Definition: xutils.h:523
static IGNORE int x_count_bits8(uint8_t x)
8bit符号なし変数のセットされたビット数を返します
Definition: xutils.h:912
static uint32_t x_rounddown_alignment(uint32_t x, uint32_t a)
X_ROUNDDOWN_ALIGNMENT()の関数版です。
Definition: xutils.h:387
static bool x_is_little_endian(void)
バイトオーダーがリトルエンディアンかどうかを返します。
Definition: xutils.h:997
static uint32_t x_little_to_host32(uint32_t x)
4Byteリトルエンディアンデータをホストのエンディアンにして返します。
Definition: xutils.h:1047
#define X_ROUNDUP_POWER_OF_TWO_PTR(x)
X_ROUNDUP_POWER_OF_TWO()のポインタ版です。
Definition: xutils.h:250
static uint16_t x_host_to_big16(uint16_t x)
2Byteホストエンディアンデータをビッグエンディアンにして返します。
Definition: xutils.h:1061
static int x_find_msb_pos16(uint16_t x)
x_find_msb8()の16bit版です
Definition: xutils.h:865
#define X_ROUNDUP_MULTIPLE_PTR(x, m)
X_ROUNDUP_MULTIPLE()のポインタ版です。
Definition: xutils.h:189
static bool x_is_multiple_ptr(const void *x, uint32_t m)
X_IS_MULTIPLE_PTR()の関数版です。
Definition: xutils.h:316
static void * x_rounddown_alignment_ptr(const void *x, uint32_t a)
X_ROUNDDOWN_ALIGNMENT_PTR()の関数版です。
Definition: xutils.h:401
#define X_ROUNDDOWN_POWER_OF_TWO(x)
xを最も近い2のべき乗に切り下げた値を返します。
Definition: xutils.h:272
static bool x_is_within_ptr(const void *ptr, const void *begin, const void *end)
ptrが指すアドレスがbegin とendの範囲内かどうかをBool値で返します。
Definition: xutils.h:739
static uint32_t x_big_to_host32(uint32_t x)
4Byteビッグエンディアンデータをホストのエンディアンにして返します。
Definition: xutils.h:1019
static uint32_t x_find_lsb32(uint32_t x)
x_find_lsb8()の32bit版です
Definition: xutils.h:824