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