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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [frags.c] - Blame information for rev 163

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 147 khays
/* 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, 2008, 2009
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 163 khays
extern fragS predefined_address_frag;
29 147 khays
 
30
/* Initialization for frag routines.  */
31
 
32
void
33
frag_init (void)
34
{
35
  zero_address_frag.fr_type = rs_fill;
36 163 khays
  predefined_address_frag.fr_type = rs_fill;
37 147 khays
}
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
      long oldc;
89 160 khays
      long newc;
90 147 khays
 
91
      /* Try to allocate a bit more than needed right now.  But don't do
92
         this if we would waste too much memory.  Especially necessary
93 160 khays
         for extremely big (like 2GB initialized) frags.  */
94 147 khays
      if (nchars < 0x10000)
95 160 khays
        newc = 2 * nchars;
96 147 khays
      else
97 160 khays
        newc = nchars + 0x10000;
98
      newc += SIZEOF_STRUCT_FRAG;
99
 
100
      /* Check for possible overflow.  */
101
      if (newc < 0)
102
        as_fatal (_("can't extend frag %u chars"), nchars);
103
 
104
      /* Force to allocate at least NEWC bytes.  */
105
      oldc = obstack_chunk_size (&frchain_now->frch_obstack);
106
      obstack_chunk_size (&frchain_now->frch_obstack) = newc;
107
 
108
      while (obstack_room (&frchain_now->frch_obstack) < nchars)
109
        {
110
          /* Not enough room in this frag.  Close it and start a new one.
111
             This must be done in a loop because the created frag may not
112
             be big enough if the current obstack chunk is used.  */
113
          frag_wane (frag_now);
114
          frag_new (0);
115
        }
116
 
117
      /* Restore the old chunk size.  */
118
      obstack_chunk_size (&frchain_now->frch_obstack) = oldc;
119 147 khays
    }
120
}
121
 
122
/* Call this to close off a completed frag, and start up a new (empty)
123
   frag, in the same subsegment as the old frag.
124
   [frchain_now remains the same but frag_now is updated.]
125
   Because this calculates the correct value of fr_fix by
126
   looking at the obstack 'frags', it needs to know how many
127
   characters at the end of the old frag belong to the maximal
128
   variable part;  The rest must belong to fr_fix.
129
   It doesn't actually set up the old frag's fr_var.  You may have
130
   set fr_var == 1, but allocated 10 chars to the end of the frag;
131
   In this case you pass old_frags_var_max_size == 10.
132
   In fact, you may use fr_var for something totally unrelated to the
133
   size of the variable part of the frag;  None of the generic frag
134
   handling code makes use of fr_var.
135
 
136
   Make a new frag, initialising some components. Link new frag at end
137
   of frchain_now.  */
138
 
139
void
140
frag_new (int old_frags_var_max_size
141
          /* Number of chars (already allocated on obstack frags) in
142
             variable_length part of frag.  */)
143
{
144
  fragS *former_last_fragP;
145
  frchainS *frchP;
146
 
147
  gas_assert (frchain_now->frch_last == frag_now);
148
 
149
  /* Fix up old frag's fr_fix.  */
150
  frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size;
151
  /* Make sure its type is valid.  */
152
  gas_assert (frag_now->fr_type != 0);
153
 
154
  /* This will align the obstack so the next struct we allocate on it
155
     will begin at a correct boundary.  */
156
  obstack_finish (&frchain_now->frch_obstack);
157
  frchP = frchain_now;
158
  know (frchP);
159
  former_last_fragP = frchP->frch_last;
160
  gas_assert (former_last_fragP != 0);
161
  gas_assert (former_last_fragP == frag_now);
162
  frag_now = frag_alloc (&frchP->frch_obstack);
163
 
164
  as_where (&frag_now->fr_file, &frag_now->fr_line);
165
 
166
  /* Generally, frag_now->points to an address rounded up to next
167
     alignment.  However, characters will add to obstack frags
168
     IMMEDIATELY after the struct frag, even if they are not starting
169
     at an alignment address.  */
170
  former_last_fragP->fr_next = frag_now;
171
  frchP->frch_last = frag_now;
172
 
173
#ifndef NO_LISTING
174
  {
175
    extern struct list_info_struct *listing_tail;
176
    frag_now->line = listing_tail;
177
  }
178
#endif
179
 
180
  gas_assert (frchain_now->frch_last == frag_now);
181
 
182
  frag_now->fr_next = NULL;
183
}
184
 
185
/* Start a new frag unless we have n more chars of room in the current frag.
186
   Close off the old frag with a .fill 0.
187
 
188
   Return the address of the 1st char to write into. Advance
189
   frag_now_growth past the new chars.  */
190
 
191
char *
192
frag_more (int nchars)
193
{
194
  register char *retval;
195
 
196
  frag_alloc_check (&frchain_now->frch_obstack);
197
  frag_grow (nchars);
198
  retval = obstack_next_free (&frchain_now->frch_obstack);
199
  obstack_blank_fast (&frchain_now->frch_obstack, nchars);
200
  return (retval);
201
}
202
 
203 160 khays
/* Close the current frag, setting its fields for a relaxable frag.  Start a
204
   new frag.  */
205 147 khays
 
206 160 khays
static void
207
frag_var_init (relax_stateT type, int max_chars, int var,
208
               relax_substateT subtype, symbolS *symbol, offsetT offset,
209
               char *opcode)
210 147 khays
{
211
  frag_now->fr_var = var;
212
  frag_now->fr_type = type;
213
  frag_now->fr_subtype = subtype;
214
  frag_now->fr_symbol = symbol;
215
  frag_now->fr_offset = offset;
216
  frag_now->fr_opcode = opcode;
217
#ifdef USING_CGEN
218
  frag_now->fr_cgen.insn = 0;
219
  frag_now->fr_cgen.opindex = 0;
220
  frag_now->fr_cgen.opinfo = 0;
221
#endif
222
#ifdef TC_FRAG_INIT
223
  TC_FRAG_INIT (frag_now);
224
#endif
225
  as_where (&frag_now->fr_file, &frag_now->fr_line);
226 160 khays
 
227 147 khays
  frag_new (max_chars);
228
}
229 160 khays
 
230
/* Start a new frag unless we have max_chars more chars of room in the
231
   current frag.  Close off the old frag with a .fill 0.
232
 
233
   Set up a machine_dependent relaxable frag, then start a new frag.
234
   Return the address of the 1st char of the var part of the old frag
235
   to write into.  */
236
 
237
char *
238
frag_var (relax_stateT type, int max_chars, int var, relax_substateT subtype,
239
          symbolS *symbol, offsetT offset, char *opcode)
240
{
241
  register char *retval;
242
 
243
  frag_grow (max_chars);
244
  retval = obstack_next_free (&frchain_now->frch_obstack);
245
  obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
246
  frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);
247
  return retval;
248
}
249 147 khays
 
250
/* OVE: This variant of frag_var assumes that space for the tail has been
251
        allocated by caller.
252
        No call to frag_grow is done.  */
253
 
254
char *
255
frag_variant (relax_stateT type, int max_chars, int var,
256
              relax_substateT subtype, symbolS *symbol, offsetT offset,
257
              char *opcode)
258
{
259
  register char *retval;
260
 
261
  retval = obstack_next_free (&frchain_now->frch_obstack);
262 160 khays
  frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);
263
 
264
  return retval;
265 147 khays
}
266
 
267
/* Reduce the variable end of a frag to a harmless state.  */
268
 
269
void
270
frag_wane (register fragS *fragP)
271
{
272
  fragP->fr_type = rs_fill;
273
  fragP->fr_offset = 0;
274
  fragP->fr_var = 0;
275
}
276
 
277
/* Return the number of bytes by which the current frag can be grown.  */
278
 
279
int
280
frag_room (void)
281
{
282
  return obstack_room (&frchain_now->frch_obstack);
283
}
284
 
285
/* Make an alignment frag.  The size of this frag will be adjusted to
286
   force the next frag to have the appropriate alignment.  ALIGNMENT
287
   is the power of two to which to align.  FILL_CHARACTER is the
288
   character to use to fill in any bytes which are skipped.  MAX is
289
   the maximum number of characters to skip when doing the alignment,
290
   or 0 if there is no maximum.  */
291
 
292
void
293
frag_align (int alignment, int fill_character, int max)
294
{
295
  if (now_seg == absolute_section)
296
    {
297
      addressT new_off;
298
      addressT mask;
299
 
300
      mask = (~(addressT) 0) << alignment;
301
      new_off = (abs_section_offset + ~mask) & mask;
302
      if (max == 0 || new_off - abs_section_offset <= (addressT) max)
303
        abs_section_offset = new_off;
304
    }
305
  else
306
    {
307
      char *p;
308
 
309
      p = frag_var (rs_align, 1, 1, (relax_substateT) max,
310
                    (symbolS *) 0, (offsetT) alignment, (char *) 0);
311
      *p = fill_character;
312
    }
313
}
314
 
315
/* Make an alignment frag like frag_align, but fill with a repeating
316
   pattern rather than a single byte.  ALIGNMENT is the power of two
317
   to which to align.  FILL_PATTERN is the fill pattern to repeat in
318
   the bytes which are skipped.  N_FILL is the number of bytes in
319
   FILL_PATTERN.  MAX is the maximum number of characters to skip when
320
   doing the alignment, or 0 if there is no maximum.  */
321
 
322
void
323
frag_align_pattern (int alignment, const char *fill_pattern,
324
                    int n_fill, int max)
325
{
326
  char *p;
327
 
328
  p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
329
                (symbolS *) 0, (offsetT) alignment, (char *) 0);
330
  memcpy (p, fill_pattern, n_fill);
331
}
332
 
333
/* The NOP_OPCODE is for the alignment fill value.  Fill it with a nop
334
   instruction so that the disassembler does not choke on it.  */
335
#ifndef NOP_OPCODE
336
#define NOP_OPCODE 0x00
337
#endif
338
 
339
/* Use this to restrict the amount of memory allocated for representing
340
   the alignment code.  Needs to be large enough to hold any fixed sized
341
   prologue plus the replicating portion.  */
342
#ifndef MAX_MEM_FOR_RS_ALIGN_CODE
343
  /* Assume that if HANDLE_ALIGN is not defined then no special action
344
     is required to code fill, which means that we get just repeat the
345
     one NOP_OPCODE byte.  */
346
# ifndef HANDLE_ALIGN
347
#  define MAX_MEM_FOR_RS_ALIGN_CODE  1
348
# else
349
#  define MAX_MEM_FOR_RS_ALIGN_CODE  ((1 << alignment) - 1)
350
# endif
351
#endif
352
 
353
void
354
frag_align_code (int alignment, int max)
355
{
356
  char *p;
357
 
358
  p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
359
                (relax_substateT) max, (symbolS *) 0,
360
                (offsetT) alignment, (char *) 0);
361
  *p = NOP_OPCODE;
362
}
363
 
364
addressT
365
frag_now_fix_octets (void)
366
{
367
  if (now_seg == absolute_section)
368
    return abs_section_offset;
369
 
370
  return ((char *) obstack_next_free (&frchain_now->frch_obstack)
371
          - frag_now->fr_literal);
372
}
373
 
374
addressT
375
frag_now_fix (void)
376
{
377
  return frag_now_fix_octets () / OCTETS_PER_BYTE;
378
}
379
 
380
void
381
frag_append_1_char (int datum)
382
{
383
  frag_alloc_check (&frchain_now->frch_obstack);
384
  if (obstack_room (&frchain_now->frch_obstack) <= 1)
385
    {
386
      frag_wane (frag_now);
387
      frag_new (0);
388
    }
389
  obstack_1grow (&frchain_now->frch_obstack, datum);
390
}
391
 
392
/* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between
393
   their start addresses.  Set OFFSET to the difference in address
394
   not already accounted for in the frag FR_ADDRESS.  */
395
 
396
bfd_boolean
397
frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, bfd_vma *offset)
398
{
399
  const fragS *frag;
400
  bfd_vma off;
401
 
402
  /* Start with offset initialised to difference between the two frags.
403
     Prior to assigning frag addresses this will be zero.  */
404
  off = frag1->fr_address - frag2->fr_address;
405
  if (frag1 == frag2)
406
    {
407
      *offset = off;
408
      return TRUE;
409
    }
410
 
411
  /* Maybe frag2 is after frag1.  */
412
  frag = frag1;
413
  while (frag->fr_type == rs_fill)
414
    {
415
      off += frag->fr_fix + frag->fr_offset * frag->fr_var;
416
      frag = frag->fr_next;
417
      if (frag == NULL)
418
        break;
419
      if (frag == frag2)
420
        {
421
          *offset = off;
422
          return TRUE;
423
        }
424
    }
425
 
426
  /* Maybe frag1 is after frag2.  */
427
  off = frag1->fr_address - frag2->fr_address;
428
  frag = frag2;
429
  while (frag->fr_type == rs_fill)
430
    {
431
      off -= frag->fr_fix + frag->fr_offset * frag->fr_var;
432
      frag = frag->fr_next;
433
      if (frag == NULL)
434
        break;
435
      if (frag == frag1)
436
        {
437
          *offset = off;
438
          return TRUE;
439
        }
440
    }
441
 
442
  return FALSE;
443
}

powered by: WebSVN 2.1.0

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