Loading...
Searching...
No Matches
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
10#pragma once
11
25
26#include <assert.h>
27#include <stdint.h>
28
29#ifdef __cplusplus
30extern "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
61uint64_t _div_mulhi64(const uint64_t a, const uint64_t b);
62
69static 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
90static inline uint32_t div_u64_by_125(uint64_t val)
91{
92 /* a higher value would overflow the result type */
93 assert(val <= 536870911999LLU);
94
95 uint32_t hi = val >> 32;
96 uint32_t lo = val;
97 uint32_t r = (lo >> 16) + (hi << 16);
98 uint32_t res = r / 125;
99 r = ((r % 125) << 16) + (lo & 0xFFFF);
100 res = (res << 16) + r / 125;
101 return res;
102}
103
110static inline uint64_t div_u64_by_1000000(uint64_t val)
111{
112 return div_u64_by_15625(val) >> 6;
113}
114
129static inline uint32_t div_u32_by_15625div512(uint32_t val)
130{
131 return ((uint64_t)(val) * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32 - 9);
132}
133
143static inline uint64_t div_u64_by_15625div512(uint64_t val)
144{
145 /*
146 * This saves around 1400 bytes of ROM on Cortex-M platforms (both ARMv6 and
147 * ARMv7) from avoiding linking against __aeabi_uldivmod and related helpers
148 */
149 if (val > 16383999997ull) {
150 /* this would overflow 2^64 in the multiplication that follows, need to
151 * use the long version */
152 return (_div_mulhi64(DIV_H_INV_15625_64, val) >> (DIV_H_INV_15625_SHIFT - 9));
153 }
154 return (val * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32 - 9);
155}
156
163static inline uint32_t div_u32_by_44488(uint32_t val)
164{
165 return ((uint64_t)val * 0xBC8F1391UL) >> (15 + 32);
166}
167
174static inline uint32_t div_u32_mod_44488(uint32_t val)
175{
176 return val - (div_u32_by_44488(val)*44488);
177}
178
179#ifdef __cplusplus
180}
181#endif
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition assert.h:135
static uint32_t div_u64_by_125(uint64_t val)
Integer divide val by 125.
Definition div.h:90
static uint32_t div_u32_mod_44488(uint32_t val)
Modulo 44488.
Definition div.h:174
static uint64_t div_u64_by_1000000(uint64_t val)
Integer divide val by 1000000.
Definition div.h:110
static uint32_t div_u32_by_15625div512(uint32_t val)
Divide val by (15625/512)
Definition div.h:129
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_64
Approximation of (2**l)/d for d=15625, l=12, 64 bits.
Definition div.h:41
#define DIV_H_INV_15625_32
Approximation of (2**l)/d for d=15625, l=12, 32 bits.
Definition div.h:36
static uint32_t div_u32_by_44488(uint32_t val)
Integer divide val by 44488.
Definition div.h:163
#define DIV_H_INV_15625_SHIFT
Required shifts for division by 15625, l above.
Definition div.h:46
static uint64_t div_u64_by_15625div512(uint64_t val)
Divide val by (15625/512)
Definition div.h:143