LLVM API Documentation
00001 //===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares some utility functions for encoding SLEB128 and 00011 // ULEB128 values. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_SUPPORT_LEB128_H 00016 #define LLVM_SUPPORT_LEB128_H 00017 00018 #include "llvm/Support/raw_ostream.h" 00019 00020 namespace llvm { 00021 00022 /// Utility function to encode a SLEB128 value to an output stream. 00023 inline void encodeSLEB128(int64_t Value, raw_ostream &OS) { 00024 bool More; 00025 do { 00026 uint8_t Byte = Value & 0x7f; 00027 // NOTE: this assumes that this signed shift is an arithmetic right shift. 00028 Value >>= 7; 00029 More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || 00030 ((Value == -1) && ((Byte & 0x40) != 0)))); 00031 if (More) 00032 Byte |= 0x80; // Mark this byte to show that more bytes will follow. 00033 OS << char(Byte); 00034 } while (More); 00035 } 00036 00037 /// Utility function to encode a ULEB128 value to an output stream. 00038 inline void encodeULEB128(uint64_t Value, raw_ostream &OS, 00039 unsigned Padding = 0) { 00040 do { 00041 uint8_t Byte = Value & 0x7f; 00042 Value >>= 7; 00043 if (Value != 0 || Padding != 0) 00044 Byte |= 0x80; // Mark this byte to show that more bytes will follow. 00045 OS << char(Byte); 00046 } while (Value != 0); 00047 00048 // Pad with 0x80 and emit a null byte at the end. 00049 if (Padding != 0) { 00050 for (; Padding != 1; --Padding) 00051 OS << '\x80'; 00052 OS << '\x00'; 00053 } 00054 } 00055 00056 /// Utility function to encode a ULEB128 value to a buffer. Returns 00057 /// the length in bytes of the encoded value. 00058 inline unsigned encodeULEB128(uint64_t Value, uint8_t *p, 00059 unsigned Padding = 0) { 00060 uint8_t *orig_p = p; 00061 do { 00062 uint8_t Byte = Value & 0x7f; 00063 Value >>= 7; 00064 if (Value != 0 || Padding != 0) 00065 Byte |= 0x80; // Mark this byte to show that more bytes will follow. 00066 *p++ = Byte; 00067 } while (Value != 0); 00068 00069 // Pad with 0x80 and emit a null byte at the end. 00070 if (Padding != 0) { 00071 for (; Padding != 1; --Padding) 00072 *p++ = '\x80'; 00073 *p++ = '\x00'; 00074 } 00075 return (unsigned)(p - orig_p); 00076 } 00077 00078 00079 /// Utility function to decode a ULEB128 value. 00080 inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr) { 00081 const uint8_t *orig_p = p; 00082 uint64_t Value = 0; 00083 unsigned Shift = 0; 00084 do { 00085 Value += uint64_t(*p & 0x7f) << Shift; 00086 Shift += 7; 00087 } while (*p++ >= 128); 00088 if (n) 00089 *n = (unsigned)(p - orig_p); 00090 return Value; 00091 } 00092 00093 /// Utility function to decode a SLEB128 value. 00094 inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr) { 00095 const uint8_t *orig_p = p; 00096 int64_t Value = 0; 00097 unsigned Shift = 0; 00098 uint8_t Byte; 00099 do { 00100 Byte = *p++; 00101 Value |= ((Byte & 0x7f) << Shift); 00102 Shift += 7; 00103 } while (Byte >= 128); 00104 // Sign extend negative numbers. 00105 if (Byte & 0x40) 00106 Value |= (-1ULL) << Shift; 00107 if (n) 00108 *n = (unsigned)(p - orig_p); 00109 return Value; 00110 } 00111 00112 00113 /// Utility function to get the size of the ULEB128-encoded value. 00114 extern unsigned getULEB128Size(uint64_t Value); 00115 00116 /// Utility function to get the size of the SLEB128-encoded value. 00117 extern unsigned getSLEB128Size(int64_t Value); 00118 00119 } // namespace llvm 00120 00121 #endif // LLVM_SYSTEM_LEB128_H