d: Merge upstream dmd, druntime 2bbf64907c, phobos b64bfbf91
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_leb128.h
blob553550d295529e18a837b98678ffa243ffe5722a
1 //===-- sanitizer_leb128.h --------------------------------------*- 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 //===----------------------------------------------------------------------===//
9 #ifndef SANITIZER_LEB128_H
10 #define SANITIZER_LEB128_H
12 #include "sanitizer_common.h"
13 #include "sanitizer_internal_defs.h"
15 namespace __sanitizer {
17 template <typename T, typename It>
18 It EncodeSLEB128(T value, It begin, It end) {
19 bool more;
20 do {
21 u8 byte = value & 0x7f;
22 // NOTE: this assumes that this signed shift is an arithmetic right shift.
23 value >>= 7;
24 more = !((((value == 0) && ((byte & 0x40) == 0)) ||
25 ((value == -1) && ((byte & 0x40) != 0))));
26 if (more)
27 byte |= 0x80;
28 if (UNLIKELY(begin == end))
29 break;
30 *(begin++) = byte;
31 } while (more);
32 return begin;
35 template <typename T, typename It>
36 It DecodeSLEB128(It begin, It end, T* v) {
37 T value = 0;
38 unsigned shift = 0;
39 u8 byte;
40 do {
41 if (UNLIKELY(begin == end))
42 return begin;
43 byte = *(begin++);
44 T slice = byte & 0x7f;
45 value |= slice << shift;
46 shift += 7;
47 } while (byte >= 128);
48 if (shift < 64 && (byte & 0x40))
49 value |= (-1ULL) << shift;
50 *v = value;
51 return begin;
54 template <typename T, typename It>
55 It EncodeULEB128(T value, It begin, It end) {
56 do {
57 u8 byte = value & 0x7f;
58 value >>= 7;
59 if (value)
60 byte |= 0x80;
61 if (UNLIKELY(begin == end))
62 break;
63 *(begin++) = byte;
64 } while (value);
65 return begin;
68 template <typename T, typename It>
69 It DecodeULEB128(It begin, It end, T* v) {
70 T value = 0;
71 unsigned shift = 0;
72 u8 byte;
73 do {
74 if (UNLIKELY(begin == end))
75 return begin;
76 byte = *(begin++);
77 T slice = byte & 0x7f;
78 value += slice << shift;
79 shift += 7;
80 } while (byte >= 128);
81 *v = value;
82 return begin;
85 } // namespace __sanitizer
87 #endif // SANITIZER_LEB128_H