]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/binutils/gas/frags.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / contrib / binutils / gas / frags.c
1 /* frags.c - manage frags -
2    Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 1998
3    Free Software Foundation, Inc.
4
5    This file is part of GAS, the GNU Assembler.
6
7    GAS is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11
12    GAS is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GAS; see the file COPYING.  If not, write to the Free
19    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 #include "as.h"
23 #include "subsegs.h"
24 #include "obstack.h"
25
26 extern fragS zero_address_frag;
27 extern fragS bss_address_frag;
28 \f
29 /* Initialization for frag routines.  */
30 void
31 frag_init ()
32 {
33   zero_address_frag.fr_type = rs_fill;
34   bss_address_frag.fr_type = rs_fill;
35 }
36 \f
37 /* Allocate a frag on the specified obstack.
38    Call this routine from everywhere else, so that all the weird alignment
39    hackery can be done in just one place.  */
40 fragS *
41 frag_alloc (ob)
42      struct obstack *ob;
43 {
44   fragS *ptr;
45   int oalign;
46
47   (void) obstack_alloc (ob, 0);
48   oalign = obstack_alignment_mask (ob);
49   obstack_alignment_mask (ob) = 0;
50   ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG);
51   obstack_alignment_mask (ob) = oalign;
52   memset (ptr, 0, SIZEOF_STRUCT_FRAG);
53   return ptr;
54 }
55 \f
56 /*
57  *                      frag_grow()
58  *
59  * Try to augment current frag by nchars chars.
60  * If there is no room, close of the current frag with a ".fill 0"
61  * and begin a new frag. Unless the new frag has nchars chars available
62  * do not return. Do not set up any fields of *now_frag.
63  */
64 void 
65 frag_grow (nchars)
66      unsigned int nchars;
67 {
68   if (obstack_room (&frchain_now->frch_obstack) < nchars)
69     {
70       unsigned int n, oldn;
71       long oldc;
72
73       frag_wane (frag_now);
74       frag_new (0);
75       oldn = (unsigned) -1;
76       oldc = frchain_now->frch_obstack.chunk_size;
77       frchain_now->frch_obstack.chunk_size = 2 * nchars;
78       while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars
79              && n < oldn)
80         {
81           frag_wane (frag_now);
82           frag_new (0);
83           oldn = n;
84         }
85       frchain_now->frch_obstack.chunk_size = oldc;
86     }
87   if (obstack_room (&frchain_now->frch_obstack) < nchars)
88     as_fatal ("Can't extend frag %d. chars", nchars);
89 }
90 \f
91 /*
92  *                      frag_new()
93  *
94  * Call this to close off a completed frag, and start up a new (empty)
95  * frag, in the same subsegment as the old frag.
96  * [frchain_now remains the same but frag_now is updated.]
97  * Because this calculates the correct value of fr_fix by
98  * looking at the obstack 'frags', it needs to know how many
99  * characters at the end of the old frag belong to (the maximal)
100  * fr_var: the rest must belong to fr_fix.
101  * It doesn't actually set up the old frag's fr_var: you may have
102  * set fr_var == 1, but allocated 10 chars to the end of the frag:
103  * in this case you pass old_frags_var_max_size == 10.
104  *
105  * Make a new frag, initialising some components. Link new frag at end
106  * of frchain_now.
107  */
108 void 
109 frag_new (old_frags_var_max_size)
110      /* Number of chars (already allocated on obstack frags) in
111         variable_length part of frag. */
112      int old_frags_var_max_size;
113 {
114   fragS *former_last_fragP;
115   frchainS *frchP;
116
117   assert (frchain_now->frch_last == frag_now);
118
119   /* Fix up old frag's fr_fix.  */
120   frag_now->fr_fix = frag_now_fix () - old_frags_var_max_size;
121   /* Make sure its type is valid.  */
122   assert (frag_now->fr_type != 0);
123
124   /* This will align the obstack so the next struct we allocate on it
125      will begin at a correct boundary. */
126   obstack_finish (&frchain_now->frch_obstack);
127   frchP = frchain_now;
128   know (frchP);
129   former_last_fragP = frchP->frch_last;
130   assert (former_last_fragP != 0);
131   assert (former_last_fragP == frag_now);
132   frag_now = frag_alloc (&frchP->frch_obstack);
133
134   as_where (&frag_now->fr_file, &frag_now->fr_line);
135
136   /* Generally, frag_now->points to an address rounded up to next
137      alignment.  However, characters will add to obstack frags
138      IMMEDIATELY after the struct frag, even if they are not starting
139      at an alignment address. */
140   former_last_fragP->fr_next = frag_now;
141   frchP->frch_last = frag_now;
142
143 #ifndef NO_LISTING
144   {
145     extern struct list_info_struct *listing_tail;
146     frag_now->line = listing_tail;
147   }
148 #endif
149
150   assert (frchain_now->frch_last == frag_now);
151
152   frag_now->fr_next = NULL;
153 }                               /* frag_new() */
154 \f
155 /*
156  *                      frag_more()
157  *
158  * Start a new frag unless we have n more chars of room in the current frag.
159  * Close off the old frag with a .fill 0.
160  *
161  * Return the address of the 1st char to write into. Advance
162  * frag_now_growth past the new chars.
163  */
164
165 char *
166 frag_more (nchars)
167      int nchars;
168 {
169   register char *retval;
170
171   if (now_seg == absolute_section)
172     {
173       as_bad ("attempt to allocate data in absolute section");
174       subseg_set (text_section, 0);
175     }
176
177   if (mri_common_symbol != NULL)
178     {
179       as_bad ("attempt to allocate data in common section");
180       mri_common_symbol = NULL;
181     }
182
183   frag_grow (nchars);
184   retval = obstack_next_free (&frchain_now->frch_obstack);
185   obstack_blank_fast (&frchain_now->frch_obstack, nchars);
186   return (retval);
187 }                               /* frag_more() */
188 \f
189 /*
190  *                      frag_var()
191  *
192  * Start a new frag unless we have max_chars more chars of room in the current frag.
193  * Close off the old frag with a .fill 0.
194  *
195  * Set up a machine_dependent relaxable frag, then start a new frag.
196  * Return the address of the 1st char of the var part of the old frag
197  * to write into.
198  */
199
200 char *
201 frag_var (type, max_chars, var, subtype, symbol, offset, opcode)
202      relax_stateT type;
203      int max_chars;
204      int var;
205      relax_substateT subtype;
206      symbolS *symbol;
207      offsetT offset;
208      char *opcode;
209 {
210   register char *retval;
211
212   frag_grow (max_chars);
213   retval = obstack_next_free (&frchain_now->frch_obstack);
214   obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
215   frag_now->fr_var = var;
216   frag_now->fr_type = type;
217   frag_now->fr_subtype = subtype;
218   frag_now->fr_symbol = symbol;
219   frag_now->fr_offset = offset;
220   frag_now->fr_opcode = opcode;
221 #ifdef TC_FRAG_INIT
222   TC_FRAG_INIT (frag_now);
223 #endif
224   as_where (&frag_now->fr_file, &frag_now->fr_line);
225   frag_new (max_chars);
226   return (retval);
227 }
228 \f
229 /*
230  *                      frag_variant()
231  *
232  * OVE: This variant of frag_var assumes that space for the tail has been
233  *      allocated by caller.
234  *      No call to frag_grow is done.
235  */
236
237 char *
238 frag_variant (type, max_chars, var, subtype, symbol, offset, opcode)
239      relax_stateT type;
240      int max_chars;
241      int var;
242      relax_substateT subtype;
243      symbolS *symbol;
244      offsetT offset;
245      char *opcode;
246 {
247   register char *retval;
248
249   retval = obstack_next_free (&frchain_now->frch_obstack);
250   frag_now->fr_var = var;
251   frag_now->fr_type = type;
252   frag_now->fr_subtype = subtype;
253   frag_now->fr_symbol = symbol;
254   frag_now->fr_offset = offset;
255   frag_now->fr_opcode = opcode;
256 #ifdef TC_FRAG_INIT
257   TC_FRAG_INIT (frag_now);
258 #endif
259   as_where (&frag_now->fr_file, &frag_now->fr_line);
260   frag_new (max_chars);
261   return (retval);
262 }                               /* frag_variant() */
263 \f
264 /*
265  *                      frag_wane()
266  *
267  * Reduce the variable end of a frag to a harmless state.
268  */
269 void 
270 frag_wane (fragP)
271      register fragS *fragP;
272 {
273   fragP->fr_type = rs_fill;
274   fragP->fr_offset = 0;
275   fragP->fr_var = 0;
276 }
277 \f
278 /* Make an alignment frag.  The size of this frag will be adjusted to
279    force the next frag to have the appropriate alignment.  ALIGNMENT
280    is the power of two to which to align.  FILL_CHARACTER is the
281    character to use to fill in any bytes which are skipped.  MAX is
282    the maximum number of characters to skip when doing the alignment,
283    or 0 if there is no maximum.  */
284
285 void 
286 frag_align (alignment, fill_character, max)
287      int alignment;
288      int fill_character;
289      int max;
290 {
291   if (now_seg == absolute_section)
292     {
293       addressT new_off;
294
295       new_off = ((abs_section_offset + alignment - 1)
296                  &~ ((1 << alignment) - 1));
297       if (max == 0 || new_off - abs_section_offset <= (addressT) max)
298         abs_section_offset = new_off;
299     }
300   else
301     {
302       char *p;
303
304       p = frag_var (rs_align, 1, 1, (relax_substateT) max,
305                     (symbolS *) 0, (offsetT) alignment, (char *) 0);
306       *p = fill_character;
307     }
308 }
309
310 /* Make an alignment frag like frag_align, but fill with a repeating
311    pattern rather than a single byte.  ALIGNMENT is the power of two
312    to which to align.  FILL_PATTERN is the fill pattern to repeat in
313    the bytes which are skipped.  N_FILL is the number of bytes in
314    FILL_PATTERN.  MAX is the maximum number of characters to skip when
315    doing the alignment, or 0 if there is no maximum.  */
316
317 void 
318 frag_align_pattern (alignment, fill_pattern, n_fill, max)
319      int alignment;
320      const char *fill_pattern;
321      int n_fill;
322      int max;
323 {
324   char *p;
325
326   p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
327                 (symbolS *) 0, (offsetT) alignment, (char *) 0);
328   memcpy (p, fill_pattern, n_fill);
329 }
330
331 addressT
332 frag_now_fix ()
333 {
334   if (now_seg == absolute_section)
335     return abs_section_offset;
336   return (addressT) ((char*) obstack_next_free (&frchain_now->frch_obstack)
337                      - frag_now->fr_literal);
338 }
339
340 void
341 frag_append_1_char (datum)
342      int datum;
343 {
344   if (obstack_room (&frchain_now->frch_obstack) <= 1)
345     {
346       frag_wane (frag_now);
347       frag_new (0);
348     }
349   obstack_1grow (&frchain_now->frch_obstack, datum);
350 }
351
352 /* end of frags.c */