/src/wireshark/wsutil/sign_ext.h
Line | Count | Source |
1 | | /** @file |
2 | | * |
3 | | * Wireshark - Network traffic analyzer |
4 | | * By Gerald Combs <gerald@wireshark.org> |
5 | | * Copyright 1998 Gerald Combs |
6 | | * |
7 | | * SPDX-License-Identifier: GPL-2.0-or-later |
8 | | */ |
9 | | |
10 | | #ifndef __WSUTIL_SIGN_EXT_H__ |
11 | | #define __WSUTIL_SIGN_EXT_H__ |
12 | | |
13 | | #include <inttypes.h> |
14 | | |
15 | | #include <glib.h> |
16 | | |
17 | | #include <wsutil/ws_assert.h> |
18 | | |
19 | | /* sign extension routines */ |
20 | | |
21 | | /** |
22 | | * @brief Sign-extends a 32-bit unsigned value from a given bit width. |
23 | | * |
24 | | * Interprets the input value as a signed integer of `no_of_bits` width and |
25 | | * extends the sign bit to the full 32-bit range. This is useful when decoding |
26 | | * signed fields packed into smaller bit widths. |
27 | | * |
28 | | * @param val The unsigned 32-bit value to sign-extend. |
29 | | * @param no_of_bits The number of significant bits (0–32). |
30 | | * @return The sign-extended 32-bit value. |
31 | | */ |
32 | | static inline uint32_t |
33 | | ws_sign_ext32(uint32_t val, int no_of_bits) |
34 | 20.0k | { |
35 | 20.0k | ws_assert (no_of_bits >= 0 && no_of_bits <= 32); |
36 | | |
37 | 20.0k | if ((no_of_bits == 0) || (no_of_bits == 32)) |
38 | 12.7k | return val; |
39 | | |
40 | | /* |
41 | | * Don't shift signed values left; that's not valid in C99, at |
42 | | * least, if the value is negative or if the shift count is |
43 | | * the number of bits in the value - 1, and we might get |
44 | | * compile-time or run-time complaints about that. |
45 | | */ |
46 | 7.30k | if (val & (1U << (no_of_bits-1))) |
47 | 2.18k | val |= (0xFFFFFFFFU << no_of_bits); |
48 | | |
49 | 7.30k | return val; |
50 | 20.0k | } Line | Count | Source | 34 | 15.9k | { | 35 | 15.9k | ws_assert (no_of_bits >= 0 && no_of_bits <= 32); | 36 | | | 37 | 15.9k | if ((no_of_bits == 0) || (no_of_bits == 32)) | 38 | 12.7k | return val; | 39 | | | 40 | | /* | 41 | | * Don't shift signed values left; that's not valid in C99, at | 42 | | * least, if the value is negative or if the shift count is | 43 | | * the number of bits in the value - 1, and we might get | 44 | | * compile-time or run-time complaints about that. | 45 | | */ | 46 | 3.17k | if (val & (1U << (no_of_bits-1))) | 47 | 927 | val |= (0xFFFFFFFFU << no_of_bits); | 48 | | | 49 | 3.17k | return val; | 50 | 15.9k | } |
Line | Count | Source | 34 | 4.00k | { | 35 | 4.00k | ws_assert (no_of_bits >= 0 && no_of_bits <= 32); | 36 | | | 37 | 4.00k | if ((no_of_bits == 0) || (no_of_bits == 32)) | 38 | 0 | return val; | 39 | | | 40 | | /* | 41 | | * Don't shift signed values left; that's not valid in C99, at | 42 | | * least, if the value is negative or if the shift count is | 43 | | * the number of bits in the value - 1, and we might get | 44 | | * compile-time or run-time complaints about that. | 45 | | */ | 46 | 4.00k | if (val & (1U << (no_of_bits-1))) | 47 | 1.20k | val |= (0xFFFFFFFFU << no_of_bits); | 48 | | | 49 | 4.00k | return val; | 50 | 4.00k | } |
Unexecuted instantiation: packet-signal-pdu.c:ws_sign_ext32 Unexecuted instantiation: packet-usb-hid.c:ws_sign_ext32 Line | Count | Source | 34 | 123 | { | 35 | 123 | ws_assert (no_of_bits >= 0 && no_of_bits <= 32); | 36 | | | 37 | 123 | if ((no_of_bits == 0) || (no_of_bits == 32)) | 38 | 0 | return val; | 39 | | | 40 | | /* | 41 | | * Don't shift signed values left; that's not valid in C99, at | 42 | | * least, if the value is negative or if the shift count is | 43 | | * the number of bits in the value - 1, and we might get | 44 | | * compile-time or run-time complaints about that. | 45 | | */ | 46 | 123 | if (val & (1U << (no_of_bits-1))) | 47 | 50 | val |= (0xFFFFFFFFU << no_of_bits); | 48 | | | 49 | 123 | return val; | 50 | 123 | } |
|
51 | | |
52 | | /** |
53 | | * @brief Sign-extends a 64-bit unsigned value from a given bit width. |
54 | | * |
55 | | * Interprets the input value as a signed integer of `no_of_bits` width and |
56 | | * extends the sign bit to the full 64-bit range. This is useful when decoding |
57 | | * signed fields packed into smaller bit widths. |
58 | | * |
59 | | * @param val The unsigned 64-bit value to sign-extend. |
60 | | * @param no_of_bits The number of significant bits (0–64). |
61 | | * @return The sign-extended 64-bit value. |
62 | | */ |
63 | | static inline uint64_t |
64 | | ws_sign_ext64(uint64_t val, int no_of_bits) |
65 | 8.93k | { |
66 | 8.93k | ws_assert (no_of_bits >= 0 && no_of_bits <= 64); |
67 | | |
68 | 8.93k | if ((no_of_bits == 0) || (no_of_bits == 64)) |
69 | 0 | return val; |
70 | | |
71 | | /* |
72 | | * Don't shift signed values left; that's not valid in C99, at |
73 | | * least, if the value is negative or if the shift count is |
74 | | * the number of bits in the value - 1, and we might get |
75 | | * compile-time or run-time complaints about that. |
76 | | */ |
77 | 8.93k | if (val & (UINT64_C(1) << (no_of_bits-1))) |
78 | 2.79k | val |= (UINT64_C(0xFFFFFFFFFFFFFFFF) << no_of_bits); |
79 | | |
80 | 8.93k | return val; |
81 | 8.93k | } Line | Count | Source | 65 | 5.48k | { | 66 | 5.48k | ws_assert (no_of_bits >= 0 && no_of_bits <= 64); | 67 | | | 68 | 5.48k | if ((no_of_bits == 0) || (no_of_bits == 64)) | 69 | 0 | return val; | 70 | | | 71 | | /* | 72 | | * Don't shift signed values left; that's not valid in C99, at | 73 | | * least, if the value is negative or if the shift count is | 74 | | * the number of bits in the value - 1, and we might get | 75 | | * compile-time or run-time complaints about that. | 76 | | */ | 77 | 5.48k | if (val & (UINT64_C(1) << (no_of_bits-1))) | 78 | 1.76k | val |= (UINT64_C(0xFFFFFFFFFFFFFFFF) << no_of_bits); | 79 | | | 80 | 5.48k | return val; | 81 | 5.48k | } |
Line | Count | Source | 65 | 3.45k | { | 66 | 3.45k | ws_assert (no_of_bits >= 0 && no_of_bits <= 64); | 67 | | | 68 | 3.45k | if ((no_of_bits == 0) || (no_of_bits == 64)) | 69 | 0 | return val; | 70 | | | 71 | | /* | 72 | | * Don't shift signed values left; that's not valid in C99, at | 73 | | * least, if the value is negative or if the shift count is | 74 | | * the number of bits in the value - 1, and we might get | 75 | | * compile-time or run-time complaints about that. | 76 | | */ | 77 | 3.45k | if (val & (UINT64_C(1) << (no_of_bits-1))) | 78 | 1.03k | val |= (UINT64_C(0xFFFFFFFFFFFFFFFF) << no_of_bits); | 79 | | | 80 | 3.45k | return val; | 81 | 3.45k | } |
Unexecuted instantiation: packet-signal-pdu.c:ws_sign_ext64 Unexecuted instantiation: packet-usb-hid.c:ws_sign_ext64 Unexecuted instantiation: asn1.c:ws_sign_ext64 |
82 | | |
83 | | /* |
84 | | static inline uint64_t |
85 | | ws_sign_ext64(uint64_t val, int no_of_bits) |
86 | | { |
87 | | int64_t sval = (val << (64 - no_of_bits)); |
88 | | |
89 | | return (uint64_t) (sval >> (64 - no_of_bits)); |
90 | | } |
91 | | */ |
92 | | |
93 | | #endif /* __WSUTIL_SIGN_EXT_H__ */ |