/* as.c - GAS literal pool management.
   Copyright (C) 1994 Free Software Foundation, Inc.
   Written by Ken Raeburn (raeburn@cygnus.com).

   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 2, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

/* This isn't quite a "constant" pool.  Some of the values may get
   adjusted at run time, e.g., for symbolic relocations when shared
   libraries are in use.  It's more of a "literal" pool.

   On the Alpha, this should be used for .lita and .lit8.  (Is there
   ever a .lit4?)  On the MIPS, it could be used for .lit4 as well.

   The expressions passed here should contain either constants or symbols,
   not a combination of both.  Typically, the constant pool is accessed
   with some sort of GP register, so the size of the pool must be kept down
   if possible.  The exception is section offsets -- if you're storing a
   pointer to the start of .data, for example, and your machine provides
   for 16-bit signed addends, you might want to store .data+32K, so that
   you can access all of the first 64K of .data with the one pointer.

   This isn't a requirement, just a guideline that can help keep .o file
   size down.  */

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

#if defined (BFD_ASSEMBLER) && defined (NEED_LITERAL_POOL)

valueT
add_to_literal_pool (sym, addend, sec, size)
     symbolS *sym;
     valueT addend;
     segT sec;
     int size;
{
  segT current_section = now_seg;
  int current_subsec = now_subseg;
  valueT offset;
  bfd_reloc_code_real_type reloc_type;
  char *p;
  segment_info_type *seginfo = seg_info (sec);
  fixS *fixp;

  offset = 0;
  /* @@ This assumes all entries in a given section will be of the same
     size...  Probably correct, but unwise to rely on.  */
  /* This must always be called with the same subsegment.  */
  if (seginfo->frchainP)
    for (fixp = seginfo->frchainP->fix_root;
	 fixp != (fixS *) NULL;
	 fixp = fixp->fx_next, offset += size)
      {
	if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
	  return offset;
      }

  subseg_set (sec, 0);
  p = frag_more (size);
  memset (p, 0, size);

  switch (size)
    {
    case 4:
      reloc_type = BFD_RELOC_32;
      break;
    case 8:
      reloc_type = BFD_RELOC_64;
      break;
    default:
      abort ();
    }
  fix_new (frag_now, p - frag_now->fr_literal, size, sym, addend, 0,
	   reloc_type);

  subseg_set (current_section, current_subsec);
  offset = seginfo->literal_pool_size;
  seginfo->literal_pool_size += size;
  return offset;
}
#endif /* BFD_ASSEMBLER */
