gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gas / cgen.c
index 410ba55c55721f247cb1375064a755e2731aa1d5..b94802ebc8f8f2427c42e16862e72ef13b4fb32b 100644 (file)
@@ -1,6 +1,5 @@
 /* GAS interface for targets using CGEN: Cpu tools GENerator.
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -18,8 +17,8 @@
    along with GAS; see the file COPYING.  If not, write to the Free Software
    Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-#include <setjmp.h>
 #include "as.h"
+#include <setjmp.h>
 #include "symcat.h"
 #include "cgen-desc.h"
 #include "subsegs.h"
@@ -27,7 +26,6 @@
 #include "dwarf2dbg.h"
 
 #include "symbols.h"
-#include "struc-symbol.h"
 
 #ifdef OBJ_COMPLEX_RELC
 static expressionS * make_right_shifted_expr
@@ -38,7 +36,7 @@ static unsigned long gas_cgen_encode_addend
    const unsigned long, const unsigned long, const unsigned long, \
    const unsigned long);
 
-static char * weak_operand_overflow_check
+static const char * weak_operand_overflow_check
   (const expressionS *, const CGEN_OPERAND *);
 
 static void queue_fixup_recursively
@@ -58,9 +56,7 @@ CGEN_CPU_DESC gas_cgen_cpu_desc;
    ??? Not currently used.  */
 
 void
-cgen_asm_record_register (name, number)
-     char *name;
-     int number;
+cgen_asm_record_register (char *name, int number)
 {
   /* Use symbol_create here instead of symbol_new so we don't try to
      output registers into the object file's symbol table.  */
@@ -95,7 +91,7 @@ static int num_fixups;
    ??? May wish to make this static and delete calls in md_assemble.  */
 
 void
-gas_cgen_init_parse ()
+gas_cgen_init_parse (void)
 {
   num_fixups = 0;
 }
@@ -103,10 +99,7 @@ gas_cgen_init_parse ()
 /* Queue a fixup.  */
 
 static void
-queue_fixup (opindex, opinfo, expP)
-     int           opindex;
-     int           opinfo;
-     expressionS * expP;
+queue_fixup (int opindex, int opinfo, expressionS *expP)
 {
   /* We need to generate a fixup for this expression.  */
   if (num_fixups >= GAS_CGEN_MAX_FIXUPS)
@@ -160,7 +153,7 @@ struct saved_fixups
 static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];
 
 void
-gas_cgen_initialize_saved_fixups_array ()
+gas_cgen_initialize_saved_fixups_array (void)
 {
   int i = 0;
 
@@ -169,8 +162,7 @@ gas_cgen_initialize_saved_fixups_array ()
 }
 
 void
-gas_cgen_save_fixups (i)
-     int i;
+gas_cgen_save_fixups (int i)
 {
   if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
     {
@@ -185,8 +177,7 @@ gas_cgen_save_fixups (i)
 }
 
 void
-gas_cgen_restore_fixups (i)
-     int i;
+gas_cgen_restore_fixups (int i)
 {
   if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
     {
@@ -201,8 +192,7 @@ gas_cgen_restore_fixups (i)
 }
 
 void
-gas_cgen_swap_fixups (i)
-     int i;
+gas_cgen_swap_fixups (int i)
 {
   if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
     {
@@ -248,15 +238,9 @@ gas_cgen_swap_fixups (i)
    operand type.  We pick a BFD reloc type in md_apply_fix.  */
 
 fixS *
-gas_cgen_record_fixup (frag, where, insn, length, operand, opinfo, symbol, offset)
-     fragS *              frag;
-     int                  where;
-     const CGEN_INSN *    insn;
-     int                  length;
-     const CGEN_OPERAND * operand;
-     int                  opinfo;
-     symbolS *            symbol;
-     offsetT              offset;
+gas_cgen_record_fixup (fragS *frag, int where, const CGEN_INSN *insn,
+                      int length, const CGEN_OPERAND *operand, int opinfo,
+                      symbolS *symbol, offsetT offset)
 {
   fixS *fixP;
 
@@ -289,14 +273,9 @@ gas_cgen_record_fixup (frag, where, insn, length, operand, opinfo, symbol, offse
    operand type.  We pick a BFD reloc type in md_apply_fix.  */
 
 fixS *
-gas_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
-     fragS *              frag;
-     int                  where;
-     const CGEN_INSN *    insn;
-     int                  length;
-     const CGEN_OPERAND * operand;
-     int                  opinfo;
-     expressionS *        exp;
+gas_cgen_record_fixup_exp (fragS *frag, int where, const CGEN_INSN *insn,
+                          int length, const CGEN_OPERAND *operand, int opinfo,
+                          expressionS *exp)
 {
   fixS *fixP;
 
@@ -345,19 +324,11 @@ static int expr_jmp_buf_p;
    The resulting value is stored in VALUEP.  */
 
 const char *
-gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
-
-#ifdef OBJ_COMPLEX_RELC
-     CGEN_CPU_DESC cd;
-#else
-     CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
-#endif
-     enum cgen_parse_operand_type want;
-     const char **strP;
-     int opindex;
-     int opinfo;
-     enum cgen_parse_operand_result *resultP;
-     bfd_vma *valueP;
+gas_cgen_parse_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
+                       enum cgen_parse_operand_type want, const char **strP,
+                       int opindex, int opinfo,
+                       enum cgen_parse_operand_result *resultP,
+                       bfd_vma *valueP)
 {
 #ifdef __STDC__
   /* These are volatile to survive the setjmp.  */
@@ -444,6 +415,8 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
 
       if (! errmsg)
        {
+         asymbol *bsym;
+
          /* Fragment the expression as necessary, and queue a reloc.  */
          memset (& dummy_fixup, 0, sizeof (fixS));
 
@@ -451,11 +424,12 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
 
          if (exp.X_op == O_symbol
              && reloc_type == BFD_RELOC_RELC
-             && exp.X_add_symbol->sy_value.X_op == O_constant
-             && (!exp.X_add_symbol->bsym
-                 || (exp.X_add_symbol->bsym->section != expr_section
-                     && exp.X_add_symbol->bsym->section != absolute_section
-                     && exp.X_add_symbol->bsym->section != undefined_section)))
+             && symbol_constant_p (exp.X_add_symbol)
+             && (!symbol_symbolS (exp.X_add_symbol)
+                 || (bsym = symbol_get_bfdsym (exp.X_add_symbol)) == NULL
+                 || (bsym->section != expr_section
+                     && bsym->section != absolute_section
+                     && bsym->section != undefined_section)))
            {
              /* Local labels will have been (eagerly) turned into constants
                 by now, due to the inappropriately deep insight of the
@@ -483,12 +457,15 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
          if (operand && (operand->hw_type == HW_H_SINT))
            signed_p = 1;
 
-         if (stmp->bsym && (stmp->bsym->section == expr_section))
+         if (symbol_symbolS (stmp)
+             && (bsym = symbol_get_bfdsym (stmp)) != NULL
+             && bsym->section == expr_section
+             && ! S_IS_LOCAL (stmp))
            {
              if (signed_p)
-               stmp->bsym->flags |= BSF_SRELC;
+               bsym->flags |= BSF_SRELC;
              else
-               stmp->bsym->flags |= BSF_RELC;
+               bsym->flags |= BSF_RELC;
            }
 
          /* Now package it all up for the fixup emitter.  */
@@ -525,8 +502,7 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
    ??? This could be done differently by adding code to `expression'.  */
 
 void
-gas_cgen_md_operand (expressionP)
-     expressionS *expressionP ATTRIBUTE_UNUSED;
+gas_cgen_md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
 {
   /* Don't longjmp if we're not called from within cgen_parse_operand().  */
   if (expr_jmp_buf_p)
@@ -541,12 +517,8 @@ gas_cgen_md_operand (expressionP)
    The "result" is stored in RESULT if non-NULL.  */
 
 void
-gas_cgen_finish_insn (insn, buf, length, relax_p, result)
-     const CGEN_INSN *insn;
-     CGEN_INSN_BYTES_PTR buf;
-     unsigned int length;
-     int relax_p;
-     finished_insnS *result;
+gas_cgen_finish_insn (const CGEN_INSN *insn, CGEN_INSN_BYTES_PTR buf,
+                     unsigned int length, int relax_p, finished_insnS *result)
 {
   int i;
   int relax_operand;
@@ -780,7 +752,7 @@ gas_cgen_encode_addend (const unsigned long start,    /* in bits */
    overflow, so signal it by returning an error string. Any other case is
    ambiguous, so we assume it's OK and return NULL.  */
 
-static char *
+static const char *
 weak_operand_overflow_check (const expressionS *  exp,
                             const CGEN_OPERAND * operand)
 {
@@ -803,12 +775,12 @@ weak_operand_overflow_check (const expressionS *  exp,
   mask = exp->X_add_number;
 
   if (exp->X_add_symbol
-      && exp->X_add_symbol->sy_value.X_op == O_constant)
-    mask |= exp->X_add_symbol->sy_value.X_add_number;
+      && symbol_constant_p (exp->X_add_symbol))
+    mask |= *symbol_X_add_number (exp->X_add_symbol);
 
   if (exp->X_op_symbol
-      && exp->X_op_symbol->sy_value.X_op == O_constant)
-    mask |= exp->X_op_symbol->sy_value.X_add_number;
+      && symbol_constant_p (exp->X_op_symbol))
+    mask |= *symbol_X_add_number (exp->X_op_symbol);
 
   /* Want to know if mask covers more bits than opmask.
      this is the same as asking if mask has any bits not in opmask,
@@ -832,18 +804,20 @@ make_right_shifted_expr (expressionS * exp,
 {
   symbolS * stmp = 0;
   expressionS * new_exp;
+  asymbol *bsym;
 
   stmp = expr_build_binary (O_right_shift,
                            make_expr_symbol (exp),
                            expr_build_uconstant (amount));
+  bsym = symbol_get_bfdsym (stmp);
 
   if (signed_p)
-    stmp->bsym->flags |= BSF_SRELC;
+    bsym->flags |= BSF_SRELC;
   else
-    stmp->bsym->flags |= BSF_RELC;
+    bsym->flags |= BSF_RELC;
 
   /* Then wrap that in a "symbol expr" for good measure.  */
-  new_exp = xmalloc (sizeof (expressionS));
+  new_exp = XNEW (expressionS);
   memset (new_exp, 0, sizeof (expressionS));
   new_exp->X_op = O_symbol;
   new_exp->X_op_symbol = 0;
@@ -868,10 +842,7 @@ make_right_shifted_expr (expressionS * exp,
    should handle them all.  */
 
 void
-gas_cgen_md_apply_fix (fixP, valP, seg)
-     fixS *   fixP;
-     valueT * valP;
-     segT     seg ATTRIBUTE_UNUSED;
+gas_cgen_md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
   char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
   valueT value = * valP;
@@ -891,8 +862,8 @@ gas_cgen_md_apply_fix (fixP, valP, seg)
       const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
       const char *errmsg;
       bfd_reloc_code_real_type reloc_type;
-      CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd));
       const CGEN_INSN *insn = fixP->fx_cgen.insn;
+#ifdef OBJ_COMPLEX_RELC
       int start;
       int length;
       int signed_p = 0;
@@ -917,6 +888,7 @@ gas_cgen_md_apply_fix (fixP, valP, seg)
          values will be signed relocs, but it's possible. */
       if (operand && (operand->hw_type == HW_H_SINT))
         signed_p = 1;
+#endif
 
       /* If the reloc has been fully resolved finish the operand here.  */
       /* FIXME: This duplicates the capabilities of code in BFD.  */
@@ -925,6 +897,8 @@ gas_cgen_md_apply_fix (fixP, valP, seg)
             finish the job.  Testing for pcrel is a temporary hack.  */
          || fixP->fx_pcrel)
        {
+         CGEN_FIELDS *fields = xmalloc (CGEN_CPU_SIZEOF_FIELDS (cd));
+
          CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
          CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);
 
@@ -948,6 +922,8 @@ gas_cgen_md_apply_fix (fixP, valP, seg)
 #endif
          if (errmsg)
            as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
+
+         free (fields);
        }
 
       if (fixP->fx_done)
@@ -1016,19 +992,40 @@ gas_cgen_md_apply_fix (fixP, valP, seg)
   fixP->fx_addnumber = value;
 }
 
+bfd_reloc_code_real_type
+gas_cgen_pcrel_r_type (bfd_reloc_code_real_type r)
+{
+  switch (r)
+    {
+    case BFD_RELOC_8:  r = BFD_RELOC_8_PCREL;  break;
+    case BFD_RELOC_16: r = BFD_RELOC_16_PCREL; break;
+    case BFD_RELOC_24: r = BFD_RELOC_24_PCREL; break;
+    case BFD_RELOC_32: r = BFD_RELOC_32_PCREL; break;
+    case BFD_RELOC_64: r = BFD_RELOC_64_PCREL; break;
+    default:
+      break;
+    }
+  return r;
+}
+
 /* Translate internal representation of relocation info to BFD target format.
 
    FIXME: To what extent can we get all relevant targets to use this?  */
 
 arelent *
-gas_cgen_tc_gen_reloc (section, fixP)
-     asection * section ATTRIBUTE_UNUSED;
-     fixS *     fixP;
+gas_cgen_tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
 {
+  bfd_reloc_code_real_type r_type = fixP->fx_r_type;
   arelent *reloc;
-  reloc = (arelent *) xmalloc (sizeof (arelent));
 
-  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+  reloc = XNEW (arelent);
+
+#ifdef GAS_CGEN_PCREL_R_TYPE
+  if (fixP->fx_pcrel)
+    r_type = GAS_CGEN_PCREL_R_TYPE (r_type);
+#endif
+  reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
+
   if (reloc->howto == (reloc_howto_type *) NULL)
     {
       as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -1038,7 +1035,7 @@ gas_cgen_tc_gen_reloc (section, fixP)
 
   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
 
-  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+  reloc->sym_ptr_ptr = XNEW (asymbol *);
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
 
   /* Use fx_offset for these cases.  */
@@ -1056,7 +1053,7 @@ gas_cgen_tc_gen_reloc (section, fixP)
    Called after gas_cgen_cpu_desc has been created.  */
 
 void
-gas_cgen_begin ()
+gas_cgen_begin (void)
 {
   if (flag_signed_overflow_ok)
     cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
This page took 0.043723 seconds and 4 git commands to generate.