1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#pragma once
14
15/* macros for doing basic math */
16
17#include <assert.h>
18#include <limits.h>
19#include <stdint.h>
20#include <utils/attribute.h>
21#include <utils/builtin.h>
22#include <stdint.h>
23#include <utils/verification.h>
24#include <utils/stringify.h>
25
26#define BIT(n) (1ul<<(n))
27#define LLBIT(n) (1ull<<(n))
28
29#define MASK_UNSAFE(x) ((BIT(x) - 1ul))
30
31/* The MASK_UNSAFE operation involves using BIT that performs a left shift, this
32 * shift is only defined by the C standard if shifting by 1 less than the
33 * number of bits in a word. MASK allows both the safe creation of masks, and for
34 * creating masks that are larger than what is possible with MASK_UNSAFE, as
35 * MASK_UNSAFE cannot create a MASK that is all 1's */
36#define MASK(n) \
37    ({  typeof (n) _n = (n); \
38        (void)assert(_n <= (sizeof(unsigned long) * 8)); \
39        (void)assert(_n > 0); \
40        MASK_UNSAFE(_n - 1) | BIT(_n - 1); \
41    })
42
43#define IS_ALIGNED(n, b) (!((n) & MASK(b)))
44
45/* Calculate the log2 by finding the most significant bit that is set.
46 * We have CLZL, which tells us how many places from the 'left' it is,
47 * and by subtracting that from the number of bits in the word (minus 1)
48 * we learn how many bits from the 'right' it is. */
49#define LOG_BASE_2(n) (sizeof(unsigned long) * CHAR_BIT - CLZL(n) - 1)
50
51/* Taken from Hacker's Delight, this works on 32 bit integers,
52 * also note that it *will* calculate the *next* power of two,
53 * i.e. NEXT_POWER_OF_2(64) == 128 not 64 */
54#define NEXT_POWER_OF_2(x)  \
55    ({ uint32_t temp = (uint32_t) x;    \
56       temp |= (temp >> 1);             \
57       temp |= (temp >> 2);             \
58       temp |= (temp >> 4);             \
59       temp |= (temp >> 8);             \
60       temp |= (temp >> 16);            \
61       temp += 1;                       \
62    })
63
64#define IS_POWER_OF_2_OR_ZERO(x) (0 == ((x) & ((x) - 1)))
65#define IS_POWER_OF_2(x) (((x) != 0) && IS_POWER_OF_2_OR_ZERO(x))
66#define ALIGN_UP(x, n) (((x) + (n) - 1) & ~((n) - 1))
67#define ALIGN_DOWN(x, n) ((x) & ~((n) - 1))
68
69#define ROUND_DOWN_UNSAFE(n, b) ((n) - ((n) % (b)))
70
71#define ROUND_DOWN(n, b) \
72    ({ typeof (n) _n = (n); \
73       typeof (b) _b = (b); \
74       _n - (_n % _b); \
75    })
76
77#define ROUND_UP_UNSAFE(n, b) ((n) + ((n) % (b) == 0 ? 0 : ((b) - ((n) % (b)))))
78
79#define ROUND_UP(n, b) \
80    ({ typeof (n) _n = (n); \
81       typeof (b) _b = (b); \
82       (_n + (_n % _b == 0 ? 0 : (_b - (_n % _b)))); \
83    })
84
85#define DIV_ROUND_UP(n,d)   \
86    ({ typeof (n) _n = (n); \
87       typeof (d) _d = (d); \
88       (_n/_d + (_n % _d == 0 ? 0 : 1)); \
89   })
90
91/* Divides and rounds to the nearest whole number
92    DIV_ROUND(5,2) returns 3
93    DIV_ROUND(7,3) returns 2 */
94#define DIV_ROUND_UNSAFE(n,d)  \
95    ({ typeof (n) _n = (n); \
96       typeof (d) _d = (d); \
97       ((_n + (_d/2)) / _d); \
98   })
99
100#define DIV_ROUND(n,d)  \
101   ({ typeof (n) _n = (n); \
102      typeof (d) _d = (d); \
103      ((_n / _d) + ((_n % _d) >= _d/2 ? 1 : 0)); \
104  })
105
106#define MIN(a,b) \
107    ({ typeof (a) _a = (a); \
108       typeof (b) _b = (b); \
109       _a < _b ? _a : _b; })
110
111/* used for compile time eval */
112#define MIN_UNSAFE(x, y) ((x) < (y) ? (x) : (y))
113
114#define MAX(a,b) \
115    ({ typeof (a) _a = (a); \
116       typeof (b) _b = (b); \
117       _a > _b ? _a : _b; })
118
119/* used for complile time eval */
120#define MAX_UNSAFE(x, y) ((x) > (y) ? (x) : (y))
121
122#define INRANGE(a, x, b) MIN(MAX(x, a), b)
123#define ISINRANGE(a, x, b) \
124    ({ typeof (x) _x = (x); \
125       _x == INRANGE(a, _x, b); })
126
127#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
128
129/* Clamp a value between two limits. Sample usage: CLAMP(-3, 7, 4) == 4. */
130#define CLAMP(min, value, max) \
131    ({  typeof (max) _max = (max); \
132        typeof (min) _min = (min); \
133        typeof (value) _value = (value); \
134        if (_value > _max) { \
135            _value = _max; \
136        } else if (_value < _min) { \
137            _value = _min; \
138        } \
139        _value;  })
140
141/* Clamp an addition. Sample usage: CLAMP_ADD(1<<30, 1<<30, INT_MAX) == INT_MAX. */
142#define CLAMP_ADD(operand1, operand2, limit) \
143    ({  typeof (operand1) _op1 = (operand1); \
144        typeof (operand2) _op2 = (operand2); \
145        typeof (limit) _limit = (limit); \
146        _limit - _op2 < _op1 ? _limit : _op1 + _op2;  })
147
148/* Clamp a subtraction. Sample usage:
149 *   CLAMP_SUB(-1 * (1<<30), -1 * (1<<30), INT_MIN) == INT_MIN.
150 */
151#define CLAMP_SUB(operand1, operand2, limit) \
152    ({  typeof (operand1) _op1 = (operand1); \
153        typeof (operand2) _op2 = (operand2); \
154        typeof (limit) _limit = (limit); \
155        _limit + _op2 > _op1 ? _limit : _op1 - _op2;  })
156
157/* Expands to a struct field declaration suitable for padding structs where each
158 * field must have a specific offset (such as in device drivers). E.g.:
159 * struct device_registers {
160 *      uint32_t reg1; // 0x00
161 *      uint32_t reg2; // 0x04
162 *      PAD_BETWEEN(0x04, 0x10, uint32_t); // expands to: uint8_t __padding4[8];
163 *      uint32_t reg3; // 0x10
164 * } PACKED;
165 *
166 * Using this macro in a struct requires that struct to be defined with
167 * the "packed" attribute.
168 *
169 * @param before    offset of struct field before padding
170 * @param after     offset of struct field after padding
171 * @param type      type of field before padding
172 */
173#define PAD_STRUCT_BETWEEN(before, after, type) \
174        uint8_t JOIN(__padding, __COUNTER__)[(after) - (before) - sizeof(type)]
175