The friendly Operating System for the Internet of Things
div.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
3  * Copyright (C) 2016 Eistec AB
4  *
5  * This file is subject to the terms and conditions of the GNU Lesser
6  * General Public License v2.1. See the file LICENSE in the top level
7  * directory for more details.
8  */
9 
23 #ifndef DIV_H
24 #define DIV_H
25 
26 #include <assert.h>
27 #include <stdint.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
36 #define DIV_H_INV_15625_32 0x431bde83ul
37 
41 #define DIV_H_INV_15625_64 0x431bde82d7b634dbull
42 
46 #define DIV_H_INV_15625_SHIFT 12
47 
61 uint64_t _div_mulhi64(const uint64_t a, const uint64_t b);
62 
69 static inline uint64_t div_u64_by_15625(uint64_t val)
70 {
71  if (val > 16383999997ull) {
72  return (_div_mulhi64(DIV_H_INV_15625_64, val) >> DIV_H_INV_15625_SHIFT);
73  }
74  return (val * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32);
75 }
76 
83 static inline uint64_t div_u64_by_1000000(uint64_t val)
84 {
85  return div_u64_by_15625(val) >> 6;
86 }
87 
102 static inline uint32_t div_u32_by_15625div512(uint32_t val)
103 {
104  return ((uint64_t)(val) * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32 - 9);
105 }
106 
116 static inline uint64_t div_u64_by_15625div512(uint64_t val)
117 {
118  /*
119  * This saves around 1400 bytes of ROM on Cortex-M platforms (both ARMv6 and
120  * ARMv7) from avoiding linking against __aeabi_uldivmod and related helpers
121  */
122  if (val > 16383999997ull) {
123  /* this would overflow 2^64 in the multiplication that follows, need to
124  * use the long version */
125  return (_div_mulhi64(DIV_H_INV_15625_64, val) >> (DIV_H_INV_15625_SHIFT - 9));
126  }
127  return (val * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32 - 9);
128 }
129 
136 static inline uint32_t div_u32_by_44488(uint32_t val)
137 {
138  return ((uint64_t)val * 0xBC8F1391UL) >> (15 + 32);
139 }
140 
147 static inline uint32_t div_u32_mod_44488(uint32_t val)
148 {
149  return val - (div_u32_by_44488(val)*44488);
150 }
151 
152 #ifdef __cplusplus
153 }
154 #endif
155 
156 #endif /* DIV_H */
static uint64_t div_u64_by_1000000(uint64_t val)
Integer divide val by 1000000.
Definition: div.h:83
#define DIV_H_INV_15625_64
Approximation of (2**l)/d for d=15625, l=12, 64 bits.
Definition: div.h:41
static uint64_t div_u64_by_15625div512(uint64_t val)
Divide val by (15625/512)
Definition: div.h:116
static uint32_t div_u32_by_44488(uint32_t val)
Integer divide val by 44488.
Definition: div.h:136
POSIX.1-2008 compliant version of the assert macro.
static uint64_t div_u64_by_15625(uint64_t val)
Integer divide val by 15625, 64 bit version.
Definition: div.h:69
#define DIV_H_INV_15625_SHIFT
Required shifts for division by 15625, l above.
Definition: div.h:46
static uint32_t div_u32_mod_44488(uint32_t val)
Modulo 44488.
Definition: div.h:147
static uint32_t div_u32_by_15625div512(uint32_t val)
Divide val by (15625/512)
Definition: div.h:102
#define DIV_H_INV_15625_32
Approximation of (2**l)/d for d=15625, l=12, 32 bits.
Definition: div.h:36