Home | History | Annotate | Line # | Download | only in config
tc-loongarch.c revision 1.1.1.2
      1      1.1  christos /* tc-loongarch.c -- Assemble for the LoongArch ISA
      2      1.1  christos 
      3  1.1.1.2  christos    Copyright (C) 2021-2024 Free Software Foundation, Inc.
      4      1.1  christos    Contributed by Loongson Ltd.
      5      1.1  christos 
      6      1.1  christos    This file is part of GAS.
      7      1.1  christos 
      8      1.1  christos    GAS is free software; you can redistribute it and/or modify
      9      1.1  christos    it under the terms of the GNU General Public License as published by
     10      1.1  christos    the Free Software Foundation; either version 3 of the license, or
     11      1.1  christos    (at your option) any later version.
     12      1.1  christos 
     13      1.1  christos    GAS is distributed in the hope that it will be useful,
     14      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16      1.1  christos    GNU General Public License for more details.
     17      1.1  christos 
     18      1.1  christos    You should have received a copy of the GNU General Public License
     19      1.1  christos    along with this program; see the file COPYING3.  If not,
     20      1.1  christos    see <http://www.gnu.org/licenses/>.  */
     21      1.1  christos 
     22      1.1  christos #include "as.h"
     23  1.1.1.2  christos #include "subsegs.h"
     24      1.1  christos #include "dw2gencfi.h"
     25      1.1  christos #include "loongarch-lex.h"
     26      1.1  christos #include "elf/loongarch.h"
     27      1.1  christos #include "opcode/loongarch.h"
     28      1.1  christos #include "obj-elf.h"
     29      1.1  christos #include "bfd/elfxx-loongarch.h"
     30      1.1  christos #include <stdlib.h>
     31      1.1  christos #include <string.h>
     32      1.1  christos #include <stdio.h>
     33      1.1  christos #include <assert.h>
     34      1.1  christos 
     35      1.1  christos /* All information about an instruction during assemble.  */
     36      1.1  christos struct loongarch_cl_insn
     37      1.1  christos {
     38      1.1  christos   /* First split string.  */
     39      1.1  christos   const char *name;
     40      1.1  christos   const char *arg_strs[MAX_ARG_NUM_PLUS_2];
     41      1.1  christos   size_t arg_num;
     42      1.1  christos 
     43      1.1  christos   /* Second analyze name_str and each actual args string to match the insn
     44      1.1  christos      in 'loongarch-opc.c'. And actual args may need be relocated.
     45      1.1  christos      We get length of insn.  If 'insn_length == 0 && insn_mo->macro != NULL',
     46      1.1  christos      it's a macro insntruction and we call 'md_assemble' recursively
     47      1.1  christos      after expanding it.  */
     48      1.1  christos   int match_now;
     49      1.1  christos   int all_match;
     50      1.1  christos 
     51      1.1  christos   const struct loongarch_opcode *insn;
     52      1.1  christos   size_t insn_length;
     53      1.1  christos 
     54      1.1  christos   offsetT args[MAX_ARG_NUM_PLUS_2];
     55      1.1  christos   struct reloc_info reloc_info[MAX_RELOC_NUMBER_A_INSN];
     56      1.1  christos   size_t reloc_num;
     57      1.1  christos 
     58      1.1  christos   /* For relax reserved.  We not support relax now.
     59      1.1  christos      'insn_length < relax_max_length' means need to relax.
     60      1.1  christos      And 'insn_length == relax_max_length' means no need to relax.  */
     61      1.1  christos   size_t relax_max_length;
     62      1.1  christos   relax_substateT subtype;
     63      1.1  christos 
     64      1.1  christos   /* Then we get the binary representation of insn
     65      1.1  christos      and write it in to section.  */
     66      1.1  christos   insn_t insn_bin;
     67      1.1  christos 
     68      1.1  christos   /* The frag that contains the instruction.  */
     69      1.1  christos   struct frag *frag;
     70      1.1  christos   /* The offset into FRAG of the first instruction byte.  */
     71      1.1  christos   long where;
     72      1.1  christos   /* The relocs associated with the instruction, if any.  */
     73      1.1  christos   fixS *fixp[MAX_RELOC_NUMBER_A_INSN];
     74  1.1.1.2  christos   /* Represents macros or instructions expanded from macro.
     75  1.1.1.2  christos      For la.local -> la.pcrel or la.pcrel -> pcalau12i + addi.d, la.pcrel,
     76  1.1.1.2  christos      pcalau12i and addi.d are expanded from macro.
     77  1.1.1.2  christos      The first bit represents expanded from one register macro (e.g.
     78  1.1.1.2  christos      la.local $t0, symbol) and emit R_LARCH_RELAX relocations.
     79  1.1.1.2  christos      The second bit represents expanded from two registers macro (e.g.
     80  1.1.1.2  christos      la.local $t0, $t1, symbol) and not emit R_LARCH_RELAX relocations.
     81  1.1.1.2  christos 
     82  1.1.1.2  christos      The macros or instructions expanded from macros do not output register
     83  1.1.1.2  christos      deprecated warning.  */
     84  1.1.1.2  christos   unsigned int expand_from_macro;
     85      1.1  christos };
     86      1.1  christos 
     87      1.1  christos #ifndef DEFAULT_ARCH
     88      1.1  christos #define DEFAULT_ARCH "loongarch64"
     89      1.1  christos #endif
     90      1.1  christos 
     91      1.1  christos /* This array holds the chars that always start a comment.  If the
     92      1.1  christos    pre-processor is disabled, these aren't very useful.  */
     93      1.1  christos const char comment_chars[] = "#";
     94      1.1  christos 
     95      1.1  christos /* This array holds the chars that only start a comment at the beginning of
     96      1.1  christos    a line.  If the line seems to have the form '# 123 filename'
     97      1.1  christos    .line and .file directives will appear in the pre-processed output.  */
     98      1.1  christos /* Note that input_file.c hand checks for '#' at the beginning of the
     99      1.1  christos    first line of the input file.  This is because the compiler outputs
    100      1.1  christos    #NO_APP at the beginning of its output.  */
    101      1.1  christos /* Also note that C style comments are always supported.  */
    102      1.1  christos const char line_comment_chars[] = "#";
    103      1.1  christos 
    104      1.1  christos /* This array holds machine specific line separator characters.  */
    105      1.1  christos const char line_separator_chars[] = ";";
    106      1.1  christos 
    107      1.1  christos /* Chars that can be used to separate mant from exp in floating point nums.  */
    108      1.1  christos const char EXP_CHARS[] = "eE";
    109      1.1  christos 
    110      1.1  christos /* Chars that mean this number is a floating point constant.  */
    111      1.1  christos /* As in 0f12.456.  */
    112      1.1  christos /* or    0d1.2345e12.  */
    113      1.1  christos const char FLT_CHARS[] = "rRsSfFdDxXpP";
    114      1.1  christos 
    115      1.1  christos const char *md_shortopts = "O::g::G:";
    116      1.1  christos 
    117      1.1  christos static const char default_arch[] = DEFAULT_ARCH;
    118      1.1  christos 
    119  1.1.1.2  christos /* The lowest 4-bit is the bytes of instructions.  */
    120  1.1.1.2  christos #define RELAX_BRANCH_16 0xc0000014
    121  1.1.1.2  christos #define RELAX_BRANCH_21 0xc0000024
    122  1.1.1.2  christos #define RELAX_BRANCH_26 0xc0000048
    123  1.1.1.2  christos 
    124  1.1.1.2  christos #define RELAX_BRANCH(x) \
    125  1.1.1.2  christos   (((x) & 0xf0000000) == 0xc0000000)
    126  1.1.1.2  christos #define RELAX_BRANCH_ENCODE(x) \
    127  1.1.1.2  christos   (BFD_RELOC_LARCH_B16 == (x) ? RELAX_BRANCH_16 : RELAX_BRANCH_21)
    128  1.1.1.2  christos 
    129      1.1  christos enum options
    130      1.1  christos {
    131      1.1  christos   OPTION_IGNORE = OPTION_MD_BASE,
    132      1.1  christos 
    133      1.1  christos   OPTION_ABI,
    134      1.1  christos   OPTION_FLOAT_ABI,
    135      1.1  christos 
    136      1.1  christos   OPTION_FLOAT_ISA,
    137      1.1  christos 
    138      1.1  christos   OPTION_LA_LOCAL_WITH_ABS,
    139      1.1  christos   OPTION_LA_GLOBAL_WITH_PCREL,
    140      1.1  christos   OPTION_LA_GLOBAL_WITH_ABS,
    141  1.1.1.2  christos   OPTION_RELAX,
    142  1.1.1.2  christos   OPTION_NO_RELAX,
    143  1.1.1.2  christos   OPTION_THIN_ADD_SUB,
    144      1.1  christos 
    145      1.1  christos   OPTION_END_OF_ENUM,
    146      1.1  christos };
    147      1.1  christos 
    148      1.1  christos struct option md_longopts[] =
    149      1.1  christos {
    150      1.1  christos   { "mabi", required_argument, NULL, OPTION_ABI },
    151      1.1  christos 
    152      1.1  christos   { "mfpu", required_argument, NULL, OPTION_FLOAT_ISA },
    153      1.1  christos 
    154      1.1  christos   { "mla-local-with-abs", no_argument, NULL, OPTION_LA_LOCAL_WITH_ABS },
    155      1.1  christos   { "mla-global-with-pcrel", no_argument, NULL, OPTION_LA_GLOBAL_WITH_PCREL },
    156      1.1  christos   { "mla-global-with-abs", no_argument, NULL, OPTION_LA_GLOBAL_WITH_ABS },
    157      1.1  christos 
    158  1.1.1.2  christos   { "mrelax", no_argument, NULL, OPTION_RELAX },
    159  1.1.1.2  christos   { "mno-relax", no_argument, NULL, OPTION_NO_RELAX },
    160  1.1.1.2  christos   { "mthin-add-sub", no_argument, NULL, OPTION_THIN_ADD_SUB},
    161  1.1.1.2  christos 
    162      1.1  christos   { NULL, no_argument, NULL, 0 }
    163      1.1  christos };
    164      1.1  christos 
    165      1.1  christos size_t md_longopts_size = sizeof (md_longopts);
    166      1.1  christos 
    167      1.1  christos int
    168      1.1  christos md_parse_option (int c, const char *arg)
    169      1.1  christos {
    170      1.1  christos   int ret = 1;
    171      1.1  christos   char lp64[256] = "";
    172      1.1  christos   char ilp32[256] = "";
    173      1.1  christos   unsigned char *suf = (unsigned char *)arg;
    174      1.1  christos 
    175  1.1.1.2  christos   lp64['s'] = lp64['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT;
    176  1.1.1.2  christos   lp64['f'] = lp64['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT;
    177  1.1.1.2  christos   lp64['d'] = lp64['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT;
    178  1.1.1.2  christos 
    179  1.1.1.2  christos   ilp32['s'] = ilp32['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT;
    180  1.1.1.2  christos   ilp32['f'] = ilp32['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT;
    181  1.1.1.2  christos   ilp32['d'] = ilp32['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT;
    182      1.1  christos 
    183      1.1  christos   switch (c)
    184      1.1  christos     {
    185      1.1  christos     case OPTION_ABI:
    186      1.1  christos       if (strncasecmp (arg, "lp64", 4) == 0 && lp64[suf[4]] != 0)
    187      1.1  christos 	{
    188      1.1  christos 	  LARCH_opts.ase_ilp32 = 1;
    189      1.1  christos 	  LARCH_opts.ase_lp64 = 1;
    190  1.1.1.2  christos 	  LARCH_opts.ase_lsx = 1;
    191  1.1.1.2  christos 	  LARCH_opts.ase_lasx = 1;
    192  1.1.1.2  christos 	  LARCH_opts.ase_lvz = 1;
    193  1.1.1.2  christos 	  LARCH_opts.ase_lbt = 1;
    194      1.1  christos 	  LARCH_opts.ase_abi = lp64[suf[4]];
    195      1.1  christos 	}
    196      1.1  christos       else if (strncasecmp (arg, "ilp32", 5) == 0 && ilp32[suf[5]] != 0)
    197      1.1  christos 	{
    198      1.1  christos 	  LARCH_opts.ase_abi = ilp32[suf[5]];
    199      1.1  christos 	  LARCH_opts.ase_ilp32 = 1;
    200      1.1  christos 	}
    201      1.1  christos       else
    202      1.1  christos 	ret = 0;
    203      1.1  christos       break;
    204      1.1  christos 
    205      1.1  christos     case OPTION_FLOAT_ISA:
    206      1.1  christos       if (strcasecmp (arg, "soft") == 0)
    207      1.1  christos 	LARCH_opts.ase_nf = 1;
    208      1.1  christos       else if (strcasecmp (arg, "single") == 0)
    209      1.1  christos 	LARCH_opts.ase_sf = 1;
    210      1.1  christos       else if (strcasecmp (arg, "double") == 0)
    211      1.1  christos 	{
    212      1.1  christos 	  LARCH_opts.ase_sf = 1;
    213      1.1  christos 	  LARCH_opts.ase_df = 1;
    214      1.1  christos 	}
    215      1.1  christos       else
    216      1.1  christos 	ret = 0;
    217      1.1  christos       break;
    218      1.1  christos 
    219      1.1  christos     case OPTION_LA_LOCAL_WITH_ABS:
    220      1.1  christos       LARCH_opts.ase_labs = 1;
    221      1.1  christos       break;
    222      1.1  christos 
    223      1.1  christos     case OPTION_LA_GLOBAL_WITH_PCREL:
    224      1.1  christos       LARCH_opts.ase_gpcr = 1;
    225      1.1  christos       break;
    226      1.1  christos 
    227      1.1  christos     case OPTION_LA_GLOBAL_WITH_ABS:
    228      1.1  christos       LARCH_opts.ase_gabs = 1;
    229      1.1  christos       break;
    230      1.1  christos 
    231  1.1.1.2  christos     case OPTION_RELAX:
    232  1.1.1.2  christos       LARCH_opts.relax = 1;
    233  1.1.1.2  christos       break;
    234  1.1.1.2  christos 
    235  1.1.1.2  christos     case OPTION_NO_RELAX:
    236  1.1.1.2  christos       LARCH_opts.relax = 0;
    237  1.1.1.2  christos       break;
    238  1.1.1.2  christos 
    239  1.1.1.2  christos     case OPTION_THIN_ADD_SUB:
    240  1.1.1.2  christos       LARCH_opts.thin_add_sub = 1;
    241  1.1.1.2  christos       break;
    242  1.1.1.2  christos 
    243      1.1  christos     case OPTION_IGNORE:
    244      1.1  christos       break;
    245      1.1  christos 
    246      1.1  christos     default:
    247      1.1  christos       ret = 0;
    248      1.1  christos       break;
    249      1.1  christos     }
    250      1.1  christos   return ret;
    251      1.1  christos }
    252      1.1  christos 
    253  1.1.1.2  christos static const char *const *r_abi_names = NULL;
    254  1.1.1.2  christos static const char *const *f_abi_names = NULL;
    255      1.1  christos static struct htab *r_htab = NULL;
    256  1.1.1.2  christos static struct htab *r_deprecated_htab = NULL;
    257      1.1  christos static struct htab *f_htab = NULL;
    258  1.1.1.2  christos static struct htab *f_deprecated_htab = NULL;
    259  1.1.1.2  christos static struct htab *fc_htab = NULL;
    260  1.1.1.2  christos static struct htab *fcn_htab = NULL;
    261      1.1  christos static struct htab *c_htab = NULL;
    262      1.1  christos static struct htab *cr_htab = NULL;
    263      1.1  christos static struct htab *v_htab = NULL;
    264      1.1  christos static struct htab *x_htab = NULL;
    265      1.1  christos 
    266      1.1  christos void
    267      1.1  christos loongarch_after_parse_args ()
    268      1.1  christos {
    269      1.1  christos   /* Set default ABI/ISA LP64D.  */
    270  1.1.1.2  christos   if (!LARCH_opts.ase_ilp32)
    271      1.1  christos     {
    272      1.1  christos       if (strcmp (default_arch, "loongarch64") == 0)
    273      1.1  christos 	{
    274  1.1.1.2  christos 	  LARCH_opts.ase_abi = EF_LOONGARCH_ABI_DOUBLE_FLOAT;
    275      1.1  christos 	  LARCH_opts.ase_ilp32 = 1;
    276      1.1  christos 	  LARCH_opts.ase_lp64 = 1;
    277  1.1.1.2  christos 	  LARCH_opts.ase_lsx = 1;
    278  1.1.1.2  christos 	  LARCH_opts.ase_lasx = 1;
    279  1.1.1.2  christos 	  LARCH_opts.ase_lvz = 1;
    280  1.1.1.2  christos 	  LARCH_opts.ase_lbt = 1;
    281      1.1  christos 	}
    282      1.1  christos       else if (strcmp (default_arch, "loongarch32") == 0)
    283      1.1  christos 	{
    284  1.1.1.2  christos 	  LARCH_opts.ase_abi = EF_LOONGARCH_ABI_DOUBLE_FLOAT;
    285      1.1  christos 	  LARCH_opts.ase_ilp32 = 1;
    286      1.1  christos 	}
    287      1.1  christos       else
    288      1.1  christos 	as_bad ("unknown default architecture `%s'", default_arch);
    289      1.1  christos     }
    290      1.1  christos 
    291  1.1.1.2  christos   LARCH_opts.ase_abi |= EF_LOONGARCH_OBJABI_V1;
    292      1.1  christos   /* Set default ISA double-float.  */
    293      1.1  christos   if (!LARCH_opts.ase_nf
    294      1.1  christos       && !LARCH_opts.ase_sf
    295      1.1  christos       && !LARCH_opts.ase_df)
    296      1.1  christos     {
    297      1.1  christos       LARCH_opts.ase_sf = 1;
    298      1.1  christos       LARCH_opts.ase_df = 1;
    299      1.1  christos     }
    300      1.1  christos 
    301      1.1  christos   size_t i;
    302      1.1  christos 
    303      1.1  christos   assert(LARCH_opts.ase_ilp32);
    304      1.1  christos 
    305      1.1  christos   /* Init ilp32/lp64 registers names.  */
    306      1.1  christos   if (!r_htab)
    307      1.1  christos     r_htab = str_htab_create (), str_hash_insert (r_htab, "", 0, 0);
    308  1.1.1.2  christos   if (!r_deprecated_htab)
    309  1.1.1.2  christos     r_deprecated_htab = str_htab_create (),
    310  1.1.1.2  christos 			str_hash_insert (r_deprecated_htab, "", 0, 0);
    311      1.1  christos 
    312  1.1.1.2  christos   r_abi_names = loongarch_r_normal_name;
    313      1.1  christos   for (i = 0; i < ARRAY_SIZE (loongarch_r_normal_name); i++)
    314      1.1  christos     str_hash_insert (r_htab, loongarch_r_normal_name[i], (void *) (i + 1), 0);
    315      1.1  christos 
    316  1.1.1.2  christos   /* Init ilp32/lp64 registers alias.  */
    317  1.1.1.2  christos   r_abi_names = loongarch_r_alias;
    318  1.1.1.2  christos   for (i = 0; i < ARRAY_SIZE (loongarch_r_alias); i++)
    319  1.1.1.2  christos     str_hash_insert (r_htab, loongarch_r_alias[i], (void *) (i + 1), 0);
    320  1.1.1.2  christos 
    321  1.1.1.2  christos   for (i = 0; i < ARRAY_SIZE (loongarch_r_alias_1); i++)
    322  1.1.1.2  christos     str_hash_insert (r_htab, loongarch_r_alias_1[i], (void *) (i + 1), 0);
    323  1.1.1.2  christos 
    324  1.1.1.2  christos   for (i = 0; i < ARRAY_SIZE (loongarch_r_alias_deprecated); i++)
    325  1.1.1.2  christos     str_hash_insert (r_deprecated_htab, loongarch_r_alias_deprecated[i],
    326  1.1.1.2  christos 	(void *) (i + 1), 0);
    327  1.1.1.2  christos 
    328      1.1  christos   if (!cr_htab)
    329      1.1  christos     cr_htab = str_htab_create (), str_hash_insert (cr_htab, "", 0, 0);
    330      1.1  christos 
    331      1.1  christos   for (i = 0; i < ARRAY_SIZE (loongarch_cr_normal_name); i++)
    332      1.1  christos     str_hash_insert (cr_htab, loongarch_cr_normal_name[i], (void *) (i + 1), 0);
    333      1.1  christos 
    334      1.1  christos   /* Init single/double float registers names.  */
    335      1.1  christos   if (LARCH_opts.ase_sf || LARCH_opts.ase_df)
    336      1.1  christos     {
    337      1.1  christos       if (!f_htab)
    338      1.1  christos 	f_htab = str_htab_create (), str_hash_insert (f_htab, "", 0, 0);
    339  1.1.1.2  christos       if (!f_deprecated_htab)
    340  1.1.1.2  christos 	f_deprecated_htab = str_htab_create (),
    341  1.1.1.2  christos 			    str_hash_insert (f_deprecated_htab, "", 0, 0);
    342      1.1  christos 
    343  1.1.1.2  christos       f_abi_names = loongarch_f_normal_name;
    344      1.1  christos       for (i = 0; i < ARRAY_SIZE (loongarch_f_normal_name); i++)
    345      1.1  christos 	str_hash_insert (f_htab, loongarch_f_normal_name[i], (void *) (i + 1),
    346      1.1  christos 			 0);
    347      1.1  christos 
    348  1.1.1.2  christos       /* Init float-ilp32/lp64 registers alias.  */
    349  1.1.1.2  christos       f_abi_names = loongarch_f_alias;
    350  1.1.1.2  christos       for (i = 0; i < ARRAY_SIZE (loongarch_f_alias); i++)
    351  1.1.1.2  christos 	str_hash_insert (f_htab, loongarch_f_alias[i],
    352  1.1.1.2  christos 	    (void *) (i + 1), 0);
    353  1.1.1.2  christos       for (i = 0; i < ARRAY_SIZE (loongarch_f_alias_deprecated); i++)
    354  1.1.1.2  christos 	str_hash_insert (f_deprecated_htab, loongarch_f_alias_deprecated[i],
    355  1.1.1.2  christos 	    (void *) (i + 1), 0);
    356  1.1.1.2  christos 
    357  1.1.1.2  christos       if (!fc_htab)
    358  1.1.1.2  christos 	fc_htab = str_htab_create (), str_hash_insert (fc_htab, "", 0, 0);
    359  1.1.1.2  christos 
    360  1.1.1.2  christos       for (i = 0; i < ARRAY_SIZE (loongarch_fc_normal_name); i++)
    361  1.1.1.2  christos 	str_hash_insert (fc_htab, loongarch_fc_normal_name[i], (void *) (i + 1),
    362  1.1.1.2  christos 			 0);
    363  1.1.1.2  christos 
    364  1.1.1.2  christos       if (!fcn_htab)
    365  1.1.1.2  christos 	fcn_htab = str_htab_create (), str_hash_insert (fcn_htab, "", 0, 0);
    366  1.1.1.2  christos 
    367  1.1.1.2  christos       for (i = 0; i < ARRAY_SIZE (loongarch_fc_numeric_name); i++)
    368  1.1.1.2  christos 	str_hash_insert (fcn_htab, loongarch_fc_numeric_name[i], (void *) (i + 1),
    369  1.1.1.2  christos 			 0);
    370  1.1.1.2  christos 
    371      1.1  christos       if (!c_htab)
    372      1.1  christos 	c_htab = str_htab_create (), str_hash_insert (c_htab, "", 0, 0);
    373      1.1  christos 
    374      1.1  christos       for (i = 0; i < ARRAY_SIZE (loongarch_c_normal_name); i++)
    375      1.1  christos 	str_hash_insert (c_htab, loongarch_c_normal_name[i], (void *) (i + 1),
    376      1.1  christos 			 0);
    377      1.1  christos 
    378      1.1  christos     }
    379      1.1  christos 
    380      1.1  christos   /* Init lsx registers names.  */
    381      1.1  christos   if (LARCH_opts.ase_lsx)
    382      1.1  christos     {
    383      1.1  christos       if (!v_htab)
    384      1.1  christos 	v_htab = str_htab_create (), str_hash_insert (v_htab, "", 0, 0);
    385      1.1  christos       for (i = 0; i < ARRAY_SIZE (loongarch_v_normal_name); i++)
    386      1.1  christos 	str_hash_insert (v_htab, loongarch_v_normal_name[i], (void *) (i + 1),
    387      1.1  christos 			 0);
    388      1.1  christos     }
    389      1.1  christos 
    390      1.1  christos   /* Init lasx registers names.  */
    391      1.1  christos   if (LARCH_opts.ase_lasx)
    392      1.1  christos     {
    393      1.1  christos       if (!x_htab)
    394      1.1  christos 	x_htab = str_htab_create (), str_hash_insert (x_htab, "", 0, 0);
    395      1.1  christos       for (i = 0; i < ARRAY_SIZE (loongarch_x_normal_name); i++)
    396      1.1  christos 	str_hash_insert (x_htab, loongarch_x_normal_name[i], (void *) (i + 1),
    397      1.1  christos 			 0);
    398      1.1  christos     }
    399      1.1  christos 
    400      1.1  christos }
    401      1.1  christos 
    402      1.1  christos const char *
    403      1.1  christos loongarch_target_format ()
    404      1.1  christos {
    405      1.1  christos   return LARCH_opts.ase_lp64 ? "elf64-loongarch" : "elf32-loongarch";
    406      1.1  christos }
    407      1.1  christos 
    408      1.1  christos void
    409      1.1  christos md_begin ()
    410      1.1  christos {
    411      1.1  christos   const struct loongarch_opcode *it;
    412      1.1  christos   struct loongarch_ase *ase;
    413      1.1  christos   for (ase = loongarch_ASEs; ase->enabled; ase++)
    414      1.1  christos     for (it = ase->opcodes; it->name; it++)
    415      1.1  christos       {
    416      1.1  christos 	if (loongarch_check_format (it->format) != 0)
    417      1.1  christos 	  as_fatal (_("insn name: %s\tformat: %s\tsyntax error"),
    418      1.1  christos 		    it->name, it->format);
    419      1.1  christos 	if (it->mask == 0 && it->macro == 0)
    420      1.1  christos 	  as_fatal (_("insn name: %s\nformat: %s\nwe want macro but "
    421      1.1  christos 		      "macro is NULL"),
    422      1.1  christos 		    it->name, it->format);
    423      1.1  christos 	if (it->macro
    424      1.1  christos 	    && loongarch_check_macro (it->format, it->macro) != 0)
    425      1.1  christos 	  as_fatal (_("insn name: %s\nformat: %s\nmacro: %s\tsyntax error"),
    426      1.1  christos 		    it->name, it->format, it->macro);
    427      1.1  christos       }
    428      1.1  christos 
    429      1.1  christos   /* FIXME: expressionS use 'offsetT' as constant,
    430      1.1  christos    * we want this is 64-bit type.  */
    431      1.1  christos   assert (8 <= sizeof (offsetT));
    432      1.1  christos }
    433      1.1  christos 
    434      1.1  christos unsigned long
    435      1.1  christos loongarch_mach (void)
    436      1.1  christos {
    437      1.1  christos   return LARCH_opts.ase_lp64 ? bfd_mach_loongarch64 : bfd_mach_loongarch32;
    438      1.1  christos }
    439      1.1  christos 
    440      1.1  christos static const expressionS const_0 = { .X_op = O_constant, .X_add_number = 0 };
    441      1.1  christos 
    442      1.1  christos /* Handle the .dtprelword and .dtpreldword pseudo-ops.  They generate
    443      1.1  christos    a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
    444      1.1  christos    use in DWARF debug information.  */
    445      1.1  christos 
    446      1.1  christos static void
    447      1.1  christos s_dtprel (int bytes)
    448      1.1  christos {
    449      1.1  christos   expressionS ex;
    450      1.1  christos   char *p;
    451      1.1  christos 
    452      1.1  christos   expression (&ex);
    453      1.1  christos 
    454      1.1  christos   if (ex.X_op != O_symbol)
    455      1.1  christos     {
    456      1.1  christos       as_bad (_("Unsupported use of %s"),
    457      1.1  christos 	      (bytes == 8 ? ".dtpreldword" : ".dtprelword"));
    458      1.1  christos       ignore_rest_of_line ();
    459      1.1  christos     }
    460      1.1  christos 
    461      1.1  christos   p = frag_more (bytes);
    462      1.1  christos   md_number_to_chars (p, 0, bytes);
    463      1.1  christos   fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
    464      1.1  christos 	       (bytes == 8
    465      1.1  christos 		? BFD_RELOC_LARCH_TLS_DTPREL64
    466      1.1  christos 		: BFD_RELOC_LARCH_TLS_DTPREL32));
    467      1.1  christos 
    468      1.1  christos   demand_empty_rest_of_line ();
    469      1.1  christos }
    470      1.1  christos 
    471      1.1  christos static const pseudo_typeS loongarch_pseudo_table[] =
    472      1.1  christos {
    473      1.1  christos   { "dword", cons, 8 },
    474      1.1  christos   { "word", cons, 4 },
    475      1.1  christos   { "half", cons, 2 },
    476      1.1  christos   { "dtprelword", s_dtprel, 4 },
    477      1.1  christos   { "dtpreldword", s_dtprel, 8 },
    478      1.1  christos   { NULL, NULL, 0 },
    479      1.1  christos };
    480      1.1  christos 
    481      1.1  christos void
    482      1.1  christos loongarch_pop_insert (void)
    483      1.1  christos {
    484      1.1  christos   pop_insert (loongarch_pseudo_table);
    485      1.1  christos }
    486      1.1  christos 
    487      1.1  christos #define INTERNAL_LABEL_SPECIAL 10
    488      1.1  christos static unsigned long internal_label_count[INTERNAL_LABEL_SPECIAL] = { 0 };
    489      1.1  christos 
    490      1.1  christos static const char *
    491      1.1  christos loongarch_internal_label_name (unsigned long label, int augend)
    492      1.1  christos {
    493      1.1  christos   static char symbol_name_build[24];
    494      1.1  christos   unsigned long want_label;
    495      1.1  christos   char *p;
    496      1.1  christos 
    497      1.1  christos   want_label = internal_label_count[label] + augend;
    498      1.1  christos 
    499      1.1  christos   p = symbol_name_build;
    500      1.1  christos #ifdef LOCAL_LABEL_PREFIX
    501      1.1  christos   *p++ = LOCAL_LABEL_PREFIX;
    502      1.1  christos #endif
    503      1.1  christos   *p++ = 'L';
    504      1.1  christos   for (; label; label /= 10)
    505      1.1  christos     *p++ = label % 10 + '0';
    506      1.1  christos   /* Make sure internal label never belong to normal label namespace.  */
    507      1.1  christos   *p++ = ':';
    508      1.1  christos   for (; want_label; want_label /= 10)
    509      1.1  christos     *p++ = want_label % 10 + '0';
    510      1.1  christos   *p++ = '\0';
    511      1.1  christos   return symbol_name_build;
    512      1.1  christos }
    513      1.1  christos 
    514      1.1  christos static void
    515      1.1  christos setup_internal_label_here (unsigned long label)
    516      1.1  christos {
    517      1.1  christos   assert (label < INTERNAL_LABEL_SPECIAL);
    518      1.1  christos   internal_label_count[label]++;
    519      1.1  christos   colon (loongarch_internal_label_name (label, 0));
    520      1.1  christos }
    521      1.1  christos 
    522      1.1  christos void
    523      1.1  christos get_internal_label (expressionS *label_expr, unsigned long label,
    524      1.1  christos 		    int augend /* 0 for previous, 1 for next.  */)
    525      1.1  christos {
    526      1.1  christos   assert (label < INTERNAL_LABEL_SPECIAL);
    527      1.1  christos     as_fatal (_("internal error: we have no internal label yet"));
    528      1.1  christos   label_expr->X_op = O_symbol;
    529      1.1  christos   label_expr->X_add_symbol =
    530      1.1  christos     symbol_find_or_make (loongarch_internal_label_name (label, augend));
    531      1.1  christos   label_expr->X_add_number = 0;
    532      1.1  christos }
    533      1.1  christos 
    534      1.1  christos static int
    535      1.1  christos is_internal_label (const char *c_str)
    536      1.1  christos {
    537      1.1  christos   do
    538      1.1  christos     {
    539      1.1  christos       if (*c_str != ':')
    540      1.1  christos 	break;
    541      1.1  christos       c_str++;
    542      1.1  christos       if (!('0' <= *c_str && *c_str <= '9'))
    543      1.1  christos 	break;
    544      1.1  christos       while ('0' <= *c_str && *c_str <= '9')
    545      1.1  christos 	c_str++;
    546      1.1  christos       if (*c_str != 'b' && *c_str != 'f')
    547      1.1  christos 	break;
    548      1.1  christos       c_str++;
    549      1.1  christos       return *c_str == '\0';
    550      1.1  christos     }
    551      1.1  christos   while (0);
    552      1.1  christos   return 0;
    553      1.1  christos }
    554      1.1  christos 
    555      1.1  christos static int
    556      1.1  christos is_label (const char *c_str)
    557      1.1  christos {
    558      1.1  christos   if (is_internal_label (c_str))
    559      1.1  christos     return 1;
    560      1.1  christos   else if ('0' <= *c_str && *c_str <= '9')
    561      1.1  christos     {
    562      1.1  christos       /* [0-9]+[bf]  */
    563      1.1  christos       while ('0' <= *c_str && *c_str <= '9')
    564      1.1  christos 	c_str++;
    565      1.1  christos       return *c_str == 'b' || *c_str == 'f';
    566      1.1  christos     }
    567      1.1  christos   else if (is_name_beginner (*c_str))
    568      1.1  christos     {
    569      1.1  christos       /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]*  */
    570      1.1  christos       c_str++;
    571      1.1  christos       while (is_part_of_name (*c_str))
    572      1.1  christos 	c_str++;
    573      1.1  christos       return *c_str == '\0';
    574      1.1  christos     }
    575      1.1  christos   else
    576      1.1  christos     return 0;
    577      1.1  christos }
    578      1.1  christos 
    579      1.1  christos static int
    580      1.1  christos is_label_with_addend (const char *c_str)
    581      1.1  christos {
    582      1.1  christos   if (is_internal_label (c_str))
    583      1.1  christos     return 1;
    584      1.1  christos   else if ('0' <= *c_str && *c_str <= '9')
    585      1.1  christos     {
    586      1.1  christos       /* [0-9]+[bf]  */
    587      1.1  christos       while ('0' <= *c_str && *c_str <= '9')
    588      1.1  christos 	c_str++;
    589      1.1  christos       if (*c_str == 'b' || *c_str == 'f')
    590      1.1  christos 	c_str++;
    591      1.1  christos       else
    592      1.1  christos 	return 0;
    593      1.1  christos       return *c_str == '\0'
    594      1.1  christos 		       || ((*c_str == '-' || *c_str == '+')
    595      1.1  christos 			   && is_unsigned (c_str + 1));
    596      1.1  christos     }
    597      1.1  christos   else if (is_name_beginner (*c_str))
    598      1.1  christos     {
    599      1.1  christos       /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]*  */
    600      1.1  christos       c_str++;
    601      1.1  christos       while (is_part_of_name (*c_str))
    602      1.1  christos 	c_str++;
    603      1.1  christos       return *c_str == '\0'
    604      1.1  christos 		       || ((*c_str == '-' || *c_str == '+')
    605      1.1  christos 			   && is_unsigned (c_str + 1));
    606      1.1  christos     }
    607      1.1  christos   else
    608      1.1  christos     return 0;
    609      1.1  christos }
    610      1.1  christos 
    611      1.1  christos static int32_t
    612      1.1  christos loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
    613      1.1  christos 					    const char *bit_field,
    614      1.1  christos 					    const char *arg, void *context)
    615      1.1  christos {
    616      1.1  christos   struct loongarch_cl_insn *ip = context;
    617      1.1  christos   offsetT imm, ret = 0;
    618      1.1  christos   size_t reloc_num_we_have = MAX_RELOC_NUMBER_A_INSN - ip->reloc_num;
    619      1.1  christos   size_t reloc_num = 0;
    620      1.1  christos 
    621      1.1  christos   if (!ip->match_now)
    622      1.1  christos     return 0;
    623      1.1  christos 
    624      1.1  christos   switch (esc_ch1)
    625      1.1  christos     {
    626      1.1  christos     case 'l':
    627      1.1  christos       switch (esc_ch2)
    628      1.1  christos 	{
    629      1.1  christos 	default:
    630      1.1  christos 	  ip->match_now = is_label (arg);
    631      1.1  christos 	  if (!ip->match_now && is_label_with_addend (arg))
    632      1.1  christos 	    as_fatal (_("This label shouldn't be with addend."));
    633      1.1  christos 	  break;
    634      1.1  christos 	case 'a':
    635      1.1  christos 	  ip->match_now = is_label_with_addend (arg);
    636      1.1  christos 	  break;
    637      1.1  christos 	}
    638      1.1  christos       break;
    639  1.1.1.2  christos     /* This is used for TLS, where the fourth operand is %le_add_r,
    640  1.1.1.2  christos        to get a relocation applied to an add instruction, for relaxation to use.
    641  1.1.1.2  christos        Two conditions, ip->match_now and reloc_num, are used to check tls insn
    642  1.1.1.2  christos        to prevent cases like add.d $a0,$a0,$a0,8.  */
    643  1.1.1.2  christos     case 't':
    644  1.1.1.2  christos       ip->match_now = loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num,
    645  1.1.1.2  christos 				reloc_num_we_have, &reloc_num, &imm) == 0;
    646      1.1  christos 
    647      1.1  christos       if (!ip->match_now)
    648      1.1  christos 	break;
    649      1.1  christos 
    650  1.1.1.2  christos       bfd_reloc_code_real_type tls_reloc_type = BFD_RELOC_LARCH_TLS_LE_ADD_R;
    651  1.1.1.2  christos 
    652  1.1.1.2  christos       if (reloc_num
    653  1.1.1.2  christos 	  && (ip->reloc_info[ip->reloc_num].type == tls_reloc_type))
    654  1.1.1.2  christos 	{
    655  1.1.1.2  christos 	  ip->reloc_num += reloc_num;
    656  1.1.1.2  christos 	  ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
    657  1.1.1.2  christos 	  ip->reloc_info[ip->reloc_num].value = const_0;
    658  1.1.1.2  christos 	  ip->reloc_num++;
    659  1.1.1.2  christos 	}
    660      1.1  christos       else
    661  1.1.1.2  christos 	ip->match_now = 0;
    662  1.1.1.2  christos       break;
    663  1.1.1.2  christos     case 's':
    664  1.1.1.2  christos     case 'u':
    665  1.1.1.2  christos       ip->match_now =
    666  1.1.1.2  christos 	loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num,
    667  1.1.1.2  christos 			      reloc_num_we_have, &reloc_num, &imm) == 0;
    668      1.1  christos 
    669      1.1  christos       if (!ip->match_now)
    670      1.1  christos 	break;
    671      1.1  christos 
    672      1.1  christos       ret = imm;
    673      1.1  christos       if (reloc_num)
    674      1.1  christos 	{
    675      1.1  christos 	  bfd_reloc_code_real_type reloc_type = BFD_RELOC_NONE;
    676      1.1  christos 	  reloc_num_we_have -= reloc_num;
    677      1.1  christos 	  if (reloc_num_we_have == 0)
    678      1.1  christos 	    as_fatal (_("expr too huge") /* Want one more reloc.  */);
    679      1.1  christos 	  if (esc_ch1 == 'u')
    680      1.1  christos 	    {
    681      1.1  christos 	      if (strncmp (bit_field, "10:12", strlen ("10:12")) == 0)
    682      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_U_10_12;
    683      1.1  christos 	    }
    684      1.1  christos 	  else if (esc_ch1 == 's')
    685      1.1  christos 	    {
    686      1.1  christos 	      if (strncmp (bit_field, "10:16<<2", strlen ("10:16<<2")) == 0)
    687      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2;
    688      1.1  christos 	      else if (strncmp (bit_field, "0:5|10:16<<2",
    689      1.1  christos 				strlen ("0:5|10:16<<2")) == 0)
    690      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2;
    691      1.1  christos 	      else if (strncmp (bit_field, "0:10|10:16<<2",
    692      1.1  christos 				strlen ("0:10|10:16<<2")) == 0)
    693      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2;
    694      1.1  christos 	      else if (strncmp (bit_field, "10:12", strlen ("10:12")) == 0)
    695      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_12;
    696      1.1  christos 	      else if (strncmp (bit_field, "5:20", strlen ("5:20")) == 0)
    697      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_5_20;
    698      1.1  christos 	      else if (strncmp (bit_field, "10:16", strlen ("10:16")) == 0)
    699      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_16;
    700      1.1  christos 	      else if (strncmp (bit_field, "10:5", strlen ("10:5")) == 0)
    701      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_5;
    702      1.1  christos 	    }
    703      1.1  christos 	  if (reloc_type == BFD_RELOC_NONE)
    704      1.1  christos 	    as_fatal (
    705      1.1  christos 		      _("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"),
    706      1.1  christos 		      esc_ch1, esc_ch2, bit_field, arg);
    707  1.1.1.2  christos 
    708  1.1.1.2  christos 	  if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16
    709  1.1.1.2  christos 	      && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2)
    710  1.1.1.2  christos 	    {
    711  1.1.1.2  christos 	      /* As we compact stack-relocs, it is no need for pop operation.
    712  1.1.1.2  christos 		 But break out until here in order to check the imm field.
    713  1.1.1.2  christos 		 May be reloc_num > 1 if implement relax?  */
    714  1.1.1.2  christos 	      ip->reloc_num += reloc_num;
    715  1.1.1.2  christos 	      reloc_type = ip->reloc_info[0].type;
    716  1.1.1.2  christos 
    717  1.1.1.2  christos 	      if (LARCH_opts.relax
    718  1.1.1.2  christos 		    && (BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_type
    719  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_LE_LO12_R == reloc_type))
    720  1.1.1.2  christos 		{
    721  1.1.1.2  christos 		  ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
    722  1.1.1.2  christos 		  ip->reloc_info[ip->reloc_num].value = const_0;
    723  1.1.1.2  christos 		  ip->reloc_num++;
    724  1.1.1.2  christos 		}
    725  1.1.1.2  christos 
    726  1.1.1.2  christos 	      /* Only one register macros (used in normal code model)
    727  1.1.1.2  christos 		 emit R_LARCH_RELAX.
    728  1.1.1.2  christos 		 LARCH_opts.ase_labs and LARCH_opts.ase_gabs are used
    729  1.1.1.2  christos 		 to generate the code model of absolute addresses, and
    730  1.1.1.2  christos 		 we do not relax this code model.  */
    731  1.1.1.2  christos 	      if (LARCH_opts.relax && (ip->expand_from_macro & 1)
    732  1.1.1.2  christos 		    && ! (LARCH_opts.ase_labs | LARCH_opts.ase_gabs)
    733  1.1.1.2  christos 		    && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_type
    734  1.1.1.2  christos 			|| BFD_RELOC_LARCH_PCALA_LO12 == reloc_type
    735  1.1.1.2  christos 			|| BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_type
    736  1.1.1.2  christos 			|| BFD_RELOC_LARCH_GOT_PC_LO12 == reloc_type
    737  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_type
    738  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_type
    739  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_type
    740  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_type
    741  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_DESC_LD == reloc_type
    742  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_DESC_CALL == reloc_type
    743  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_type
    744  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_IE_PC_LO12 == reloc_type))
    745  1.1.1.2  christos 		{
    746  1.1.1.2  christos 		  ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
    747  1.1.1.2  christos 		  ip->reloc_info[ip->reloc_num].value = const_0;
    748  1.1.1.2  christos 		  ip->reloc_num++;
    749  1.1.1.2  christos 		}
    750  1.1.1.2  christos 	      break;
    751  1.1.1.2  christos 	    }
    752      1.1  christos 	  reloc_num++;
    753      1.1  christos 	  ip->reloc_num += reloc_num;
    754      1.1  christos 	  ip->reloc_info[ip->reloc_num - 1].type = reloc_type;
    755      1.1  christos 	  ip->reloc_info[ip->reloc_num - 1].value = const_0;
    756      1.1  christos 	}
    757      1.1  christos       break;
    758      1.1  christos     case 'r':
    759      1.1  christos       imm = (intptr_t) str_hash_find (r_htab, arg);
    760      1.1  christos       ip->match_now = 0 < imm;
    761      1.1  christos       ret = imm - 1;
    762  1.1.1.2  christos       if (ip->match_now)
    763  1.1.1.2  christos 	break;
    764  1.1.1.2  christos       /* Handle potential usage of deprecated register aliases.  */
    765  1.1.1.2  christos       imm = (intptr_t) str_hash_find (r_deprecated_htab, arg);
    766  1.1.1.2  christos       ip->match_now = 0 < imm;
    767  1.1.1.2  christos       ret = imm - 1;
    768  1.1.1.2  christos       /* !ip->expand_from_macro: avoiding duplicate output warnings,
    769  1.1.1.2  christos 	 only the first macro output warning.  */
    770  1.1.1.2  christos       if (ip->match_now && !ip->expand_from_macro)
    771  1.1.1.2  christos 	as_warn (_("register alias %s is deprecated, use %s instead"),
    772  1.1.1.2  christos 		 arg, r_abi_names[ret]);
    773      1.1  christos       break;
    774      1.1  christos     case 'f':
    775  1.1.1.2  christos       switch (esc_ch2)
    776  1.1.1.2  christos 	{
    777  1.1.1.2  christos 	case 'c':
    778  1.1.1.2  christos 	  imm = (intptr_t) str_hash_find (fc_htab, arg);
    779  1.1.1.2  christos 	  if (0 >= imm)
    780  1.1.1.2  christos 	    {
    781  1.1.1.2  christos 	      imm = (intptr_t) str_hash_find (fcn_htab, arg);
    782  1.1.1.2  christos 	    }
    783  1.1.1.2  christos 	  break;
    784  1.1.1.2  christos 	default:
    785  1.1.1.2  christos 	  imm = (intptr_t) str_hash_find (f_htab, arg);
    786  1.1.1.2  christos 	}
    787  1.1.1.2  christos       ip->match_now = 0 < imm;
    788  1.1.1.2  christos       ret = imm - 1;
    789  1.1.1.2  christos       if (ip->match_now && !ip->expand_from_macro)
    790  1.1.1.2  christos 	break;
    791  1.1.1.2  christos       /* Handle potential usage of deprecated register aliases.  */
    792  1.1.1.2  christos       imm = (intptr_t) str_hash_find (f_deprecated_htab, arg);
    793      1.1  christos       ip->match_now = 0 < imm;
    794      1.1  christos       ret = imm - 1;
    795  1.1.1.2  christos       if (ip->match_now)
    796  1.1.1.2  christos 	as_warn (_("register alias %s is deprecated, use %s instead"),
    797  1.1.1.2  christos 		 arg, f_abi_names[ret]);
    798      1.1  christos       break;
    799      1.1  christos     case 'c':
    800      1.1  christos       switch (esc_ch2)
    801      1.1  christos 	{
    802      1.1  christos 	case 'r':
    803      1.1  christos 	  imm = (intptr_t) str_hash_find (cr_htab, arg);
    804      1.1  christos 	  break;
    805      1.1  christos 	default:
    806      1.1  christos 	  imm = (intptr_t) str_hash_find (c_htab, arg);
    807      1.1  christos 	}
    808      1.1  christos       ip->match_now = 0 < imm;
    809      1.1  christos       ret = imm - 1;
    810      1.1  christos       break;
    811      1.1  christos     case 'v':
    812      1.1  christos       imm = (intptr_t) str_hash_find (v_htab, arg);
    813      1.1  christos       ip->match_now = 0 < imm;
    814      1.1  christos       ret = imm - 1;
    815      1.1  christos       break;
    816      1.1  christos     case 'x':
    817      1.1  christos       imm = (intptr_t) str_hash_find (x_htab, arg);
    818      1.1  christos       ip->match_now = 0 < imm;
    819      1.1  christos       ret = imm - 1;
    820      1.1  christos       break;
    821      1.1  christos     case '\0':
    822      1.1  christos       ip->all_match = ip->match_now;
    823      1.1  christos       ip->insn_length =
    824      1.1  christos 	ip->insn->mask ? loongarch_insn_length (ip->insn->match) : 0;
    825      1.1  christos       /* FIXME: now we have no relax insn.  */
    826      1.1  christos       ip->relax_max_length = ip->insn_length;
    827      1.1  christos       break;
    828      1.1  christos     default:
    829      1.1  christos       as_fatal (_("unknown escape"));
    830      1.1  christos     }
    831      1.1  christos 
    832      1.1  christos   do
    833      1.1  christos     {
    834      1.1  christos       /* Check imm overflow.  */
    835      1.1  christos       int bit_width, bits_needed_s, bits_needed_u;
    836      1.1  christos       char *t;
    837      1.1  christos 
    838      1.1  christos       if (!ip->match_now)
    839      1.1  christos 	break;
    840      1.1  christos 
    841      1.1  christos       if (0 < reloc_num)
    842      1.1  christos 	break;
    843      1.1  christos 
    844      1.1  christos       bit_width = loongarch_get_bit_field_width (bit_field, &t);
    845      1.1  christos 
    846      1.1  christos       if (bit_width == -1)
    847      1.1  christos 	/* No specify bit width.  */
    848      1.1  christos 	break;
    849      1.1  christos 
    850      1.1  christos       imm = ret;
    851      1.1  christos       if (t[0] == '<' && t[1] == '<')
    852      1.1  christos 	{
    853      1.1  christos 	  int i = strtol (t += 2, &t, 10), j;
    854      1.1  christos 	  for (j = i; 0 < j; j--, imm >>= 1)
    855      1.1  christos 	    if (imm & 1)
    856      1.1  christos 	      as_fatal (_("require imm low %d bit is 0."), i);
    857      1.1  christos 	}
    858      1.1  christos 
    859      1.1  christos       if (*t == '+')
    860      1.1  christos 	imm -= strtol (t, &t, 10);
    861      1.1  christos 
    862      1.1  christos       bits_needed_s = loongarch_bits_imm_needed (imm, 1);
    863      1.1  christos       bits_needed_u = loongarch_bits_imm_needed (imm, 0);
    864      1.1  christos 
    865      1.1  christos       if ((esc_ch1 == 's' && bit_width < bits_needed_s)
    866      1.1  christos 	  || (esc_ch1 != 's' && bit_width < bits_needed_u))
    867      1.1  christos 	/* How to do after we detect overflow.  */
    868      1.1  christos 	as_fatal (_("Immediate overflow.\n"
    869      1.1  christos 		    "format: %c%c%s\n"
    870      1.1  christos 		    "arg: %s"),
    871      1.1  christos 		  esc_ch1, esc_ch2, bit_field, arg);
    872      1.1  christos     }
    873      1.1  christos   while (0);
    874      1.1  christos 
    875      1.1  christos   if (esc_ch1 != '\0')
    876      1.1  christos     {
    877      1.1  christos       ip->args[ip->arg_num] = ret;
    878      1.1  christos       ip->arg_num++;
    879      1.1  christos     }
    880      1.1  christos   return ret;
    881      1.1  christos }
    882      1.1  christos 
    883      1.1  christos static void
    884      1.1  christos get_loongarch_opcode (struct loongarch_cl_insn *insn)
    885      1.1  christos {
    886      1.1  christos   const struct loongarch_opcode *it;
    887      1.1  christos   struct loongarch_ase *ase;
    888      1.1  christos   for (ase = loongarch_ASEs; ase->enabled; ase++)
    889      1.1  christos     {
    890      1.1  christos       if (!*ase->enabled || (ase->include && !*ase->include)
    891      1.1  christos 	  || (ase->exclude && *ase->exclude))
    892      1.1  christos 	continue;
    893      1.1  christos 
    894      1.1  christos       if (!ase->name_hash_entry)
    895      1.1  christos 	{
    896      1.1  christos 	  ase->name_hash_entry = str_htab_create ();
    897      1.1  christos 	  for (it = ase->opcodes; it->name; it++)
    898  1.1.1.2  christos 	    {
    899  1.1.1.2  christos 	      if ((!it->include || (it->include && *it->include))
    900  1.1.1.2  christos 		  && (!it->exclude || (it->exclude && !(*it->exclude)))
    901  1.1.1.2  christos 		  && !(it->pinfo & INSN_DIS_ALIAS))
    902  1.1.1.2  christos 		str_hash_insert (ase->name_hash_entry, it->name,
    903  1.1.1.2  christos 				 (void *) it, 0);
    904  1.1.1.2  christos 	    }
    905      1.1  christos 	}
    906      1.1  christos 
    907      1.1  christos       if ((it = str_hash_find (ase->name_hash_entry, insn->name)) == NULL)
    908      1.1  christos 	continue;
    909      1.1  christos 
    910      1.1  christos       do
    911      1.1  christos 	{
    912      1.1  christos 	  insn->insn = it;
    913      1.1  christos 	  insn->match_now = 1;
    914      1.1  christos 	  insn->all_match = 0;
    915      1.1  christos 	  insn->arg_num = 0;
    916      1.1  christos 	  insn->reloc_num = 0;
    917      1.1  christos 	  insn->insn_bin = (loongarch_foreach_args
    918      1.1  christos 			    (it->format, insn->arg_strs,
    919      1.1  christos 			     loongarch_args_parser_can_match_arg_helper,
    920      1.1  christos 			     insn));
    921      1.1  christos 	  if (insn->all_match && !(it->include && !*it->include)
    922      1.1  christos 	      && !(it->exclude && *it->exclude))
    923      1.1  christos 	    {
    924      1.1  christos 	      insn->insn_bin |= it->match;
    925      1.1  christos 	      return;
    926      1.1  christos 	    }
    927      1.1  christos 	  it++;
    928      1.1  christos 	}
    929      1.1  christos       while (it->name && strcasecmp (it->name, insn->name) == 0);
    930      1.1  christos     }
    931      1.1  christos }
    932      1.1  christos 
    933      1.1  christos static int
    934      1.1  christos check_this_insn_before_appending (struct loongarch_cl_insn *ip)
    935      1.1  christos {
    936      1.1  christos   int ret = 0;
    937  1.1.1.2  christos 
    938  1.1.1.2  christos   if (strncmp (ip->name, "la.abs", 6) == 0)
    939      1.1  christos     {
    940      1.1  christos       ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_MARK_LA;
    941  1.1.1.2  christos       ip->reloc_info[ip->reloc_num].value = const_0;
    942      1.1  christos       ip->reloc_num++;
    943      1.1  christos     }
    944      1.1  christos   else if (ip->insn->mask == 0xffff8000
    945  1.1.1.2  christos 	   /* amcas.b  rd, rk, rj  */
    946  1.1.1.2  christos 	   && ((ip->insn_bin & 0xfff80000) == 0x38580000
    947  1.1.1.2  christos 	       /* amswap.w  rd, rk, rj  */
    948  1.1.1.2  christos 	       || (ip->insn_bin & 0xfff00000) == 0x38600000
    949      1.1  christos 	       /* ammax_db.wu  rd, rk, rj  */
    950      1.1  christos 	       || (ip->insn_bin & 0xffff0000) == 0x38700000
    951      1.1  christos 	       /* ammin_db.wu  rd, rk, rj  */
    952      1.1  christos 	       || (ip->insn_bin & 0xffff0000) == 0x38710000))
    953      1.1  christos     {
    954      1.1  christos       /* For AMO insn amswap.[wd], amadd.[wd], etc.  */
    955      1.1  christos       if (ip->args[0] != 0
    956      1.1  christos 	  && (ip->args[0] == ip->args[1] || ip->args[0] == ip->args[2]))
    957      1.1  christos 	as_fatal (_("AMO insns require rd != base && rd != rt"
    958      1.1  christos 		    " when rd isn't $r0"));
    959      1.1  christos     }
    960      1.1  christos   else if ((ip->insn->mask == 0xffe08000
    961      1.1  christos 	    /* bstrins.w  rd, rj, msbw, lsbw  */
    962      1.1  christos 	    && (ip->insn_bin & 0xffe00000) == 0x00600000)
    963      1.1  christos 	   || (ip->insn->mask == 0xffc00000
    964      1.1  christos 	       /* bstrins.d  rd, rj, msbd, lsbd  */
    965      1.1  christos 	       && (ip->insn_bin & 0xff800000) == 0x00800000))
    966      1.1  christos     {
    967      1.1  christos       /* For bstr(ins|pick).[wd].  */
    968      1.1  christos       if (ip->args[2] < ip->args[3])
    969      1.1  christos 	as_fatal (_("bstr(ins|pick).[wd] require msbd >= lsbd"));
    970      1.1  christos     }
    971      1.1  christos   else if (ip->insn->mask != 0 && (ip->insn_bin & 0xfe0003c0) == 0x04000000
    972      1.1  christos 	   /* csrxchg  rd, rj, csr_num  */
    973      1.1  christos 	   && (strcmp ("csrxchg", ip->name) == 0))
    974      1.1  christos     as_fatal (_("csrxchg require rj != $r0 && rj != $r1"));
    975      1.1  christos 
    976      1.1  christos   return ret;
    977      1.1  christos }
    978      1.1  christos 
    979      1.1  christos static void
    980      1.1  christos install_insn (const struct loongarch_cl_insn *insn)
    981      1.1  christos {
    982      1.1  christos   char *f = insn->frag->fr_literal + insn->where;
    983      1.1  christos   if (0 < insn->insn_length)
    984      1.1  christos     md_number_to_chars (f, insn->insn_bin, insn->insn_length);
    985      1.1  christos }
    986      1.1  christos 
    987      1.1  christos static void
    988      1.1  christos move_insn (struct loongarch_cl_insn *insn, fragS *frag, long where)
    989      1.1  christos {
    990      1.1  christos   size_t i;
    991      1.1  christos   insn->frag = frag;
    992      1.1  christos   insn->where = where;
    993      1.1  christos   for (i = 0; i < insn->reloc_num; i++)
    994      1.1  christos     {
    995  1.1.1.2  christos       if (insn->fixp[i])
    996  1.1.1.2  christos 	{
    997  1.1.1.2  christos 	  insn->fixp[i]->fx_frag = frag;
    998  1.1.1.2  christos 	  insn->fixp[i]->fx_where = where;
    999  1.1.1.2  christos 	}
   1000      1.1  christos     }
   1001      1.1  christos   install_insn (insn);
   1002      1.1  christos }
   1003      1.1  christos 
   1004      1.1  christos /* Add INSN to the end of the output.  */
   1005      1.1  christos static void
   1006      1.1  christos append_fixed_insn (struct loongarch_cl_insn *insn)
   1007      1.1  christos {
   1008  1.1.1.2  christos   /* Ensure the jirl is emitted to the same frag as the pcaddu18i.  */
   1009  1.1.1.2  christos   if (BFD_RELOC_LARCH_CALL36 == insn->reloc_info[0].type)
   1010  1.1.1.2  christos     frag_grow (8);
   1011  1.1.1.2  christos 
   1012      1.1  christos   char *f = frag_more (insn->insn_length);
   1013      1.1  christos   move_insn (insn, frag_now, f - frag_now->fr_literal);
   1014      1.1  christos }
   1015      1.1  christos 
   1016  1.1.1.2  christos /* Add instructions based on the worst-case scenario firstly.  */
   1017  1.1.1.2  christos static void
   1018  1.1.1.2  christos append_relaxed_branch_insn (struct loongarch_cl_insn *insn, int max_chars,
   1019  1.1.1.2  christos 	    int var, relax_substateT subtype, symbolS *symbol, offsetT offset)
   1020  1.1.1.2  christos {
   1021  1.1.1.2  christos   frag_grow (max_chars);
   1022  1.1.1.2  christos   move_insn (insn, frag_now, frag_more (0) - frag_now->fr_literal);
   1023  1.1.1.2  christos   frag_var (rs_machine_dependent, max_chars, var,
   1024  1.1.1.2  christos 	    subtype, symbol, offset, NULL);
   1025  1.1.1.2  christos }
   1026  1.1.1.2  christos 
   1027      1.1  christos static void
   1028      1.1  christos append_fixp_and_insn (struct loongarch_cl_insn *ip)
   1029      1.1  christos {
   1030      1.1  christos   reloc_howto_type *howto;
   1031  1.1.1.2  christos   bfd_reloc_code_real_type r_type;
   1032      1.1  christos   struct reloc_info *reloc_info = ip->reloc_info;
   1033      1.1  christos   size_t i;
   1034      1.1  christos 
   1035      1.1  christos   dwarf2_emit_insn (0);
   1036      1.1  christos 
   1037      1.1  christos   for (i = 0; i < ip->reloc_num; i++)
   1038      1.1  christos     {
   1039  1.1.1.2  christos       r_type = reloc_info[i].type;
   1040  1.1.1.2  christos 
   1041  1.1.1.2  christos       if (r_type != BFD_RELOC_UNUSED)
   1042  1.1.1.2  christos 	{
   1043  1.1.1.2  christos 
   1044  1.1.1.2  christos 	  gas_assert (&(reloc_info[i].value));
   1045  1.1.1.2  christos 	  if (BFD_RELOC_LARCH_B16 == r_type || BFD_RELOC_LARCH_B21 == r_type)
   1046  1.1.1.2  christos 	    {
   1047  1.1.1.2  christos 	      int min_bytes = 4; /* One branch instruction.  */
   1048  1.1.1.2  christos 	      unsigned max_bytes = 8; /* Branch and jump instructions.  */
   1049  1.1.1.2  christos 
   1050  1.1.1.2  christos 	      if (now_seg == absolute_section)
   1051  1.1.1.2  christos 		{
   1052  1.1.1.2  christos 		  as_bad (_("relaxable branches not supported in absolute section"));
   1053  1.1.1.2  christos 		  return;
   1054  1.1.1.2  christos 		}
   1055  1.1.1.2  christos 
   1056  1.1.1.2  christos 	      append_relaxed_branch_insn (ip, max_bytes, min_bytes,
   1057  1.1.1.2  christos 					  RELAX_BRANCH_ENCODE (r_type),
   1058  1.1.1.2  christos 					  reloc_info[i].value.X_add_symbol,
   1059  1.1.1.2  christos 					  reloc_info[i].value.X_add_number);
   1060  1.1.1.2  christos 	      return;
   1061  1.1.1.2  christos 	    }
   1062  1.1.1.2  christos 	  else
   1063  1.1.1.2  christos 	    {
   1064  1.1.1.2  christos 	      howto = bfd_reloc_type_lookup (stdoutput, r_type);
   1065  1.1.1.2  christos 	      if (howto == NULL)
   1066  1.1.1.2  christos 		as_fatal (_("no HOWTO loong relocation number %d"), r_type);
   1067  1.1.1.2  christos 
   1068  1.1.1.2  christos 	      ip->fixp[i] = fix_new_exp (ip->frag, ip->where,
   1069  1.1.1.2  christos 					 bfd_get_reloc_size (howto),
   1070  1.1.1.2  christos 					 &reloc_info[i].value, FALSE, r_type);
   1071  1.1.1.2  christos 	    }
   1072  1.1.1.2  christos 	}
   1073      1.1  christos     }
   1074      1.1  christos 
   1075      1.1  christos   if (ip->insn_length < ip->relax_max_length)
   1076      1.1  christos     as_fatal (_("Internal error: not support relax now"));
   1077      1.1  christos   else
   1078      1.1  christos     append_fixed_insn (ip);
   1079  1.1.1.2  christos 
   1080  1.1.1.2  christos   /* We need to start a new frag after any instruction that can be
   1081  1.1.1.2  christos      optimized away or compressed by the linker during relaxation, to prevent
   1082  1.1.1.2  christos      the assembler from computing static offsets across such an instruction.
   1083  1.1.1.2  christos 
   1084  1.1.1.2  christos      This is necessary to get correct .eh_frame FDE DW_CFA_advance_loc info.
   1085  1.1.1.2  christos      If one cfi_insn_data's two symbols are not in the same frag, it will
   1086  1.1.1.2  christos      generate ADD and SUB relocations pairs to calculate DW_CFA_advance_loc.
   1087  1.1.1.2  christos      (gas/dw2gencfi.c: output_cfi_insn:
   1088  1.1.1.2  christos      if (symbol_get_frag (to) == symbol_get_frag (from)))
   1089  1.1.1.2  christos 
   1090  1.1.1.2  christos      For macro instructions, only the first instruction expanded from macro
   1091  1.1.1.2  christos      need to start a new frag.  */
   1092  1.1.1.2  christos   if (LARCH_opts.relax
   1093  1.1.1.2  christos       && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_info[0].type
   1094  1.1.1.2  christos 	  || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type
   1095  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_info[0].type
   1096  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_LE_ADD_R == reloc_info[0].type
   1097  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_info[0].type
   1098  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_info[0].type
   1099  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_info[0].type
   1100  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_info[0].type
   1101  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_DESC_LD == reloc_info[0].type
   1102  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_DESC_CALL == reloc_info[0].type
   1103  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_info[0].type
   1104  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_IE_PC_LO12 == reloc_info[0].type))
   1105  1.1.1.2  christos     {
   1106  1.1.1.2  christos       frag_wane (frag_now);
   1107  1.1.1.2  christos       frag_new (0);
   1108  1.1.1.2  christos     }
   1109      1.1  christos }
   1110      1.1  christos 
   1111      1.1  christos /* Ask helper for returning a malloced c_str or NULL.  */
   1112      1.1  christos static char *
   1113      1.1  christos assember_macro_helper (const char *const args[], void *context_ptr)
   1114      1.1  christos {
   1115      1.1  christos   struct loongarch_cl_insn *insn = context_ptr;
   1116      1.1  christos   char *ret = NULL;
   1117      1.1  christos   if ( strcmp (insn->name, "li.w") == 0 || strcmp (insn->name, "li.d") == 0)
   1118      1.1  christos     {
   1119      1.1  christos       char args_buf[50], insns_buf[200];
   1120      1.1  christos       const char *arg_strs[6];
   1121      1.1  christos       uint32_t hi32, lo32;
   1122      1.1  christos 
   1123      1.1  christos       /* We pay attention to sign extend beacause it is chance of reduce insn.
   1124      1.1  christos 	 The exception is 12-bit and hi-12-bit unsigned,
   1125      1.1  christos 	 we need a 'ori' or a 'lu52i.d' accordingly.  */
   1126      1.1  christos       char all0_bit_vec, sign_bit_vec, allf_bit_vec, paritial_is_sext_of_prev;
   1127      1.1  christos 
   1128      1.1  christos       lo32 = insn->args[1] & 0xffffffff;
   1129      1.1  christos       hi32 = insn->args[1] >> 32;
   1130      1.1  christos 
   1131      1.1  christos       if (strcmp (insn->name, "li.w") == 0)
   1132      1.1  christos 	{
   1133      1.1  christos 	  if (hi32 != 0 && hi32 != 0xffffffff)
   1134      1.1  christos 	    as_fatal (_("li overflow: hi32:0x%x lo32:0x%x"), hi32, lo32);
   1135      1.1  christos 	  hi32 = lo32 & 0x80000000 ? 0xffffffff : 0;
   1136      1.1  christos 	}
   1137      1.1  christos 
   1138      1.1  christos       if (strcmp (insn->name, "li.d") == 0 && !LARCH_opts.ase_lp64)
   1139      1.1  christos 	as_fatal (_("we can't li.d on 32bit-arch"));
   1140      1.1  christos 
   1141      1.1  christos       snprintf (args_buf, sizeof (args_buf), "0x%x,0x%x,0x%x,0x%x,%s",
   1142      1.1  christos 		(hi32 >> 20) & 0xfff, hi32 & 0xfffff, (lo32 >> 12) & 0xfffff,
   1143      1.1  christos 		lo32 & 0xfff, args[0]);
   1144      1.1  christos       loongarch_split_args_by_comma (args_buf, arg_strs);
   1145      1.1  christos 
   1146      1.1  christos       all0_bit_vec =
   1147      1.1  christos 	((((hi32 & 0xfff00000) == 0) << 3) | (((hi32 & 0x000fffff) == 0) << 2)
   1148      1.1  christos 	 | (((lo32 & 0xfffff000) == 0) << 1) | ((lo32 & 0x00000fff) == 0));
   1149      1.1  christos       sign_bit_vec =
   1150      1.1  christos 	((((hi32 & 0x80000000) != 0) << 3) | (((hi32 & 0x00080000) != 0) << 2)
   1151      1.1  christos 	 | (((lo32 & 0x80000000) != 0) << 1) | ((lo32 & 0x00000800) != 0));
   1152      1.1  christos       allf_bit_vec =
   1153      1.1  christos 	((((hi32 & 0xfff00000) == 0xfff00000) << 3)
   1154      1.1  christos 	 | (((hi32 & 0x000fffff) == 0x000fffff) << 2)
   1155      1.1  christos 	 | (((lo32 & 0xfffff000) == 0xfffff000) << 1)
   1156      1.1  christos 	 | ((lo32 & 0x00000fff) == 0x00000fff));
   1157      1.1  christos       paritial_is_sext_of_prev =
   1158      1.1  christos 	(all0_bit_vec ^ allf_bit_vec) & (all0_bit_vec ^ (sign_bit_vec << 1));
   1159      1.1  christos 
   1160      1.1  christos       static const char *const li_32bit[] =
   1161      1.1  christos 	{
   1162      1.1  christos 	  "lu12i.w %5,%3&0x80000?%3-0x100000:%3;ori %5,%5,%4;",
   1163      1.1  christos 	  "lu12i.w %5,%3&0x80000?%3-0x100000:%3;",
   1164      1.1  christos 	  "addi.w %5,$r0,%4&0x800?%4-0x1000:%4;",
   1165      1.1  christos 	  "or %5,$r0,$r0;",
   1166      1.1  christos 	};
   1167      1.1  christos       static const char *const li_hi_32bit[] =
   1168      1.1  christos 	{
   1169      1.1  christos 	  "lu32i.d %5,%2&0x80000?%2-0x100000:%2;"
   1170      1.1  christos 	  "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;",
   1171      1.1  christos 	  "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;",
   1172      1.1  christos 	  "lu32i.d %5,%2&0x80000?%2-0x100000:%2;",
   1173      1.1  christos 	  "",
   1174      1.1  christos 	};
   1175      1.1  christos       do
   1176      1.1  christos 	{
   1177      1.1  christos 	  insns_buf[0] = '\0';
   1178      1.1  christos 	  if (paritial_is_sext_of_prev == 0x7)
   1179      1.1  christos 	    {
   1180      1.1  christos 	      strcat (insns_buf, "lu52i.d %5,$r0,%1&0x800?%1-0x1000:%1;");
   1181      1.1  christos 	      break;
   1182      1.1  christos 	    }
   1183      1.1  christos 	  if ((all0_bit_vec & 0x3) == 0x2)
   1184      1.1  christos 	    strcat (insns_buf, "ori %5,$r0,%4;");
   1185      1.1  christos 	  else
   1186      1.1  christos 	    strcat (insns_buf, li_32bit[paritial_is_sext_of_prev & 0x3]);
   1187      1.1  christos 	  strcat (insns_buf, li_hi_32bit[paritial_is_sext_of_prev >> 2]);
   1188      1.1  christos 	}
   1189      1.1  christos       while (0);
   1190      1.1  christos 
   1191      1.1  christos       ret = loongarch_expand_macro (insns_buf, arg_strs, NULL, NULL,
   1192      1.1  christos 				    sizeof (args_buf));
   1193      1.1  christos     }
   1194  1.1.1.2  christos 
   1195      1.1  christos   return ret;
   1196      1.1  christos }
   1197      1.1  christos 
   1198      1.1  christos /* Accept instructions separated by ';'
   1199      1.1  christos  * assuming 'not starting with space and not ending with space' or pass in
   1200      1.1  christos  * empty c_str.  */
   1201      1.1  christos static void
   1202  1.1.1.2  christos loongarch_assemble_INSNs (char *str, unsigned int expand_from_macro)
   1203      1.1  christos {
   1204      1.1  christos   char *rest;
   1205      1.1  christos   size_t len_str = strlen(str);
   1206      1.1  christos 
   1207      1.1  christos   for (rest = str; *rest != ';' && *rest != '\0'; rest++);
   1208      1.1  christos   if (*rest == ';')
   1209      1.1  christos     *rest++ = '\0';
   1210      1.1  christos 
   1211      1.1  christos   if (*str == ':')
   1212      1.1  christos     {
   1213      1.1  christos       str++;
   1214      1.1  christos       setup_internal_label_here (strtol (str, &str, 10));
   1215      1.1  christos       str++;
   1216      1.1  christos     }
   1217      1.1  christos 
   1218      1.1  christos   do
   1219      1.1  christos     {
   1220      1.1  christos       if (*str == '\0')
   1221      1.1  christos 	break;
   1222      1.1  christos 
   1223      1.1  christos       struct loongarch_cl_insn the_one = { 0 };
   1224      1.1  christos       the_one.name = str;
   1225  1.1.1.2  christos       the_one.expand_from_macro = expand_from_macro;
   1226      1.1  christos 
   1227      1.1  christos       for (; *str && *str != ' '; str++)
   1228      1.1  christos 	;
   1229      1.1  christos       if (*str == ' ')
   1230      1.1  christos 	*str++ = '\0';
   1231      1.1  christos 
   1232      1.1  christos       loongarch_split_args_by_comma (str, the_one.arg_strs);
   1233      1.1  christos       get_loongarch_opcode (&the_one);
   1234      1.1  christos 
   1235      1.1  christos       if (!the_one.all_match)
   1236      1.1  christos 	{
   1237      1.1  christos 	  char *ss = loongarch_cat_splited_strs (the_one.arg_strs);
   1238      1.1  christos 	  as_bad (_("no match insn: %s\t%s"), the_one.name, ss ? ss : "");
   1239      1.1  christos 	  free(ss);
   1240      1.1  christos 	  return;
   1241      1.1  christos 	}
   1242      1.1  christos 
   1243      1.1  christos       if (check_this_insn_before_appending (&the_one) != 0)
   1244      1.1  christos 	break;
   1245      1.1  christos 
   1246      1.1  christos       append_fixp_and_insn (&the_one);
   1247  1.1.1.2  christos 
   1248  1.1.1.2  christos       /* Expanding macro instructions.  */
   1249      1.1  christos       if (the_one.insn_length == 0 && the_one.insn->macro)
   1250      1.1  christos 	{
   1251  1.1.1.2  christos 	  unsigned int new_expand_from_macro = 0;
   1252  1.1.1.2  christos 	  if (2 == the_one.arg_num)
   1253  1.1.1.2  christos 	    new_expand_from_macro |= 1;
   1254  1.1.1.2  christos 	  else if (3 == the_one.arg_num)
   1255  1.1.1.2  christos 	    new_expand_from_macro |= 2;
   1256  1.1.1.2  christos 
   1257      1.1  christos 	  char *c_str = loongarch_expand_macro (the_one.insn->macro,
   1258      1.1  christos 						the_one.arg_strs,
   1259      1.1  christos 						assember_macro_helper,
   1260      1.1  christos 						&the_one, len_str);
   1261  1.1.1.2  christos 	  /* The first instruction expanded from macro.  */
   1262  1.1.1.2  christos 	  loongarch_assemble_INSNs (c_str, new_expand_from_macro);
   1263      1.1  christos 	  free (c_str);
   1264      1.1  christos 	}
   1265      1.1  christos     }
   1266      1.1  christos   while (0);
   1267      1.1  christos 
   1268  1.1.1.2  christos   /* The rest instructions expanded from macro, split by semicolon(;),
   1269  1.1.1.2  christos      assembly one by one.  */
   1270      1.1  christos   if (*rest != '\0')
   1271  1.1.1.2  christos     loongarch_assemble_INSNs (rest, expand_from_macro);
   1272      1.1  christos }
   1273      1.1  christos 
   1274      1.1  christos void
   1275      1.1  christos md_assemble (char *str)
   1276      1.1  christos {
   1277  1.1.1.2  christos   loongarch_assemble_INSNs (str, 0);
   1278      1.1  christos }
   1279      1.1  christos 
   1280      1.1  christos const char *
   1281      1.1  christos md_atof (int type, char *litP, int *sizeP)
   1282      1.1  christos {
   1283      1.1  christos   return ieee_md_atof (type, litP, sizeP, FALSE);
   1284      1.1  christos }
   1285      1.1  christos 
   1286      1.1  christos void
   1287      1.1  christos md_number_to_chars (char *buf, valueT val, int n)
   1288      1.1  christos {
   1289      1.1  christos   number_to_chars_littleendian (buf, val, n);
   1290      1.1  christos }
   1291      1.1  christos 
   1292      1.1  christos /* The location from which a PC relative jump should be calculated,
   1293      1.1  christos    given a PC relative reloc.  */
   1294      1.1  christos long
   1295      1.1  christos md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
   1296      1.1  christos {
   1297      1.1  christos   return 0;
   1298      1.1  christos }
   1299      1.1  christos 
   1300      1.1  christos static void fix_reloc_insn (fixS *fixP, bfd_vma reloc_val, char *buf)
   1301      1.1  christos {
   1302      1.1  christos   reloc_howto_type *howto;
   1303      1.1  christos   insn_t insn;
   1304      1.1  christos   howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
   1305      1.1  christos 
   1306      1.1  christos   insn = bfd_getl32 (buf);
   1307      1.1  christos 
   1308  1.1.1.2  christos   if (!loongarch_adjust_reloc_bitsfield (NULL, howto, &reloc_val))
   1309  1.1.1.2  christos     as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
   1310      1.1  christos 
   1311      1.1  christos   insn = (insn & (insn_t)howto->src_mask)
   1312      1.1  christos     | ((insn & (~(insn_t)howto->dst_mask)) | reloc_val);
   1313      1.1  christos 
   1314      1.1  christos   bfd_putl32 (insn, buf);
   1315      1.1  christos }
   1316      1.1  christos 
   1317      1.1  christos void
   1318      1.1  christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   1319      1.1  christos {
   1320      1.1  christos   static int64_t stack_top;
   1321      1.1  christos   static int last_reloc_is_sop_push_pcrel_1 = 0;
   1322      1.1  christos   int last_reloc_is_sop_push_pcrel = last_reloc_is_sop_push_pcrel_1;
   1323  1.1.1.2  christos   segT sub_segment;
   1324      1.1  christos   last_reloc_is_sop_push_pcrel_1 = 0;
   1325      1.1  christos 
   1326      1.1  christos   char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
   1327      1.1  christos   switch (fixP->fx_r_type)
   1328      1.1  christos     {
   1329      1.1  christos     case BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL:
   1330      1.1  christos     case BFD_RELOC_LARCH_SOP_PUSH_TLS_GD:
   1331      1.1  christos     case BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT:
   1332  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LE_HI20:
   1333  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LE_LO12:
   1334  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LE64_LO20:
   1335  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LE64_HI12:
   1336  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE_PC_HI20:
   1337  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE_PC_LO12:
   1338  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE64_PC_LO20:
   1339  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE64_PC_HI12:
   1340  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE_HI20:
   1341  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE_LO12:
   1342  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE64_LO20:
   1343  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE64_HI12:
   1344  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LD_PC_HI20:
   1345  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LD_HI20:
   1346  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_GD_PC_HI20:
   1347  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_GD_HI20:
   1348  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_PC_HI20:
   1349  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_PC_LO12:
   1350  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC64_PC_LO20:
   1351  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC64_PC_HI12:
   1352  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_HI20:
   1353  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_LO12:
   1354  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC64_LO20:
   1355  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC64_HI12:
   1356  1.1.1.2  christos       /* Add tls lo (got_lo reloc type).  */
   1357  1.1.1.2  christos       if (fixP->fx_addsy == NULL)
   1358  1.1.1.2  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
   1359  1.1.1.2  christos 		      _("Relocation against a constant"));
   1360  1.1.1.2  christos       S_SET_THREAD_LOCAL (fixP->fx_addsy);
   1361  1.1.1.2  christos       break;
   1362  1.1.1.2  christos 
   1363      1.1  christos     case BFD_RELOC_LARCH_SOP_PUSH_PCREL:
   1364      1.1  christos       if (fixP->fx_addsy == NULL)
   1365      1.1  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
   1366      1.1  christos 		      _("Relocation against a constant"));
   1367      1.1  christos 
   1368  1.1.1.2  christos       last_reloc_is_sop_push_pcrel_1 = 1;
   1369  1.1.1.2  christos       if (S_GET_SEGMENT (fixP->fx_addsy) == seg)
   1370  1.1.1.2  christos 	stack_top = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
   1371  1.1.1.2  christos 		     - (fixP->fx_where + fixP->fx_frag->fr_address));
   1372  1.1.1.2  christos       else
   1373  1.1.1.2  christos 	stack_top = 0;
   1374  1.1.1.2  christos       break;
   1375  1.1.1.2  christos 
   1376  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_LD:
   1377  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_CALL:
   1378      1.1  christos       break;
   1379      1.1  christos 
   1380      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_10_5:
   1381      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_10_12:
   1382      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_U_10_12:
   1383      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_10_16:
   1384      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2:
   1385      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_5_20:
   1386      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_U:
   1387      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2:
   1388      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2:
   1389      1.1  christos       if (!last_reloc_is_sop_push_pcrel)
   1390      1.1  christos 	break;
   1391      1.1  christos 
   1392      1.1  christos       fix_reloc_insn (fixP, (bfd_vma)stack_top, buf);
   1393      1.1  christos       break;
   1394      1.1  christos 
   1395  1.1.1.2  christos     /* LARCH only has R_LARCH_64/32, not has R_LARCH_24/16/8.
   1396  1.1.1.2  christos        For BFD_RELOC_64/32, if fx_addsy and fx_subsy not null, wer need
   1397  1.1.1.2  christos        generate BFD_RELOC_LARCH_ADD64/32 and BFD_RELOC_LARCH_SUB64/32 here.
   1398  1.1.1.2  christos        Then will parse howto table bfd_reloc_code_real_type to generate
   1399  1.1.1.2  christos        R_LARCH_ADD64/32 and R_LARCH_SUB64/32 reloc at tc_gen_reloc function.
   1400  1.1.1.2  christos        If only fx_addsy not null, skip here directly, then generate
   1401  1.1.1.2  christos        R_LARCH_64/32.
   1402  1.1.1.2  christos 
   1403  1.1.1.2  christos        For BFD_RELOC_24/16/8, if fx_addsy and fx_subsy not null, wer need
   1404  1.1.1.2  christos        generate BFD_RELOC_LARCH_ADD24/16/8 and BFD_RELOC_LARCH_SUB24/16/8 here.
   1405  1.1.1.2  christos        Then will parse howto table bfd_reloc_code_real_type to generate
   1406  1.1.1.2  christos        R_LARCH_ADD24/16/8 and R_LARCH_SUB24/16/8 reloc at tc_gen_reloc
   1407  1.1.1.2  christos        function. If only fx_addsy not null, we generate
   1408  1.1.1.2  christos        BFD_RELOC_LARCH_ADD24/16/8 only, then generate R_LARCH_24/16/8.
   1409  1.1.1.2  christos        To avoid R_LARCH_ADDxx add extra value, we write 0 first
   1410  1.1.1.2  christos        (use md_number_to_chars (buf, 0, fixP->fx_size)).  */
   1411      1.1  christos     case BFD_RELOC_64:
   1412      1.1  christos     case BFD_RELOC_32:
   1413  1.1.1.2  christos       if (fixP->fx_pcrel)
   1414  1.1.1.2  christos 	{
   1415  1.1.1.2  christos 	  switch (fixP->fx_r_type)
   1416  1.1.1.2  christos 	    {
   1417  1.1.1.2  christos 	    case BFD_RELOC_64:
   1418  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_64_PCREL;
   1419  1.1.1.2  christos 	      break;
   1420  1.1.1.2  christos 	    case BFD_RELOC_32:
   1421  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL;
   1422  1.1.1.2  christos 	      break;
   1423  1.1.1.2  christos 	    default:
   1424  1.1.1.2  christos 	      break;
   1425  1.1.1.2  christos 	    }
   1426  1.1.1.2  christos 	}
   1427  1.1.1.2  christos 
   1428  1.1.1.2  christos       /* If symbol in .eh_frame the address may be adjusted, and contents of
   1429  1.1.1.2  christos 	 .eh_frame will be adjusted, so use pc-relative relocation for FDE
   1430  1.1.1.2  christos 	 initial location.
   1431  1.1.1.2  christos 	 The Option of mthin-add-sub does not affect the generation of
   1432  1.1.1.2  christos 	 R_LARCH_32_PCREL relocation in .eh_frame.  */
   1433  1.1.1.2  christos       if (fixP->fx_r_type == BFD_RELOC_32
   1434  1.1.1.2  christos 	  && fixP->fx_addsy && fixP->fx_subsy
   1435  1.1.1.2  christos 	  && (sub_segment = S_GET_SEGMENT (fixP->fx_subsy))
   1436  1.1.1.2  christos 	  && strcmp (sub_segment->name, ".eh_frame") == 0
   1437  1.1.1.2  christos 	  && S_GET_VALUE (fixP->fx_subsy)
   1438  1.1.1.2  christos 	  == fixP->fx_frag->fr_address + fixP->fx_where)
   1439  1.1.1.2  christos 	{
   1440  1.1.1.2  christos 	  fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL;
   1441  1.1.1.2  christos 	  fixP->fx_subsy = NULL;
   1442  1.1.1.2  christos 	  break;
   1443  1.1.1.2  christos 	}
   1444  1.1.1.2  christos 
   1445  1.1.1.2  christos       if (fixP->fx_addsy && fixP->fx_subsy)
   1446      1.1  christos 	{
   1447      1.1  christos 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
   1448      1.1  christos 	  fixP->fx_next->fx_addsy = fixP->fx_subsy;
   1449      1.1  christos 	  fixP->fx_next->fx_subsy = NULL;
   1450      1.1  christos 	  fixP->fx_next->fx_offset = 0;
   1451      1.1  christos 	  fixP->fx_subsy = NULL;
   1452      1.1  christos 
   1453      1.1  christos 	  switch (fixP->fx_r_type)
   1454      1.1  christos 	    {
   1455      1.1  christos 	    case BFD_RELOC_64:
   1456      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD64;
   1457      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB64;
   1458      1.1  christos 	      break;
   1459      1.1  christos 	    case BFD_RELOC_32:
   1460      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD32;
   1461      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB32;
   1462      1.1  christos 	      break;
   1463  1.1.1.2  christos 	    default:
   1464  1.1.1.2  christos 	      break;
   1465  1.1.1.2  christos 	    }
   1466  1.1.1.2  christos 
   1467  1.1.1.2  christos 	  md_number_to_chars (buf, 0, fixP->fx_size);
   1468  1.1.1.2  christos 	}
   1469  1.1.1.2  christos 
   1470  1.1.1.2  christos       if (fixP->fx_addsy == NULL)
   1471  1.1.1.2  christos 	{
   1472  1.1.1.2  christos 	  fixP->fx_done = 1;
   1473  1.1.1.2  christos 	  md_number_to_chars (buf, *valP, fixP->fx_size);
   1474  1.1.1.2  christos 	}
   1475  1.1.1.2  christos       break;
   1476  1.1.1.2  christos 
   1477  1.1.1.2  christos     case BFD_RELOC_24:
   1478  1.1.1.2  christos     case BFD_RELOC_16:
   1479  1.1.1.2  christos     case BFD_RELOC_8:
   1480  1.1.1.2  christos       if (fixP->fx_addsy)
   1481  1.1.1.2  christos 	{
   1482  1.1.1.2  christos 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
   1483  1.1.1.2  christos 	  fixP->fx_next->fx_addsy = fixP->fx_subsy;
   1484  1.1.1.2  christos 	  fixP->fx_next->fx_subsy = NULL;
   1485  1.1.1.2  christos 	  fixP->fx_next->fx_offset = 0;
   1486  1.1.1.2  christos 	  fixP->fx_subsy = NULL;
   1487  1.1.1.2  christos 
   1488  1.1.1.2  christos 	  switch (fixP->fx_r_type)
   1489  1.1.1.2  christos 	    {
   1490      1.1  christos 	    case BFD_RELOC_24:
   1491      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD24;
   1492      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB24;
   1493      1.1  christos 	      break;
   1494      1.1  christos 	    case BFD_RELOC_16:
   1495      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD16;
   1496      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16;
   1497      1.1  christos 	      break;
   1498      1.1  christos 	    case BFD_RELOC_8:
   1499      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD8;
   1500      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8;
   1501      1.1  christos 	      break;
   1502      1.1  christos 	    default:
   1503      1.1  christos 	      break;
   1504      1.1  christos 	    }
   1505  1.1.1.2  christos 
   1506      1.1  christos 	  md_number_to_chars (buf, 0, fixP->fx_size);
   1507  1.1.1.2  christos 
   1508      1.1  christos 	  if (fixP->fx_next->fx_addsy == NULL)
   1509      1.1  christos 	    fixP->fx_next->fx_done = 1;
   1510      1.1  christos 	}
   1511  1.1.1.2  christos 
   1512      1.1  christos       if (fixP->fx_addsy == NULL)
   1513      1.1  christos 	{
   1514      1.1  christos 	  fixP->fx_done = 1;
   1515      1.1  christos 	  md_number_to_chars (buf, *valP, fixP->fx_size);
   1516      1.1  christos 	}
   1517      1.1  christos       break;
   1518      1.1  christos 
   1519  1.1.1.2  christos     case BFD_RELOC_LARCH_CFA:
   1520  1.1.1.2  christos       if (fixP->fx_addsy && fixP->fx_subsy)
   1521  1.1.1.2  christos 	{
   1522  1.1.1.2  christos 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
   1523  1.1.1.2  christos 	  fixP->fx_next->fx_addsy = fixP->fx_subsy;
   1524  1.1.1.2  christos 	  fixP->fx_next->fx_subsy = NULL;
   1525  1.1.1.2  christos 	  fixP->fx_next->fx_offset = 0;
   1526  1.1.1.2  christos 	  fixP->fx_subsy = NULL;
   1527  1.1.1.2  christos 
   1528  1.1.1.2  christos 	  unsigned int subtype;
   1529  1.1.1.2  christos 	  offsetT loc;
   1530  1.1.1.2  christos 	  subtype = bfd_get_8 (NULL, &((fragS *)
   1531  1.1.1.2  christos 		      (fixP->fx_frag->fr_opcode))->fr_literal[fixP->fx_where]);
   1532  1.1.1.2  christos 	  loc = fixP->fx_frag->fr_fix - (subtype & 7);
   1533  1.1.1.2  christos 	  switch (subtype)
   1534  1.1.1.2  christos 	    {
   1535  1.1.1.2  christos 	    case DW_CFA_advance_loc1:
   1536  1.1.1.2  christos 	      fixP->fx_where = loc + 1;
   1537  1.1.1.2  christos 	      fixP->fx_next->fx_where = loc + 1;
   1538  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD8;
   1539  1.1.1.2  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8;
   1540  1.1.1.2  christos 	      md_number_to_chars (buf+1, 0, fixP->fx_size);
   1541  1.1.1.2  christos 	      break;
   1542  1.1.1.2  christos 
   1543  1.1.1.2  christos 	    case DW_CFA_advance_loc2:
   1544  1.1.1.2  christos 	      fixP->fx_size = 2;
   1545  1.1.1.2  christos 	      fixP->fx_next->fx_size = 2;
   1546  1.1.1.2  christos 	      fixP->fx_where = loc + 1;
   1547  1.1.1.2  christos 	      fixP->fx_next->fx_where = loc + 1;
   1548  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD16;
   1549  1.1.1.2  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16;
   1550  1.1.1.2  christos 	      md_number_to_chars (buf+1, 0, fixP->fx_size);
   1551  1.1.1.2  christos 	      break;
   1552  1.1.1.2  christos 
   1553  1.1.1.2  christos 	    case DW_CFA_advance_loc4:
   1554  1.1.1.2  christos 	      fixP->fx_size = 4;
   1555  1.1.1.2  christos 	      fixP->fx_next->fx_size = 4;
   1556  1.1.1.2  christos 	      fixP->fx_where = loc;
   1557  1.1.1.2  christos 	      fixP->fx_next->fx_where = loc;
   1558  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD32;
   1559  1.1.1.2  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB32;
   1560  1.1.1.2  christos 	      md_number_to_chars (buf+1, 0, fixP->fx_size);
   1561  1.1.1.2  christos 	      break;
   1562  1.1.1.2  christos 
   1563  1.1.1.2  christos 	    default:
   1564  1.1.1.2  christos 	      if (subtype < 0x80 && (subtype & 0x40))
   1565  1.1.1.2  christos 		{
   1566  1.1.1.2  christos 		  /* DW_CFA_advance_loc.  */
   1567  1.1.1.2  christos 		  fixP->fx_frag = (fragS *) fixP->fx_frag->fr_opcode;
   1568  1.1.1.2  christos 		  fixP->fx_next->fx_frag = fixP->fx_frag;
   1569  1.1.1.2  christos 		  fixP->fx_r_type = BFD_RELOC_LARCH_ADD6;
   1570  1.1.1.2  christos 		  fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB6;
   1571  1.1.1.2  christos 		  md_number_to_chars (buf, 0x40, fixP->fx_size);
   1572  1.1.1.2  christos 		  }
   1573  1.1.1.2  christos 	      else
   1574  1.1.1.2  christos 		as_fatal (_("internal: bad CFA value #%d"), subtype);
   1575  1.1.1.2  christos 	      break;
   1576  1.1.1.2  christos 	    }
   1577  1.1.1.2  christos 	}
   1578  1.1.1.2  christos       break;
   1579  1.1.1.2  christos 
   1580  1.1.1.2  christos     case BFD_RELOC_LARCH_B16:
   1581  1.1.1.2  christos     case BFD_RELOC_LARCH_B21:
   1582  1.1.1.2  christos     case BFD_RELOC_LARCH_B26:
   1583  1.1.1.2  christos       if (fixP->fx_addsy == NULL)
   1584  1.1.1.2  christos 	{
   1585  1.1.1.2  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   1586  1.1.1.2  christos 			_ ("Relocation against a constant."));
   1587  1.1.1.2  christos 	}
   1588  1.1.1.2  christos       if (S_GET_SEGMENT (fixP->fx_addsy) == seg
   1589  1.1.1.2  christos 	  && !S_FORCE_RELOC (fixP->fx_addsy, 1))
   1590  1.1.1.2  christos 	{
   1591  1.1.1.2  christos 	  int64_t sym_addend = S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset;
   1592  1.1.1.2  christos 	  int64_t pc = fixP->fx_where + fixP->fx_frag->fr_address;
   1593  1.1.1.2  christos 	  fix_reloc_insn (fixP, sym_addend - pc, buf);
   1594  1.1.1.2  christos 
   1595  1.1.1.2  christos 	  /* If relax, symbol value may change at link time, so reloc need to
   1596  1.1.1.2  christos 	     be saved.  */
   1597  1.1.1.2  christos 	  if (!LARCH_opts.relax)
   1598  1.1.1.2  christos 	    fixP->fx_done = 1;
   1599  1.1.1.2  christos 	}
   1600  1.1.1.2  christos       break;
   1601  1.1.1.2  christos 
   1602  1.1.1.2  christos     /* Because ADD_ULEB128/SUB_ULEB128 always occur in pairs.
   1603  1.1.1.2  christos        So just deal with one is ok.
   1604  1.1.1.2  christos     case BFD_RELOC_LARCH_ADD_ULEB128:  */
   1605  1.1.1.2  christos     case BFD_RELOC_LARCH_SUB_ULEB128:
   1606  1.1.1.2  christos       {
   1607  1.1.1.2  christos 	unsigned int len = 0;
   1608  1.1.1.2  christos 	len = loongarch_get_uleb128_length ((bfd_byte *)buf);
   1609  1.1.1.2  christos 	bfd_byte *endp = (bfd_byte*) buf + len -1;
   1610  1.1.1.2  christos 	/* Clean the uleb128 value to 0. Do not reduce the length.  */
   1611  1.1.1.2  christos 	memset (buf, 0x80, len - 1);
   1612  1.1.1.2  christos 	*endp = 0;
   1613  1.1.1.2  christos 	break;
   1614  1.1.1.2  christos       }
   1615  1.1.1.2  christos 
   1616      1.1  christos     default:
   1617      1.1  christos       break;
   1618      1.1  christos     }
   1619      1.1  christos }
   1620      1.1  christos 
   1621      1.1  christos int
   1622      1.1  christos md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
   1623      1.1  christos 			       asection *segtype ATTRIBUTE_UNUSED)
   1624      1.1  christos {
   1625  1.1.1.2  christos   return (fragp->fr_var = 4);
   1626      1.1  christos }
   1627      1.1  christos 
   1628      1.1  christos /* Translate internal representation of relocation info to BFD target
   1629      1.1  christos    format.  */
   1630      1.1  christos arelent *
   1631      1.1  christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
   1632      1.1  christos {
   1633      1.1  christos   arelent *reloc = (arelent *) xmalloc (sizeof (arelent));
   1634      1.1  christos 
   1635      1.1  christos   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
   1636      1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   1637      1.1  christos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   1638      1.1  christos   reloc->addend = fixp->fx_offset;
   1639      1.1  christos 
   1640      1.1  christos   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   1641      1.1  christos   if (reloc->howto == NULL)
   1642      1.1  christos     {
   1643      1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
   1644      1.1  christos 		    _("cannot represent %s relocation in object file"),
   1645      1.1  christos 		    bfd_get_reloc_code_name (fixp->fx_r_type));
   1646      1.1  christos       return NULL;
   1647      1.1  christos     }
   1648      1.1  christos 
   1649      1.1  christos   return reloc;
   1650      1.1  christos }
   1651      1.1  christos 
   1652      1.1  christos /* Standard calling conventions leave the CFA at SP on entry.  */
   1653      1.1  christos void
   1654      1.1  christos loongarch_cfi_frame_initial_instructions (void)
   1655      1.1  christos {
   1656      1.1  christos   cfi_add_CFA_def_cfa_register (3 /* $sp */);
   1657      1.1  christos }
   1658      1.1  christos 
   1659  1.1.1.2  christos void
   1660  1.1.1.2  christos loongarch_pre_output_hook (void)
   1661      1.1  christos {
   1662  1.1.1.2  christos   const frchainS *frch;
   1663  1.1.1.2  christos   segT s;
   1664  1.1.1.2  christos 
   1665  1.1.1.2  christos   if (!LARCH_opts.relax)
   1666  1.1.1.2  christos     return;
   1667  1.1.1.2  christos 
   1668  1.1.1.2  christos   /* Save the current segment info.  */
   1669  1.1.1.2  christos   segT seg = now_seg;
   1670  1.1.1.2  christos   subsegT subseg = now_subseg;
   1671  1.1.1.2  christos 
   1672  1.1.1.2  christos   for (s = stdoutput->sections; s; s = s->next)
   1673  1.1.1.2  christos     for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next)
   1674  1.1.1.2  christos       {
   1675  1.1.1.2  christos 	fragS *frag;
   1676  1.1.1.2  christos 
   1677  1.1.1.2  christos 	for (frag = frch->frch_root; frag; frag = frag->fr_next)
   1678  1.1.1.2  christos 	  {
   1679  1.1.1.2  christos 	    if (frag->fr_type == rs_cfa)
   1680  1.1.1.2  christos 	      {
   1681  1.1.1.2  christos 		expressionS exp;
   1682  1.1.1.2  christos 		expressionS *symval;
   1683  1.1.1.2  christos 
   1684  1.1.1.2  christos 		symval = symbol_get_value_expression (frag->fr_symbol);
   1685  1.1.1.2  christos 		exp.X_op = O_subtract;
   1686  1.1.1.2  christos 		exp.X_add_symbol = symval->X_add_symbol;
   1687  1.1.1.2  christos 		exp.X_add_number = 0;
   1688  1.1.1.2  christos 		exp.X_op_symbol = symval->X_op_symbol;
   1689  1.1.1.2  christos 
   1690  1.1.1.2  christos 		/* We must set the segment before creating a frag after all
   1691  1.1.1.2  christos 		   frag chains have been chained together.  */
   1692  1.1.1.2  christos 		subseg_set (s, frch->frch_subseg);
   1693  1.1.1.2  christos 
   1694  1.1.1.2  christos 		fix_new_exp (frag, (int) frag->fr_offset, 1, &exp, 0,
   1695  1.1.1.2  christos 			     BFD_RELOC_LARCH_CFA);
   1696  1.1.1.2  christos 	      }
   1697  1.1.1.2  christos 	  }
   1698  1.1.1.2  christos       }
   1699  1.1.1.2  christos 
   1700  1.1.1.2  christos   /* Restore the original segment info.  */
   1701  1.1.1.2  christos   subseg_set (seg, subseg);
   1702      1.1  christos }
   1703      1.1  christos 
   1704      1.1  christos void
   1705      1.1  christos tc_loongarch_parse_to_dw2regnum (expressionS *exp)
   1706      1.1  christos {
   1707      1.1  christos   expression_and_evaluate (exp);
   1708      1.1  christos }
   1709      1.1  christos 
   1710      1.1  christos void
   1711      1.1  christos md_show_usage (FILE *stream)
   1712      1.1  christos {
   1713      1.1  christos   fprintf (stream, _("LARCH options:\n"));
   1714      1.1  christos   /* FIXME */
   1715  1.1.1.2  christos   fprintf (stream, _("\
   1716  1.1.1.2  christos   -mthin-add-sub	  Convert a pair of R_LARCH_ADD32/64 and R_LARCH_SUB32/64 to\n\
   1717  1.1.1.2  christos 			  R_LARCH_32/64_PCREL as much as possible\n\
   1718  1.1.1.2  christos 			  The option does not affect the generation of R_LARCH_32_PCREL\n\
   1719  1.1.1.2  christos 			  relocations in .eh_frame\n"));
   1720  1.1.1.2  christos }
   1721  1.1.1.2  christos 
   1722  1.1.1.2  christos static void
   1723  1.1.1.2  christos loongarch_make_nops (char *buf, bfd_vma bytes)
   1724  1.1.1.2  christos {
   1725  1.1.1.2  christos   bfd_vma i = 0;
   1726  1.1.1.2  christos 
   1727  1.1.1.2  christos   /* Fill with 4-byte NOPs.  */
   1728  1.1.1.2  christos   for ( ; i < bytes; i += 4)
   1729  1.1.1.2  christos     number_to_chars_littleendian (buf + i, LARCH_NOP, 4);
   1730  1.1.1.2  christos }
   1731  1.1.1.2  christos 
   1732  1.1.1.2  christos /* Called from md_do_align.  Used to create an alignment frag in a
   1733  1.1.1.2  christos    code section by emitting a worst-case NOP sequence that the linker
   1734  1.1.1.2  christos    will later relax to the correct number of NOPs.  We can't compute
   1735  1.1.1.2  christos    the correct alignment now because of other linker relaxations.  */
   1736  1.1.1.2  christos 
   1737  1.1.1.2  christos bool
   1738  1.1.1.2  christos loongarch_frag_align_code (int n, int max)
   1739  1.1.1.2  christos {
   1740  1.1.1.2  christos   char *nops;
   1741  1.1.1.2  christos   symbolS *s;
   1742  1.1.1.2  christos   expressionS ex;
   1743  1.1.1.2  christos 
   1744  1.1.1.2  christos   bfd_vma insn_alignment = 4;
   1745  1.1.1.2  christos   bfd_vma bytes = (bfd_vma) 1 << n;
   1746  1.1.1.2  christos   bfd_vma worst_case_bytes = bytes - insn_alignment;
   1747  1.1.1.2  christos 
   1748  1.1.1.2  christos   /* If we are moving to a smaller alignment than the instruction size, then no
   1749  1.1.1.2  christos      alignment is required.  */
   1750  1.1.1.2  christos   if (bytes <= insn_alignment)
   1751  1.1.1.2  christos     return true;
   1752  1.1.1.2  christos 
   1753  1.1.1.2  christos   /* When not relaxing, loongarch_handle_align handles code alignment.  */
   1754  1.1.1.2  christos   if (!LARCH_opts.relax)
   1755  1.1.1.2  christos     return false;
   1756  1.1.1.2  christos 
   1757  1.1.1.2  christos   nops = frag_more (worst_case_bytes);
   1758  1.1.1.2  christos 
   1759  1.1.1.2  christos   s = symbol_find (".Lla-relax-align");
   1760  1.1.1.2  christos   if (s == NULL)
   1761  1.1.1.2  christos     s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg,
   1762  1.1.1.2  christos 				      &zero_address_frag, 0);
   1763  1.1.1.2  christos 
   1764  1.1.1.2  christos   ex.X_add_symbol = s;
   1765  1.1.1.2  christos   ex.X_op = O_symbol;
   1766  1.1.1.2  christos   ex.X_add_number = (max << 8) | n;
   1767  1.1.1.2  christos 
   1768  1.1.1.2  christos   loongarch_make_nops (nops, worst_case_bytes);
   1769  1.1.1.2  christos 
   1770  1.1.1.2  christos   fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
   1771  1.1.1.2  christos 	       &ex, false, BFD_RELOC_LARCH_ALIGN);
   1772  1.1.1.2  christos 
   1773  1.1.1.2  christos   /* We need to start a new frag after the alignment which may be removed by
   1774  1.1.1.2  christos      the linker, to prevent the assembler from computing static offsets.
   1775  1.1.1.2  christos      This is necessary to get correct EH info.  */
   1776  1.1.1.2  christos   frag_wane (frag_now);
   1777  1.1.1.2  christos   frag_new (0);
   1778  1.1.1.2  christos 
   1779  1.1.1.2  christos   return true;
   1780      1.1  christos }
   1781      1.1  christos 
   1782      1.1  christos /* Fill in an rs_align_code fragment.  We want to fill 'andi $r0,$r0,0'.  */
   1783      1.1  christos void
   1784      1.1  christos loongarch_handle_align (fragS *fragp)
   1785      1.1  christos {
   1786      1.1  christos   /* char nop_opcode; */
   1787      1.1  christos   char *p;
   1788      1.1  christos   int bytes, size, excess;
   1789      1.1  christos   valueT opcode;
   1790      1.1  christos 
   1791      1.1  christos   if (fragp->fr_type != rs_align_code)
   1792      1.1  christos     return;
   1793      1.1  christos 
   1794      1.1  christos   struct loongarch_cl_insn nop =
   1795      1.1  christos     { .name = "andi", .arg_strs = { "$r0", "$r0", "0", NULL } };
   1796      1.1  christos 
   1797      1.1  christos   get_loongarch_opcode (&nop);
   1798      1.1  christos   gas_assert (nop.all_match);
   1799      1.1  christos 
   1800      1.1  christos   p = fragp->fr_literal + fragp->fr_fix;
   1801      1.1  christos   opcode = nop.insn_bin;
   1802      1.1  christos   size = 4;
   1803      1.1  christos 
   1804      1.1  christos   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   1805      1.1  christos   excess = bytes % size;
   1806      1.1  christos 
   1807      1.1  christos   gas_assert (excess < 4);
   1808      1.1  christos   fragp->fr_fix += excess;
   1809      1.1  christos 
   1810      1.1  christos   while (excess-- != 0)
   1811      1.1  christos     *p++ = 0;
   1812      1.1  christos 
   1813      1.1  christos   md_number_to_chars (p, opcode, size);
   1814      1.1  christos   fragp->fr_var = size;
   1815      1.1  christos }
   1816      1.1  christos 
   1817  1.1.1.2  christos /* Scan uleb128 subtraction expressions and insert fixups for them.
   1818  1.1.1.2  christos    e.g., .uleb128 .L1 - .L0
   1819  1.1.1.2  christos    Because relaxation may change the value of the subtraction, we
   1820  1.1.1.2  christos    must resolve them at link-time.  */
   1821  1.1.1.2  christos 
   1822  1.1.1.2  christos static void
   1823  1.1.1.2  christos loongarch_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
   1824  1.1.1.2  christos 		      asection *sec, void *xxx ATTRIBUTE_UNUSED)
   1825  1.1.1.2  christos {
   1826  1.1.1.2  christos   segment_info_type *seginfo = seg_info (sec);
   1827  1.1.1.2  christos   struct frag *fragP;
   1828  1.1.1.2  christos 
   1829  1.1.1.2  christos   subseg_set (sec, 0);
   1830  1.1.1.2  christos 
   1831  1.1.1.2  christos   for (fragP = seginfo->frchainP->frch_root;
   1832  1.1.1.2  christos        fragP; fragP = fragP->fr_next)
   1833  1.1.1.2  christos     {
   1834  1.1.1.2  christos       expressionS *exp, *exp_dup;
   1835  1.1.1.2  christos 
   1836  1.1.1.2  christos       if (fragP->fr_type != rs_leb128  || fragP->fr_symbol == NULL)
   1837  1.1.1.2  christos 	continue;
   1838  1.1.1.2  christos 
   1839  1.1.1.2  christos       exp = symbol_get_value_expression (fragP->fr_symbol);
   1840  1.1.1.2  christos 
   1841  1.1.1.2  christos       if (exp->X_op != O_subtract)
   1842  1.1.1.2  christos 	continue;
   1843  1.1.1.2  christos 
   1844  1.1.1.2  christos       /* FIXME: Skip for .sleb128.  */
   1845  1.1.1.2  christos       if (fragP->fr_subtype != 0)
   1846  1.1.1.2  christos 	continue;
   1847  1.1.1.2  christos 
   1848  1.1.1.2  christos       exp_dup = xmemdup (exp, sizeof (*exp), sizeof (*exp));
   1849  1.1.1.2  christos       exp_dup->X_op = O_symbol;
   1850  1.1.1.2  christos       exp_dup->X_op_symbol = NULL;
   1851  1.1.1.2  christos 
   1852  1.1.1.2  christos       exp_dup->X_add_symbol = exp->X_add_symbol;
   1853  1.1.1.2  christos       fix_new_exp (fragP, fragP->fr_fix, 0,
   1854  1.1.1.2  christos 		   exp_dup, 0, BFD_RELOC_LARCH_ADD_ULEB128);
   1855  1.1.1.2  christos 
   1856  1.1.1.2  christos       /* From binutils/testsuite/binutils-all/dw5.S
   1857  1.1.1.2  christos 	 section .debug_rnglists
   1858  1.1.1.2  christos 	 .uleb128 .Letext0-.Ltext0    Range length (*.LLRL2)
   1859  1.1.1.2  christos     Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
   1860  1.1.1.2  christos 0000000000000015  0000000200000079 R_LARCH_ADD_ULEB128    0000000000000000 .text + 2
   1861  1.1.1.2  christos 0000000000000015  000000020000007a R_LARCH_SUB_ULEB128    0000000000000000 .text + 0.  */
   1862  1.1.1.2  christos 
   1863  1.1.1.2  christos       /* Only the ADD_ULEB128 has X_add_number (Addend)?  */
   1864  1.1.1.2  christos       exp_dup->X_add_number = 0;
   1865  1.1.1.2  christos       exp_dup->X_add_symbol = exp->X_op_symbol;
   1866  1.1.1.2  christos       fix_new_exp (fragP, fragP->fr_fix, 0,
   1867  1.1.1.2  christos 		   exp_dup, 0, BFD_RELOC_LARCH_SUB_ULEB128);
   1868  1.1.1.2  christos     }
   1869  1.1.1.2  christos }
   1870  1.1.1.2  christos 
   1871  1.1.1.2  christos void
   1872  1.1.1.2  christos loongarch_md_finish (void)
   1873  1.1.1.2  christos {
   1874  1.1.1.2  christos   /* Insert relocations for uleb128 directives, so the values can be recomputed
   1875  1.1.1.2  christos      at link time.  */
   1876  1.1.1.2  christos   if (LARCH_opts.relax)
   1877  1.1.1.2  christos     bfd_map_over_sections (stdoutput, loongarch_insert_uleb128_fixes, NULL);
   1878  1.1.1.2  christos }
   1879  1.1.1.2  christos 
   1880      1.1  christos void
   1881      1.1  christos loongarch_elf_final_processing (void)
   1882      1.1  christos {
   1883      1.1  christos   elf_elfheader (stdoutput)->e_flags = LARCH_opts.ase_abi;
   1884      1.1  christos }
   1885  1.1.1.2  christos 
   1886  1.1.1.2  christos /* Compute the length of a branch sequence, and adjust the stored length
   1887  1.1.1.2  christos    accordingly.  If FRAGP is NULL, the worst-case length is returned.  */
   1888  1.1.1.2  christos static unsigned
   1889  1.1.1.2  christos loongarch_relaxed_branch_length (fragS *fragp, asection *sec, int update)
   1890  1.1.1.2  christos {
   1891  1.1.1.2  christos   int length = 4;
   1892  1.1.1.2  christos 
   1893  1.1.1.2  christos   if (!fragp)
   1894  1.1.1.2  christos     return 8;
   1895  1.1.1.2  christos 
   1896  1.1.1.2  christos   if (fragp->fr_symbol != NULL
   1897  1.1.1.2  christos       && S_IS_DEFINED (fragp->fr_symbol)
   1898  1.1.1.2  christos       && !S_IS_WEAK (fragp->fr_symbol)
   1899  1.1.1.2  christos       && sec == S_GET_SEGMENT (fragp->fr_symbol))
   1900  1.1.1.2  christos     {
   1901  1.1.1.2  christos       offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
   1902  1.1.1.2  christos 
   1903  1.1.1.2  christos       val -= fragp->fr_address + fragp->fr_fix;
   1904  1.1.1.2  christos 
   1905  1.1.1.2  christos       if (RELAX_BRANCH_16 == fragp->fr_subtype
   1906  1.1.1.2  christos 	  && OUT_OF_RANGE (val, 16, 2))
   1907  1.1.1.2  christos 	{
   1908  1.1.1.2  christos 	  length = 8;
   1909  1.1.1.2  christos 	  if (update)
   1910  1.1.1.2  christos 	    fragp->fr_subtype = RELAX_BRANCH_26;
   1911  1.1.1.2  christos 	}
   1912  1.1.1.2  christos 
   1913  1.1.1.2  christos       if (RELAX_BRANCH_21 == fragp->fr_subtype
   1914  1.1.1.2  christos 	  && OUT_OF_RANGE (val, 21, 2))
   1915  1.1.1.2  christos 	{
   1916  1.1.1.2  christos 	  length = 8;
   1917  1.1.1.2  christos 	  if (update)
   1918  1.1.1.2  christos 	    fragp->fr_subtype = RELAX_BRANCH_26;
   1919  1.1.1.2  christos 	}
   1920  1.1.1.2  christos 
   1921  1.1.1.2  christos       if (RELAX_BRANCH_26 == fragp->fr_subtype)
   1922  1.1.1.2  christos 	length = 8;
   1923  1.1.1.2  christos     }
   1924  1.1.1.2  christos 
   1925  1.1.1.2  christos   return length;
   1926  1.1.1.2  christos }
   1927  1.1.1.2  christos 
   1928  1.1.1.2  christos int
   1929  1.1.1.2  christos loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED,
   1930  1.1.1.2  christos 		      fragS *fragp ATTRIBUTE_UNUSED,
   1931  1.1.1.2  christos 		      long stretch ATTRIBUTE_UNUSED)
   1932  1.1.1.2  christos {
   1933  1.1.1.2  christos   if (RELAX_BRANCH (fragp->fr_subtype))
   1934  1.1.1.2  christos     {
   1935  1.1.1.2  christos       offsetT old_var = fragp->fr_var;
   1936  1.1.1.2  christos       fragp->fr_var = loongarch_relaxed_branch_length (fragp, sec, true);
   1937  1.1.1.2  christos       return fragp->fr_var - old_var;
   1938  1.1.1.2  christos     }
   1939  1.1.1.2  christos   return 0;
   1940  1.1.1.2  christos }
   1941  1.1.1.2  christos 
   1942  1.1.1.2  christos /* Expand far branches to multi-instruction sequences.
   1943  1.1.1.2  christos    Branch instructions:
   1944  1.1.1.2  christos    beq, bne, blt, bgt, bltz, bgtz, ble, bge, blez, bgez
   1945  1.1.1.2  christos    bltu, bgtu, bleu, bgeu
   1946  1.1.1.2  christos    beqz, bnez, bceqz, bcnez.  */
   1947  1.1.1.2  christos 
   1948  1.1.1.2  christos static void
   1949  1.1.1.2  christos loongarch_convert_frag_branch (fragS *fragp)
   1950  1.1.1.2  christos {
   1951  1.1.1.2  christos   bfd_byte *buf;
   1952  1.1.1.2  christos   expressionS exp;
   1953  1.1.1.2  christos   fixS *fixp;
   1954  1.1.1.2  christos   insn_t insn;
   1955  1.1.1.2  christos 
   1956  1.1.1.2  christos   buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
   1957  1.1.1.2  christos 
   1958  1.1.1.2  christos   exp.X_op = O_symbol;
   1959  1.1.1.2  christos   exp.X_add_symbol = fragp->fr_symbol;
   1960  1.1.1.2  christos   exp.X_add_number = fragp->fr_offset;
   1961  1.1.1.2  christos 
   1962  1.1.1.2  christos   gas_assert ((fragp->fr_subtype & 0xf) == fragp->fr_var);
   1963  1.1.1.2  christos 
   1964  1.1.1.2  christos   /* blt $t0, $t1, .L1
   1965  1.1.1.2  christos      nop
   1966  1.1.1.2  christos      change to:
   1967  1.1.1.2  christos      bge $t0, $t1, .L2
   1968  1.1.1.2  christos      b .L1
   1969  1.1.1.2  christos    .L2:
   1970  1.1.1.2  christos      nop  */
   1971  1.1.1.2  christos   switch (fragp->fr_subtype)
   1972  1.1.1.2  christos     {
   1973  1.1.1.2  christos     case RELAX_BRANCH_26:
   1974  1.1.1.2  christos       insn = bfd_getl32 (buf);
   1975  1.1.1.2  christos       /* Invert the branch condition.  */
   1976  1.1.1.2  christos       if (LARCH_FLOAT_BRANCH == (insn & LARCH_BRANCH_OPCODE_MASK))
   1977  1.1.1.2  christos 	insn ^= LARCH_FLOAT_BRANCH_INVERT_BIT;
   1978  1.1.1.2  christos       else
   1979  1.1.1.2  christos 	insn ^= LARCH_BRANCH_INVERT_BIT;
   1980  1.1.1.2  christos       insn |= ENCODE_BRANCH16_IMM (8);  /* Set target to PC + 8.  */
   1981  1.1.1.2  christos       bfd_putl32 (insn, buf);
   1982  1.1.1.2  christos       buf += 4;
   1983  1.1.1.2  christos 
   1984  1.1.1.2  christos       /* Add the B instruction and jump to the original target.  */
   1985  1.1.1.2  christos       bfd_putl32 (LARCH_B, buf);
   1986  1.1.1.2  christos       fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
   1987  1.1.1.2  christos 			  4, &exp, false, BFD_RELOC_LARCH_B26);
   1988  1.1.1.2  christos       buf += 4;
   1989  1.1.1.2  christos       break;
   1990  1.1.1.2  christos     case RELAX_BRANCH_21:
   1991  1.1.1.2  christos       fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
   1992  1.1.1.2  christos 			  4, &exp, false, BFD_RELOC_LARCH_B21);
   1993  1.1.1.2  christos       buf += 4;
   1994  1.1.1.2  christos       break;
   1995  1.1.1.2  christos     case RELAX_BRANCH_16:
   1996  1.1.1.2  christos       fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
   1997  1.1.1.2  christos 			  4, &exp, false, BFD_RELOC_LARCH_B16);
   1998  1.1.1.2  christos       buf += 4;
   1999  1.1.1.2  christos       break;
   2000  1.1.1.2  christos 
   2001  1.1.1.2  christos     default:
   2002  1.1.1.2  christos       abort();
   2003  1.1.1.2  christos     }
   2004  1.1.1.2  christos 
   2005  1.1.1.2  christos   fixp->fx_file = fragp->fr_file;
   2006  1.1.1.2  christos   fixp->fx_line = fragp->fr_line;
   2007  1.1.1.2  christos 
   2008  1.1.1.2  christos   gas_assert (buf == (bfd_byte *)fragp->fr_literal
   2009  1.1.1.2  christos 	      + fragp->fr_fix + fragp->fr_var);
   2010  1.1.1.2  christos 
   2011  1.1.1.2  christos   fragp->fr_fix += fragp->fr_var;
   2012  1.1.1.2  christos }
   2013  1.1.1.2  christos 
   2014  1.1.1.2  christos /* Relax a machine dependent frag.  This returns the amount by which
   2015  1.1.1.2  christos    the current size of the frag should change.  */
   2016  1.1.1.2  christos 
   2017  1.1.1.2  christos void
   2018  1.1.1.2  christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
   2019  1.1.1.2  christos 		 fragS *fragp)
   2020  1.1.1.2  christos {
   2021  1.1.1.2  christos   gas_assert (RELAX_BRANCH (fragp->fr_subtype));
   2022  1.1.1.2  christos   loongarch_convert_frag_branch (fragp);
   2023  1.1.1.2  christos }
   2024