remove some duplicate #include's.
[deliverable/binutils-gdb.git] / gas / cgen.c
index 7c4d12f3c1043756bcfd657d5b48f196dd3855ae..5a5378999598b5117533ccd17371608e7101d772 100644 (file)
@@ -1,34 +1,33 @@
 /* GAS interface for targets using CGEN: Cpu tools GENerator.
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+   2006 Free Software Foundation, Inc.
 
-This file is part of GAS, the GNU Assembler.
+   This file is part of GAS, the GNU Assembler.
 
-GAS is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+   GAS is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
 
-GAS is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   GAS is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with GAS; see the file COPYING.  If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   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 "ansidecl.h"
-#include "libiberty.h"
-#include "bfd.h"
+#include "as.h"
 #include "symcat.h"
 #include "cgen-desc.h"
-#include "as.h"
 #include "subsegs.h"
 #include "cgen.h"
 #include "dwarf2dbg.h"
 
+static void queue_fixup (int, int, expressionS *);
+
 /* Opcode table descriptor, must be set by md_begin.  */
 
 CGEN_CPU_DESC gas_cgen_cpu_desc;
@@ -59,7 +58,8 @@ cgen_asm_record_register (name, number)
    OPINDEX is the index in the operand table.
    OPINFO is something the caller chooses to help in reloc determination.  */
 
-struct fixup {
+struct fixup
+{
   int opindex;
   int opinfo;
   expressionS exp;
@@ -103,14 +103,14 @@ queue_fixup (opindex, opinfo, expP)
    to keep track of how many fixup chains have been stored and which
    elements of the array they are in.
 
-   The algorithms used are the same as in the old scheme.  Other than the 
-   "array-ness" of the whole thing, the functionality is identical to the 
+   The algorithms used are the same as in the old scheme.  Other than the
+   "array-ness" of the whole thing, the functionality is identical to the
    old scheme.
 
    gas_cgen_initialize_saved_fixups_array():
       Sets num_fixups_in_chain to 0 for each element. Call this from
       md_begin() if you plan to use these functions and you want the
-      fixup count in each element to be set to 0 intially.  This is
+      fixup count in each element to be set to 0 initially.  This is
       not necessary, but it's included just in case.  It performs
       the same function for each element in the array of fixup chains
       that gas_init_parse() performs for the current fixups.
@@ -128,81 +128,86 @@ queue_fixup (opindex, opinfo, expP)
        element - swap the current fixups with those in this element number.
 */
 
-struct saved_fixups {
-     struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
-     int num_fixups_in_chain;
+struct saved_fixups
+{
+  struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
+  int num_fixups_in_chain;
 };
 
 static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];
 
-void 
+void
 gas_cgen_initialize_saved_fixups_array ()
 {
-   int i = 0;
-   while (i < MAX_SAVED_FIXUP_CHAINS)
-      stored_fixups[i++].num_fixups_in_chain = 0;
+  int i = 0;
+
+  while (i < MAX_SAVED_FIXUP_CHAINS)
+    stored_fixups[i++].num_fixups_in_chain = 0;
 }
 
-void 
-gas_cgen_save_fixups (int i)
+void
+gas_cgen_save_fixups (i)
+     int i;
 {
-      if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
-      {
-          as_fatal("Index into stored_fixups[] out of bounds.");
-          return;
-      }
-      stored_fixups[i].num_fixups_in_chain = num_fixups;
-      memcpy(stored_fixups[i].fixup_chain, fixups,
-                    sizeof (fixups[0])*num_fixups);
-      num_fixups = 0;
+  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
+    {
+      as_fatal ("index into stored_fixups[] out of bounds");
+      return;
+    }
+
+  stored_fixups[i].num_fixups_in_chain = num_fixups;
+  memcpy (stored_fixups[i].fixup_chain, fixups,
+         sizeof (fixups[0]) * num_fixups);
+  num_fixups = 0;
 }
 
-void 
-gas_cgen_restore_fixups (int i)
+void
+gas_cgen_restore_fixups (i)
+     int i;
 {
-      if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
-      {
-          as_fatal("Index into stored_fixups[] out of bounds.");
-          return;
-      }
-      num_fixups = stored_fixups[i].num_fixups_in_chain;
-      memcpy(fixups,stored_fixups[i].fixup_chain,
-                    (sizeof (stored_fixups[i].fixup_chain[0]))*num_fixups);
-      stored_fixups[i].num_fixups_in_chain = 0;
+  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
+    {
+      as_fatal ("index into stored_fixups[] out of bounds");
+      return;
+    }
+
+  num_fixups = stored_fixups[i].num_fixups_in_chain;
+  memcpy (fixups, stored_fixups[i].fixup_chain,
+         (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups);
+  stored_fixups[i].num_fixups_in_chain = 0;
 }
 
-void 
-gas_cgen_swap_fixups (int i)
+void
+gas_cgen_swap_fixups (i)
+     int i;
 {
-     int tmp;
-     struct fixup tmp_fixup;
-
-     if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
-     {
-         as_fatal("Index into stored_fixups[] out of bounds.");
-         return;
-     }
-
-     if (num_fixups == 0)
-     {
-       gas_cgen_restore_fixups (i);
-     }
-     else if (stored_fixups[i].num_fixups_in_chain == 0)
-     {
-       gas_cgen_save_fixups (i);
-     }
-     else
-     {
-       tmp = stored_fixups[i].num_fixups_in_chain;
-       stored_fixups[i].num_fixups_in_chain = num_fixups;
-       num_fixups = tmp;
-
-       for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
-       {
-         tmp_fixup          = stored_fixups[i].fixup_chain [tmp];
-         stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
-         fixups [tmp]       = tmp_fixup;
-       }
+  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
+    {
+      as_fatal ("index into stored_fixups[] out of bounds");
+      return;
+    }
+
+  if (num_fixups == 0)
+    gas_cgen_restore_fixups (i);
+
+  else if (stored_fixups[i].num_fixups_in_chain == 0)
+    gas_cgen_save_fixups (i);
+
+  else
+    {
+      int tmp;
+      struct fixup tmp_fixup;
+
+      tmp = stored_fixups[i].num_fixups_in_chain;
+      stored_fixups[i].num_fixups_in_chain = num_fixups;
+      num_fixups = tmp;
+
+      for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
+       {
+         tmp_fixup = stored_fixups[i].fixup_chain [tmp];
+         stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
+         fixups [tmp] = tmp_fixup;
+       }
     }
 }
 
@@ -234,7 +239,6 @@ gas_cgen_record_fixup (frag, where, insn, length, operand, opinfo, symbol, offse
 
   /* It may seem strange to use operand->attrs and not insn->attrs here,
      but it is the operand that has a pc relative relocation.  */
-
   fixP = fix_new (frag, where, length / 8, symbol, offset,
                  CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
                  (bfd_reloc_code_real_type)
@@ -273,7 +277,6 @@ gas_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
 
   /* It may seem strange to use operand->attrs and not insn->attrs here,
      but it is the operand that has a pc relative relocation.  */
-
   fixP = fix_new_exp (frag, where, length / 8, exp,
                      CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
                      (bfd_reloc_code_real_type)
@@ -314,11 +317,13 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
   /* These are volatile to survive the setjmp.  */
   char * volatile hold;
   enum cgen_parse_operand_result * volatile resultP_1;
+  volatile int opinfo_1;
 #else
   static char *hold;
   static enum cgen_parse_operand_result *resultP_1;
+  int opinfo_1;
 #endif
-  const char *errmsg = NULL;
+  const char *errmsg;
   expressionS exp;
 
   if (want == CGEN_PARSE_OPERAND_INIT)
@@ -330,6 +335,7 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
   resultP_1 = resultP;
   hold = input_line_pointer;
   input_line_pointer = (char *) *strP;
+  opinfo_1 = opinfo;
 
   /* We rely on md_operand to longjmp back to us.
      This is done via gas_cgen_md_operand.  */
@@ -338,16 +344,21 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
       expr_jmp_buf_p = 0;
       input_line_pointer = (char *) hold;
       *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
-      return "illegal operand";
+      return _("illegal operand");
     }
 
   expr_jmp_buf_p = 1;
   expression (&exp);
   expr_jmp_buf_p = 0;
+  errmsg = NULL;
 
   *strP = input_line_pointer;
   input_line_pointer = hold;
 
+#ifdef TC_CGEN_PARSE_FIX_EXP
+  opinfo_1 = TC_CGEN_PARSE_FIX_EXP (opinfo_1, & exp);
+#endif 
+
   /* FIXME: Need to check `want'.  */
 
   switch (exp.X_op)
@@ -361,6 +372,8 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
       *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
       break;
     case O_constant:
+      if (want == CGEN_PARSE_OPERAND_SYMBOLIC)
+       goto de_fault;
       *valueP = exp.X_add_number;
       *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER;
       break;
@@ -368,8 +381,9 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
       *valueP = exp.X_add_number;
       *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER;
       break;
+    de_fault:
     default:
-      queue_fixup (opindex, opinfo, &exp);
+      queue_fixup (opindex, opinfo_1, &exp);
       *valueP = 0;
       *resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
       break;
@@ -424,7 +438,7 @@ gas_cgen_finish_insn (insn, buf, length, relax_p, result)
      Relaxable instructions: We need to ensure we allocate enough
      space for the largest insn.  */
 
-  if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX))
+  if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
     /* These currently shouldn't get here.  */
     abort ();
 
@@ -508,7 +522,7 @@ gas_cgen_finish_insn (insn, buf, length, relax_p, result)
   /* If we're recording insns as numbers (rather than a string of bytes),
      target byte order handling is deferred until now.  */
 #if CGEN_INT_INSN_P
-  cgen_put_insn_value (gas_cgen_cpu_desc, f, length, *buf);
+  cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) f, length, *buf);
 #else
   memcpy (f, buf, byte_len);
 #endif
@@ -524,7 +538,7 @@ gas_cgen_finish_insn (insn, buf, length, relax_p, result)
        cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex);
 
       /* Don't create fixups for these.  That's done during relaxation.
-        We don't need to test for CGEN_INSN_RELAX as they can't get here
+        We don't need to test for CGEN_INSN_RELAXED as they can't get here
         (see above).  */
       if (relax_p
          && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)
@@ -562,50 +576,23 @@ gas_cgen_finish_insn (insn, buf, length, relax_p, result)
    handles the rest.  bfd_install_relocation (or some other bfd function)
    should handle them all.  */
 
-int
-gas_cgen_md_apply_fix3 (fixP, valueP, seg)
+void
+gas_cgen_md_apply_fix (fixP, valP, seg)
      fixS *   fixP;
-     valueT * valueP;
+     valueT * valP;
      segT     seg ATTRIBUTE_UNUSED;
 {
   char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
-  valueT value;
+  valueT value = * valP;
   /* Canonical name, since used a lot.  */
   CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
 
-  /* FIXME FIXME FIXME: The value we are passed in *valuep includes
-     the symbol values.  Since we are using BFD_ASSEMBLER, if we are
-     doing this relocation the code in write.c is going to call
-     bfd_install_relocation, which is also going to use the symbol
-     value.  That means that if the reloc is fully resolved we want to
-     use *valuep since bfd_install_relocation is not being used.
-     However, if the reloc is not fully resolved we do not want to use
-     *valuep, and must use fx_offset instead.  However, if the reloc
-     is PC relative, we do want to use *valuep since it includes the
-     result of md_pcrel_from.  This is confusing.  */
-
   if (fixP->fx_addsy == (symbolS *) NULL)
-    {
-      value = *valueP;
-      fixP->fx_done = 1;
-    }
-  else if (fixP->fx_pcrel)
-    value = *valueP;
-  else
-    {
-      value = fixP->fx_offset;
-      if (fixP->fx_subsy != (symbolS *) NULL)
-       {
-         if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
-           value -= S_GET_VALUE (fixP->fx_subsy);
-         else
-           {
-             /* We don't actually support subtracting a symbol.  */
-             as_bad_where (fixP->fx_file, fixP->fx_line,
-                           _("expression too complex"));
-           }
-       }
-    }
+    fixP->fx_done = 1;
+
+  /* We don't actually support subtracting a symbol.  */
+  if (fixP->fx_subsy != (symbolS *) NULL)
+    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
 
   if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
     {
@@ -629,17 +616,19 @@ gas_cgen_md_apply_fix3 (fixP, valueP, seg)
 #if CGEN_INT_INSN_P
          {
            CGEN_INSN_INT insn_value =
-             cgen_get_insn_value (cd, where, CGEN_INSN_BITSIZE (insn));
+             cgen_get_insn_value (cd, (unsigned char *) where,
+                                  CGEN_INSN_BITSIZE (insn));
 
            /* ??? 0 is passed for `pc'.  */
            errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
                                                   &insn_value, (bfd_vma) 0);
-           cgen_put_insn_value (cd, where, CGEN_INSN_BITSIZE (insn),
-                                insn_value);
+           cgen_put_insn_value (cd, (unsigned char *) where,
+                                CGEN_INSN_BITSIZE (insn), insn_value);
          }
 #else
          /* ??? 0 is passed for `pc'.  */
-         errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields, where,
+         errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
+                                                (unsigned char *) where,
                                                 (bfd_vma) 0);
 #endif
          if (errmsg)
@@ -647,7 +636,7 @@ gas_cgen_md_apply_fix3 (fixP, valueP, seg)
        }
 
       if (fixP->fx_done)
-       return 1;
+       return;
 
       /* The operand isn't fully resolved.  Determine a BFD reloc value
         based on the operand information and leave it to
@@ -655,16 +644,15 @@ gas_cgen_md_apply_fix3 (fixP, valueP, seg)
         partial_inplace == false.  */
 
       reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
+
       if (reloc_type != BFD_RELOC_NONE)
-       {
-         fixP->fx_r_type = reloc_type;
-       }
+       fixP->fx_r_type = reloc_type;
       else
        {
          as_bad_where (fixP->fx_file, fixP->fx_line,
                        _("unresolved expression that must be resolved"));
          fixP->fx_done = 1;
-         return 1;
+         return;
        }
     }
   else if (fixP->fx_done)
@@ -692,17 +680,13 @@ gas_cgen_md_apply_fix3 (fixP, valueP, seg)
          break;
        }
     }
-  else
-    {
-      /* bfd_install_relocation will be called to finish things up.  */
-    }
+  /* else
+     bfd_install_relocation will be called to finish things up.  */
 
   /* Tuck `value' away for use by tc_gen_reloc.
      See the comment describing fx_addnumber in write.h.
      This field is misnamed (or misused :-).  */
   fixP->fx_addnumber = value;
-
-  return 1;
 }
 
 /* Translate internal representation of relocation info to BFD target format.
@@ -741,3 +725,15 @@ gas_cgen_tc_gen_reloc (section, fixP)
   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   return reloc;
 }
+
+/* Perform any cgen specific initialisation.
+   Called after gas_cgen_cpu_desc has been created.  */
+
+void
+gas_cgen_begin ()
+{
+  if (flag_signed_overflow_ok)
+    cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
+  else
+    cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);
+}
This page took 0.043147 seconds and 4 git commands to generate.