Loading...
Searching...
No Matches
div.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2015 Kaspar Schleiser <kaspar@schleiser.de>
3 * SPDX-FileCopyrightText: 2016 Eistec AB
4 * SPDX-License-Identifier: LGPL-2.1-only
5 */
6
7#pragma once
8
22
23#include <assert.h>
24#include <stdint.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
33#define DIV_H_INV_15625_32 0x431bde83ul
34
38#define DIV_H_INV_15625_64 0x431bde82d7b634dbull
39
43#define DIV_H_INV_15625_SHIFT 12
44
58uint64_t _div_mulhi64(const uint64_t a, const uint64_t b);
59
66static inline uint64_t div_u64_by_15625(uint64_t val)
67{
68 if (val > 16383999997ull) {
69 return (_div_mulhi64(DIV_H_INV_15625_64, val) >> DIV_H_INV_15625_SHIFT);
70 }
71 return (val * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32);
72}
73
87static inline uint32_t div_u64_by_125(uint64_t val)
88{
89 /* a higher value would overflow the result type */
90 assert(val <= 536870911999LLU);
91
92 uint32_t hi = val >> 32;
93 uint32_t lo = val;
94 uint32_t r = (lo >> 16) + (hi << 16);
95 uint32_t res = r / 125;
96 r = ((r % 125) << 16) + (lo & 0xFFFF);
97 res = (res << 16) + r / 125;
98 return res;
99}
100
107static inline uint64_t div_u64_by_1000000(uint64_t val)
108{
109 return div_u64_by_15625(val) >> 6;
110}
111
126static inline uint32_t div_u32_by_15625div512(uint32_t val)
127{
128 return ((uint64_t)(val) * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32 - 9);
129}
130
140static inline uint64_t div_u64_by_15625div512(uint64_t val)
141{
142 /*
143 * This saves around 1400 bytes of ROM on Cortex-M platforms (both ARMv6 and
144 * ARMv7) from avoiding linking against __aeabi_uldivmod and related helpers
145 */
146 if (val > 16383999997ull) {
147 /* this would overflow 2^64 in the multiplication that follows, need to
148 * use the long version */
149 return (_div_mulhi64(DIV_H_INV_15625_64, val) >> (DIV_H_INV_15625_SHIFT - 9));
150 }
151 return (val * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32 - 9);
152}
153
160static inline uint32_t div_u32_by_44488(uint32_t val)
161{
162 return ((uint64_t)val * 0xBC8F1391UL) >> (15 + 32);
163}
164
171static inline uint32_t div_u32_mod_44488(uint32_t val)
172{
173 return val - (div_u32_by_44488(val)*44488);
174}
175
176#ifdef __cplusplus
177}
178#endif
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition assert.h:143
static uint32_t div_u64_by_125(uint64_t val)
Integer divide val by 125.
Definition div.h:87
static uint32_t div_u32_mod_44488(uint32_t val)
Modulo 44488.
Definition div.h:171
static uint64_t div_u64_by_1000000(uint64_t val)
Integer divide val by 1000000.
Definition div.h:107
static uint32_t div_u32_by_15625div512(uint32_t val)
Divide val by (15625/512)
Definition div.h:126
static uint64_t div_u64_by_15625(uint64_t val)
Integer divide val by 15625, 64 bit version.
Definition div.h:66
#define DIV_H_INV_15625_64
Approximation of (2**l)/d for d=15625, l=12, 64 bits.
Definition div.h:38
#define DIV_H_INV_15625_32
Approximation of (2**l)/d for d=15625, l=12, 32 bits.
Definition div.h:33
static uint32_t div_u32_by_44488(uint32_t val)
Integer divide val by 44488.
Definition div.h:160
#define DIV_H_INV_15625_SHIFT
Required shifts for division by 15625, l above.
Definition div.h:43
static uint64_t div_u64_by_15625div512(uint64_t val)
Divide val by (15625/512)
Definition div.h:140