OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gas/] [frags.c] - Blame information for rev 856

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* frags.c - manage frags -
2
   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3
   1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GAS, the GNU Assembler.
7
 
8
   GAS is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
 
13
   GAS is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with GAS; see the file COPYING.  If not, write to the Free
20
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
22
 
23
#include "as.h"
24
#include "subsegs.h"
25
#include "obstack.h"
26
 
27
extern fragS zero_address_frag;
28
extern fragS bss_address_frag;
29
 
30
/* Initialization for frag routines.  */
31
 
32
void
33
frag_init (void)
34
{
35
  zero_address_frag.fr_type = rs_fill;
36
  bss_address_frag.fr_type = rs_fill;
37
}
38
 
39
/* Check that we're not trying to assemble into a section that can't
40
   allocate frags (currently, this is only possible in the absolute
41
   section), or into an mri common.  */
42
 
43
static void
44
frag_alloc_check (const struct obstack *ob)
45
{
46
  if (ob->chunk_size == 0)
47
    {
48
      as_bad (_("attempt to allocate data in absolute section"));
49
      subseg_set (text_section, 0);
50
    }
51
 
52
  if (mri_common_symbol != NULL)
53
    {
54
      as_bad (_("attempt to allocate data in common section"));
55
      mri_common_symbol = NULL;
56
    }
57
}
58
 
59
/* Allocate a frag on the specified obstack.
60
   Call this routine from everywhere else, so that all the weird alignment
61
   hackery can be done in just one place.  */
62
 
63
fragS *
64
frag_alloc (struct obstack *ob)
65
{
66
  fragS *ptr;
67
  int oalign;
68
 
69
  (void) obstack_alloc (ob, 0);
70
  oalign = obstack_alignment_mask (ob);
71
  obstack_alignment_mask (ob) = 0;
72
  ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG);
73
  obstack_alignment_mask (ob) = oalign;
74
  memset (ptr, 0, SIZEOF_STRUCT_FRAG);
75
  return ptr;
76
}
77
 
78
/* Try to augment current frag by nchars chars.
79
   If there is no room, close of the current frag with a ".fill 0"
80
   and begin a new frag. Unless the new frag has nchars chars available
81
   do not return. Do not set up any fields of *now_frag.  */
82
 
83
void
84
frag_grow (unsigned int nchars)
85
{
86
  if (obstack_room (&frchain_now->frch_obstack) < nchars)
87
    {
88
      unsigned int n;
89
      long oldc;
90
 
91
      frag_wane (frag_now);
92
      frag_new (0);
93
      oldc = frchain_now->frch_obstack.chunk_size;
94
      /* Try to allocate a bit more than needed right now.  But don't do
95
         this if we would waste too much memory.  Especially necessary
96
         for extremely big (like 2GB initialized) frags.  */
97
      if (nchars < 0x10000)
98
        frchain_now->frch_obstack.chunk_size = 2 * nchars;
99
      else
100
        frchain_now->frch_obstack.chunk_size = nchars + 0x10000;
101
      frchain_now->frch_obstack.chunk_size += SIZEOF_STRUCT_FRAG;
102
      if (frchain_now->frch_obstack.chunk_size > 0)
103
        while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars
104
               && (unsigned long) frchain_now->frch_obstack.chunk_size > nchars)
105
          {
106
            frag_wane (frag_now);
107
            frag_new (0);
108
          }
109
      frchain_now->frch_obstack.chunk_size = oldc;
110
    }
111
  if (obstack_room (&frchain_now->frch_obstack) < nchars)
112
    as_fatal (_("can't extend frag %u chars"), nchars);
113
}
114
 
115
/* Call this to close off a completed frag, and start up a new (empty)
116
   frag, in the same subsegment as the old frag.
117
   [frchain_now remains the same but frag_now is updated.]
118
   Because this calculates the correct value of fr_fix by
119
   looking at the obstack 'frags', it needs to know how many
120
   characters at the end of the old frag belong to the maximal
121
   variable part;  The rest must belong to fr_fix.
122
   It doesn't actually set up the old frag's fr_var.  You may have
123
   set fr_var == 1, but allocated 10 chars to the end of the frag;
124
   In this case you pass old_frags_var_max_size == 10.
125
   In fact, you may use fr_var for something totally unrelated to the
126
   size of the variable part of the frag;  None of the generic frag
127
   handling code makes use of fr_var.
128
 
129
   Make a new frag, initialising some components. Link new frag at end
130
   of frchain_now.  */
131
 
132
void
133
frag_new (int old_frags_var_max_size
134
          /* Number of chars (already allocated on obstack frags) in
135
             variable_length part of frag.  */)
136
{
137
  fragS *former_last_fragP;
138
  frchainS *frchP;
139
 
140
  assert (frchain_now->frch_last == frag_now);
141
 
142
  /* Fix up old frag's fr_fix.  */
143
  frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size;
144
  /* Make sure its type is valid.  */
145
  assert (frag_now->fr_type != 0);
146
 
147
  /* This will align the obstack so the next struct we allocate on it
148
     will begin at a correct boundary.  */
149
  obstack_finish (&frchain_now->frch_obstack);
150
  frchP = frchain_now;
151
  know (frchP);
152
  former_last_fragP = frchP->frch_last;
153
  assert (former_last_fragP != 0);
154
  assert (former_last_fragP == frag_now);
155
  frag_now = frag_alloc (&frchP->frch_obstack);
156
 
157
  as_where (&frag_now->fr_file, &frag_now->fr_line);
158
 
159
  /* Generally, frag_now->points to an address rounded up to next
160
     alignment.  However, characters will add to obstack frags
161
     IMMEDIATELY after the struct frag, even if they are not starting
162
     at an alignment address.  */
163
  former_last_fragP->fr_next = frag_now;
164
  frchP->frch_last = frag_now;
165
 
166
#ifndef NO_LISTING
167
  {
168
    extern struct list_info_struct *listing_tail;
169
    frag_now->line = listing_tail;
170
  }
171
#endif
172
 
173
  assert (frchain_now->frch_last == frag_now);
174
 
175
  frag_now->fr_next = NULL;
176
}
177
 
178
/* Start a new frag unless we have n more chars of room in the current frag.
179
   Close off the old frag with a .fill 0.
180
 
181
   Return the address of the 1st char to write into. Advance
182
   frag_now_growth past the new chars.  */
183
 
184
char *
185
frag_more (int nchars)
186
{
187
  register char *retval;
188
 
189
  frag_alloc_check (&frchain_now->frch_obstack);
190
  frag_grow (nchars);
191
  retval = obstack_next_free (&frchain_now->frch_obstack);
192
  obstack_blank_fast (&frchain_now->frch_obstack, nchars);
193
  return (retval);
194
}
195
 
196
/* Start a new frag unless we have max_chars more chars of room in the
197
   current frag.  Close off the old frag with a .fill 0.
198
 
199
   Set up a machine_dependent relaxable frag, then start a new frag.
200
   Return the address of the 1st char of the var part of the old frag
201
   to write into.  */
202
 
203
char *
204
frag_var (relax_stateT type, int max_chars, int var, relax_substateT subtype,
205
          symbolS *symbol, offsetT offset, char *opcode)
206
{
207
  register char *retval;
208
 
209
  frag_grow (max_chars);
210
  retval = obstack_next_free (&frchain_now->frch_obstack);
211
  obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
212
  frag_now->fr_var = var;
213
  frag_now->fr_type = type;
214
  frag_now->fr_subtype = subtype;
215
  frag_now->fr_symbol = symbol;
216
  frag_now->fr_offset = offset;
217
  frag_now->fr_opcode = opcode;
218
#ifdef USING_CGEN
219
  frag_now->fr_cgen.insn = 0;
220
  frag_now->fr_cgen.opindex = 0;
221
  frag_now->fr_cgen.opinfo = 0;
222
#endif
223
#ifdef TC_FRAG_INIT
224
  TC_FRAG_INIT (frag_now);
225
#endif
226
  as_where (&frag_now->fr_file, &frag_now->fr_line);
227
  frag_new (max_chars);
228
  return (retval);
229
}
230
 
231
/* OVE: This variant of frag_var assumes that space for the tail has been
232
        allocated by caller.
233
        No call to frag_grow is done.  */
234
 
235
char *
236
frag_variant (relax_stateT type, int max_chars, int var,
237
              relax_substateT subtype, symbolS *symbol, offsetT offset,
238
              char *opcode)
239
{
240
  register char *retval;
241
 
242
  retval = obstack_next_free (&frchain_now->frch_obstack);
243
  frag_now->fr_var = var;
244
  frag_now->fr_type = type;
245
  frag_now->fr_subtype = subtype;
246
  frag_now->fr_symbol = symbol;
247
  frag_now->fr_offset = offset;
248
  frag_now->fr_opcode = opcode;
249
#ifdef USING_CGEN
250
  frag_now->fr_cgen.insn = 0;
251
  frag_now->fr_cgen.opindex = 0;
252
  frag_now->fr_cgen.opinfo = 0;
253
#endif
254
#ifdef TC_FRAG_INIT
255
  TC_FRAG_INIT (frag_now);
256
#endif
257
  as_where (&frag_now->fr_file, &frag_now->fr_line);
258
  frag_new (max_chars);
259
  return (retval);
260
}
261
 
262
/* Reduce the variable end of a frag to a harmless state.  */
263
 
264
void
265
frag_wane (register fragS *fragP)
266
{
267
  fragP->fr_type = rs_fill;
268
  fragP->fr_offset = 0;
269
  fragP->fr_var = 0;
270
}
271
 
272
/* Return the number of bytes by which the current frag can be grown.  */
273
 
274
int
275
frag_room (void)
276
{
277
  return obstack_room (&frchain_now->frch_obstack);
278
}
279
 
280
/* Make an alignment frag.  The size of this frag will be adjusted to
281
   force the next frag to have the appropriate alignment.  ALIGNMENT
282
   is the power of two to which to align.  FILL_CHARACTER is the
283
   character to use to fill in any bytes which are skipped.  MAX is
284
   the maximum number of characters to skip when doing the alignment,
285
   or 0 if there is no maximum.  */
286
 
287
void
288
frag_align (int alignment, int fill_character, int max)
289
{
290
  if (now_seg == absolute_section)
291
    {
292
      addressT new_off;
293
      addressT mask;
294
 
295
      mask = (~(addressT) 0) << alignment;
296
      new_off = (abs_section_offset + ~mask) & mask;
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 (int alignment, const char *fill_pattern,
319
                    int n_fill, int max)
320
{
321
  char *p;
322
 
323
  p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
324
                (symbolS *) 0, (offsetT) alignment, (char *) 0);
325
  memcpy (p, fill_pattern, n_fill);
326
}
327
 
328
/* The NOP_OPCODE is for the alignment fill value.  Fill it with a nop
329
   instruction so that the disassembler does not choke on it.  */
330
#ifndef NOP_OPCODE
331
#define NOP_OPCODE 0x00
332
#endif
333
 
334
/* Use this to restrict the amount of memory allocated for representing
335
   the alignment code.  Needs to be large enough to hold any fixed sized
336
   prologue plus the replicating portion.  */
337
#ifndef MAX_MEM_FOR_RS_ALIGN_CODE
338
  /* Assume that if HANDLE_ALIGN is not defined then no special action
339
     is required to code fill, which means that we get just repeat the
340
     one NOP_OPCODE byte.  */
341
# ifndef HANDLE_ALIGN
342
#  define MAX_MEM_FOR_RS_ALIGN_CODE  1
343
# else
344
#  define MAX_MEM_FOR_RS_ALIGN_CODE  ((1 << alignment) - 1)
345
# endif
346
#endif
347
 
348
void
349
frag_align_code (int alignment, int max)
350
{
351
  char *p;
352
 
353
  p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
354
                (relax_substateT) max, (symbolS *) 0,
355
                (offsetT) alignment, (char *) 0);
356
  *p = NOP_OPCODE;
357
}
358
 
359
addressT
360
frag_now_fix_octets (void)
361
{
362
  if (now_seg == absolute_section)
363
    return abs_section_offset;
364
 
365
  return ((char *) obstack_next_free (&frchain_now->frch_obstack)
366
          - frag_now->fr_literal);
367
}
368
 
369
addressT
370
frag_now_fix (void)
371
{
372
  return frag_now_fix_octets () / OCTETS_PER_BYTE;
373
}
374
 
375
void
376
frag_append_1_char (int datum)
377
{
378
  frag_alloc_check (&frchain_now->frch_obstack);
379
  if (obstack_room (&frchain_now->frch_obstack) <= 1)
380
    {
381
      frag_wane (frag_now);
382
      frag_new (0);
383
    }
384
  obstack_1grow (&frchain_now->frch_obstack, datum);
385
}
386
 
387
/* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between
388
   their start addresses.  Set OFFSET to the difference in address
389
   not already accounted for in the frag FR_ADDRESS.  */
390
 
391
bfd_boolean
392
frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, bfd_vma *offset)
393
{
394
  const fragS *frag;
395
  bfd_vma off;
396
 
397
  /* Start with offset initialised to difference between the two frags.
398
     Prior to assigning frag addresses this will be zero.  */
399
  off = frag1->fr_address - frag2->fr_address;
400
  if (frag1 == frag2)
401
    {
402
      *offset = off;
403
      return TRUE;
404
    }
405
 
406
  /* Maybe frag2 is after frag1.  */
407
  frag = frag1;
408
  while (frag->fr_type == rs_fill)
409
    {
410
      off += frag->fr_fix + frag->fr_offset * frag->fr_var;
411
      frag = frag->fr_next;
412
      if (frag == NULL)
413
        break;
414
      if (frag == frag2)
415
        {
416
          *offset = off;
417
          return TRUE;
418
        }
419
    }
420
 
421
  /* Maybe frag1 is after frag2.  */
422
  off = frag1->fr_address - frag2->fr_address;
423
  frag = frag2;
424
  while (frag->fr_type == rs_fill)
425
    {
426
      off -= frag->fr_fix + frag->fr_offset * frag->fr_var;
427
      frag = frag->fr_next;
428
      if (frag == NULL)
429
        break;
430
      if (frag == frag1)
431
        {
432
          *offset = off;
433
          return TRUE;
434
        }
435
    }
436
 
437
  return FALSE;
438
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.