CSKY: Support attribute section.
[deliverable/binutils-gdb.git] / gas / config / tc-csky.c
index be54afbd679cc7e8ab207de47268faf14f3f3ed5..9f2975e5f685e718930fdcc924535c714f4d05a0 100644 (file)
@@ -212,7 +212,7 @@ enum
 unsigned int mach_flag = 0;
 unsigned int arch_flag = 0;
 unsigned int other_flag = 0;
-unsigned int isa_flag = 0;
+BFD_HOST_U_64_BIT isa_flag = 0;
 unsigned int dsp_flag = 0;
 
 typedef struct stack_size_entry
@@ -233,7 +233,7 @@ struct csky_cpu_info
 {
   const char *name;
   unsigned int mach_flag;
-  unsigned int isa_flag;
+  BFD_HOST_U_64_BIT isa_flag;
 };
 
 typedef enum
@@ -249,7 +249,7 @@ struct csky_macro_info
   const char *name;
   /* How many operands : if operands == 5, all of 1,2,3,4 are ok.  */
   long oprnd_num;
-  int isa_flag;
+  BFD_HOST_U_64_BIT isa_flag;
   /* Do the work.  */
   void (*handle_func)(void);
 };
@@ -272,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.  */
@@ -563,13 +564,15 @@ const struct csky_arch_info csky_archs[] =
   {"ck801",  CSKY_ARCH_801,  bfd_mach_ck801},
   {"ck802",  CSKY_ARCH_802,  bfd_mach_ck802},
   {"ck803",  CSKY_ARCH_803,  bfd_mach_ck803},
-#define CSKY_ARCH_807_BASE    CSKY_ARCH_807 | CSKY_ARCH_DSP
-#define CSKY_ARCH_810_BASE    CSKY_ARCH_810 | CSKY_ARCH_DSP
-  {"ck807",  CSKY_ARCH_807_BASE,  bfd_mach_ck807},
-  {"ck810",  CSKY_ARCH_810_BASE,  bfd_mach_ck810},
+  {"ck807",  CSKY_ARCH_807,  bfd_mach_ck807},
+  {"ck810",  CSKY_ARCH_810,  bfd_mach_ck810},
+  {"ck860",  CSKY_ARCH_860,  bfd_mach_ck860},
   {NULL, 0, 0}
 };
 
+#define CSKY_ARCH_807_BASE    CSKY_ARCH_807 | CSKY_ARCH_DSP
+#define CSKY_ARCH_810_BASE    CSKY_ARCH_810 | CSKY_ARCH_DSP
+
 /* C-SKY cpus table.  */
 const struct csky_cpu_info csky_cpus[] =
 {
@@ -603,6 +606,7 @@ const struct csky_cpu_info csky_cpus[] =
   /* CK803 series.  */
 #define CSKY_ISA_803    (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
 #define CSKY_ISA_803R1  (CSKY_ISA_803 | CSKYV2_ISA_3E3R1)
+#define CSKY_ISA_803R2  (CSKY_ISA_803 | CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2)
 #define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
   {"ck803", CSKY_ARCH_803, CSKY_ISA_803 },
   {"ck803h", CSKY_ARCH_803, CSKY_ISA_803 },
@@ -635,6 +639,22 @@ const struct csky_cpu_info csky_cpus[] =
   {"ck803eftr1", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
   {"ck803ehftr1", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R1 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
 
+  {"ck803r2", CSKY_ARCH_803, CSKY_ISA_803R2},
+  {"ck803hr2", CSKY_ARCH_803, CSKY_ISA_803R2},
+  {"ck803tr2", CSKY_ARCH_803, CSKY_ISA_803R2 | CSKY_ISA_TRUST},
+  {"ck803htr2", CSKY_ARCH_803, CSKY_ISA_803R2 | CSKY_ISA_TRUST},
+  {"ck803fr2", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803R2 | CSKY_ISA_FLOAT_803},
+  {"ck803fhr2", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803R2 | CSKY_ISA_FLOAT_803},
+  {"ck803er2", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R2 | CSKY_ISA_DSP_ENHANCE},
+  {"ck803ehr2", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R2 | CSKY_ISA_DSP_ENHANCE},
+  {"ck803etr2", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R2 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_TRUST},
+  {"ck803ehtr2", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R2 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_TRUST},
+  {"ck803efr2", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R2 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803},
+  {"ck803efhr2", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R2 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803},
+  {"ck803ftr2", CSKY_ARCH_803 | CSKY_ARCH_FLOAT, CSKY_ISA_803R2 | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
+  {"ck803eftr2", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R2 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
+  {"ck803efhtr2", CSKY_ARCH_803 | CSKY_ARCH_DSP | CSKY_ARCH_FLOAT, CSKY_ISA_803R2 | CSKY_ISA_DSP_ENHANCE | CSKY_ISA_FLOAT_803 | CSKY_ISA_TRUST},
+
   {"ck803s", CSKY_ARCH_803, CSKY_ISA_803R1 },
   {"ck803se", CSKY_ARCH_803 | CSKY_ARCH_DSP, CSKY_ISA_803R1 | CSKYV2_ISA_DSP},
   {"ck803sj", CSKY_ARCH_803 | CSKY_ARCH_JAVA, CSKY_ISA_803R1 | CSKY_ISA_JAVA},
@@ -665,6 +685,11 @@ const struct csky_cpu_info csky_cpus[] =
   {"ck810ft", CSKY_ARCH_810_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_VDSP | CSKY_ISA_FLOAT_810 | CSKY_ISA_TRUST},
   {"ck810ftv", CSKY_ARCH_810_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_VDSP | CSKY_ISA_FLOAT_810 | CSKY_ISA_TRUST},
 
+  /* CK860 Series.  */
+#define CSKY_ISA_860    (CSKY_ISA_810 | CSKYV2_ISA_10E60)
+#define CSKY_ISA_FLOAT_860 (CSKY_ISA_FLOAT_810)
+  {"ck860", CSKY_ARCH_860, CSKY_ISA_860},
+
   {NULL, 0, 0}
 };
 
@@ -754,8 +779,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[] =
 {
@@ -1161,6 +1186,78 @@ md_show_usage (FILE *fp)
   -mvdsp                       enable vector DSP instructions\n"));
 }
 
+static void set_csky_attribute (void)
+{
+  if (mach_flag & CSKY_ARCH_DSP)
+    {
+      if (dsp_flag & CSKY_DSP_FLAG_V2)
+       {
+         /* Set DSPV2.  */
+         bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                                   Tag_CSKY_DSP_VERSION,
+                                   VAL_CSKY_DSP_VERSION_2);
+       }
+      else if (isa_flag & CSKY_ISA_DSP)
+       {
+         /* Set DSP extension.  */
+         bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                                   Tag_CSKY_DSP_VERSION,
+                                   VAL_CSKY_DSP_VERSION_EXTENSION);
+       }
+      /* Set VDSP attribute.  */
+      if (isa_flag & CSKY_ISA_VDSP)
+       bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                                 Tag_CSKY_VDSP_VERSION,
+                                 VAL_CSKY_VDSP_VERSION_1);
+
+      else if (isa_flag & CSKY_ISA_VDSP_2)
+       bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                                 Tag_CSKY_VDSP_VERSION,
+                                 VAL_CSKY_VDSP_VERSION_2);
+
+    }
+
+  if (mach_flag & CSKY_ARCH_FLOAT)
+    {
+      unsigned int val = VAL_CSKY_FPU_HARDFP_SINGLE;
+      if (IS_CSKY_ARCH_V1 (mach_flag)) {
+       bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                                 Tag_CSKY_FPU_VERSION,
+                                 VAL_CSKY_FPU_VERSION_1);
+      }
+      else
+       {
+         if (isa_flag & CSKY_ISA_FLOAT_3E4)
+           {
+             bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                                       Tag_CSKY_FPU_VERSION,
+                                       VAL_CSKY_FPU_VERSION_2);
+             val |= VAL_CSKY_FPU_HARDFP_DOUBLE;
+           }
+         else
+           {
+             bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                                       Tag_CSKY_FPU_VERSION,
+                                       VAL_CSKY_FPU_VERSION_2);
+           }
+
+         bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                                   Tag_CSKY_FPU_HARDFP,
+                                   val);
+         bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
+                                   Tag_CSKY_FPU_NUMBER_MODULE,
+                                   "IEEE 754");
+       }
+    }
+
+
+  bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                           Tag_CSKY_ISA_FLAGS, isa_flag);
+
+  bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
+                           Tag_CSKY_ISA_EXT_FLAGS, (isa_flag >> 32));
+}
+
 /* Target-specific initialization and option handling.  */
 
 void
@@ -1181,13 +1278,22 @@ 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)
-    mach_flag |= arch_flag | flags;
+    {
+      if ((arch_flag & CSKY_ARCH_MASK) == CSKY_ARCH_810
+         || ((arch_flag & CSKY_ARCH_MASK) == CSKY_ARCH_807)) {
+         /* CK807 and CK810 have DSP instruction by default.  */
+         mach_flag |= CSKY_ARCH_DSP;
+      }
+      mach_flag |= arch_flag | flags;
+    }
   else
     {
 #ifdef TARGET_WITH_CPU
@@ -1229,6 +1335,8 @@ md_begin (void)
   for (p_arch = csky_archs; p_arch->arch_flag != 0; p_arch++)
     if ((mach_flag & CSKY_ARCH_MASK) == (p_arch->arch_flag & CSKY_ARCH_MASK))
       {
+       bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
+                                    Tag_CSKY_ARCH_NAME, p_arch->name);
        bfd_mach_flag =  p_arch->bfd_mach_flag;
        break;
       }
@@ -1237,6 +1345,8 @@ md_begin (void)
   for (p_cpu = csky_cpus; p_cpu->mach_flag != 0; p_cpu++)
     if ((mach_flag & CPU_ARCH_MASK) == p_cpu->mach_flag)
       {
+       bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
+                                    Tag_CSKY_CPU_NAME, p_cpu->name);
        isa_flag |= p_cpu->isa_flag;
        break;
       }
@@ -1247,16 +1357,36 @@ md_begin (void)
     {
       if (IS_CSKY_ARCH_803 (mach_flag))
        {
-         /* In 803, dspv1 is conflict with dspv2. We keep dspv2.  */
-         if ((dsp_flag & CSKY_DSP_FLAG_V1) && (dsp_flag & CSKY_DSP_FLAG_V2))
-           as_warn (_("option -mdsp conflicts with -medsp, only enabling -medsp"));
-         isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
-         isa_flag |= CSKY_ISA_DSP_ENHANCE;
+         if ((dsp_flag & CSKY_DSP_FLAG_V1))
+           {
+             isa_flag |= (CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
+             isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
+           }
+
+         if ((dsp_flag & CSKY_DSP_FLAG_V2))
+           {
+             isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
+             isa_flag |= CSKY_ISA_DSP_ENHANCE;
+           }
+
+         if ((dsp_flag & CSKY_DSP_FLAG_V1)
+             && (dsp_flag & CSKY_DSP_FLAG_V2))
+           {
+             /* In 803, dspv1 is conflict with dspv2. We keep dspv2.  */
+             as_warn ("option -mdsp conflicts with -medsp, only enabling -medsp");
+        dsp_flag &= ~CSKY_DSP_FLAG_V1;
+             isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
+             isa_flag |= CSKY_ISA_DSP_ENHANCE;
+           }
        }
       else
        {
-         isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
-         as_warn (_("-medsp option is only supported by ck803s, ignoring -medsp"));
+         if (dsp_flag & CSKY_DSP_FLAG_V2)
+           {
+             dsp_flag &= ~CSKY_DSP_FLAG_V2;
+             isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
+             as_warn ("-medsp option is only supported by ck803s, ignoring -medsp");
+           }
        }
       ;
     }
@@ -1318,7 +1448,7 @@ md_begin (void)
       else
        do_intr_stack = 1;
     }
-  /* TODO: add isa_flag(SIMP/CACHE/APS).  */
+  /* Add isa_flag(SIMP/CACHE/APS).  */
   isa_flag |= (mach_flag & CSKY_ARCH_MAC) ? CSKY_ISA_MAC : 0;
   isa_flag |= (mach_flag & CSKY_ARCH_MP) ? CSKY_ISA_MP : 0;
   isa_flag |= (mach_flag & CSKY_ARCH_CP) ? CSKY_ISA_CP : 0;
@@ -1354,22 +1484,23 @@ 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, opcode, 0);
   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, macro, 0);
   if (do_nolrw && (isa_flag & CSKYV2_ISA_1E2) != 0)
-    hash_insert (csky_macros_hash,
-                v2_lrw_macro_opcode.name,
-                (char *)&v2_lrw_macro_opcode);
+    str_hash_insert (csky_macros_hash,
+                    v2_lrw_macro_opcode.name, &v2_lrw_macro_opcode, 0);
   /* Set e_flag to ELF Head.  */
-  bfd_set_private_flags (stdoutput, mach_flag);
+  bfd_set_private_flags (stdoutput, mach_flag & ~(0xffff));
   /* Set bfd_mach to bfd backend data.  */
   bfd_set_arch_mach (stdoutput, bfd_arch_csky, bfd_mach_flag);
+
+  set_csky_attribute ();
 }
 
 /* The C-SKY assembler emits mapping symbols $t and $d to mark the
@@ -1396,7 +1527,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;
 }
 
@@ -2328,7 +2459,8 @@ csky_get_freg_val (char *str, int *len)
 {
   int reg = 0;
   char *s = NULL;
-  if ((str[0] == 'v' || str[0] == 'f') && (str[1] == 'r'))
+  if ((TOLOWER(str[0]) == 'v' || TOLOWER(str[0]) == 'f')
+      && (TOLOWER(str[1]) == 'r'))
     {
       /* It is fpu register.  */
       s = &str[2];
@@ -2931,10 +3063,10 @@ 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,
-                                                         macro_name);
-  csky_insn.opcode = (struct csky_opcode *) hash_find (csky_opcodes_hash,
-                                                       name);
+  csky_insn.macro = (struct csky_macro_info *) str_hash_find (csky_macros_hash,
+                                                             macro_name);
+  csky_insn.opcode = (struct csky_opcode *) str_hash_find (csky_opcodes_hash,
+                                                          name);
 
   if (csky_insn.macro == NULL && csky_insn.opcode == NULL)
     return FALSE;
@@ -3155,7 +3287,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;
@@ -3189,7 +3321,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 +3355,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 +3405,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 +4275,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;
 }
 
@@ -4902,6 +5035,7 @@ md_apply_fix (fixS   *fixP,
           struct tls_addend *ta = &(fixP->tc_fix_data);
           fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
                              - (ta->frag->fr_address + ta->offset));
+          *valP = fixP->fx_offset;
         }
         /* Fall through.  */
        case BFD_RELOC_CKCORE_TLS_LE32:
@@ -4963,6 +5097,7 @@ md_apply_fix (fixS   *fixP,
        struct tls_addend *ta = &(fixP->tc_fix_data);
        fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
                           - (ta->frag->fr_address + ta->offset));
+       *valP = fixP->fx_offset;
       }
       /* Fall through.  */
     case BFD_RELOC_CKCORE_TLS_LE32:
@@ -5953,7 +6088,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;
 
@@ -6291,7 +6426,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)
     {
@@ -6329,7 +6464,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;
 
@@ -6347,7 +6482,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)
     {
@@ -6898,7 +7033,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,
@@ -6908,6 +7044,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.033346 seconds and 4 git commands to generate.