1 /* Generic streaming support for basic data types. 2 3 Copyright (C) 2011-2018 Free Software Foundation, Inc. 4 Contributed by Diego Novillo <dnovillo@google.com> 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 3, or (at your option) any later 11 version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22 #include "config.h" 23 #include "system.h" 24 #include "coretypes.h" 25 #include "backend.h" 26 #include "tree.h" 27 #include "gimple.h" 28 #include "cgraph.h" 29 #include "data-streamer.h" 30 31 /* Pack WORK into BP in a variant of uleb format. */ 32 33 void 34 bp_pack_var_len_unsigned (struct bitpack_d *bp, unsigned HOST_WIDE_INT work) 35 { 36 do 37 { 38 unsigned int half_byte = (work & 0x7); 39 work >>= 3; 40 if (work != 0) 41 /* More half_bytes to follow. */ 42 half_byte |= 0x8; 43 44 bp_pack_value (bp, half_byte, 4); 45 } 46 while (work != 0); 47 } 48 49 50 /* Pack WORK into BP in a variant of sleb format. */ 51 52 void 53 bp_pack_var_len_int (struct bitpack_d *bp, HOST_WIDE_INT work) 54 { 55 int more, half_byte; 56 57 do 58 { 59 half_byte = (work & 0x7); 60 /* arithmetic shift */ 61 work >>= 3; 62 more = !((work == 0 && (half_byte & 0x4) == 0) 63 || (work == -1 && (half_byte & 0x4) != 0)); 64 if (more) 65 half_byte |= 0x8; 66 67 bp_pack_value (bp, half_byte, 4); 68 } 69 while (more); 70 } 71 72 73 /* Unpack VAL from BP in a variant of uleb format. */ 74 75 unsigned HOST_WIDE_INT 76 bp_unpack_var_len_unsigned (struct bitpack_d *bp) 77 { 78 unsigned HOST_WIDE_INT result = 0; 79 int shift = 0; 80 unsigned HOST_WIDE_INT half_byte; 81 82 while (true) 83 { 84 half_byte = bp_unpack_value (bp, 4); 85 result |= (half_byte & 0x7) << shift; 86 shift += 3; 87 if ((half_byte & 0x8) == 0) 88 return result; 89 } 90 } 91 92 93 /* Unpack VAL from BP in a variant of sleb format. */ 94 95 HOST_WIDE_INT 96 bp_unpack_var_len_int (struct bitpack_d *bp) 97 { 98 HOST_WIDE_INT result = 0; 99 int shift = 0; 100 unsigned HOST_WIDE_INT half_byte; 101 102 while (true) 103 { 104 half_byte = bp_unpack_value (bp, 4); 105 result |= (half_byte & 0x7) << shift; 106 shift += 3; 107 if ((half_byte & 0x8) == 0) 108 { 109 if ((shift < HOST_BITS_PER_WIDE_INT) && (half_byte & 0x4)) 110 result |= - (HOST_WIDE_INT_1U << shift); 111 112 return result; 113 } 114 } 115 } 116