1 /* Generic streaming support for basic data types. 2 3 Copyright (C) 2011-2024 Free Software Foundation, Inc. 4 Contributed by Diego Novillo <dnovillo (at) 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 117 /* Pack REAL_VALUE_TYPE R into BP. */ 118 119 void 120 bp_pack_real_value (struct bitpack_d *bp, const REAL_VALUE_TYPE *r) 121 { 122 bp_pack_value (bp, r->cl, 2); 123 bp_pack_value (bp, r->decimal, 1); 124 bp_pack_value (bp, r->sign, 1); 125 bp_pack_value (bp, r->signalling, 1); 126 bp_pack_value (bp, r->canonical, 1); 127 bp_pack_value (bp, r->uexp, EXP_BITS); 128 for (unsigned i = 0; i < SIGSZ; i++) 129 bp_pack_value (bp, r->sig[i], HOST_BITS_PER_LONG); 130 } 131 132 /* Unpack REAL_VALUE_TYPE R from BP. */ 133 134 void 135 bp_unpack_real_value (struct bitpack_d *bp, REAL_VALUE_TYPE *r) 136 { 137 /* Clear all bits of the real value type so that we can later do 138 bitwise comparisons to see if two values are the same. */ 139 memset (r, 0, sizeof (*r)); 140 r->cl = (unsigned) bp_unpack_value (bp, 2); 141 r->decimal = (unsigned) bp_unpack_value (bp, 1); 142 r->sign = (unsigned) bp_unpack_value (bp, 1); 143 r->signalling = (unsigned) bp_unpack_value (bp, 1); 144 r->canonical = (unsigned) bp_unpack_value (bp, 1); 145 r->uexp = (unsigned) bp_unpack_value (bp, EXP_BITS); 146 for (unsigned i = 0; i < SIGSZ; i++) 147 r->sig[i] = (unsigned long) bp_unpack_value (bp, HOST_BITS_PER_LONG); 148 } 149