1218822Sdim/* literal.c - GAS literal pool management.
2218822Sdim   Copyright 1994, 2000, 2005 Free Software Foundation, Inc.
333965Sjdp   Written by Ken Raeburn (raeburn@cygnus.com).
433965Sjdp
533965Sjdp   This file is part of GAS, the GNU Assembler.
633965Sjdp
733965Sjdp   GAS is free software; you can redistribute it and/or modify
833965Sjdp   it under the terms of the GNU General Public License as published by
933965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1033965Sjdp   any later version.
1133965Sjdp
1233965Sjdp   GAS is distributed in the hope that it will be useful,
1333965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1433965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965Sjdp   GNU General Public License for more details.
1633965Sjdp
1733965Sjdp   You should have received a copy of the GNU General Public License
1833965Sjdp   along with GAS; see the file COPYING.  If not, write to
19218822Sdim   the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2033965Sjdp
2133965Sjdp/* This isn't quite a "constant" pool.  Some of the values may get
2233965Sjdp   adjusted at run time, e.g., for symbolic relocations when shared
2333965Sjdp   libraries are in use.  It's more of a "literal" pool.
2433965Sjdp
2533965Sjdp   On the Alpha, this should be used for .lita and .lit8.  (Is there
2633965Sjdp   ever a .lit4?)  On the MIPS, it could be used for .lit4 as well.
2733965Sjdp
2833965Sjdp   The expressions passed here should contain either constants or symbols,
2933965Sjdp   not a combination of both.  Typically, the constant pool is accessed
3033965Sjdp   with some sort of GP register, so the size of the pool must be kept down
3133965Sjdp   if possible.  The exception is section offsets -- if you're storing a
3233965Sjdp   pointer to the start of .data, for example, and your machine provides
3333965Sjdp   for 16-bit signed addends, you might want to store .data+32K, so that
3433965Sjdp   you can access all of the first 64K of .data with the one pointer.
3533965Sjdp
3633965Sjdp   This isn't a requirement, just a guideline that can help keep .o file
3733965Sjdp   size down.  */
3833965Sjdp
3933965Sjdp#include "as.h"
4033965Sjdp#include "subsegs.h"
4133965Sjdp
42218822Sdim#ifdef NEED_LITERAL_POOL
4333965Sjdp
4433965SjdpvalueT
4533965Sjdpadd_to_literal_pool (sym, addend, sec, size)
4633965Sjdp     symbolS *sym;
4733965Sjdp     valueT addend;
4833965Sjdp     segT sec;
4933965Sjdp     int size;
5033965Sjdp{
5133965Sjdp  segT current_section = now_seg;
5233965Sjdp  int current_subsec = now_subseg;
5333965Sjdp  valueT offset;
5433965Sjdp  bfd_reloc_code_real_type reloc_type;
5533965Sjdp  char *p;
5633965Sjdp  segment_info_type *seginfo = seg_info (sec);
5733965Sjdp  fixS *fixp;
5833965Sjdp
5933965Sjdp  offset = 0;
6033965Sjdp  /* @@ This assumes all entries in a given section will be of the same
6133965Sjdp     size...  Probably correct, but unwise to rely on.  */
6233965Sjdp  /* This must always be called with the same subsegment.  */
6333965Sjdp  if (seginfo->frchainP)
6433965Sjdp    for (fixp = seginfo->frchainP->fix_root;
6533965Sjdp	 fixp != (fixS *) NULL;
6633965Sjdp	 fixp = fixp->fx_next, offset += size)
6733965Sjdp      {
6833965Sjdp	if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
6933965Sjdp	  return offset;
7033965Sjdp      }
7133965Sjdp
7233965Sjdp  subseg_set (sec, 0);
7333965Sjdp  p = frag_more (size);
7433965Sjdp  memset (p, 0, size);
7533965Sjdp
7633965Sjdp  switch (size)
7733965Sjdp    {
7833965Sjdp    case 4:
7933965Sjdp      reloc_type = BFD_RELOC_32;
8033965Sjdp      break;
8133965Sjdp    case 8:
8233965Sjdp      reloc_type = BFD_RELOC_64;
8333965Sjdp      break;
8433965Sjdp    default:
8533965Sjdp      abort ();
8633965Sjdp    }
8733965Sjdp  fix_new (frag_now, p - frag_now->fr_literal, size, sym, addend, 0,
8833965Sjdp	   reloc_type);
8933965Sjdp
9033965Sjdp  subseg_set (current_section, current_subsec);
9133965Sjdp  offset = seginfo->literal_pool_size;
9233965Sjdp  seginfo->literal_pool_size += size;
9333965Sjdp  return offset;
9433965Sjdp}
95218822Sdim#endif
96