Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libc/src/__support/endian_internal.h
213766 views
1
//===-- Endianness support --------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLVM_LIBC_SRC___SUPPORT_ENDIAN_INTERNAL_H
10
#define LLVM_LIBC_SRC___SUPPORT_ENDIAN_INTERNAL_H
11
12
#include "common.h"
13
#include "src/__support/macros/config.h"
14
15
#include <stdint.h>
16
17
namespace LIBC_NAMESPACE_DECL {
18
19
// We rely on compiler preprocessor defines to allow for cross compilation.
20
#if !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__) || \
21
!defined(__ORDER_BIG_ENDIAN__)
22
#error "Missing preprocessor definitions for endianness detection."
23
#endif
24
25
namespace internal {
26
27
// Converts uint8_t, uint16_t, uint32_t, uint64_t to its big or little endian
28
// counterpart.
29
// We use explicit template specialization:
30
// - to prevent accidental integer promotion.
31
// - to prevent fallback in (unlikely) case of middle-endianness.
32
33
template <unsigned ORDER> struct Endian {
34
static constexpr const bool IS_LITTLE = ORDER == __ORDER_LITTLE_ENDIAN__;
35
static constexpr const bool IS_BIG = ORDER == __ORDER_BIG_ENDIAN__;
36
template <typename T> LIBC_INLINE static T to_big_endian(T value);
37
template <typename T> LIBC_INLINE static T to_little_endian(T value);
38
};
39
40
// Little Endian specializations
41
template <>
42
template <>
43
LIBC_INLINE uint8_t
44
Endian<__ORDER_LITTLE_ENDIAN__>::to_big_endian<uint8_t>(uint8_t v) {
45
return v;
46
}
47
template <>
48
template <>
49
LIBC_INLINE uint8_t
50
Endian<__ORDER_LITTLE_ENDIAN__>::to_little_endian<uint8_t>(uint8_t v) {
51
return v;
52
}
53
template <>
54
template <>
55
LIBC_INLINE uint16_t
56
Endian<__ORDER_LITTLE_ENDIAN__>::to_big_endian<uint16_t>(uint16_t v) {
57
return __builtin_bswap16(v);
58
}
59
template <>
60
template <>
61
LIBC_INLINE uint16_t
62
Endian<__ORDER_LITTLE_ENDIAN__>::to_little_endian<uint16_t>(uint16_t v) {
63
return v;
64
}
65
template <>
66
template <>
67
LIBC_INLINE uint32_t
68
Endian<__ORDER_LITTLE_ENDIAN__>::to_big_endian<uint32_t>(uint32_t v) {
69
return __builtin_bswap32(v);
70
}
71
template <>
72
template <>
73
LIBC_INLINE uint32_t
74
Endian<__ORDER_LITTLE_ENDIAN__>::to_little_endian<uint32_t>(uint32_t v) {
75
return v;
76
}
77
template <>
78
template <>
79
LIBC_INLINE uint64_t
80
Endian<__ORDER_LITTLE_ENDIAN__>::to_big_endian<uint64_t>(uint64_t v) {
81
return __builtin_bswap64(v);
82
}
83
template <>
84
template <>
85
LIBC_INLINE uint64_t
86
Endian<__ORDER_LITTLE_ENDIAN__>::to_little_endian<uint64_t>(uint64_t v) {
87
return v;
88
}
89
90
// Big Endian specializations
91
template <>
92
template <>
93
LIBC_INLINE uint8_t
94
Endian<__ORDER_BIG_ENDIAN__>::to_big_endian<uint8_t>(uint8_t v) {
95
return v;
96
}
97
template <>
98
template <>
99
LIBC_INLINE uint8_t
100
Endian<__ORDER_BIG_ENDIAN__>::to_little_endian<uint8_t>(uint8_t v) {
101
return v;
102
}
103
template <>
104
template <>
105
LIBC_INLINE uint16_t
106
Endian<__ORDER_BIG_ENDIAN__>::to_big_endian<uint16_t>(uint16_t v) {
107
return v;
108
}
109
template <>
110
template <>
111
LIBC_INLINE uint16_t
112
Endian<__ORDER_BIG_ENDIAN__>::to_little_endian<uint16_t>(uint16_t v) {
113
return __builtin_bswap16(v);
114
}
115
template <>
116
template <>
117
LIBC_INLINE uint32_t
118
Endian<__ORDER_BIG_ENDIAN__>::to_big_endian<uint32_t>(uint32_t v) {
119
return v;
120
}
121
template <>
122
template <>
123
LIBC_INLINE uint32_t
124
Endian<__ORDER_BIG_ENDIAN__>::to_little_endian<uint32_t>(uint32_t v) {
125
return __builtin_bswap32(v);
126
}
127
template <>
128
template <>
129
LIBC_INLINE uint64_t
130
Endian<__ORDER_BIG_ENDIAN__>::to_big_endian<uint64_t>(uint64_t v) {
131
return v;
132
}
133
template <>
134
template <>
135
LIBC_INLINE uint64_t
136
Endian<__ORDER_BIG_ENDIAN__>::to_little_endian<uint64_t>(uint64_t v) {
137
return __builtin_bswap64(v);
138
}
139
140
} // namespace internal
141
142
using Endian = internal::Endian<__BYTE_ORDER__>;
143
144
} // namespace LIBC_NAMESPACE_DECL
145
146
#endif // LLVM_LIBC_SRC___SUPPORT_ENDIAN_INTERNAL_H
147
148