1#ifndef QEMU_RANGE_H
2#define QEMU_RANGE_H
3
4#include <inttypes.h>
5#include <qemu/typedefs.h>
6
7/*
8 * Operations on 64 bit address ranges.
9 * Notes:
10 *   - ranges must not wrap around 0, but can include the last byte ~0x0LL.
11 *   - this can not represent a full 0 to ~0x0LL range.
12 */
13
14/* A structure representing a range of addresses. */
15struct Range {
16    uint64_t begin; /* First byte of the range, or 0 if empty. */
17    uint64_t end;   /* 1 + the last byte. 0 if range empty or ends at ~0x0LL. */
18};
19
20static inline void range_extend(Range *range, Range *extend_by)
21{
22    if (!extend_by->begin && !extend_by->end) {
23        return;
24    }
25    if (!range->begin && !range->end) {
26        *range = *extend_by;
27        return;
28    }
29    if (range->begin > extend_by->begin) {
30        range->begin = extend_by->begin;
31    }
32    /* Compare last byte in case region ends at ~0x0LL */
33    if (range->end - 1 < extend_by->end - 1) {
34        range->end = extend_by->end;
35    }
36}
37
38/* Get last byte of a range from offset + length.
39 * Undefined for ranges that wrap around 0. */
40static inline uint64_t range_get_last(uint64_t offset, uint64_t len)
41{
42    return offset + len - 1;
43}
44
45/* Check whether a given range covers a given byte. */
46static inline int range_covers_byte(uint64_t offset, uint64_t len,
47                                    uint64_t byte)
48{
49    return offset <= byte && byte <= range_get_last(offset, len);
50}
51
52/* Check whether 2 given ranges overlap.
53 * Undefined if ranges that wrap around 0. */
54static inline int ranges_overlap(uint64_t first1, uint64_t len1,
55                                 uint64_t first2, uint64_t len2)
56{
57    uint64_t last1 = range_get_last(first1, len1);
58    uint64_t last2 = range_get_last(first2, len2);
59
60    return !(last2 < first1 || last1 < first2);
61}
62
63#endif
64