OSDN Git Service

* gcc.target/i386/sse-22a.c: New test.
[pf3gnuchains/gcc-fork.git] / gcc / data-streamer.h
1 /* Generic streaming support for various data types.
2
3    Copyright 2011 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 #ifndef GCC_DATA_STREAMER_H
23 #define GCC_DATA_STREAMER_H
24
25 #include "vec.h"
26 #include "lto-streamer.h"
27
28 /* Data structures used to pack values and bitflags into a vector of
29    words.  Used to stream values of a fixed number of bits in a space
30    efficient way.  */
31 static unsigned const BITS_PER_BITPACK_WORD = HOST_BITS_PER_WIDE_INT;
32
33 typedef unsigned HOST_WIDE_INT bitpack_word_t;
34 DEF_VEC_I(bitpack_word_t);
35 DEF_VEC_ALLOC_I(bitpack_word_t, heap);
36
37 struct bitpack_d
38 {
39   /* The position of the first unused or unconsumed bit in the word.  */
40   unsigned pos;
41
42   /* The current word we are (un)packing.  */
43   bitpack_word_t word;
44
45   /* The lto_output_stream or the lto_input_block we are streaming to/from.  */
46   void *stream;
47 };
48
49
50 /* String hashing.  */
51 struct string_slot
52 {
53   const char *s;
54   int len;
55   unsigned int slot_num;
56 };
57
58
59 /* Returns a hash code for P.  Adapted from libiberty's htab_hash_string
60    to support strings that may not end in '\0'.  */
61
62 static inline hashval_t
63 hash_string_slot_node (const void *p)
64 {
65   const struct string_slot *ds = (const struct string_slot *) p;
66   hashval_t r = ds->len;
67   int i;
68
69   for (i = 0; i < ds->len; i++)
70      r = r * 67 + (unsigned)ds->s[i] - 113;
71   return r;
72 }
73
74 /* Returns nonzero if P1 and P2 are equal.  */
75
76 static inline int
77 eq_string_slot_node (const void *p1, const void *p2)
78 {
79   const struct string_slot *ds1 = (const struct string_slot *) p1;
80   const struct string_slot *ds2 = (const struct string_slot *) p2;
81
82   if (ds1->len == ds2->len)
83     return memcmp (ds1->s, ds2->s, ds1->len) == 0;
84
85   return 0;
86 }
87
88 /* Returns a new bit-packing context for bit-packing into S.  */
89 static inline struct bitpack_d
90 bitpack_create (struct lto_output_stream *s)
91 {
92   struct bitpack_d bp;
93   bp.pos = 0;
94   bp.word = 0;
95   bp.stream = (void *)s;
96   return bp;
97 }
98
99 /* Pack the NBITS bit sized value VAL into the bit-packing context BP.  */
100 static inline void
101 bp_pack_value (struct bitpack_d *bp, bitpack_word_t val, unsigned nbits)
102 {
103   bitpack_word_t word = bp->word;
104   int pos = bp->pos;
105
106   /* Verify that VAL fits in the NBITS.  */
107   gcc_checking_assert (nbits == BITS_PER_BITPACK_WORD
108                        || !(val & ~(((bitpack_word_t)1<<nbits)-1)));
109
110   /* If val does not fit into the current bitpack word switch to the
111      next one.  */
112   if (pos + nbits > BITS_PER_BITPACK_WORD)
113     {
114       lto_output_uleb128_stream ((struct lto_output_stream *) bp->stream, word);
115       word = val;
116       pos = nbits;
117     }
118   else
119     {
120       word |= val << pos;
121       pos += nbits;
122     }
123   bp->word = word;
124   bp->pos = pos;
125 }
126
127 /* Finishes bit-packing of BP.  */
128 static inline void
129 lto_output_bitpack (struct bitpack_d *bp)
130 {
131   lto_output_uleb128_stream ((struct lto_output_stream *) bp->stream,
132                              bp->word);
133   bp->word = 0;
134   bp->pos = 0;
135 }
136
137 /* Returns a new bit-packing context for bit-unpacking from IB.  */
138 static inline struct bitpack_d
139 lto_input_bitpack (struct lto_input_block *ib)
140 {
141   struct bitpack_d bp;
142   bp.word = lto_input_uleb128 (ib);
143   bp.pos = 0;
144   bp.stream = (void *)ib;
145   return bp;
146 }
147
148 /* Unpacks NBITS bits from the bit-packing context BP and returns them.  */
149 static inline bitpack_word_t
150 bp_unpack_value (struct bitpack_d *bp, unsigned nbits)
151 {
152   bitpack_word_t mask, val;
153   int pos = bp->pos;
154
155   mask = (nbits == BITS_PER_BITPACK_WORD
156           ? (bitpack_word_t) -1
157           : ((bitpack_word_t) 1 << nbits) - 1);
158
159   /* If there are not continuous nbits in the current bitpack word
160      switch to the next one.  */
161   if (pos + nbits > BITS_PER_BITPACK_WORD)
162     {
163       bp->word = val = lto_input_uleb128 ((struct lto_input_block *)bp->stream);
164       bp->pos = nbits;
165       return val & mask;
166     }
167   val = bp->word;
168   val >>= pos;
169   bp->pos = pos + nbits;
170
171   return val & mask;
172 }
173
174
175 /* Write a character to the output block.  */
176
177 static inline void
178 lto_output_1_stream (struct lto_output_stream *obs, char c)
179 {
180   /* No space left.  */
181   if (obs->left_in_block == 0)
182     lto_append_block (obs);
183
184   /* Write the actual character.  */
185   *obs->current_pointer = c;
186   obs->current_pointer++;
187   obs->total_size++;
188   obs->left_in_block--;
189 }
190
191
192 /* Read byte from the input block.  */
193
194 static inline unsigned char
195 lto_input_1_unsigned (struct lto_input_block *ib)
196 {
197   if (ib->p >= ib->len)
198     lto_section_overrun (ib);
199   return (ib->data[ib->p++]);
200 }
201
202 /* Output VAL into OBS and verify it is in range MIN...MAX that is supposed
203    to be compile time constant.
204    Be host independent, limit range to 31bits.  */
205
206 static inline void
207 lto_output_int_in_range (struct lto_output_stream *obs,
208                          HOST_WIDE_INT min,
209                          HOST_WIDE_INT max,
210                          HOST_WIDE_INT val)
211 {
212   HOST_WIDE_INT range = max - min;
213
214   gcc_checking_assert (val >= min && val <= max && range > 0
215                        && range < 0x7fffffff);
216
217   val -= min;
218   lto_output_1_stream (obs, val & 255);
219   if (range >= 0xff)
220     lto_output_1_stream (obs, (val >> 8) & 255);
221   if (range >= 0xffff)
222     lto_output_1_stream (obs, (val >> 16) & 255);
223   if (range >= 0xffffff)
224     lto_output_1_stream (obs, (val >> 24) & 255);
225 }
226
227 /* Input VAL into OBS and verify it is in range MIN...MAX that is supposed
228    to be compile time constant.  PURPOSE is used for error reporting.  */
229
230 static inline HOST_WIDE_INT
231 lto_input_int_in_range (struct lto_input_block *ib,
232                         const char *purpose,
233                         HOST_WIDE_INT min,
234                         HOST_WIDE_INT max)
235 {
236   HOST_WIDE_INT range = max - min;
237   HOST_WIDE_INT val = lto_input_1_unsigned (ib);
238
239   gcc_checking_assert (range > 0 && range < 0x7fffffff);
240
241   if (range >= 0xff)
242     val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 8;
243   if (range >= 0xffff)
244     val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 16;
245   if (range >= 0xffffff)
246     val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 24;
247   val += min;
248   if (val < min || val > max)
249     lto_value_range_error (purpose, val, min, max);
250   return val;
251 }
252
253 /* Output VAL into BP and verify it is in range MIN...MAX that is supposed
254    to be compile time constant.
255    Be host independent, limit range to 31bits.  */
256
257 static inline void
258 bp_pack_int_in_range (struct bitpack_d *bp,
259                       HOST_WIDE_INT min,
260                       HOST_WIDE_INT max,
261                       HOST_WIDE_INT val)
262 {
263   HOST_WIDE_INT range = max - min;
264   int nbits = floor_log2 (range) + 1;
265
266   gcc_checking_assert (val >= min && val <= max && range > 0
267                        && range < 0x7fffffff);
268
269   val -= min;
270   bp_pack_value (bp, val, nbits);
271 }
272
273 /* Input VAL into BP and verify it is in range MIN...MAX that is supposed
274    to be compile time constant.  PURPOSE is used for error reporting.  */
275
276 static inline HOST_WIDE_INT
277 bp_unpack_int_in_range (struct bitpack_d *bp,
278                         const char *purpose,
279                         HOST_WIDE_INT min,
280                         HOST_WIDE_INT max)
281 {
282   HOST_WIDE_INT range = max - min;
283   int nbits = floor_log2 (range) + 1;
284   HOST_WIDE_INT val = bp_unpack_value (bp, nbits);
285
286   gcc_checking_assert (range > 0 && range < 0x7fffffff);
287
288   if (val < min || val > max)
289     lto_value_range_error (purpose, val, min, max);
290   return val;
291 }
292
293 /* Output VAL of type "enum enum_name" into OBS.
294    Assume range 0...ENUM_LAST - 1.  */
295 #define lto_output_enum(obs,enum_name,enum_last,val) \
296   lto_output_int_in_range ((obs), 0, (int)(enum_last) - 1, (int)(val))
297
298 /* Input enum of type "enum enum_name" from IB.
299    Assume range 0...ENUM_LAST - 1.  */
300 #define lto_input_enum(ib,enum_name,enum_last) \
301   (enum enum_name)lto_input_int_in_range ((ib), #enum_name, 0, \
302                                           (int)(enum_last) - 1)
303
304 /* Output VAL of type "enum enum_name" into BP.
305    Assume range 0...ENUM_LAST - 1.  */
306 #define bp_pack_enum(bp,enum_name,enum_last,val) \
307   bp_pack_int_in_range ((bp), 0, (int)(enum_last) - 1, (int)(val))
308
309 /* Input enum of type "enum enum_name" from BP.
310    Assume range 0...ENUM_LAST - 1.  */
311 #define bp_unpack_enum(bp,enum_name,enum_last) \
312   (enum enum_name)bp_unpack_int_in_range ((bp), #enum_name, 0, \
313                                         (int)(enum_last) - 1)
314
315 /* Output the start of a record with TAG to output block OB.  */
316
317 static inline void
318 output_record_start (struct output_block *ob, enum LTO_tags tag)
319 {
320   lto_output_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS, tag);
321 }
322
323 /* Return the next tag in the input block IB.  */
324
325 static inline enum LTO_tags
326 input_record_start (struct lto_input_block *ib)
327 {
328   return lto_input_enum (ib, LTO_tags, LTO_NUM_TAGS);
329 }
330
331 /* In data-streamer.c  */
332 void bp_pack_var_len_unsigned (struct bitpack_d *, unsigned HOST_WIDE_INT);
333 void bp_pack_var_len_int (struct bitpack_d *, HOST_WIDE_INT);
334 unsigned HOST_WIDE_INT bp_unpack_var_len_unsigned (struct bitpack_d *);
335 HOST_WIDE_INT bp_unpack_var_len_int (struct bitpack_d *);
336
337 /* In data-streamer-out.c  */
338 void output_zero (struct output_block *);
339 void output_uleb128 (struct output_block *, unsigned HOST_WIDE_INT);
340 void output_sleb128 (struct output_block *, HOST_WIDE_INT);
341 void lto_output_string (struct output_block *, struct lto_output_stream *,
342                         const char *, bool);
343 unsigned lto_string_index (struct output_block *, const char *, unsigned int,
344                            bool);
345 void lto_output_string_with_length (struct output_block *,
346                                     struct lto_output_stream *,
347                                     const char *, unsigned int, bool);
348 const char *input_string_internal (struct data_in *, struct lto_input_block *,
349                                    unsigned int *);
350
351 /* In data-streamer-in.c  */
352 const char *string_for_index (struct data_in *, unsigned int, unsigned int *);
353 const char *lto_input_string (struct data_in *, struct lto_input_block *);
354
355 #endif  /* GCC_DATA_STREAMER_H  */