Rearrange symbol_create parameters
[deliverable/binutils-gdb.git] / gas / config / tc-csky.c
index bd0672f77cdf7d9ca4b9ea6fbf56b087bd87ba44..ec1ea944a0fb4d0fe907b8a0c37f0475a58aa97b 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-csky.c -- Assembler for C-SKY
-   Copyright (C) 1989-2018 Free Software Foundation, Inc.
+   Copyright (C) 1989-2020 Free Software Foundation, Inc.
    Created by Lifang Xia (lifang_xia@c-sky.com)
    Contributed by C-SKY Microsystems and Mentor Graphics.
 
@@ -29,7 +29,6 @@
 #include "subsegs.h"
 #include "obstack.h"
 #include "libiberty.h"
-#include "struc-symbol.h"
 
 #ifdef OBJ_ELF
 #include "elf/csky.h"
@@ -273,6 +272,7 @@ struct csky_insn_info
   struct csky_macro_info *macro;
   /* Insn size for check_literal.  */
   unsigned int isize;
+  unsigned int last_isize;
   /* Max size of insn for relax frag_var.  */
   unsigned int max;
   /* Indicates which element is in csky_opcode_info op[] array.  */
@@ -755,8 +755,8 @@ size_t md_longopts_size = sizeof (md_longopts);
 
 static struct csky_insn_info csky_insn;
 
-static struct hash_control *csky_opcodes_hash;
-static struct hash_control *csky_macros_hash;
+static htab_t csky_opcodes_hash;
+static htab_t csky_macros_hash;
 
 static struct csky_macro_info v1_macros_table[] =
 {
@@ -1182,9 +1182,11 @@ md_begin (void)
 
   if (mach_flag != 0)
     {
-      if ((mach_flag & CSKY_ARCH_MASK) != arch_flag && arch_flag != 0)
+      if (((mach_flag & CSKY_ARCH_MASK) != (arch_flag & CSKY_ARCH_MASK))
+          && arch_flag != 0)
        as_warn (_("-mcpu conflict with -march option, using -mcpu"));
-      if ((mach_flag & ~CSKY_ARCH_MASK) != flags && flags != 0)
+      if (((mach_flag & ~CSKY_ARCH_MASK) != (flags & ~CSKY_ARCH_MASK))
+         && flags != 0)
        as_warn (_("-mcpu conflict with other model parameters, using -mcpu"));
     }
   else if (arch_flag != 0)
@@ -1355,16 +1357,16 @@ md_begin (void)
     }
 
   /* Establish hash table for opcodes and macros.  */
-  csky_macros_hash = hash_new ();
-  csky_opcodes_hash = hash_new ();
+  csky_macros_hash = str_htab_create ();
+  csky_opcodes_hash = str_htab_create ();
   for ( ; opcode->mnemonic != NULL; opcode++)
     if ((isa_flag & (opcode->isa_flag16 | opcode->isa_flag32)) != 0)
-      hash_insert (csky_opcodes_hash, opcode->mnemonic, (char *)opcode);
+      str_hash_insert (csky_opcodes_hash, opcode->mnemonic, (char *)opcode);
   for ( ; macro->name != NULL; macro++)
     if ((isa_flag & macro->isa_flag) != 0)
-      hash_insert (csky_macros_hash, macro->name, (char *)macro);
+      str_hash_insert (csky_macros_hash, macro->name, (char *)macro);
   if (do_nolrw && (isa_flag & CSKYV2_ISA_1E2) != 0)
-    hash_insert (csky_macros_hash,
+    str_hash_insert (csky_macros_hash,
                 v2_lrw_macro_opcode.name,
                 (char *)&v2_lrw_macro_opcode);
   /* Set e_flag to ELF Head.  */
@@ -1397,7 +1399,7 @@ make_mapping_symbol (map_state state, valueT value, fragS *frag)
       abort ();
     }
 
-  symbolP = symbol_new (symname, now_seg, value, frag);
+  symbolP = symbol_new (symname, now_seg, frag, value);
   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
 }
 
@@ -1778,8 +1780,8 @@ static char *
 parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
 {
   int length;                       /* Number of chars in an object.  */
-  register char const *err = NULL;  /* Error from scanning float literal.  */
-  char temp[8];
+  const char *err = NULL;           /* Error from scanning float literal.  */
+  unsigned char temp[8];
 
   /* input_line_pointer->1st char of a flonum (we hope!).  */
   input_line_pointer = s;
@@ -1789,9 +1791,9 @@ parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
     input_line_pointer += 2;
 
   if (isdouble)
-    err = md_atof ('d', temp, &length);
+    err = md_atof ('d', (char *) temp, &length);
   else
-    err = md_atof ('f', temp, &length);
+    err = md_atof ('f', (char *) temp, &length);
   know (length <= 8);
   know (err != NULL || length > 0);
 
@@ -1819,41 +1821,42 @@ parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
     {
       uint32_t fnum;
       if (target_big_endian)
-       fnum = (((temp[0] << 24) & 0xffffffff)
-               | ((temp[1] << 16) & 0xffffff)
-               | ((temp[2] << 8) & 0xffff)
-               | (temp[3] & 0xff));
+       fnum = (((uint32_t) temp[0] << 24)
+               | (temp[1] << 16)
+               | (temp[2] << 8)
+               | temp[3]);
       else
-       fnum = (((temp[3] << 24) & 0xffffffff)
-                          | ((temp[2] << 16) & 0xffffff)
-                          | ((temp[1] << 8) & 0xffff)
-                          | (temp[0] & 0xff));
-      e->X_add_number = fnum;    }
+       fnum = (((uint32_t) temp[3] << 24)
+               | (temp[2] << 16)
+               | (temp[1] << 8)
+               | temp[0]);
+      e->X_add_number = fnum;
+    }
   else
     {
       if (target_big_endian)
        {
-         *dbnum = (((temp[0] << 24) & 0xffffffff)
-                   | ((temp[1] << 16) & 0xffffff)
-                   | ((temp[2] << 8) & 0xffff)
-                   | (temp[3] & 0xff));
+         *dbnum = (((uint32_t) temp[0] << 24)
+                   | (temp[1] << 16)
+                   | (temp[2] << 8)
+                   | temp[3]);
          *dbnum <<= 32;
-         *dbnum |= (((temp[4] << 24) & 0xffffffff)
-                    | ((temp[5] << 16) & 0xffffff)
-                    | ((temp[6] << 8) & 0xffff)
-                    | (temp[7] & 0xff));
+         *dbnum |= (((uint32_t) temp[4] << 24)
+                    | (temp[5] << 16)
+                    | (temp[6] << 8)
+                    | temp[7]);
        }
       else
        {
-         *dbnum = (((temp[7] << 24) & 0xffffffff)
-                   | ((temp[6] << 16) & 0xffffff)
-                   | ((temp[5] << 8) & 0xffff)
-                   | (temp[4] & 0xff));
+         *dbnum = (((uint32_t) temp[7] << 24)
+                   | (temp[6] << 16)
+                   | (temp[5] << 8)
+                   | temp[4]);
          *dbnum <<= 32;
-         *dbnum |= (((temp[3] << 24) & 0xffffffff)
-                    | ((temp[2] << 16) & 0xffffff)
-                    | ((temp[1] << 8) & 0xffff)
-                    | (temp[0] & 0xff));
+         *dbnum |= (((uint32_t) temp[3] << 24)
+                    | (temp[2] << 16)
+                    | (temp[1] << 8)
+                    | temp[0]);
       }
     }
   return input_line_pointer;
@@ -2931,9 +2934,9 @@ parse_opcode (char *str)
   csky_insn.number = csky_count_operands (opcode_end);
 
   /* Find hash by name in csky_macros_hash and csky_opcodes_hash.  */
-  csky_insn.macro = (struct csky_macro_info *) hash_find (csky_macros_hash,
+  csky_insn.macro = (struct csky_macro_info *) str_hash_find (csky_macros_hash,
                                                          macro_name);
-  csky_insn.opcode = (struct csky_opcode *) hash_find (csky_opcodes_hash,
+  csky_insn.opcode = (struct csky_opcode *) str_hash_find (csky_opcodes_hash,
                                                        name);
 
   if (csky_insn.macro == NULL && csky_insn.opcode == NULL)
@@ -3155,7 +3158,7 @@ get_operand_value (struct csky_opcode_info *op,
            {
              const char *name = "movi";
              csky_insn.opcode = (struct csky_opcode *)
-               hash_find (csky_opcodes_hash, name);
+               str_hash_find (csky_opcodes_hash, name);
              csky_insn.val[csky_insn.idx - 1] = 1 << val;
            }
          return TRUE;
@@ -3166,7 +3169,7 @@ get_operand_value (struct csky_opcode_info *op,
     case OPRND_TYPE_IMM5b_1_31:
       return is_imm_over_range (oper, 1, 31, -1);
     case OPRND_TYPE_IMM5b_POWER:
-      if (is_imm_over_range (oper, 1, ~(1 << 31), 1 << 31))
+      if (is_imm_over_range (oper, 1, (1u << 31) - 1, 1u << 31))
        {
          int log;
          int val = csky_insn.val[csky_insn.idx - 1];
@@ -3179,7 +3182,7 @@ get_operand_value (struct csky_opcode_info *op,
 
       /* This type for "mgeni" in csky v1 ISA.  */
       case OPRND_TYPE_IMM5b_7_31_POWER:
-       if (is_imm_over_range (oper, 1, ~(1 << 31), 1 << 31))
+       if (is_imm_over_range (oper, 1, (1u << 31) - 1, 1u << 31))
          {
            int log;
            int val = csky_insn.val[csky_insn.idx - 1];
@@ -3189,7 +3192,7 @@ get_operand_value (struct csky_opcode_info *op,
              {
                const char *name = "movi";
                csky_insn.opcode = (struct csky_opcode *)
-                 hash_find (csky_opcodes_hash, name);
+                 str_hash_find (csky_opcodes_hash, name);
                as_warn (_("translating mgeni to movi"));
              }
            else
@@ -3223,7 +3226,7 @@ get_operand_value (struct csky_opcode_info *op,
            {
              const char *op_movi = "movi";
              csky_insn.opcode = (struct csky_opcode *)
-               hash_find (csky_opcodes_hash, op_movi);
+               str_hash_find (csky_opcodes_hash, op_movi);
              if (csky_insn.opcode == NULL)
                return FALSE;
              csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
@@ -3273,7 +3276,7 @@ get_operand_value (struct csky_opcode_info *op,
            {
              const char *op_movi = "movi";
              csky_insn.opcode = (struct csky_opcode *)
-               hash_find (csky_opcodes_hash, op_movi);
+               str_hash_find (csky_opcodes_hash, op_movi);
              if (csky_insn.opcode == NULL)
                return FALSE;
              csky_insn.val[csky_insn.idx - 1] = (1 << (mask_val + 1)) - 1;
@@ -4143,6 +4146,7 @@ md_assemble (char *str)
        check_literals (csky_insn.opcode->transfer, csky_insn.max);
     }
 
+  csky_insn.last_isize = csky_insn.isize;
   insn_reloc = BFD_RELOC_NONE;
 }
 
@@ -4196,7 +4200,7 @@ void
 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec,  fragS *fragp)
 {
   offsetT disp;
-  char *buf = fragp->fr_fix + fragp->fr_literal;
+  char *buf = fragp->fr_fix + &fragp->fr_literal[0];
 
   gas_assert (fragp->fr_symbol);
   if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
@@ -4427,6 +4431,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec,  fragS *fragp)
                buf[20] = (disp >> 8) & 0xff;
                buf[21] = disp & 0xff;
              }
+           buf[22] = 0;  /* initialise.  */
+           buf[23] = 0;
            fragp->fr_fix += C32_LEN_PIC;
 
          } /* end if is_unaligned.  */
@@ -4920,7 +4926,9 @@ md_apply_fix (fixS   *fixP,
   /* We can handle these relocs.  */
   switch (fixP->fx_r_type)
     {
+    case BFD_RELOC_32_PCREL:
     case BFD_RELOC_CKCORE_PCREL32:
+      fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
       break;
     case BFD_RELOC_VTABLE_INHERIT:
       fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTINHERIT;
@@ -5133,6 +5141,10 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
 {
   arelent *rel;
 
+  if (fixP->fx_pcrel
+      && fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR32)
+      fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
+
   rel = xmalloc (sizeof (arelent));
   rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
@@ -5489,7 +5501,7 @@ get_macro_reg_vals (int *reg1, int *reg2, int *reg3)
   s += nlen;
   if (*s != '\0')
     {
-      csky_show_error (ERROR_BAD_END, 0, NULL, NULL);
+      csky_show_error (ERROR_BAD_END, 0, s, NULL);
       return FALSE;
     }
   if (*reg1 == -1 || *reg2 == -1 || *reg3 == -1)
@@ -5945,7 +5957,7 @@ v1_work_jbsr (void)
       /* Using jsri instruction.  */
       const char *name = "jsri";
       csky_insn.opcode = (struct csky_opcode *)
-       hash_find (csky_opcodes_hash, name);
+       str_hash_find (csky_opcodes_hash, name);
       csky_insn.opcode_idx = 0;
       csky_insn.isize = 2;
 
@@ -6283,7 +6295,7 @@ v2_work_rotlc (void)
 {
   const char *name = "addc";
   csky_insn.opcode
-    = (struct csky_opcode *) hash_find (csky_opcodes_hash, name);
+    = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
   csky_insn.opcode_idx = 0;
   if (csky_insn.isize == 2)
     {
@@ -6321,7 +6333,7 @@ v2_work_bgeni (void)
       val >>= 16;
     }
   csky_insn.opcode
-    = (struct csky_opcode *) hash_find (csky_opcodes_hash, name);
+    = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
   csky_insn.opcode_idx = 0;
   csky_insn.val[1] = val;
 
@@ -6339,7 +6351,7 @@ v2_work_not (void)
 {
   const char *name = "nor";
   csky_insn.opcode
-    = (struct csky_opcode *) hash_find (csky_opcodes_hash, name);
+    = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
   csky_insn.opcode_idx = 0;
   if (csky_insn.number == 1)
     {
@@ -6777,8 +6789,9 @@ v2_work_movih (void)
           || (csky_insn.e1.X_op == O_symbol && insn_reloc != BFD_RELOC_NONE))
     {
       if (csky_insn.e1.X_op_symbol != 0
-         && csky_insn.e1.X_op_symbol->sy_value.X_op == O_constant
-         && 16 == csky_insn.e1.X_op_symbol->sy_value.X_add_number)
+         && symbol_constant_p (csky_insn.e1.X_op_symbol)
+         && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
+         && 16 == S_GET_VALUE (csky_insn.e1.X_op_symbol))
        {
          csky_insn.e1.X_op = O_symbol;
          if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
@@ -6827,8 +6840,9 @@ v2_work_ori (void)
     }
   else if (csky_insn.e1.X_op == O_bit_and)
     {
-      if (csky_insn.e1.X_op_symbol->sy_value.X_op == O_constant
-         && 0xffff == csky_insn.e1.X_op_symbol->sy_value.X_add_number)
+      if (symbol_constant_p (csky_insn.e1.X_op_symbol)
+         && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
+         && 0xffff == S_GET_VALUE (csky_insn.e1.X_op_symbol))
        {
          csky_insn.e1.X_op = O_symbol;
          if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
@@ -6888,7 +6902,8 @@ dsp_work_bloop (void)
   csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
   csky_insn.isize = 4;
 
-  if (csky_insn.e1.X_op == O_symbol
+  if (csky_insn.number == 3
+      && csky_insn.e1.X_op == O_symbol
       && csky_insn.e2.X_op == O_symbol)
     {
        fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
@@ -6898,6 +6913,23 @@ dsp_work_bloop (void)
                     4, &csky_insn.e2, 1,
                     BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4);
     }
+  else if (csky_insn.number == 2
+          && csky_insn.e1.X_op == O_symbol)
+    {
+      fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
+                  4, &csky_insn.e1, 1,
+                  BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
+      if (csky_insn.last_isize == 2)
+       csky_insn.inst |= (0xf << 12);
+      else if (csky_insn.last_isize != 0)
+       csky_insn.inst |= (0xe << 12);
+      else
+       {
+         void *arg = (void *)"bloop can not be the first instruction"\
+                     "when the end label is not specified.\n";
+         csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
+       }
+    }
 
   csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
   return TRUE;
This page took 0.031032 seconds and 4 git commands to generate.