home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Atari / Gnu / gassrc04.zoo / frags.c < prev    next >
C/C++ Source or Header  |  1991-01-24  |  8KB  |  293 lines

  1. /* frags.c - manage frags -
  2.    Copyright (C) 1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "as.h"
  21. #include "subsegs.h"
  22. #include "obstack.h"
  23. #include "frags.h"
  24. #include "struc-symbol.h"
  25.  
  26. struct obstack  frags;    /* All, and only, frags live here. */
  27.  
  28. fragS zero_address_frag = {
  29.     0,            /* fr_address */
  30.     NULL,            /* fr_next */
  31.     0,            /* fr_fix */
  32.     0,            /* fr_var */
  33.     0,            /* fr_symbol */
  34.     0,            /* fr_offset */
  35.     NULL,            /* fr_opcode */
  36.     rs_fill,        /* fr_type */
  37.     0,            /* fr_subtype */
  38.     0,            /* fr_pcrel_adjust */
  39.     0,            /* fr_bsr */
  40.     0            /* fr_literal [0] */
  41. };
  42.  
  43. fragS bss_address_frag = {
  44.     0,            /* fr_address. Gets filled in to make up
  45.                    sy_value-s. */
  46.     NULL,            /* fr_next */
  47.     0,            /* fr_fix */
  48.     0,            /* fr_var */
  49.     0,            /* fr_symbol */
  50.     0,            /* fr_offset */
  51.     NULL,            /* fr_opcode */
  52.     rs_fill,        /* fr_type */
  53.     0,            /* fr_subtype */
  54.     0,            /* fr_pcrel_adjust */
  55.     0,            /* fr_bsr */
  56.     0            /* fr_literal [0] */
  57. };
  58.  
  59. /*
  60.  *            frag_grow()
  61.  *
  62.  * Internal.
  63.  * Try to augment current frag by nchars chars.
  64.  * If there is no room, close of the current frag with a ".fill 0"
  65.  * and begin a new frag. Unless the new frag has nchars chars available
  66.  * do not return. Do not set up any fields of *now_frag.
  67.  */
  68. static  void
  69. frag_grow (nchars)
  70. int     nchars;
  71. {
  72.     if (obstack_room (&frags) < nchars) {
  73.     unsigned int n,oldn;
  74.     long oldc;
  75.  
  76.     frag_wane (frag_now);
  77.     frag_new (0);
  78.     oldn=(unsigned)-1;
  79.     oldc=frags.chunk_size;
  80.     frags.chunk_size=2*nchars;
  81.     while((n=obstack_room(&frags))<nchars && n<oldn) {
  82.         frag_wane(frag_now);
  83.         frag_new(0);
  84.         oldn=n;
  85.     }
  86.     frags.chunk_size=oldc;
  87.     }
  88.     if (obstack_room (&frags) < nchars)
  89.     as_fatal ("Can't extend frag %d. chars", nchars);
  90. }
  91.  
  92. /*
  93.  *            frag_new()
  94.  *
  95.  * Call this to close off a completed frag, and start up a new (empty)
  96.  * frag, in the same subsegment as the old frag.
  97.  * [frchain_now remains the same but frag_now is updated.]
  98.  * Because this calculates the correct value of fr_fix by
  99.  * looking at the obstack 'frags', it needs to know how many
  100.  * characters at the end of the old frag belong to (the maximal)
  101.  * fr_var: the rest must belong to fr_fix.
  102.  * It doesn't actually set up the old frag's fr_var: you may have
  103.  * set fr_var == 1, but allocated 10 chars to the end of the frag:
  104.  * in this case you pass old_frags_var_max_size == 10.
  105.  *
  106.  * Make a new frag, initialising some components. Link new frag at end
  107.  * of frchain_now.
  108.  */
  109. void
  110. frag_new (old_frags_var_max_size)
  111. int     old_frags_var_max_size;    /* Number of chars (already allocated on
  112.                    obstack frags) */
  113.  /* in variable_length part of frag. */
  114. {
  115.     register    fragS * former_last_fragP;
  116. /*    char   *throw_away_pointer; JF unused */
  117.     register    frchainS * frchP;
  118.     long    tmp;        /* JF */
  119.  
  120.     frag_now->fr_fix = (char *) (obstack_next_free (&frags)) -
  121.     (frag_now->fr_literal) - old_frags_var_max_size;
  122.  /* Fix up old frag's fr_fix. */
  123.  
  124.     obstack_finish (&frags);
  125.  /* This will align the obstack so the */
  126.  /* next struct we allocate on it will */
  127.  /* begin at a correct boundary. */
  128.     frchP = frchain_now;
  129.     know (frchP);
  130.     former_last_fragP = frchP->frch_last;
  131.     know (former_last_fragP);
  132.     know (former_last_fragP == frag_now);
  133.     obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
  134.  /* We expect this will begin at a correct */
  135.  /* boundary for a struct. */
  136.     tmp=obstack_alignment_mask(&frags);
  137.     obstack_alignment_mask(&frags)=0;        /* Turn off alignment */
  138.                             /* If we ever hit a machine
  139.                            where strings must be
  140.                            aligned, we Lose Big */
  141.  frag_now=(fragS *)obstack_finish(&frags);
  142.     obstack_alignment_mask(&frags)=tmp;        /* Restore alignment */
  143.  
  144.  /* Just in case we don't get zero'd bytes */
  145.  bzero(frag_now, SIZEOF_STRUCT_FRAG);
  146.  
  147. /*    obstack_unaligned_done (&frags, &frag_now); */
  148. /*    know (frags.obstack_c_next_free == frag_now->fr_literal); */
  149.  /* Generally, frag_now->points to an */
  150.  /* address rounded up to next alignment. */
  151.  /* However, characters will add to obstack */
  152.  /* frags IMMEDIATELY after the struct frag, */
  153.  /* even if they are not starting at an */
  154.  /* alignment address. */
  155.     former_last_fragP->fr_next = frag_now;
  156.     frchP->frch_last = frag_now;
  157.     frag_now->fr_next = NULL;
  158. }                /* frag_new() */
  159.  
  160. /*
  161.  *            frag_more()
  162.  *
  163.  * Start a new frag unless we have n more chars of room in the current frag.
  164.  * Close off the old frag with a .fill 0.
  165.  *
  166.  * Return the address of the 1st char to write into. Advance
  167.  * frag_now_growth past the new chars.
  168.  */
  169.  
  170. char   *
  171. frag_more (nchars)
  172. int     nchars;
  173. {
  174.     register char  *retval;
  175.  
  176.     frag_grow (nchars);
  177.     retval = obstack_next_free (&frags);
  178.     obstack_blank_fast (&frags, nchars);
  179.     return (retval);
  180. }                /* frag_more() */
  181.  
  182. /*
  183.  *            frag_var()
  184.  *
  185.  * Start a new frag unless we have max_chars more chars of room in the current frag.
  186.  * Close off the old frag with a .fill 0.
  187.  *
  188.  * Set up a machine_dependent relaxable frag, then start a new frag.
  189.  * Return the address of the 1st char of the var part of the old frag
  190.  * to write into.
  191.  */
  192.  
  193. char   *
  194. frag_var (type, max_chars, var, subtype, symbol, offset, opcode)
  195. relax_stateT    type;
  196. int        max_chars;
  197. int        var;
  198. relax_substateT    subtype;
  199. symbolS *    symbol;
  200. long int    offset;
  201. char *        opcode;
  202. {
  203.     register char  *retval;
  204.  
  205.     frag_grow (max_chars);
  206.     retval = obstack_next_free (&frags);
  207.     obstack_blank_fast (&frags, max_chars);
  208.     frag_now->fr_var = var;
  209.     frag_now->fr_type = type;
  210.     frag_now->fr_subtype = subtype;
  211.     frag_now->fr_symbol = symbol;
  212.     frag_now->fr_offset = offset;
  213.     frag_now->fr_opcode = opcode;
  214.     /* default these to zero. */
  215.     frag_now->fr_pcrel_adjust = 0;
  216.     frag_now->fr_bsr = 0;
  217.     frag_new (max_chars);
  218.     return (retval);
  219. }                /* frag_var() */
  220.  
  221. /*
  222.  *            frag_variant()
  223.  *
  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.  *      Two new arguments have been added.
  228.  */
  229.  
  230. char   *
  231. frag_variant (type, max_chars, var, subtype, symbol, offset, opcode, pcrel_adjust,bsr)
  232.      relax_stateT     type;
  233.      int         max_chars;
  234.      int         var;
  235.      relax_substateT     subtype;
  236.      symbolS        *symbol;
  237.      long int         offset;
  238.      char        *opcode;
  239.      char         pcrel_adjust;
  240.      char         bsr;
  241. {
  242.     register char  *retval;
  243.  
  244. /*    frag_grow (max_chars); */
  245.     retval = obstack_next_free (&frags);
  246. /*  obstack_blank_fast (&frags, max_chars); */ /* OVE: so far the only diff */
  247.     frag_now->fr_var = var;
  248.     frag_now->fr_type = type;
  249.     frag_now->fr_subtype = subtype;
  250.     frag_now->fr_symbol = symbol;
  251.     frag_now->fr_offset = offset;
  252.     frag_now->fr_opcode = opcode;
  253.     frag_now->fr_pcrel_adjust = pcrel_adjust;
  254.     frag_now->fr_bsr = bsr;
  255.     frag_new (max_chars);
  256.     return (retval);
  257. }                /* frag_variant() */
  258.  
  259. /*
  260.  *            frag_wane()
  261.  *
  262.  * Reduce the variable end of a frag to a harmless state.
  263.  */
  264. void
  265. frag_wane (fragP)
  266. register    fragS * fragP;
  267. {
  268.     fragP->fr_type = rs_fill;
  269.     fragP->fr_offset = 0;
  270.     fragP->fr_var = 0;
  271. }
  272.  
  273. /*
  274.  *            frag_align()
  275.  *
  276.  * Make a frag for ".align foo,bar". Call is "frag_align (foo,bar);".
  277.  * Foo & bar are absolute integers.
  278.  *
  279.  * Call to close off the current frag with a ".align", then start a new
  280.  * (so far empty) frag, in the same subsegment as the last frag.
  281.  */
  282.  
  283. void
  284. frag_align (alignment, fill_character)
  285. int     alignment;
  286. int     fill_character;
  287. {
  288.     *(frag_var (rs_align, 1, 1, (relax_substateT)0, (symbolS *)0,
  289.  (long)alignment, (char *)0)) = fill_character;
  290. }
  291.  
  292. /* end: frags.c */
  293.