]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/frags.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / gas / frags.c
CommitLineData
fecd2382 1/* frags.c - manage frags -
1356d77d
ILT
2
3 Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
4
a39116f1 5 This file is part of GAS, the GNU Assembler.
1356d77d 6
a39116f1
RP
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.
1356d77d 11
a39116f1
RP
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.
1356d77d 16
a39116f1
RP
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
1356d77d 19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
fecd2382
RP
20
21#include "as.h"
22#include "subsegs.h"
23#include "obstack.h"
24
1356d77d 25struct obstack frags; /* All, and only, frags live here. */
fecd2382 26
1356d77d
ILT
27extern fragS zero_address_frag;
28extern fragS bss_address_frag;
29\f
30/* Initialization for frag routines. */
31void
32frag_init ()
33{
34 zero_address_frag.fr_type = rs_fill;
35 bss_address_frag.fr_type = rs_fill;
36 obstack_begin (&frags, 5000);
37}
fecd2382
RP
38\f
39/*
40 * frag_grow()
41 *
fecd2382
RP
42 * Try to augment current frag by nchars chars.
43 * If there is no room, close of the current frag with a ".fill 0"
44 * and begin a new frag. Unless the new frag has nchars chars available
45 * do not return. Do not set up any fields of *now_frag.
46 */
1356d77d
ILT
47void
48frag_grow (nchars)
49 unsigned int nchars;
fecd2382 50{
1356d77d
ILT
51 if (obstack_room (&frags) < nchars)
52 {
53 unsigned int n, oldn;
54 long oldc;
55
56 frag_wane (frag_now);
57 frag_new (0);
58 oldn = (unsigned) -1;
59 oldc = frags.chunk_size;
60 frags.chunk_size = 2 * nchars;
61 while ((n = obstack_room (&frags)) < nchars && n < oldn)
62 {
63 frag_wane (frag_now);
64 frag_new (0);
65 oldn = n;
fecd2382 66 }
1356d77d
ILT
67 frags.chunk_size = oldc;
68 }
69 if (obstack_room (&frags) < nchars)
70 as_fatal ("Can't extend frag %d. chars", nchars);
71} /* frag_grow() */
fecd2382
RP
72\f
73/*
74 * frag_new()
75 *
76 * Call this to close off a completed frag, and start up a new (empty)
77 * frag, in the same subsegment as the old frag.
78 * [frchain_now remains the same but frag_now is updated.]
79 * Because this calculates the correct value of fr_fix by
80 * looking at the obstack 'frags', it needs to know how many
81 * characters at the end of the old frag belong to (the maximal)
82 * fr_var: the rest must belong to fr_fix.
83 * It doesn't actually set up the old frag's fr_var: you may have
84 * set fr_var == 1, but allocated 10 chars to the end of the frag:
85 * in this case you pass old_frags_var_max_size == 10.
86 *
87 * Make a new frag, initialising some components. Link new frag at end
88 * of frchain_now.
89 */
1356d77d
ILT
90void
91frag_new (old_frags_var_max_size)
92 int old_frags_var_max_size;/* Number of chars (already allocated on
fecd2382 93 obstack frags) */
1356d77d 94 /* in variable_length part of frag. */
fecd2382 95{
1356d77d
ILT
96 register fragS *former_last_fragP;
97 register frchainS *frchP;
98 long tmp;
99
100 frag_now->fr_fix = frag_now_fix () - old_frags_var_max_size;
101 /* Fix up old frag's fr_fix. */
102
103 obstack_finish (&frags);
104 /* This will align the obstack so the next struct we allocate on it
105 will begin at a correct boundary. */
106 frchP = frchain_now;
107 know (frchP);
108 former_last_fragP = frchP->frch_last;
109 know (former_last_fragP);
110 know (former_last_fragP == frag_now);
111 obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
112 /* We expect this will begin at a correct boundary for a struct. */
113 tmp = obstack_alignment_mask (&frags);
114 obstack_alignment_mask (&frags) = 0; /* Turn off alignment */
115 /* If we ever hit a machine where strings must be aligned, we Lose
116 Big. */
117 frag_now = (fragS *) obstack_finish (&frags);
118 obstack_alignment_mask (&frags) = tmp; /* Restore alignment */
119
120 /* Just in case we don't get zero'd bytes */
121 memset (frag_now, '\0', SIZEOF_STRUCT_FRAG);
122
123 /* Generally, frag_now->points to an address rounded up to next
124 alignment. However, characters will add to obstack frags
125 IMMEDIATELY after the struct frag, even if they are not starting
126 at an alignment address. */
127 former_last_fragP->fr_next = frag_now;
128 frchP->frch_last = frag_now;
129
a39116f1 130#ifndef NO_LISTING
1356d77d
ILT
131 {
132 extern struct list_info_struct *listing_tail;
133 frag_now->line = listing_tail;
134 }
a39116f1 135#endif
1356d77d
ILT
136
137 frag_now->fr_next = NULL;
fecd2382
RP
138} /* frag_new() */
139\f
140/*
141 * frag_more()
142 *
143 * Start a new frag unless we have n more chars of room in the current frag.
144 * Close off the old frag with a .fill 0.
145 *
146 * Return the address of the 1st char to write into. Advance
147 * frag_now_growth past the new chars.
148 */
149
1356d77d
ILT
150char *
151frag_more (nchars)
152 int nchars;
fecd2382 153{
1356d77d
ILT
154 register char *retval;
155
a2acbf8d
ILT
156 if (now_seg == absolute_section)
157 {
158 as_bad ("attempt to allocate data in absolute section");
159 subseg_set (text_section, 0);
160 }
161
1356d77d
ILT
162 if (mri_common_symbol != NULL)
163 {
164 as_bad ("attempt to allocate data in common section");
165 mri_common_symbol = NULL;
166 }
167
168 frag_grow (nchars);
169 retval = obstack_next_free (&frags);
170 obstack_blank_fast (&frags, nchars);
171 return (retval);
fecd2382
RP
172} /* frag_more() */
173\f
174/*
175 * frag_var()
176 *
177 * Start a new frag unless we have max_chars more chars of room in the current frag.
178 * Close off the old frag with a .fill 0.
179 *
180 * Set up a machine_dependent relaxable frag, then start a new frag.
181 * Return the address of the 1st char of the var part of the old frag
182 * to write into.
183 */
184
1356d77d
ILT
185char *
186frag_var (type, max_chars, var, subtype, symbol, offset, opcode)
187 relax_stateT type;
188 int max_chars;
189 int var;
190 relax_substateT subtype;
191 symbolS *symbol;
192 long offset;
193 char *opcode;
fecd2382 194{
1356d77d
ILT
195 register char *retval;
196
197 frag_grow (max_chars);
198 retval = obstack_next_free (&frags);
199 obstack_blank_fast (&frags, max_chars);
200 frag_now->fr_var = var;
201 frag_now->fr_type = type;
202 frag_now->fr_subtype = subtype;
203 frag_now->fr_symbol = symbol;
204 frag_now->fr_offset = offset;
205 frag_now->fr_opcode = opcode;
206 /* default these to zero. */
207 frag_now->fr_pcrel_adjust = 0;
208 frag_now->fr_bsr = 0;
209 frag_new (max_chars);
210 return (retval);
211}
fecd2382
RP
212\f
213/*
214 * frag_variant()
215 *
216 * OVE: This variant of frag_var assumes that space for the tail has been
217 * allocated by caller.
218 * No call to frag_grow is done.
219 * Two new arguments have been added.
220 */
221
1356d77d
ILT
222char *
223frag_variant (type, max_chars, var, subtype, symbol, offset, opcode)
224 relax_stateT type;
225 int max_chars;
226 int var;
227 relax_substateT subtype;
228 symbolS *symbol;
229 long offset;
230 char *opcode;
fecd2382 231{
1356d77d
ILT
232 register char *retval;
233
234 retval = obstack_next_free (&frags);
235 frag_now->fr_var = var;
236 frag_now->fr_type = type;
237 frag_now->fr_subtype = subtype;
238 frag_now->fr_symbol = symbol;
239 frag_now->fr_offset = offset;
240 frag_now->fr_opcode = opcode;
241 frag_now->fr_pcrel_adjust = 0;
242 frag_now->fr_bsr = 0;
243 frag_new (max_chars);
244 return (retval);
fecd2382
RP
245} /* frag_variant() */
246\f
247/*
248 * frag_wane()
249 *
250 * Reduce the variable end of a frag to a harmless state.
251 */
1356d77d
ILT
252void
253frag_wane (fragP)
254 register fragS *fragP;
fecd2382 255{
1356d77d
ILT
256 fragP->fr_type = rs_fill;
257 fragP->fr_offset = 0;
258 fragP->fr_var = 0;
fecd2382
RP
259}
260\f
261/*
262 * frag_align()
263 *
264 * Make a frag for ".align foo,bar". Call is "frag_align (foo,bar);".
265 * Foo & bar are absolute integers.
266 *
267 * Call to close off the current frag with a ".align", then start a new
268 * (so far empty) frag, in the same subsegment as the last frag.
269 */
270
1356d77d
ILT
271void
272frag_align (alignment, fill_character)
273 int alignment;
274 int fill_character;
fecd2382 275{
1356d77d
ILT
276 char *p;
277 p = frag_var (rs_align, 1, 1, (relax_substateT) 0,
278 (symbolS *) 0, (long) alignment, (char *) 0);
279 *p = fill_character;
280}
281
282void
283frag_align_pattern (alignment, fill_pattern, n_fill)
284 int alignment;
285 const char *fill_pattern;
286 int n_fill;
287{
288 char *p;
289 p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) 0,
290 (symbolS *) 0, (long) alignment, (char *) 0);
291 memcpy (p, fill_pattern, n_fill);
292}
293
294int
295frag_now_fix ()
296{
a2acbf8d
ILT
297 if (now_seg == absolute_section)
298 return abs_section_offset;
1356d77d
ILT
299 return (char*)obstack_next_free (&frags) - frag_now->fr_literal;
300}
301
302void
303frag_append_1_char (datum)
304 int datum;
305{
306 if (obstack_room (&frags) <= 1)
307 {
308 frag_wane (frag_now);
309 frag_new (0);
310 }
311 obstack_1grow (&frags, datum);
312}
fecd2382 313
8b228fe9 314/* end of frags.c */