Home | History | Annotate | Line # | Download | only in gcc
      1 /* Generic streaming support for basic data types.
      2 
      3    Copyright (C) 2011-2022 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