literal.c revision 33965
150476Speter/* as.c - GAS literal pool management.
22011Swollman   Copyright (C) 1994 Free Software Foundation, Inc.
32011Swollman   Written by Ken Raeburn (raeburn@cygnus.com).
42011Swollman
5249778Sjoel   This file is part of GAS, the GNU Assembler.
62011Swollman
779538Sru   GAS is free software; you can redistribute it and/or modify
82011Swollman   it under the terms of the GNU General Public License as published by
92011Swollman   the Free Software Foundation; either version 2, or (at your option)
10107788Sru   any later version.
112011Swollman
122011Swollman   GAS is distributed in the hope that it will be useful,
132011Swollman   but WITHOUT ANY WARRANTY; without even the implied warranty of
142012Swollman   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152011Swollman   GNU General Public License for more details.
16107788Sru
1768962Sru   You should have received a copy of the GNU General Public License
18107788Sru   along with GAS; see the file COPYING.  If not, write to
192011Swollman   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
202011Swollman
212011Swollman/* This isn't quite a "constant" pool.  Some of the values may get
222011Swollman   adjusted at run time, e.g., for symbolic relocations when shared
232011Swollman   libraries are in use.  It's more of a "literal" pool.
242011Swollman
252011Swollman   On the Alpha, this should be used for .lita and .lit8.  (Is there
262011Swollman   ever a .lit4?)  On the MIPS, it could be used for .lit4 as well.
272011Swollman
282011Swollman   The expressions passed here should contain either constants or symbols,
292011Swollman   not a combination of both.  Typically, the constant pool is accessed
302011Swollman   with some sort of GP register, so the size of the pool must be kept down
312011Swollman   if possible.  The exception is section offsets -- if you're storing a
322011Swollman   pointer to the start of .data, for example, and your machine provides
33131530Sru   for 16-bit signed addends, you might want to store .data+32K, so that
34131530Sru   you can access all of the first 64K of .data with the one pointer.
352011Swollman
362011Swollman   This isn't a requirement, just a guideline that can help keep .o file
372011Swollman   size down.  */
382011Swollman
392011Swollman#include "as.h"
4020460Smpp#include "subsegs.h"
4120460Smpp
4220460Smpp#if defined (BFD_ASSEMBLER) && defined (NEED_LITERAL_POOL)
432011Swollman
4420460SmppvalueT
4520460Smppadd_to_literal_pool (sym, addend, sec, size)
4620460Smpp     symbolS *sym;
4720460Smpp     valueT addend;
4820460Smpp     segT sec;
4920460Smpp     int size;
5020460Smpp{
5120460Smpp  segT current_section = now_seg;
5220460Smpp  int current_subsec = now_subseg;
5320460Smpp  valueT offset;
5420460Smpp  bfd_reloc_code_real_type reloc_type;
5520460Smpp  char *p;
5620460Smpp  segment_info_type *seginfo = seg_info (sec);
5720460Smpp  fixS *fixp;
5820460Smpp
5920460Smpp  offset = 0;
6020460Smpp  /* @@ This assumes all entries in a given section will be of the same
6120460Smpp     size...  Probably correct, but unwise to rely on.  */
6220460Smpp  /* This must always be called with the same subsegment.  */
6320460Smpp  if (seginfo->frchainP)
6420460Smpp    for (fixp = seginfo->frchainP->fix_root;
6520460Smpp	 fixp != (fixS *) NULL;
6620460Smpp	 fixp = fixp->fx_next, offset += size)
6720460Smpp      {
6820460Smpp	if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
6920460Smpp	  return offset;
7020460Smpp      }
7120460Smpp
7220460Smpp  subseg_set (sec, 0);
7320460Smpp  p = frag_more (size);
7420460Smpp  memset (p, 0, size);
7520460Smpp
7620460Smpp  switch (size)
7771101Sru    {
78134714Salfred    case 4:
79134714Salfred      reloc_type = BFD_RELOC_32;
80134714Salfred      break;
81134714Salfred    case 8:
8257168Sobrien      reloc_type = BFD_RELOC_64;
8357168Sobrien      break;
8457168Sobrien    default:
8557168Sobrien      abort ();
86119964Sru    }
8757168Sobrien  fix_new (frag_now, p - frag_now->fr_literal, size, sym, addend, 0,
8857168Sobrien	   reloc_type);
8920456Smpp
9020460Smpp  subseg_set (current_section, current_subsec);
9120460Smpp  offset = seginfo->literal_pool_size;
9220460Smpp  seginfo->literal_pool_size += size;
9320456Smpp  return offset;
9459523Schris}
9520460Smpp#endif /* BFD_ASSEMBLER */
9620460Smpp