Adds the new Fields and Operand types for the new instructions in Armv8.4-a.
[deliverable/binutils-gdb.git] / gas / config / tc-sh64.c
index fe82b4632cc5115d9d58c9fe9ae5d32c82b20cd2..6f39c37a8cfafe3fc16536c3dc1581774a1a7b2a 100644 (file)
@@ -1,11 +1,11 @@
 /* tc-sh64.c -- Assemble code for the SuperH SH SHcompact and SHmedia.
-   Copyright 2000, 2001, 2002, 2003 Free Software Foundation.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
 
    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)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
@@ -15,8 +15,8 @@
 
    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.  */
+   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* This file defines SHmedia ISA-specific functions and includes tc-sh.c.
    The SHcompact ISA is in all useful aspects the "old" sh4 as implemented
@@ -25,7 +25,6 @@
 
 #define HAVE_SH64
 
-#include <stdio.h>
 #include "as.h"
 #include "safe-ctype.h"
 #include "opcodes/sh64-opc.h"
@@ -39,7 +38,7 @@
    symbol" or local symbol.  */
 #define DATALABEL_SUFFIX " DL"
 
-/* See shmedia_md_apply_fix3 and shmedia_md_pcrel_from_section for usage.  */
+/* See shmedia_md_apply_fix and shmedia_md_pcrel_from_section for usage.  */
 #define SHMEDIA_MD_PCREL_FROM_FIX(FIXP) \
  ((FIXP)->fx_size + (FIXP)->fx_where + (FIXP)->fx_frag->fr_address - 4)
 
@@ -134,9 +133,10 @@ static const unsigned char shmedia_little_nop_pattern[4] =
  };
 
 static void shmedia_md_begin (void);
-static int shmedia_parse_reg (char *, int *, int *, shmedia_arg_type);
+static int shmedia_parse_reg (char *, shmedia_arg_type *, int *,
+                             shmedia_arg_type);
 static void shmedia_md_assemble (char *);
-static void shmedia_md_apply_fix3 (fixS *, valueT *);
+static void shmedia_md_apply_fix (fixS *, valueT *);
 static int shmedia_md_estimate_size_before_relax (fragS *, segT);
 static int shmedia_init_reloc (arelent *, fixS *);
 static char *shmedia_get_operands (shmedia_opcode_info *, char *,
@@ -284,7 +284,7 @@ shmedia_frob_file_before_adjust (void)
 
       if (mainsym != NULL
          && S_GET_OTHER (mainsym) != STO_SH5_ISA32
-         && (S_IS_EXTERN (mainsym) || S_IS_WEAK (mainsym)))
+         && (S_IS_EXTERNAL (mainsym) || S_IS_WEAK (mainsym)))
        {
          symp->sy_value.X_op = O_symbol;
          symp->sy_value.X_add_symbol = mainsym;
@@ -440,7 +440,7 @@ shmedia_frob_section_type (asection *sec)
       sec_elf_data = sh64_elf_section_data (sec)->sh64_info;
       if (sec_elf_data == NULL)
        {
-         sec_elf_data = xcalloc (1, sizeof (*sec_elf_data));
+         sec_elf_data = XCNEW (struct sh64_section_data);
          sh64_elf_section_data (sec)->sh64_info = sec_elf_data;
        }
 
@@ -577,10 +577,10 @@ shmedia_init_reloc (arelent *rel, fixS *fixP)
   return 0;
 }
 
-/* Hook called from md_apply_fix3 in tc-sh.c.  */
+/* Hook called from md_apply_fix in tc-sh.c.  */
 
 static void
-shmedia_md_apply_fix3 (fixS *fixP, valueT *valp)
+shmedia_md_apply_fix (fixS *fixP, valueT *valp)
 {
   offsetT val = *valp;
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
@@ -602,7 +602,7 @@ shmedia_md_apply_fix3 (fixS *fixP, valueT *valp)
          /* Because write.c calls MD_PCREL_FROM_SECTION twice, we need to
             undo one of the adjustments, if the relocation is not
             actually for a symbol within the same segment (which we
-            cannot check, because we're not called from md_apply_fix3, so
+            cannot check, because we're not called from md_apply_fix, so
             we have to keep the reloc).  FIXME: This is a bug in
             write.c:fixup_segment affecting most targets that change
             ordinary relocs to pcrel relocs in md_apply_fix.  */
@@ -691,7 +691,7 @@ shmedia_md_apply_fix3 (fixS *fixP, valueT *valp)
   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
     {
       /* Emit error for an out-of-range value.  */
-      shmedia_check_limits (valp, fixP->fx_r_type, fixP);
+      shmedia_check_limits ((offsetT *) valp, fixP->fx_r_type, fixP);
 
       switch (fixP->fx_r_type)
        {
@@ -823,7 +823,7 @@ shmedia_md_convert_frag (bfd *output_bfd ATTRIBUTE_UNUSED,
        || sh_relax
        || symbolP == NULL
        || ! S_IS_DEFINED (symbolP)
-       || S_IS_EXTERN (symbolP)
+       || S_IS_EXTERNAL (symbolP)
        || S_IS_WEAK (symbolP)
        || (S_GET_SEGMENT (fragP->fr_symbol) != absolute_section
           && S_GET_SEGMENT (fragP->fr_symbol) != seg));
@@ -1474,7 +1474,7 @@ shmedia_check_limits (offsetT *valp, bfd_reloc_code_real_type reloc,
 {
   offsetT val = *valp;
 
-  char *msg = NULL;
+  const char *msg = NULL;
 
   switch (reloc)
     {
@@ -1533,7 +1533,7 @@ shmedia_check_limits (offsetT *valp, bfd_reloc_code_real_type reloc,
 
     case BFD_RELOC_SH_IMMU16:
       if (val < 0 || val > (1 << 16) - 1)
-       msg = _("invalid operand, not an 16-bit unsigned value: %d");
+       msg = _("invalid operand, not a 16-bit unsigned value: %d");
       break;
 
     case BFD_RELOC_SH_PT_16:
@@ -1612,7 +1612,8 @@ shmedia_immediate_op (char *where, shmedia_operand_info *op, int pcrel,
    chars consumed.  */
 
 static int
-shmedia_parse_reg (char *src, int *mode, int *reg, shmedia_arg_type argtype)
+shmedia_parse_reg (char *src, shmedia_arg_type *mode, int *reg,
+                  shmedia_arg_type argtype)
 {
   int l0 = TOLOWER (src[0]);
   int l1 = l0 ? TOLOWER (src[1]) : 0;
@@ -2021,7 +2022,7 @@ shmedia_md_estimate_size_before_relax (fragS *fragP,
          offsetT value = fragP->fr_offset
            + (fragP->fr_symbol == NULL ? 0 : S_GET_VALUE (fragP->fr_symbol));
 
-         if (value >= ((offsetT) -1 << 15) && value < ((offsetT) 1 << 15))
+         if (value >= (-((offsetT) 1 << 15)) && value < ((offsetT) 1 << 15))
            {
              /* Fits in 16-bit signed number.  */
              int what = GET_WHAT (fragP->fr_subtype);
@@ -2204,16 +2205,16 @@ static char *
 shmedia_parse_exp (char *s, shmedia_operand_info *op)
 {
   char *save;
-  char *new;
+  char *new_pointer;
 
   save = input_line_pointer;
   input_line_pointer = s;
   expression (&op->immediate);
   if (op->immediate.X_op == O_absent)
     as_bad (_("missing operand"));
-  new = input_line_pointer;
+  new_pointer = input_line_pointer;
   input_line_pointer = save;
-  return new;
+  return new_pointer;
 }
 
 /* Parse an operand.  Store pointer to next character in *PTR.  */
@@ -2223,7 +2224,7 @@ shmedia_get_operand (char **ptr, shmedia_operand_info *op,
                     shmedia_arg_type argtype)
 {
   char *src = *ptr;
-  int mode = -1;
+  shmedia_arg_type mode = (shmedia_arg_type) -1;
   unsigned int len;
 
   len = shmedia_parse_reg (src, &mode, &(op->reg), argtype);
@@ -2677,7 +2678,10 @@ shmedia_build_Mytes (shmedia_opcode_info *opcode,
 
            /* Don't allow complex expressions here.  */
            if (opjp->immediate.X_op_symbol != NULL)
-             return 0;
+             {
+               as_bad (_("invalid operand: expression in PT target"));
+               return 0;
+             }
 
            if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
              init = max = min = SH64PCRELPLT;
@@ -2714,7 +2718,10 @@ shmedia_build_Mytes (shmedia_opcode_info *opcode,
 
            /* Don't allow complex expressions here.  */
            if (opjp->immediate.X_op_symbol != NULL)
-             return 0;
+             {
+               as_bad (_("invalid operand: expression in PT target"));
+               return 0;
+             }
 
            if (opjp->reloctype == BFD_RELOC_32_PLT_PCREL)
              init = max = min = SH64PCRELPLT;
@@ -2730,7 +2737,7 @@ shmedia_build_Mytes (shmedia_opcode_info *opcode,
                        insn_loc);
            else
              /* This reloc-type is just temporary, so we can distinguish
-                PTA from PT.  It is changed in shmedia_md_apply_fix3 to
+                PTA from PT.  It is changed in shmedia_md_apply_fix to
                 BFD_RELOC_SH_PT_16.  */
              insn |= shmedia_immediate_op (insn_loc, opjp, 1,
                                            opjp->reloctype == BFD_RELOC_NONE
@@ -2922,14 +2929,14 @@ sh64_target_format (void)
 {
 #ifdef TE_NetBSD
   /* For NetBSD, if the ISA is unspecified, always use SHmedia.  */
-  if (sh64_isa_mode == sh64_isa_unspecified)
+  if (preset_target_arch == 0 && sh64_isa_mode == sh64_isa_unspecified)
     sh64_isa_mode = sh64_isa_shmedia;
 
   /* If the ABI is unspecified, select a default: based on how
      we were configured: sh64 == sh64_abi_64, else sh64_abi_32.  */
   if (sh64_abi == sh64_abi_unspecified)
     {
-      if (sh64_isa_mode == sh64_isa_shcompact)
+      if (preset_target_arch != 0 || sh64_isa_mode == sh64_isa_shcompact)
        sh64_abi = sh64_abi_32;
       else if (strncmp (TARGET_CPU, "sh64", 4) == 0)
         sh64_abi = sh64_abi_64;
@@ -2939,7 +2946,7 @@ sh64_target_format (void)
 #endif
 
 #ifdef TE_LINUX
-  if (sh64_isa_mode == sh64_isa_unspecified)
+  if (preset_target_arch == 0 && sh64_isa_mode == sh64_isa_unspecified)
     sh64_isa_mode = sh64_isa_shmedia;
 
   if (sh64_abi == sh64_abi_unspecified)
@@ -3023,16 +3030,14 @@ sh64_target_mach (void)
   return (sh64_abi == sh64_abi_64) ? bfd_mach_sh5 : 0;
 }
 
-/* This is MD_PCREL_FROM_SECTION, we we define so it is called instead of
+/* This is MD_PCREL_FROM_SECTION, we define so it is called instead of
    md_pcrel_from (in tc-sh.c).  */
 
 valueT
 shmedia_md_pcrel_from_section (struct fix *fixP, segT sec ATTRIBUTE_UNUSED)
 {
-  know (fixP->fx_frag->fr_type == rs_machine_dependent);
-
   /* Use the ISA for the instruction to decide which offset to use.  We
-     can glean it from the fisup type.  */
+     can glean it from the fixup type.  */
   switch (fixP->fx_r_type)
     {
     case BFD_RELOC_SH_IMM_LOW16:
@@ -3060,8 +3065,7 @@ shmedia_md_pcrel_from_section (struct fix *fixP, segT sec ATTRIBUTE_UNUSED)
 
     case BFD_RELOC_64:
     case BFD_RELOC_64_PCREL:
-      know (0 /* Shouldn't get here.  */);
-      break;
+      /* Fall through.  */
 
     default:
       /* If section was SHcompact, use its function.  */
@@ -3238,8 +3242,9 @@ sh64_frob_label (symbolS *symp)
    symbol hook.  */
 
 int
-sh64_consume_datalabel (const char *name, expressionS *exp, char *cp,
-                       segT (*operandf) (expressionS *))
+sh64_consume_datalabel (const char *name, expressionS *exp,
+                       enum expr_mode mode, char *cp,
+                       segT (*operandf) (expressionS *, enum expr_mode))
 {
   static int parsing_datalabel = 0;
 
@@ -3252,7 +3257,7 @@ sh64_consume_datalabel (const char *name, expressionS *exp, char *cp,
 
       *input_line_pointer = *cp;
       parsing_datalabel = 1;
-      (*operandf) (exp);
+      (*operandf) (exp, expr_normal);
       parsing_datalabel = save_parsing_datalabel;
 
       if (exp->X_op == O_symbol || exp->X_op == O_PIC_reloc)
@@ -3269,9 +3274,8 @@ sh64_consume_datalabel (const char *name, expressionS *exp, char *cp,
          else
            {
              symbolS *dl_symp;
-             const char *name = S_GET_NAME (symp);
-             char *dl_name
-               = xmalloc (strlen (name) + sizeof (DATALABEL_SUFFIX));
+             const char * sname = S_GET_NAME (symp);
+             char *dl_name = concat (sname, DATALABEL_SUFFIX, (char *) NULL);
 
              /* Now we copy the datalabel-qualified symbol into a symbol
                 with the same name, but with " DL" appended.  We mark the
@@ -3279,13 +3283,11 @@ sh64_consume_datalabel (const char *name, expressionS *exp, char *cp,
                 the main symbol, so we don't have to inspect all symbol
                 names.  Note that use of "datalabel" is not expected to
                 be a common case.  */
-             strcpy (dl_name, name);
-             strcat (dl_name, DATALABEL_SUFFIX);
 
              /* A FAKE_LABEL_NAME marks "$" or ".".  There can be any
                 number of them and all have the same (faked) name; we
                 must make a new one each time.  */
-             if (strcmp (name, FAKE_LABEL_NAME) == 0)
+             if (strcmp (sname, FAKE_LABEL_NAME) == 0)
                dl_symp = symbol_make (dl_name);
              else
                dl_symp = symbol_find_or_make (dl_name);
@@ -3325,7 +3327,7 @@ sh64_consume_datalabel (const char *name, expressionS *exp, char *cp,
       return 1;
     }
 
-  return sh_parse_name (name, exp, cp);
+  return sh_parse_name (name, exp, mode, cp);
 }
 
 /* This function is called just before symbols are being output.  It
@@ -3507,3 +3509,18 @@ sh64_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
   input_line_pointer = eol;
 }
 
+int
+sh64_fake_label (const char *name)
+{
+  size_t len;
+
+  if (strcmp (name, FAKE_LABEL_NAME) == 0)
+    return 1;
+
+  len = strlen (name);
+  if (len >= (sizeof (DATALABEL_SUFFIX) - 1))
+    return strcmp (&name [len - sizeof (DATALABEL_SUFFIX) + 1],
+                  DATALABEL_SUFFIX) == 0;
+
+  return 0;
+}
This page took 0.04985 seconds and 4 git commands to generate.