1//===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file declares some utility functions for encoding SLEB128 and 11// ULEB128 values. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_SUPPORT_LEB128_H 16#define LLVM_SUPPORT_LEB128_H 17 18#include "llvm/Support/raw_ostream.h" 19 20namespace llvm { 21 22/// Utility function to encode a SLEB128 value to an output stream. 23inline void encodeSLEB128(int64_t Value, raw_ostream &OS) { 24 bool More; 25 do { 26 uint8_t Byte = Value & 0x7f; 27 // NOTE: this assumes that this signed shift is an arithmetic right shift. 28 Value >>= 7; 29 More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || 30 ((Value == -1) && ((Byte & 0x40) != 0)))); 31 if (More) 32 Byte |= 0x80; // Mark this byte to show that more bytes will follow. 33 OS << char(Byte); 34 } while (More); 35} 36 37/// Utility function to encode a ULEB128 value to an output stream. 38inline void encodeULEB128(uint64_t Value, raw_ostream &OS, 39 unsigned Padding = 0) { 40 do { 41 uint8_t Byte = Value & 0x7f; 42 Value >>= 7; 43 if (Value != 0 || Padding != 0) 44 Byte |= 0x80; // Mark this byte to show that more bytes will follow. 45 OS << char(Byte); 46 } while (Value != 0); 47 48 // Pad with 0x80 and emit a null byte at the end. 49 if (Padding != 0) { 50 for (; Padding != 1; --Padding) 51 OS << '\x80'; 52 OS << '\x00'; 53 } 54} 55 56/// Utility function to encode a ULEB128 value to a buffer. Returns 57/// the length in bytes of the encoded value. 58inline unsigned encodeULEB128(uint64_t Value, uint8_t *p, 59 unsigned Padding = 0) { 60 uint8_t *orig_p = p; 61 do { 62 uint8_t Byte = Value & 0x7f; 63 Value >>= 7; 64 if (Value != 0 || Padding != 0) 65 Byte |= 0x80; // Mark this byte to show that more bytes will follow. 66 *p++ = Byte; 67 } while (Value != 0); 68 69 // Pad with 0x80 and emit a null byte at the end. 70 if (Padding != 0) { 71 for (; Padding != 1; --Padding) 72 *p++ = '\x80'; 73 *p++ = '\x00'; 74 } 75 return (unsigned)(p - orig_p); 76} 77 78 79/// Utility function to decode a ULEB128 value. 80inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr) { 81 const uint8_t *orig_p = p; 82 uint64_t Value = 0; 83 unsigned Shift = 0; 84 do { 85 Value += (*p & 0x7f) << Shift; 86 Shift += 7; 87 } while (*p++ >= 128); 88 if (n) 89 *n = (unsigned)(p - orig_p); 90 return Value; 91} 92 93/// Utility function to get the size of the ULEB128-encoded value. 94extern unsigned getULEB128Size(uint64_t Value); 95 96/// Utility function to get the size of the SLEB128-encoded value. 97extern unsigned getSLEB128Size(int64_t Value); 98 99} // namespace llvm 100 101#endif // LLVM_SYSTEM_LEB128_H 102