xref: /netbsd/external/gpl3/binutils/dist/gas/literal.c (revision f22f0ef4)
12a6b7db3Sskrll /* literal.c - GAS literal pool management.
2*f22f0ef4Schristos    Copyright (C) 1994-2022 Free Software Foundation, Inc.
32a6b7db3Sskrll    Written by Ken Raeburn (raeburn@cygnus.com).
42a6b7db3Sskrll 
52a6b7db3Sskrll    This file is part of GAS, the GNU Assembler.
62a6b7db3Sskrll 
72a6b7db3Sskrll    GAS is free software; you can redistribute it and/or modify
82a6b7db3Sskrll    it under the terms of the GNU General Public License as published by
92a6b7db3Sskrll    the Free Software Foundation; either version 3, or (at your option)
102a6b7db3Sskrll    any later version.
112a6b7db3Sskrll 
122a6b7db3Sskrll    GAS is distributed in the hope that it will be useful,
132a6b7db3Sskrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
142a6b7db3Sskrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152a6b7db3Sskrll    GNU General Public License for more details.
162a6b7db3Sskrll 
172a6b7db3Sskrll    You should have received a copy of the GNU General Public License
182a6b7db3Sskrll    along with GAS; see the file COPYING.  If not, write to
192a6b7db3Sskrll    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
202a6b7db3Sskrll    Boston, MA 02110-1301, USA.  */
212a6b7db3Sskrll 
222a6b7db3Sskrll /* This isn't quite a "constant" pool.  Some of the values may get
232a6b7db3Sskrll    adjusted at run time, e.g., for symbolic relocations when shared
242a6b7db3Sskrll    libraries are in use.  It's more of a "literal" pool.
252a6b7db3Sskrll 
262a6b7db3Sskrll    On the Alpha, this should be used for .lita and .lit8.  (Is there
272a6b7db3Sskrll    ever a .lit4?)  On the MIPS, it could be used for .lit4 as well.
282a6b7db3Sskrll 
292a6b7db3Sskrll    The expressions passed here should contain either constants or symbols,
302a6b7db3Sskrll    not a combination of both.  Typically, the constant pool is accessed
312a6b7db3Sskrll    with some sort of GP register, so the size of the pool must be kept down
322a6b7db3Sskrll    if possible.  The exception is section offsets -- if you're storing a
332a6b7db3Sskrll    pointer to the start of .data, for example, and your machine provides
342a6b7db3Sskrll    for 16-bit signed addends, you might want to store .data+32K, so that
352a6b7db3Sskrll    you can access all of the first 64K of .data with the one pointer.
362a6b7db3Sskrll 
372a6b7db3Sskrll    This isn't a requirement, just a guideline that can help keep .o file
382a6b7db3Sskrll    size down.  */
392a6b7db3Sskrll 
402a6b7db3Sskrll #include "as.h"
412a6b7db3Sskrll #include "subsegs.h"
422a6b7db3Sskrll 
432a6b7db3Sskrll #ifdef NEED_LITERAL_POOL
442a6b7db3Sskrll 
452a6b7db3Sskrll valueT
add_to_literal_pool(symbolS * sym,valueT addend,segT sec,int size)4675f9f1baSchristos add_to_literal_pool (symbolS *sym, valueT addend, segT sec, int size)
472a6b7db3Sskrll {
482a6b7db3Sskrll   segT current_section = now_seg;
492a6b7db3Sskrll   int current_subsec = now_subseg;
502a6b7db3Sskrll   valueT offset;
512a6b7db3Sskrll   bfd_reloc_code_real_type reloc_type;
522a6b7db3Sskrll   char *p;
532a6b7db3Sskrll   segment_info_type *seginfo = seg_info (sec);
542a6b7db3Sskrll   fixS *fixp;
552a6b7db3Sskrll 
562a6b7db3Sskrll   offset = 0;
572a6b7db3Sskrll   /* @@ This assumes all entries in a given section will be of the same
582a6b7db3Sskrll      size...  Probably correct, but unwise to rely on.  */
592a6b7db3Sskrll   /* This must always be called with the same subsegment.  */
602a6b7db3Sskrll   if (seginfo->frchainP)
612a6b7db3Sskrll     for (fixp = seginfo->frchainP->fix_root;
622a6b7db3Sskrll 	 fixp != (fixS *) NULL;
632a6b7db3Sskrll 	 fixp = fixp->fx_next, offset += size)
642a6b7db3Sskrll       {
652a6b7db3Sskrll 	if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
662a6b7db3Sskrll 	  return offset;
672a6b7db3Sskrll       }
682a6b7db3Sskrll 
692a6b7db3Sskrll   subseg_set (sec, 0);
702a6b7db3Sskrll   p = frag_more (size);
712a6b7db3Sskrll   memset (p, 0, size);
722a6b7db3Sskrll 
732a6b7db3Sskrll   switch (size)
742a6b7db3Sskrll     {
752a6b7db3Sskrll     case 4:
762a6b7db3Sskrll       reloc_type = BFD_RELOC_32;
772a6b7db3Sskrll       break;
782a6b7db3Sskrll     case 8:
792a6b7db3Sskrll       reloc_type = BFD_RELOC_64;
802a6b7db3Sskrll       break;
812a6b7db3Sskrll     default:
822a6b7db3Sskrll       abort ();
832a6b7db3Sskrll     }
842a6b7db3Sskrll   fix_new (frag_now, p - frag_now->fr_literal, size, sym, addend, 0,
852a6b7db3Sskrll 	   reloc_type);
862a6b7db3Sskrll 
872a6b7db3Sskrll   subseg_set (current_section, current_subsec);
882a6b7db3Sskrll   offset = seginfo->literal_pool_size;
892a6b7db3Sskrll   seginfo->literal_pool_size += size;
902a6b7db3Sskrll   return offset;
912a6b7db3Sskrll }
922a6b7db3Sskrll #endif
93