Ignore:
Timestamp:
Aug 16, 2003, 6:59:22 PM (22 years ago)
Author:
bird
Message:

binutils v2.14 - offical sources.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/GNU/src/binutils/gas/cgen.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.1.1.2
    r608 r609  
    11/* GAS interface for targets using CGEN: Cpu tools GENerator.
    2    Copyright 1996, 1997, 1998, 1999, 2000, 2001
     2   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    33   Free Software Foundation, Inc.
    44
    5 This file is part of GAS, the GNU Assembler.
    6 
    7 GAS is free software; you can redistribute it and/or modify
    8 it under the terms of the GNU General Public License as published by
    9 the Free Software Foundation; either version 2, or (at your option)
    10 any later version.
    11 
    12 GAS is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GAS; see the file COPYING.  If not, write to the Free Software
    19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
     5   This file is part of GAS, the GNU Assembler.
     6
     7   GAS is free software; you can redistribute it and/or modify
     8   it under the terms of the GNU General Public License as published by
     9   the Free Software Foundation; either version 2, or (at your option)
     10   any later version.
     11
     12   GAS is distributed in the hope that it will be useful,
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15   GNU General Public License for more details.
     16
     17   You should have received a copy of the GNU General Public License
     18   along with GAS; see the file COPYING.  If not, write to the Free Software
     19   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    2020
    2121#include <setjmp.h>
     
    3030#include "dwarf2dbg.h"
    3131
     32static void queue_fixup PARAMS ((int, int, expressionS *));
     33
    3234/* Opcode table descriptor, must be set by md_begin.  */
    3335
     
    6062   OPINFO is something the caller chooses to help in reloc determination.  */
    6163
    62 struct fixup {
     64struct fixup
     65{
    6366  int opindex;
    6467  int opinfo;
     
    9598}
    9699
    97 /* The following three functions allow a backup of the fixup chain to be made,
    98    and to have this backup be swapped with the current chain.  This allows
    99    certain ports, eg the m32r, to swap two instructions and swap their fixups
    100    at the same time.  */
    101 /* ??? I think with cgen_asm_finish_insn (or something else) there is no
    102    more need for this.  */
    103 
    104 static struct fixup saved_fixups[GAS_CGEN_MAX_FIXUPS];
    105 static int saved_num_fixups;
    106 
    107 void
    108 gas_cgen_save_fixups ()
    109 {
    110   saved_num_fixups = num_fixups;
    111 
    112   memcpy (saved_fixups, fixups, sizeof (fixups[0]) * num_fixups);
    113 
     100/* The following functions allow fixup chains to be stored, retrieved,
     101   and swapped.  They are a generalization of a pre-existing scheme
     102   for storing, restoring and swapping fixup chains that was used by
     103   the m32r port.  The functionality is essentially the same, only
     104   instead of only being able to store a single fixup chain, an entire
     105   array of fixup chains can be stored.  It is the user's responsibility
     106   to keep track of how many fixup chains have been stored and which
     107   elements of the array they are in.
     108
     109   The algorithms used are the same as in the old scheme.  Other than the
     110   "array-ness" of the whole thing, the functionality is identical to the
     111   old scheme.
     112
     113   gas_cgen_initialize_saved_fixups_array():
     114      Sets num_fixups_in_chain to 0 for each element. Call this from
     115      md_begin() if you plan to use these functions and you want the
     116      fixup count in each element to be set to 0 initially.  This is
     117      not necessary, but it's included just in case.  It performs
     118      the same function for each element in the array of fixup chains
     119      that gas_init_parse() performs for the current fixups.
     120
     121   gas_cgen_save_fixups (element):
     122      element - element number of the array you wish to store the fixups
     123                to.  No mechanism is built in for tracking what element
     124                was last stored to.
     125
     126   gas_cgen_restore_fixups (element):
     127      element - element number of the array you wish to restore the fixups
     128                from.
     129
     130   gas_cgen_swap_fixups(int element):
     131       element - swap the current fixups with those in this element number.
     132*/
     133
     134struct saved_fixups
     135{
     136  struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
     137  int num_fixups_in_chain;
     138};
     139
     140static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];
     141
     142void
     143gas_cgen_initialize_saved_fixups_array ()
     144{
     145  int i = 0;
     146
     147  while (i < MAX_SAVED_FIXUP_CHAINS)
     148    stored_fixups[i++].num_fixups_in_chain = 0;
     149}
     150
     151void
     152gas_cgen_save_fixups (i)
     153     int i;
     154{
     155  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
     156    {
     157      as_fatal ("index into stored_fixups[] out of bounds");
     158      return;
     159    }
     160
     161  stored_fixups[i].num_fixups_in_chain = num_fixups;
     162  memcpy (stored_fixups[i].fixup_chain, fixups,
     163          sizeof (fixups[0]) * num_fixups);
    114164  num_fixups = 0;
    115165}
    116166
    117167void
    118 gas_cgen_restore_fixups ()
    119 {
    120   num_fixups = saved_num_fixups;
    121 
    122   memcpy (fixups, saved_fixups, sizeof (fixups[0]) * num_fixups);
    123 
    124   saved_num_fixups = 0;
    125 }
    126 
    127 void
    128 gas_cgen_swap_fixups ()
    129 {
    130   int tmp;
    131   struct fixup tmp_fixup;
     168gas_cgen_restore_fixups (i)
     169     int i;
     170{
     171  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
     172    {
     173      as_fatal ("index into stored_fixups[] out of bounds");
     174      return;
     175    }
     176
     177  num_fixups = stored_fixups[i].num_fixups_in_chain;
     178  memcpy (fixups, stored_fixups[i].fixup_chain,
     179          (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups);
     180  stored_fixups[i].num_fixups_in_chain = 0;
     181}
     182
     183void
     184gas_cgen_swap_fixups (i)
     185     int i;
     186{
     187  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
     188    {
     189      as_fatal ("index into stored_fixups[] out of bounds");
     190      return;
     191    }
    132192
    133193  if (num_fixups == 0)
    134     {
    135       gas_cgen_restore_fixups ();
    136     }
    137   else if (saved_num_fixups == 0)
    138     {
    139       gas_cgen_save_fixups ();
    140     }
     194    gas_cgen_restore_fixups (i);
     195
     196  else if (stored_fixups[i].num_fixups_in_chain == 0)
     197    gas_cgen_save_fixups (i);
     198
    141199  else
    142200    {
    143       tmp = saved_num_fixups;
    144       saved_num_fixups = num_fixups;
     201      int tmp;
     202      struct fixup tmp_fixup;
     203
     204      tmp = stored_fixups[i].num_fixups_in_chain;
     205      stored_fixups[i].num_fixups_in_chain = num_fixups;
    145206      num_fixups = tmp;
    146207
    147208      for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
    148209        {
    149           tmp_fixup          = saved_fixups [tmp];
    150           saved_fixups [tmp] = fixups [tmp];
    151           fixups [tmp]       = tmp_fixup;
     210          tmp_fixup = stored_fixups[i].fixup_chain [tmp];
     211          stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
     212          fixups [tmp] = tmp_fixup;
    152213        }
    153214    }
     
    165226   operands residing in the insn, but instead just use the
    166227   operand index.  This lets us easily handle fixups for any
    167    operand type.  We pick a BFD reloc type in md_apply_fix.  */
     228   operand type.  We pick a BFD reloc type in md_apply_fix3.  */
    168229
    169230fixS *
     
    182243  /* It may seem strange to use operand->attrs and not insn->attrs here,
    183244     but it is the operand that has a pc relative relocation.  */
    184 
    185245  fixP = fix_new (frag, where, length / 8, symbol, offset,
    186246                  CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
     
    205265   operands residing in the insn, but instead just use the
    206266   operand index.  This lets us easily handle fixups for any
    207    operand type.  We pick a BFD reloc type in md_apply_fix.  */
     267   operand type.  We pick a BFD reloc type in md_apply_fix3.  */
    208268
    209269fixS *
     
    221281  /* It may seem strange to use operand->attrs and not insn->attrs here,
    222282     but it is the operand that has a pc relative relocation.  */
    223 
    224283  fixP = fix_new_exp (frag, where, length / 8, exp,
    225284                      CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
     
    266325  static enum cgen_parse_operand_result *resultP_1;
    267326#endif
    268   const char *errmsg = NULL;
     327  const char *errmsg;
    269328  expressionS exp;
    270329
     
    286345      input_line_pointer = (char *) hold;
    287346      *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
    288       return "illegal operand";
     347      return _("illegal operand");
    289348    }
    290349
     
    292351  expression (&exp);
    293352  expr_jmp_buf_p = 0;
     353  errmsg = NULL;
    294354
    295355  *strP = input_line_pointer;
     
    510570   should handle them all.  */
    511571
    512 int
    513 gas_cgen_md_apply_fix3 (fixP, valueP, seg)
     572void
     573gas_cgen_md_apply_fix3 (fixP, valP, seg)
    514574     fixS *   fixP;
    515      valueT * valueP;
     575     valueT * valP;
    516576     segT     seg ATTRIBUTE_UNUSED;
    517577{
    518578  char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
    519   valueT value;
     579  valueT value = * valP;
    520580  /* Canonical name, since used a lot.  */
    521581  CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
    522582
    523   /* FIXME FIXME FIXME: The value we are passed in *valuep includes
    524      the symbol values.  Since we are using BFD_ASSEMBLER, if we are
    525      doing this relocation the code in write.c is going to call
    526      bfd_install_relocation, which is also going to use the symbol
    527      value.  That means that if the reloc is fully resolved we want to
    528      use *valuep since bfd_install_relocation is not being used.
    529      However, if the reloc is not fully resolved we do not want to use
    530      *valuep, and must use fx_offset instead.  However, if the reloc
    531      is PC relative, we do want to use *valuep since it includes the
    532      result of md_pcrel_from.  This is confusing.  */
    533 
    534583  if (fixP->fx_addsy == (symbolS *) NULL)
    535     {
    536       value = *valueP;
    537       fixP->fx_done = 1;
    538     }
    539   else if (fixP->fx_pcrel)
    540     value = *valueP;
    541   else
    542     {
    543       value = fixP->fx_offset;
    544       if (fixP->fx_subsy != (symbolS *) NULL)
    545         {
    546           if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
    547             value -= S_GET_VALUE (fixP->fx_subsy);
    548           else
    549             {
    550               /* We don't actually support subtracting a symbol.  */
    551               as_bad_where (fixP->fx_file, fixP->fx_line,
    552                             _("expression too complex"));
    553             }
    554         }
    555     }
     584    fixP->fx_done = 1;
     585
     586  /* We don't actually support subtracting a symbol.  */
     587  if (fixP->fx_subsy != (symbolS *) NULL)
     588    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
    556589
    557590  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
     
    595628
    596629      if (fixP->fx_done)
    597         return 1;
     630        return;
    598631
    599632      /* The operand isn't fully resolved.  Determine a BFD reloc value
     
    603636
    604637      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
     638
    605639      if (reloc_type != BFD_RELOC_NONE)
    606         {
    607           fixP->fx_r_type = reloc_type;
    608         }
     640        fixP->fx_r_type = reloc_type;
    609641      else
    610642        {
     
    612644                        _("unresolved expression that must be resolved"));
    613645          fixP->fx_done = 1;
    614           return 1;
     646          return;
    615647        }
    616648    }
     
    640672        }
    641673    }
    642   else
    643     {
    644       /* bfd_install_relocation will be called to finish things up.  */
    645     }
     674  /* else
     675     bfd_install_relocation will be called to finish things up.  */
    646676
    647677  /* Tuck `value' away for use by tc_gen_reloc.
     
    649679     This field is misnamed (or misused :-).  */
    650680  fixP->fx_addnumber = value;
    651 
    652   return 1;
    653681}
    654682
     
    689717  return reloc;
    690718}
     719
     720/* Perform any cgen specific initialisation.
     721   Called after gas_cgen_cpu_desc has been created.  */
     722
     723void
     724gas_cgen_begin ()
     725{
     726  if (flag_signed_overflow_ok)
     727    cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
     728  else
     729    cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);
     730}
Note: See TracChangeset for help on using the changeset viewer.