/* frags.c - manage frags -
   Copyright (C) 1987-2014 Free Software Foundation, Inc.

   This file is part of GAS, the GNU Assembler.

   GAS is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GAS is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GAS; see the file COPYING.  If not, write to the Free
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */

#include "as.h"
#include "subsegs.h"
#include "obstack.h"

extern fragS zero_address_frag;
extern fragS predefined_address_frag;

static int totalfrags;

int
get_frag_count (void)
{
  return totalfrags;
}

void
clear_frag_count (void)
{
  totalfrags = 0;
}

/* Initialization for frag routines.  */

void
frag_init (void)
{
  zero_address_frag.fr_type = rs_fill;
  predefined_address_frag.fr_type = rs_fill;
}

/* Check that we're not trying to assemble into a section that can't
   allocate frags (currently, this is only possible in the absolute
   section), or into an mri common.  */

static void
frag_alloc_check (const struct obstack *ob)
{
  if (ob->chunk_size == 0)
    {
      as_bad (_("attempt to allocate data in absolute section"));
      subseg_set (text_section, 0);
    }

  if (mri_common_symbol != NULL)
    {
      as_bad (_("attempt to allocate data in common section"));
      mri_common_symbol = NULL;
    }
}

/* Allocate a frag on the specified obstack.
   Call this routine from everywhere else, so that all the weird alignment
   hackery can be done in just one place.  */

fragS *
frag_alloc (struct obstack *ob)
{
  fragS *ptr;
  int oalign;

  (void) obstack_alloc (ob, 0);
  oalign = obstack_alignment_mask (ob);
  obstack_alignment_mask (ob) = 0;
  ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG);
  obstack_alignment_mask (ob) = oalign;
  memset (ptr, 0, SIZEOF_STRUCT_FRAG);
  totalfrags++;
  return ptr;
}

/* Try to augment current frag by nchars chars.
   If there is no room, close of the current frag with a ".fill 0"
   and begin a new frag. Unless the new frag has nchars chars available
   do not return. Do not set up any fields of *now_frag.  */

void
frag_grow (size_t nchars)
{
  if (obstack_room (&frchain_now->frch_obstack) < nchars)
    {
      size_t oldc;
      size_t newc;

      /* Try to allocate a bit more than needed right now.  But don't do
         this if we would waste too much memory.  Especially necessary
         for extremely big (like 2GB initialized) frags.  */
      if (nchars < 0x10000)
        newc = 2 * nchars;
      else
        newc = nchars + 0x10000;
      newc += SIZEOF_STRUCT_FRAG;

      /* Check for possible overflow.  */
      if (newc < nchars)
        as_fatal (_("can't extend frag %lu chars"), (unsigned long) nchars);

      /* Force to allocate at least NEWC bytes, but not less than the
         default.  */
      oldc = obstack_chunk_size (&frchain_now->frch_obstack);
      if (newc > oldc)
	obstack_chunk_size (&frchain_now->frch_obstack) = newc;

      while (obstack_room (&frchain_now->frch_obstack) < nchars)
        {
          /* Not enough room in this frag.  Close it and start a new one.
             This must be done in a loop because the created frag may not
             be big enough if the current obstack chunk is used.  */
          frag_wane (frag_now);
          frag_new (0);
        }

      /* Restore the old chunk size.  */
      obstack_chunk_size (&frchain_now->frch_obstack) = oldc;
    }
}

/* Call this to close off a completed frag, and start up a new (empty)
   frag, in the same subsegment as the old frag.
   [frchain_now remains the same but frag_now is updated.]
   Because this calculates the correct value of fr_fix by
   looking at the obstack 'frags', it needs to know how many
   characters at the end of the old frag belong to the maximal
   variable part;  The rest must belong to fr_fix.
   It doesn't actually set up the old frag's fr_var.  You may have
   set fr_var == 1, but allocated 10 chars to the end of the frag;
   In this case you pass old_frags_var_max_size == 10.
   In fact, you may use fr_var for something totally unrelated to the
   size of the variable part of the frag;  None of the generic frag
   handling code makes use of fr_var.

   Make a new frag, initialising some components. Link new frag at end
   of frchain_now.  */

void
frag_new (size_t old_frags_var_max_size
	  /* Number of chars (already allocated on obstack frags) in
	     variable_length part of frag.  */)
{
  fragS *former_last_fragP;
  frchainS *frchP;

  gas_assert (frchain_now->frch_last == frag_now);

  /* Fix up old frag's fr_fix.  */
  frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size;
  /* Make sure its type is valid.  */
  gas_assert (frag_now->fr_type != 0);

  /* This will align the obstack so the next struct we allocate on it
     will begin at a correct boundary.  */
  obstack_finish (&frchain_now->frch_obstack);
  frchP = frchain_now;
  know (frchP);
  former_last_fragP = frchP->frch_last;
  gas_assert (former_last_fragP != 0);
  gas_assert (former_last_fragP == frag_now);
  frag_now = frag_alloc (&frchP->frch_obstack);

  as_where (&frag_now->fr_file, &frag_now->fr_line);

  /* Generally, frag_now->points to an address rounded up to next
     alignment.  However, characters will add to obstack frags
     IMMEDIATELY after the struct frag, even if they are not starting
     at an alignment address.  */
  former_last_fragP->fr_next = frag_now;
  frchP->frch_last = frag_now;

#ifndef NO_LISTING
  {
    extern struct list_info_struct *listing_tail;
    frag_now->line = listing_tail;
  }
#endif

  gas_assert (frchain_now->frch_last == frag_now);

  frag_now->fr_next = NULL;
}

/* Start a new frag unless we have n more chars of room in the current frag.
   Close off the old frag with a .fill 0.

   Return the address of the 1st char to write into. Advance
   frag_now_growth past the new chars.  */

char *
frag_more (size_t nchars)
{
  register char *retval;

  frag_alloc_check (&frchain_now->frch_obstack);
  frag_grow (nchars);
  retval = obstack_next_free (&frchain_now->frch_obstack);
  obstack_blank_fast (&frchain_now->frch_obstack, nchars);
  return (retval);
}

/* Close the current frag, setting its fields for a relaxable frag.  Start a
   new frag.  */

static void
frag_var_init (relax_stateT type, size_t max_chars, size_t var,
	       relax_substateT subtype, symbolS *symbol, offsetT offset,
               char *opcode)
{
  frag_now->fr_var = var;
  frag_now->fr_type = type;
  frag_now->fr_subtype = subtype;
  frag_now->fr_symbol = symbol;
  frag_now->fr_offset = offset;
  frag_now->fr_opcode = opcode;
#ifdef USING_CGEN
  frag_now->fr_cgen.insn = 0;
  frag_now->fr_cgen.opindex = 0;
  frag_now->fr_cgen.opinfo = 0;
#endif
#ifdef TC_FRAG_INIT
  TC_FRAG_INIT (frag_now);
#endif
  as_where (&frag_now->fr_file, &frag_now->fr_line);

  frag_new (max_chars);
}

/* Start a new frag unless we have max_chars more chars of room in the
   current frag.  Close off the old frag with a .fill 0.

   Set up a machine_dependent relaxable frag, then start a new frag.
   Return the address of the 1st char of the var part of the old frag
   to write into.  */

char *
frag_var (relax_stateT type, size_t max_chars, size_t var,
	  relax_substateT subtype, symbolS *symbol, offsetT offset,
	  char *opcode)
{
  register char *retval;

  frag_grow (max_chars);
  retval = obstack_next_free (&frchain_now->frch_obstack);
  obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
  frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);
  return retval;
}

/* OVE: This variant of frag_var assumes that space for the tail has been
	allocated by caller.
	No call to frag_grow is done.  */

char *
frag_variant (relax_stateT type, size_t max_chars, size_t var,
	      relax_substateT subtype, symbolS *symbol, offsetT offset,
	      char *opcode)
{
  register char *retval;

  retval = obstack_next_free (&frchain_now->frch_obstack);
  frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);

  return retval;
}

/* Reduce the variable end of a frag to a harmless state.  */

void
frag_wane (register fragS *fragP)
{
  fragP->fr_type = rs_fill;
  fragP->fr_offset = 0;
  fragP->fr_var = 0;
}

/* Return the number of bytes by which the current frag can be grown.  */

size_t
frag_room (void)
{
  return obstack_room (&frchain_now->frch_obstack);
}

/* Make an alignment frag.  The size of this frag will be adjusted to
   force the next frag to have the appropriate alignment.  ALIGNMENT
   is the power of two to which to align.  FILL_CHARACTER is the
   character to use to fill in any bytes which are skipped.  MAX is
   the maximum number of characters to skip when doing the alignment,
   or 0 if there is no maximum.  */

void
frag_align (int alignment, int fill_character, int max)
{
  if (now_seg == absolute_section)
    {
      addressT new_off;
      addressT mask;

      mask = (~(addressT) 0) << alignment;
      new_off = (abs_section_offset + ~mask) & mask;
      if (max == 0 || new_off - abs_section_offset <= (addressT) max)
	abs_section_offset = new_off;
    }
  else
    {
      char *p;

      p = frag_var (rs_align, 1, 1, (relax_substateT) max,
		    (symbolS *) 0, (offsetT) alignment, (char *) 0);
      *p = fill_character;
    }
}

/* Make an alignment frag like frag_align, but fill with a repeating
   pattern rather than a single byte.  ALIGNMENT is the power of two
   to which to align.  FILL_PATTERN is the fill pattern to repeat in
   the bytes which are skipped.  N_FILL is the number of bytes in
   FILL_PATTERN.  MAX is the maximum number of characters to skip when
   doing the alignment, or 0 if there is no maximum.  */

void
frag_align_pattern (int alignment, const char *fill_pattern,
		    size_t n_fill, int max)
{
  char *p;

  p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
		(symbolS *) 0, (offsetT) alignment, (char *) 0);
  memcpy (p, fill_pattern, n_fill);
}

/* The NOP_OPCODE is for the alignment fill value.  Fill it with a nop
   instruction so that the disassembler does not choke on it.  */
#ifndef NOP_OPCODE
#define NOP_OPCODE 0x00
#endif

/* Use this to restrict the amount of memory allocated for representing
   the alignment code.  Needs to be large enough to hold any fixed sized
   prologue plus the replicating portion.  */
#ifndef MAX_MEM_FOR_RS_ALIGN_CODE
  /* Assume that if HANDLE_ALIGN is not defined then no special action
     is required to code fill, which means that we get just repeat the
     one NOP_OPCODE byte.  */
# ifndef HANDLE_ALIGN
#  define MAX_MEM_FOR_RS_ALIGN_CODE  1
# else
#  define MAX_MEM_FOR_RS_ALIGN_CODE  ((1 << alignment) - 1)
# endif
#endif

void
frag_align_code (int alignment, int max)
{
  char *p;

  p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
		(relax_substateT) max, (symbolS *) 0,
		(offsetT) alignment, (char *) 0);
  *p = NOP_OPCODE;
}

addressT
frag_now_fix_octets (void)
{
  if (now_seg == absolute_section)
    return abs_section_offset;

  return ((char *) obstack_next_free (&frchain_now->frch_obstack)
	  - frag_now->fr_literal);
}

addressT
frag_now_fix (void)
{
  return frag_now_fix_octets () / OCTETS_PER_BYTE;
}

void
frag_append_1_char (int datum)
{
  frag_alloc_check (&frchain_now->frch_obstack);
  if (obstack_room (&frchain_now->frch_obstack) <= 1)
    {
      frag_wane (frag_now);
      frag_new (0);
    }
  obstack_1grow (&frchain_now->frch_obstack, datum);
}

/* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between
   their start addresses.  Set OFFSET to the difference in address
   not already accounted for in the frag FR_ADDRESS.  */

bfd_boolean
frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, offsetT *offset)
{
  const fragS *frag;
  offsetT off;

  /* Start with offset initialised to difference between the two frags.
     Prior to assigning frag addresses this will be zero.  */
  off = frag1->fr_address - frag2->fr_address;
  if (frag1 == frag2)
    {
      *offset = off;
      return TRUE;
    }

  /* Maybe frag2 is after frag1.  */
  frag = frag1;
  while (frag->fr_type == rs_fill)
    {
      off += frag->fr_fix + frag->fr_offset * frag->fr_var;
      frag = frag->fr_next;
      if (frag == NULL)
	break;
      if (frag == frag2)
	{
	  *offset = off;
	  return TRUE;
	}
    }

  /* Maybe frag1 is after frag2.  */
  off = frag1->fr_address - frag2->fr_address;
  frag = frag2;
  while (frag->fr_type == rs_fill)
    {
      off -= frag->fr_fix + frag->fr_offset * frag->fr_var;
      frag = frag->fr_next;
      if (frag == NULL)
	break;
      if (frag == frag1)
	{
	  *offset = off;
	  return TRUE;
	}
    }

  return FALSE;
}
