Home | History | Annotate | Line # | Download | only in config
      1      1.1  christos /* tc-loongarch.c -- Assemble for the LoongArch ISA
      2      1.1  christos 
      3  1.1.1.3  christos    Copyright (C) 2021-2025 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.1.3  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.3  christos static bool call36 = 0;
    120  1.1.1.3  christos 
    121  1.1.1.2  christos /* The lowest 4-bit is the bytes of instructions.  */
    122  1.1.1.2  christos #define RELAX_BRANCH_16 0xc0000014
    123  1.1.1.2  christos #define RELAX_BRANCH_21 0xc0000024
    124  1.1.1.2  christos #define RELAX_BRANCH_26 0xc0000048
    125  1.1.1.2  christos 
    126  1.1.1.2  christos #define RELAX_BRANCH(x) \
    127  1.1.1.2  christos   (((x) & 0xf0000000) == 0xc0000000)
    128  1.1.1.2  christos #define RELAX_BRANCH_ENCODE(x) \
    129  1.1.1.2  christos   (BFD_RELOC_LARCH_B16 == (x) ? RELAX_BRANCH_16 : RELAX_BRANCH_21)
    130  1.1.1.2  christos 
    131  1.1.1.3  christos #define ALIGN_MAX_ADDEND(n, max) ((max << 8) | n)
    132  1.1.1.3  christos #define ALIGN_MAX_NOP_BYTES(addend) ((1 << (addend & 0xff)) - 4)
    133  1.1.1.3  christos #define FRAG_AT_START_OF_SECTION(frag)	\
    134  1.1.1.3  christos   (0 == frag->fr_address && 0 == frag->fr_fix)
    135  1.1.1.3  christos 
    136      1.1  christos enum options
    137      1.1  christos {
    138      1.1  christos   OPTION_IGNORE = OPTION_MD_BASE,
    139      1.1  christos 
    140      1.1  christos   OPTION_ABI,
    141      1.1  christos   OPTION_FLOAT_ABI,
    142      1.1  christos   OPTION_FLOAT_ISA,
    143      1.1  christos 
    144      1.1  christos   OPTION_LA_LOCAL_WITH_ABS,
    145      1.1  christos   OPTION_LA_GLOBAL_WITH_PCREL,
    146      1.1  christos   OPTION_LA_GLOBAL_WITH_ABS,
    147  1.1.1.3  christos 
    148  1.1.1.2  christos   OPTION_RELAX,
    149  1.1.1.2  christos   OPTION_NO_RELAX,
    150  1.1.1.3  christos 
    151  1.1.1.2  christos   OPTION_THIN_ADD_SUB,
    152  1.1.1.3  christos   OPTION_IGNORE_START_ALIGN,
    153      1.1  christos 
    154      1.1  christos   OPTION_END_OF_ENUM,
    155      1.1  christos };
    156      1.1  christos 
    157  1.1.1.3  christos const struct option md_longopts[] =
    158      1.1  christos {
    159      1.1  christos   { "mabi", required_argument, NULL, OPTION_ABI },
    160      1.1  christos 
    161      1.1  christos   { "mfpu", required_argument, NULL, OPTION_FLOAT_ISA },
    162      1.1  christos 
    163      1.1  christos   { "mla-local-with-abs", no_argument, NULL, OPTION_LA_LOCAL_WITH_ABS },
    164      1.1  christos   { "mla-global-with-pcrel", no_argument, NULL, OPTION_LA_GLOBAL_WITH_PCREL },
    165      1.1  christos   { "mla-global-with-abs", no_argument, NULL, OPTION_LA_GLOBAL_WITH_ABS },
    166      1.1  christos 
    167  1.1.1.2  christos   { "mrelax", no_argument, NULL, OPTION_RELAX },
    168  1.1.1.2  christos   { "mno-relax", no_argument, NULL, OPTION_NO_RELAX },
    169  1.1.1.2  christos   { "mthin-add-sub", no_argument, NULL, OPTION_THIN_ADD_SUB},
    170  1.1.1.3  christos   { "mignore-start-align", no_argument, NULL, OPTION_IGNORE_START_ALIGN},
    171  1.1.1.2  christos 
    172      1.1  christos   { NULL, no_argument, NULL, 0 }
    173      1.1  christos };
    174      1.1  christos 
    175  1.1.1.3  christos const size_t md_longopts_size = sizeof (md_longopts);
    176      1.1  christos 
    177      1.1  christos int
    178      1.1  christos md_parse_option (int c, const char *arg)
    179      1.1  christos {
    180      1.1  christos   int ret = 1;
    181      1.1  christos   char lp64[256] = "";
    182      1.1  christos   char ilp32[256] = "";
    183      1.1  christos 
    184  1.1.1.2  christos   lp64['s'] = lp64['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT;
    185  1.1.1.2  christos   lp64['f'] = lp64['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT;
    186  1.1.1.2  christos   lp64['d'] = lp64['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT;
    187  1.1.1.2  christos 
    188  1.1.1.2  christos   ilp32['s'] = ilp32['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT;
    189  1.1.1.2  christos   ilp32['f'] = ilp32['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT;
    190  1.1.1.2  christos   ilp32['d'] = ilp32['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT;
    191      1.1  christos 
    192      1.1  christos   switch (c)
    193      1.1  christos     {
    194      1.1  christos     case OPTION_ABI:
    195  1.1.1.3  christos       if (strncasecmp (arg, "lp64", 4) == 0 && lp64[arg[4] & 0xff] != 0)
    196      1.1  christos 	{
    197      1.1  christos 	  LARCH_opts.ase_ilp32 = 1;
    198      1.1  christos 	  LARCH_opts.ase_lp64 = 1;
    199  1.1.1.2  christos 	  LARCH_opts.ase_lsx = 1;
    200  1.1.1.2  christos 	  LARCH_opts.ase_lasx = 1;
    201  1.1.1.2  christos 	  LARCH_opts.ase_lvz = 1;
    202  1.1.1.2  christos 	  LARCH_opts.ase_lbt = 1;
    203  1.1.1.3  christos 	  LARCH_opts.ase_abi = lp64[arg[4] & 0xff];
    204      1.1  christos 	}
    205  1.1.1.3  christos       else if (strncasecmp (arg, "ilp32", 5) == 0 && ilp32[arg[5] & 0xff] != 0)
    206      1.1  christos 	{
    207  1.1.1.3  christos 	  LARCH_opts.ase_abi = ilp32[arg[5] & 0xff];
    208      1.1  christos 	  LARCH_opts.ase_ilp32 = 1;
    209      1.1  christos 	}
    210      1.1  christos       else
    211      1.1  christos 	ret = 0;
    212      1.1  christos       break;
    213      1.1  christos 
    214      1.1  christos     case OPTION_FLOAT_ISA:
    215      1.1  christos       if (strcasecmp (arg, "soft") == 0)
    216      1.1  christos 	LARCH_opts.ase_nf = 1;
    217      1.1  christos       else if (strcasecmp (arg, "single") == 0)
    218      1.1  christos 	LARCH_opts.ase_sf = 1;
    219      1.1  christos       else if (strcasecmp (arg, "double") == 0)
    220      1.1  christos 	{
    221      1.1  christos 	  LARCH_opts.ase_sf = 1;
    222      1.1  christos 	  LARCH_opts.ase_df = 1;
    223      1.1  christos 	}
    224      1.1  christos       else
    225      1.1  christos 	ret = 0;
    226      1.1  christos       break;
    227      1.1  christos 
    228      1.1  christos     case OPTION_LA_LOCAL_WITH_ABS:
    229      1.1  christos       LARCH_opts.ase_labs = 1;
    230      1.1  christos       break;
    231      1.1  christos 
    232      1.1  christos     case OPTION_LA_GLOBAL_WITH_PCREL:
    233      1.1  christos       LARCH_opts.ase_gpcr = 1;
    234      1.1  christos       break;
    235      1.1  christos 
    236      1.1  christos     case OPTION_LA_GLOBAL_WITH_ABS:
    237      1.1  christos       LARCH_opts.ase_gabs = 1;
    238      1.1  christos       break;
    239      1.1  christos 
    240  1.1.1.2  christos     case OPTION_RELAX:
    241  1.1.1.2  christos       LARCH_opts.relax = 1;
    242  1.1.1.2  christos       break;
    243  1.1.1.2  christos 
    244  1.1.1.2  christos     case OPTION_NO_RELAX:
    245  1.1.1.2  christos       LARCH_opts.relax = 0;
    246  1.1.1.2  christos       break;
    247  1.1.1.2  christos 
    248  1.1.1.2  christos     case OPTION_THIN_ADD_SUB:
    249  1.1.1.2  christos       LARCH_opts.thin_add_sub = 1;
    250  1.1.1.2  christos       break;
    251  1.1.1.2  christos 
    252  1.1.1.3  christos     case OPTION_IGNORE_START_ALIGN:
    253  1.1.1.3  christos       LARCH_opts.ignore_start_align = 1;
    254  1.1.1.3  christos       break;
    255  1.1.1.3  christos 
    256      1.1  christos     case OPTION_IGNORE:
    257      1.1  christos       break;
    258      1.1  christos 
    259      1.1  christos     default:
    260      1.1  christos       ret = 0;
    261      1.1  christos       break;
    262      1.1  christos     }
    263      1.1  christos   return ret;
    264      1.1  christos }
    265      1.1  christos 
    266  1.1.1.2  christos static const char *const *r_abi_names = NULL;
    267  1.1.1.2  christos static const char *const *f_abi_names = NULL;
    268      1.1  christos static struct htab *r_htab = NULL;
    269  1.1.1.2  christos static struct htab *r_deprecated_htab = NULL;
    270      1.1  christos static struct htab *f_htab = NULL;
    271  1.1.1.2  christos static struct htab *f_deprecated_htab = NULL;
    272  1.1.1.2  christos static struct htab *fc_htab = NULL;
    273  1.1.1.2  christos static struct htab *fcn_htab = NULL;
    274      1.1  christos static struct htab *c_htab = NULL;
    275      1.1  christos static struct htab *cr_htab = NULL;
    276      1.1  christos static struct htab *v_htab = NULL;
    277      1.1  christos static struct htab *x_htab = NULL;
    278  1.1.1.3  christos static struct htab *cfi_r_htab = NULL;
    279  1.1.1.3  christos static struct htab *cfi_f_htab = NULL;
    280      1.1  christos 
    281      1.1  christos void
    282      1.1  christos loongarch_after_parse_args ()
    283      1.1  christos {
    284      1.1  christos   /* Set default ABI/ISA LP64D.  */
    285  1.1.1.2  christos   if (!LARCH_opts.ase_ilp32)
    286      1.1  christos     {
    287      1.1  christos       if (strcmp (default_arch, "loongarch64") == 0)
    288      1.1  christos 	{
    289  1.1.1.2  christos 	  LARCH_opts.ase_abi = EF_LOONGARCH_ABI_DOUBLE_FLOAT;
    290      1.1  christos 	  LARCH_opts.ase_ilp32 = 1;
    291      1.1  christos 	  LARCH_opts.ase_lp64 = 1;
    292  1.1.1.2  christos 	  LARCH_opts.ase_lsx = 1;
    293  1.1.1.2  christos 	  LARCH_opts.ase_lasx = 1;
    294  1.1.1.2  christos 	  LARCH_opts.ase_lvz = 1;
    295  1.1.1.2  christos 	  LARCH_opts.ase_lbt = 1;
    296      1.1  christos 	}
    297      1.1  christos       else if (strcmp (default_arch, "loongarch32") == 0)
    298      1.1  christos 	{
    299  1.1.1.2  christos 	  LARCH_opts.ase_abi = EF_LOONGARCH_ABI_DOUBLE_FLOAT;
    300      1.1  christos 	  LARCH_opts.ase_ilp32 = 1;
    301      1.1  christos 	}
    302      1.1  christos       else
    303      1.1  christos 	as_bad ("unknown default architecture `%s'", default_arch);
    304      1.1  christos     }
    305      1.1  christos 
    306  1.1.1.2  christos   LARCH_opts.ase_abi |= EF_LOONGARCH_OBJABI_V1;
    307      1.1  christos   /* Set default ISA double-float.  */
    308      1.1  christos   if (!LARCH_opts.ase_nf
    309      1.1  christos       && !LARCH_opts.ase_sf
    310      1.1  christos       && !LARCH_opts.ase_df)
    311      1.1  christos     {
    312      1.1  christos       LARCH_opts.ase_sf = 1;
    313      1.1  christos       LARCH_opts.ase_df = 1;
    314      1.1  christos     }
    315      1.1  christos 
    316      1.1  christos   size_t i;
    317      1.1  christos 
    318      1.1  christos   assert(LARCH_opts.ase_ilp32);
    319      1.1  christos 
    320      1.1  christos   /* Init ilp32/lp64 registers names.  */
    321      1.1  christos   if (!r_htab)
    322  1.1.1.3  christos     r_htab = str_htab_create ();
    323  1.1.1.2  christos   if (!r_deprecated_htab)
    324  1.1.1.3  christos     r_deprecated_htab = str_htab_create ();
    325  1.1.1.3  christos   /* Init cfi registers alias.  */
    326  1.1.1.3  christos   if (!cfi_r_htab)
    327  1.1.1.3  christos     cfi_r_htab = str_htab_create ();
    328      1.1  christos 
    329  1.1.1.2  christos   r_abi_names = loongarch_r_normal_name;
    330      1.1  christos   for (i = 0; i < ARRAY_SIZE (loongarch_r_normal_name); i++)
    331  1.1.1.3  christos     {
    332  1.1.1.3  christos       str_hash_insert_int (r_htab, loongarch_r_normal_name[i], i, 0);
    333  1.1.1.3  christos       str_hash_insert_int (cfi_r_htab, loongarch_r_normal_name[i], i, 0);
    334  1.1.1.3  christos     }
    335  1.1.1.2  christos   /* Init ilp32/lp64 registers alias.  */
    336  1.1.1.2  christos   r_abi_names = loongarch_r_alias;
    337  1.1.1.2  christos   for (i = 0; i < ARRAY_SIZE (loongarch_r_alias); i++)
    338  1.1.1.3  christos     {
    339  1.1.1.3  christos       str_hash_insert_int (r_htab, loongarch_r_alias[i], i, 0);
    340  1.1.1.3  christos       str_hash_insert_int (cfi_r_htab, loongarch_r_alias[i], i, 0);
    341  1.1.1.3  christos     }
    342  1.1.1.2  christos 
    343  1.1.1.2  christos   for (i = 0; i < ARRAY_SIZE (loongarch_r_alias_1); i++)
    344  1.1.1.3  christos     str_hash_insert_int (r_htab, loongarch_r_alias_1[i], i, 0);
    345  1.1.1.2  christos 
    346  1.1.1.2  christos   for (i = 0; i < ARRAY_SIZE (loongarch_r_alias_deprecated); i++)
    347  1.1.1.3  christos     str_hash_insert_int (r_deprecated_htab, loongarch_r_alias_deprecated[i],
    348  1.1.1.3  christos 			 i, 0);
    349  1.1.1.3  christos 
    350  1.1.1.3  christos   /* The .cfi directive supports register aliases without the "$" prefix.  */
    351  1.1.1.3  christos   for (i = 0; i < ARRAY_SIZE (loongarch_r_cfi_name); i++)
    352  1.1.1.3  christos     {
    353  1.1.1.3  christos       str_hash_insert_int (cfi_r_htab, loongarch_r_cfi_name[i], i, 0);
    354  1.1.1.3  christos       str_hash_insert_int (cfi_r_htab, loongarch_r_cfi_name_alias[i], i, 0);
    355  1.1.1.3  christos     }
    356  1.1.1.2  christos 
    357      1.1  christos   if (!cr_htab)
    358  1.1.1.3  christos     cr_htab = str_htab_create ();
    359      1.1  christos 
    360      1.1  christos   for (i = 0; i < ARRAY_SIZE (loongarch_cr_normal_name); i++)
    361  1.1.1.3  christos     str_hash_insert_int (cr_htab, loongarch_cr_normal_name[i], i, 0);
    362      1.1  christos 
    363      1.1  christos   /* Init single/double float registers names.  */
    364      1.1  christos   if (LARCH_opts.ase_sf || LARCH_opts.ase_df)
    365      1.1  christos     {
    366      1.1  christos       if (!f_htab)
    367  1.1.1.3  christos 	f_htab = str_htab_create ();
    368  1.1.1.2  christos       if (!f_deprecated_htab)
    369  1.1.1.3  christos 	f_deprecated_htab = str_htab_create ();
    370  1.1.1.3  christos       if (!cfi_f_htab)
    371  1.1.1.3  christos 	cfi_f_htab = str_htab_create ();
    372      1.1  christos 
    373  1.1.1.2  christos       f_abi_names = loongarch_f_normal_name;
    374      1.1  christos       for (i = 0; i < ARRAY_SIZE (loongarch_f_normal_name); i++)
    375  1.1.1.3  christos 	{
    376  1.1.1.3  christos 	  str_hash_insert_int (f_htab, loongarch_f_normal_name[i], i, 0);
    377  1.1.1.3  christos 	  str_hash_insert_int (cfi_f_htab, loongarch_f_normal_name[i], i, 0);
    378  1.1.1.3  christos 	}
    379  1.1.1.2  christos       /* Init float-ilp32/lp64 registers alias.  */
    380  1.1.1.2  christos       f_abi_names = loongarch_f_alias;
    381  1.1.1.2  christos       for (i = 0; i < ARRAY_SIZE (loongarch_f_alias); i++)
    382  1.1.1.3  christos 	{
    383  1.1.1.3  christos 	  str_hash_insert_int (f_htab, loongarch_f_alias[i], i, 0);
    384  1.1.1.3  christos 	  str_hash_insert_int (cfi_f_htab, loongarch_f_alias[i], i, 0);
    385  1.1.1.3  christos 	}
    386  1.1.1.2  christos       for (i = 0; i < ARRAY_SIZE (loongarch_f_alias_deprecated); i++)
    387  1.1.1.3  christos 	str_hash_insert_int (f_deprecated_htab, loongarch_f_alias_deprecated[i],
    388  1.1.1.3  christos 			     i, 0);
    389  1.1.1.3  christos 
    390  1.1.1.3  christos   /* The .cfi directive supports register aliases without the "$" prefix.  */
    391  1.1.1.3  christos   for (i = 0; i < ARRAY_SIZE (loongarch_f_cfi_name); i++)
    392  1.1.1.3  christos     {
    393  1.1.1.3  christos       str_hash_insert_int (cfi_f_htab, loongarch_f_cfi_name[i], i, 0);
    394  1.1.1.3  christos       str_hash_insert_int (cfi_f_htab, loongarch_f_cfi_name_alias[i], i, 0);
    395  1.1.1.3  christos     }
    396  1.1.1.2  christos 
    397  1.1.1.2  christos       if (!fc_htab)
    398  1.1.1.3  christos 	fc_htab = str_htab_create ();
    399  1.1.1.2  christos 
    400  1.1.1.2  christos       for (i = 0; i < ARRAY_SIZE (loongarch_fc_normal_name); i++)
    401  1.1.1.3  christos 	str_hash_insert_int (fc_htab, loongarch_fc_normal_name[i], i, 0);
    402  1.1.1.2  christos 
    403  1.1.1.2  christos       if (!fcn_htab)
    404  1.1.1.3  christos 	fcn_htab = str_htab_create ();
    405  1.1.1.2  christos 
    406  1.1.1.2  christos       for (i = 0; i < ARRAY_SIZE (loongarch_fc_numeric_name); i++)
    407  1.1.1.3  christos 	str_hash_insert_int (fcn_htab, loongarch_fc_numeric_name[i], i, 0);
    408  1.1.1.2  christos 
    409      1.1  christos       if (!c_htab)
    410  1.1.1.3  christos 	c_htab = str_htab_create ();
    411      1.1  christos 
    412      1.1  christos       for (i = 0; i < ARRAY_SIZE (loongarch_c_normal_name); i++)
    413  1.1.1.3  christos 	str_hash_insert_int (c_htab, loongarch_c_normal_name[i], i, 0);
    414      1.1  christos 
    415      1.1  christos     }
    416      1.1  christos 
    417      1.1  christos   /* Init lsx registers names.  */
    418      1.1  christos   if (LARCH_opts.ase_lsx)
    419      1.1  christos     {
    420      1.1  christos       if (!v_htab)
    421  1.1.1.3  christos 	v_htab = str_htab_create ();
    422      1.1  christos       for (i = 0; i < ARRAY_SIZE (loongarch_v_normal_name); i++)
    423  1.1.1.3  christos 	str_hash_insert_int (v_htab, loongarch_v_normal_name[i], i, 0);
    424      1.1  christos     }
    425      1.1  christos 
    426      1.1  christos   /* Init lasx registers names.  */
    427      1.1  christos   if (LARCH_opts.ase_lasx)
    428      1.1  christos     {
    429      1.1  christos       if (!x_htab)
    430  1.1.1.3  christos 	x_htab = str_htab_create ();
    431      1.1  christos       for (i = 0; i < ARRAY_SIZE (loongarch_x_normal_name); i++)
    432  1.1.1.3  christos 	str_hash_insert_int (x_htab, loongarch_x_normal_name[i], i, 0);
    433      1.1  christos     }
    434      1.1  christos 
    435      1.1  christos }
    436      1.1  christos 
    437      1.1  christos const char *
    438      1.1  christos loongarch_target_format ()
    439      1.1  christos {
    440      1.1  christos   return LARCH_opts.ase_lp64 ? "elf64-loongarch" : "elf32-loongarch";
    441      1.1  christos }
    442      1.1  christos 
    443  1.1.1.3  christos typedef struct
    444  1.1.1.3  christos {
    445  1.1.1.3  christos   unsigned int sec_id;
    446  1.1.1.3  christos   symbolS *s;
    447  1.1.1.3  christos } align_sec_sym;
    448  1.1.1.3  christos 
    449  1.1.1.3  christos static htab_t align_hash;
    450  1.1.1.3  christos 
    451  1.1.1.3  christos static hashval_t
    452  1.1.1.3  christos align_sec_sym_hash (const void *entry)
    453  1.1.1.3  christos {
    454  1.1.1.3  christos   const align_sec_sym *e = entry;
    455  1.1.1.3  christos   return e->sec_id;
    456  1.1.1.3  christos }
    457  1.1.1.3  christos 
    458  1.1.1.3  christos static int
    459  1.1.1.3  christos align_sec_sym_eq (const void *entry1, const void *entry2)
    460  1.1.1.3  christos {
    461  1.1.1.3  christos   const align_sec_sym *e1 = entry1, *e2 = entry2;
    462  1.1.1.3  christos   return e1->sec_id == e2->sec_id;
    463  1.1.1.3  christos }
    464  1.1.1.3  christos 
    465  1.1.1.3  christos /* Make align symbol be in same section with alignment directive.
    466  1.1.1.3  christos    If the symbol is only created at the first time to handle alignment
    467  1.1.1.3  christos    directive.  This means that all other sections may use this symbol.
    468  1.1.1.3  christos    If the section of this symbol is discarded, there may be problems.  */
    469  1.1.1.3  christos 
    470  1.1.1.3  christos static symbolS *get_align_symbol (segT sec)
    471  1.1.1.3  christos {
    472  1.1.1.3  christos   align_sec_sym search = { sec->id, NULL };
    473  1.1.1.3  christos   align_sec_sym *pentry = htab_find (align_hash, &search);
    474  1.1.1.3  christos   if (pentry)
    475  1.1.1.3  christos     return pentry->s;
    476  1.1.1.3  christos 
    477  1.1.1.3  christos   /* If we not find the symbol in this section.  Create and insert it.  */
    478  1.1.1.3  christos   symbolS *s = (symbolS *)local_symbol_make (".Lla-relax-align", sec,
    479  1.1.1.3  christos 					     &zero_address_frag, 0);
    480  1.1.1.3  christos   align_sec_sym entry = { sec->id, s };
    481  1.1.1.3  christos   align_sec_sym **slot = (align_sec_sym **) htab_find_slot (align_hash,
    482  1.1.1.3  christos 							    &entry, INSERT);
    483  1.1.1.3  christos   if (slot == NULL)
    484  1.1.1.3  christos     return NULL;
    485  1.1.1.3  christos   *slot = xmalloc (sizeof (align_sec_sym));
    486  1.1.1.3  christos   if (*slot == NULL)
    487  1.1.1.3  christos     return NULL;
    488  1.1.1.3  christos   **slot = entry;
    489  1.1.1.3  christos   return entry.s;
    490  1.1.1.3  christos }
    491  1.1.1.3  christos 
    492      1.1  christos void
    493      1.1  christos md_begin ()
    494      1.1  christos {
    495      1.1  christos   const struct loongarch_opcode *it;
    496      1.1  christos   struct loongarch_ase *ase;
    497      1.1  christos   for (ase = loongarch_ASEs; ase->enabled; ase++)
    498      1.1  christos     for (it = ase->opcodes; it->name; it++)
    499      1.1  christos       {
    500      1.1  christos 	if (loongarch_check_format (it->format) != 0)
    501      1.1  christos 	  as_fatal (_("insn name: %s\tformat: %s\tsyntax error"),
    502      1.1  christos 		    it->name, it->format);
    503      1.1  christos 	if (it->mask == 0 && it->macro == 0)
    504      1.1  christos 	  as_fatal (_("insn name: %s\nformat: %s\nwe want macro but "
    505      1.1  christos 		      "macro is NULL"),
    506      1.1  christos 		    it->name, it->format);
    507      1.1  christos 	if (it->macro
    508      1.1  christos 	    && loongarch_check_macro (it->format, it->macro) != 0)
    509      1.1  christos 	  as_fatal (_("insn name: %s\nformat: %s\nmacro: %s\tsyntax error"),
    510      1.1  christos 		    it->name, it->format, it->macro);
    511      1.1  christos       }
    512      1.1  christos 
    513  1.1.1.3  christos   align_hash = htab_create (10, align_sec_sym_hash, align_sec_sym_eq, free);
    514  1.1.1.3  christos 
    515      1.1  christos   /* FIXME: expressionS use 'offsetT' as constant,
    516      1.1  christos    * we want this is 64-bit type.  */
    517      1.1  christos   assert (8 <= sizeof (offsetT));
    518      1.1  christos }
    519      1.1  christos 
    520  1.1.1.3  christos /* Called just before the assembler exits.  */
    521  1.1.1.3  christos 
    522  1.1.1.3  christos void
    523  1.1.1.3  christos loongarch_md_end (void)
    524  1.1.1.3  christos {
    525  1.1.1.3  christos   htab_delete (align_hash);
    526  1.1.1.3  christos }
    527  1.1.1.3  christos 
    528      1.1  christos unsigned long
    529      1.1  christos loongarch_mach (void)
    530      1.1  christos {
    531      1.1  christos   return LARCH_opts.ase_lp64 ? bfd_mach_loongarch64 : bfd_mach_loongarch32;
    532      1.1  christos }
    533      1.1  christos 
    534      1.1  christos static const expressionS const_0 = { .X_op = O_constant, .X_add_number = 0 };
    535      1.1  christos 
    536      1.1  christos /* Handle the .dtprelword and .dtpreldword pseudo-ops.  They generate
    537      1.1  christos    a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
    538      1.1  christos    use in DWARF debug information.  */
    539      1.1  christos 
    540      1.1  christos static void
    541      1.1  christos s_dtprel (int bytes)
    542      1.1  christos {
    543      1.1  christos   expressionS ex;
    544      1.1  christos   char *p;
    545      1.1  christos 
    546      1.1  christos   expression (&ex);
    547      1.1  christos 
    548      1.1  christos   if (ex.X_op != O_symbol)
    549      1.1  christos     {
    550      1.1  christos       as_bad (_("Unsupported use of %s"),
    551      1.1  christos 	      (bytes == 8 ? ".dtpreldword" : ".dtprelword"));
    552      1.1  christos       ignore_rest_of_line ();
    553      1.1  christos     }
    554      1.1  christos 
    555      1.1  christos   p = frag_more (bytes);
    556      1.1  christos   md_number_to_chars (p, 0, bytes);
    557      1.1  christos   fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
    558      1.1  christos 	       (bytes == 8
    559      1.1  christos 		? BFD_RELOC_LARCH_TLS_DTPREL64
    560      1.1  christos 		: BFD_RELOC_LARCH_TLS_DTPREL32));
    561      1.1  christos 
    562      1.1  christos   demand_empty_rest_of_line ();
    563      1.1  christos }
    564      1.1  christos 
    565  1.1.1.3  christos struct LARCH_option_stack
    566  1.1.1.3  christos {
    567  1.1.1.3  christos   struct LARCH_option_stack *next;
    568  1.1.1.3  christos   struct loongarch_ASEs_option options;
    569  1.1.1.3  christos };
    570  1.1.1.3  christos 
    571  1.1.1.3  christos static struct LARCH_option_stack *LARCH_opts_stack = NULL;
    572  1.1.1.3  christos 
    573  1.1.1.3  christos /* Handle the .option pseudo-op.
    574  1.1.1.3  christos    The alignment of .align is done by R_LARCH_ALIGN at link time.
    575  1.1.1.3  christos    If the .align directive is within the range controlled by
    576  1.1.1.3  christos    .option norelax, that is, relax is turned off, R_LARCH_ALIGN
    577  1.1.1.3  christos    cannot be generated, which may cause ld to be unable to handle
    578  1.1.1.3  christos    the alignment.  */
    579  1.1.1.3  christos static void
    580  1.1.1.3  christos s_loongarch_option (int x ATTRIBUTE_UNUSED)
    581  1.1.1.3  christos {
    582  1.1.1.3  christos   char *name = input_line_pointer, ch;
    583  1.1.1.3  christos   while (!is_end_of_stmt (*input_line_pointer))
    584  1.1.1.3  christos     ++input_line_pointer;
    585  1.1.1.3  christos   ch = *input_line_pointer;
    586  1.1.1.3  christos   *input_line_pointer = '\0';
    587  1.1.1.3  christos 
    588  1.1.1.3  christos   if (strcmp (name, "relax") == 0)
    589  1.1.1.3  christos     LARCH_opts.relax = 1;
    590  1.1.1.3  christos   else if (strcmp (name, "norelax") == 0)
    591  1.1.1.3  christos     LARCH_opts.relax = 0;
    592  1.1.1.3  christos   else if (strcmp (name, "push") == 0)
    593  1.1.1.3  christos     {
    594  1.1.1.3  christos       struct LARCH_option_stack *s;
    595  1.1.1.3  christos 
    596  1.1.1.3  christos       s = XNEW (struct LARCH_option_stack);
    597  1.1.1.3  christos       s->next = LARCH_opts_stack;
    598  1.1.1.3  christos       s->options = LARCH_opts;
    599  1.1.1.3  christos       LARCH_opts_stack = s;
    600  1.1.1.3  christos     }
    601  1.1.1.3  christos   else if (strcmp (name, "pop") == 0)
    602  1.1.1.3  christos     {
    603  1.1.1.3  christos       struct LARCH_option_stack *s;
    604  1.1.1.3  christos 
    605  1.1.1.3  christos       s = LARCH_opts_stack;
    606  1.1.1.3  christos       if (s == NULL)
    607  1.1.1.3  christos 	as_bad (_(".option pop with no .option push"));
    608  1.1.1.3  christos       else
    609  1.1.1.3  christos 	{
    610  1.1.1.3  christos 	  LARCH_opts_stack = s->next;
    611  1.1.1.3  christos 	  LARCH_opts = s->options;
    612  1.1.1.3  christos 	  free (s);
    613  1.1.1.3  christos 	}
    614  1.1.1.3  christos     }
    615  1.1.1.3  christos   else
    616  1.1.1.3  christos     {
    617  1.1.1.3  christos       as_warn (_("unrecognized .option directive: %s"), name);
    618  1.1.1.3  christos     }
    619  1.1.1.3  christos   *input_line_pointer = ch;
    620  1.1.1.3  christos   demand_empty_rest_of_line ();
    621  1.1.1.3  christos }
    622  1.1.1.3  christos 
    623      1.1  christos static const pseudo_typeS loongarch_pseudo_table[] =
    624      1.1  christos {
    625      1.1  christos   { "dword", cons, 8 },
    626      1.1  christos   { "word", cons, 4 },
    627      1.1  christos   { "half", cons, 2 },
    628      1.1  christos   { "dtprelword", s_dtprel, 4 },
    629      1.1  christos   { "dtpreldword", s_dtprel, 8 },
    630  1.1.1.3  christos   { "option", s_loongarch_option, 0},
    631      1.1  christos   { NULL, NULL, 0 },
    632      1.1  christos };
    633      1.1  christos 
    634      1.1  christos void
    635      1.1  christos loongarch_pop_insert (void)
    636      1.1  christos {
    637      1.1  christos   pop_insert (loongarch_pseudo_table);
    638      1.1  christos }
    639      1.1  christos 
    640      1.1  christos #define INTERNAL_LABEL_SPECIAL 10
    641      1.1  christos static unsigned long internal_label_count[INTERNAL_LABEL_SPECIAL] = { 0 };
    642      1.1  christos 
    643      1.1  christos static const char *
    644      1.1  christos loongarch_internal_label_name (unsigned long label, int augend)
    645      1.1  christos {
    646      1.1  christos   static char symbol_name_build[24];
    647      1.1  christos   unsigned long want_label;
    648      1.1  christos   char *p;
    649      1.1  christos 
    650      1.1  christos   want_label = internal_label_count[label] + augend;
    651      1.1  christos 
    652      1.1  christos   p = symbol_name_build;
    653      1.1  christos #ifdef LOCAL_LABEL_PREFIX
    654      1.1  christos   *p++ = LOCAL_LABEL_PREFIX;
    655      1.1  christos #endif
    656      1.1  christos   *p++ = 'L';
    657      1.1  christos   for (; label; label /= 10)
    658      1.1  christos     *p++ = label % 10 + '0';
    659      1.1  christos   /* Make sure internal label never belong to normal label namespace.  */
    660      1.1  christos   *p++ = ':';
    661      1.1  christos   for (; want_label; want_label /= 10)
    662      1.1  christos     *p++ = want_label % 10 + '0';
    663      1.1  christos   *p++ = '\0';
    664      1.1  christos   return symbol_name_build;
    665      1.1  christos }
    666      1.1  christos 
    667      1.1  christos static void
    668      1.1  christos setup_internal_label_here (unsigned long label)
    669      1.1  christos {
    670      1.1  christos   assert (label < INTERNAL_LABEL_SPECIAL);
    671      1.1  christos   internal_label_count[label]++;
    672      1.1  christos   colon (loongarch_internal_label_name (label, 0));
    673      1.1  christos }
    674      1.1  christos 
    675      1.1  christos void
    676      1.1  christos get_internal_label (expressionS *label_expr, unsigned long label,
    677      1.1  christos 		    int augend /* 0 for previous, 1 for next.  */)
    678      1.1  christos {
    679      1.1  christos   assert (label < INTERNAL_LABEL_SPECIAL);
    680      1.1  christos     as_fatal (_("internal error: we have no internal label yet"));
    681      1.1  christos   label_expr->X_op = O_symbol;
    682      1.1  christos   label_expr->X_add_symbol =
    683      1.1  christos     symbol_find_or_make (loongarch_internal_label_name (label, augend));
    684      1.1  christos   label_expr->X_add_number = 0;
    685      1.1  christos }
    686      1.1  christos 
    687      1.1  christos static int
    688      1.1  christos is_internal_label (const char *c_str)
    689      1.1  christos {
    690      1.1  christos   do
    691      1.1  christos     {
    692      1.1  christos       if (*c_str != ':')
    693      1.1  christos 	break;
    694      1.1  christos       c_str++;
    695      1.1  christos       if (!('0' <= *c_str && *c_str <= '9'))
    696      1.1  christos 	break;
    697      1.1  christos       while ('0' <= *c_str && *c_str <= '9')
    698      1.1  christos 	c_str++;
    699      1.1  christos       if (*c_str != 'b' && *c_str != 'f')
    700      1.1  christos 	break;
    701      1.1  christos       c_str++;
    702      1.1  christos       return *c_str == '\0';
    703      1.1  christos     }
    704      1.1  christos   while (0);
    705      1.1  christos   return 0;
    706      1.1  christos }
    707      1.1  christos 
    708      1.1  christos static int
    709      1.1  christos is_label (const char *c_str)
    710      1.1  christos {
    711      1.1  christos   if (is_internal_label (c_str))
    712      1.1  christos     return 1;
    713      1.1  christos   else if ('0' <= *c_str && *c_str <= '9')
    714      1.1  christos     {
    715      1.1  christos       /* [0-9]+[bf]  */
    716      1.1  christos       while ('0' <= *c_str && *c_str <= '9')
    717      1.1  christos 	c_str++;
    718      1.1  christos       return *c_str == 'b' || *c_str == 'f';
    719      1.1  christos     }
    720      1.1  christos   else if (is_name_beginner (*c_str))
    721      1.1  christos     {
    722      1.1  christos       /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]*  */
    723      1.1  christos       c_str++;
    724      1.1  christos       while (is_part_of_name (*c_str))
    725      1.1  christos 	c_str++;
    726      1.1  christos       return *c_str == '\0';
    727      1.1  christos     }
    728      1.1  christos   else
    729      1.1  christos     return 0;
    730      1.1  christos }
    731      1.1  christos 
    732      1.1  christos static int
    733      1.1  christos is_label_with_addend (const char *c_str)
    734      1.1  christos {
    735      1.1  christos   if (is_internal_label (c_str))
    736      1.1  christos     return 1;
    737      1.1  christos   else if ('0' <= *c_str && *c_str <= '9')
    738      1.1  christos     {
    739      1.1  christos       /* [0-9]+[bf]  */
    740      1.1  christos       while ('0' <= *c_str && *c_str <= '9')
    741      1.1  christos 	c_str++;
    742      1.1  christos       if (*c_str == 'b' || *c_str == 'f')
    743      1.1  christos 	c_str++;
    744      1.1  christos       else
    745      1.1  christos 	return 0;
    746      1.1  christos       return *c_str == '\0'
    747      1.1  christos 		       || ((*c_str == '-' || *c_str == '+')
    748      1.1  christos 			   && is_unsigned (c_str + 1));
    749      1.1  christos     }
    750      1.1  christos   else if (is_name_beginner (*c_str))
    751      1.1  christos     {
    752      1.1  christos       /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]*  */
    753      1.1  christos       c_str++;
    754      1.1  christos       while (is_part_of_name (*c_str))
    755      1.1  christos 	c_str++;
    756      1.1  christos       return *c_str == '\0'
    757      1.1  christos 		       || ((*c_str == '-' || *c_str == '+')
    758      1.1  christos 			   && is_unsigned (c_str + 1));
    759      1.1  christos     }
    760      1.1  christos   else
    761      1.1  christos     return 0;
    762      1.1  christos }
    763      1.1  christos 
    764      1.1  christos static int32_t
    765      1.1  christos loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
    766      1.1  christos 					    const char *bit_field,
    767      1.1  christos 					    const char *arg, void *context)
    768      1.1  christos {
    769      1.1  christos   struct loongarch_cl_insn *ip = context;
    770      1.1  christos   offsetT imm, ret = 0;
    771      1.1  christos   size_t reloc_num_we_have = MAX_RELOC_NUMBER_A_INSN - ip->reloc_num;
    772      1.1  christos   size_t reloc_num = 0;
    773      1.1  christos 
    774      1.1  christos   if (!ip->match_now)
    775      1.1  christos     return 0;
    776      1.1  christos 
    777      1.1  christos   switch (esc_ch1)
    778      1.1  christos     {
    779      1.1  christos     case 'l':
    780      1.1  christos       switch (esc_ch2)
    781      1.1  christos 	{
    782      1.1  christos 	default:
    783      1.1  christos 	  ip->match_now = is_label (arg);
    784      1.1  christos 	  if (!ip->match_now && is_label_with_addend (arg))
    785      1.1  christos 	    as_fatal (_("This label shouldn't be with addend."));
    786      1.1  christos 	  break;
    787      1.1  christos 	case 'a':
    788      1.1  christos 	  ip->match_now = is_label_with_addend (arg);
    789      1.1  christos 	  break;
    790      1.1  christos 	}
    791      1.1  christos       break;
    792  1.1.1.2  christos     /* This is used for TLS, where the fourth operand is %le_add_r,
    793  1.1.1.2  christos        to get a relocation applied to an add instruction, for relaxation to use.
    794  1.1.1.2  christos        Two conditions, ip->match_now and reloc_num, are used to check tls insn
    795  1.1.1.2  christos        to prevent cases like add.d $a0,$a0,$a0,8.  */
    796  1.1.1.2  christos     case 't':
    797  1.1.1.2  christos       ip->match_now = loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num,
    798  1.1.1.2  christos 				reloc_num_we_have, &reloc_num, &imm) == 0;
    799      1.1  christos 
    800      1.1  christos       if (!ip->match_now)
    801      1.1  christos 	break;
    802      1.1  christos 
    803  1.1.1.2  christos       bfd_reloc_code_real_type tls_reloc_type = BFD_RELOC_LARCH_TLS_LE_ADD_R;
    804  1.1.1.2  christos 
    805  1.1.1.2  christos       if (reloc_num
    806  1.1.1.2  christos 	  && (ip->reloc_info[ip->reloc_num].type == tls_reloc_type))
    807  1.1.1.2  christos 	{
    808  1.1.1.2  christos 	  ip->reloc_num += reloc_num;
    809  1.1.1.2  christos 	  ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
    810  1.1.1.2  christos 	  ip->reloc_info[ip->reloc_num].value = const_0;
    811  1.1.1.2  christos 	  ip->reloc_num++;
    812  1.1.1.2  christos 	}
    813      1.1  christos       else
    814  1.1.1.2  christos 	ip->match_now = 0;
    815  1.1.1.2  christos       break;
    816  1.1.1.2  christos     case 's':
    817  1.1.1.2  christos     case 'u':
    818  1.1.1.2  christos       ip->match_now =
    819  1.1.1.2  christos 	loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num,
    820  1.1.1.2  christos 			      reloc_num_we_have, &reloc_num, &imm) == 0;
    821      1.1  christos 
    822      1.1  christos       if (!ip->match_now)
    823      1.1  christos 	break;
    824      1.1  christos 
    825      1.1  christos       ret = imm;
    826      1.1  christos       if (reloc_num)
    827      1.1  christos 	{
    828      1.1  christos 	  bfd_reloc_code_real_type reloc_type = BFD_RELOC_NONE;
    829      1.1  christos 	  reloc_num_we_have -= reloc_num;
    830      1.1  christos 	  if (reloc_num_we_have == 0)
    831      1.1  christos 	    as_fatal (_("expr too huge") /* Want one more reloc.  */);
    832      1.1  christos 	  if (esc_ch1 == 'u')
    833      1.1  christos 	    {
    834      1.1  christos 	      if (strncmp (bit_field, "10:12", strlen ("10:12")) == 0)
    835      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_U_10_12;
    836      1.1  christos 	    }
    837      1.1  christos 	  else if (esc_ch1 == 's')
    838      1.1  christos 	    {
    839      1.1  christos 	      if (strncmp (bit_field, "10:16<<2", strlen ("10:16<<2")) == 0)
    840      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2;
    841      1.1  christos 	      else if (strncmp (bit_field, "0:5|10:16<<2",
    842      1.1  christos 				strlen ("0:5|10:16<<2")) == 0)
    843      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2;
    844      1.1  christos 	      else if (strncmp (bit_field, "0:10|10:16<<2",
    845      1.1  christos 				strlen ("0:10|10:16<<2")) == 0)
    846      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2;
    847      1.1  christos 	      else if (strncmp (bit_field, "10:12", strlen ("10:12")) == 0)
    848      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_12;
    849      1.1  christos 	      else if (strncmp (bit_field, "5:20", strlen ("5:20")) == 0)
    850      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_5_20;
    851      1.1  christos 	      else if (strncmp (bit_field, "10:16", strlen ("10:16")) == 0)
    852      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_16;
    853      1.1  christos 	      else if (strncmp (bit_field, "10:5", strlen ("10:5")) == 0)
    854      1.1  christos 		reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_5;
    855      1.1  christos 	    }
    856      1.1  christos 	  if (reloc_type == BFD_RELOC_NONE)
    857      1.1  christos 	    as_fatal (
    858      1.1  christos 		      _("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"),
    859      1.1  christos 		      esc_ch1, esc_ch2, bit_field, arg);
    860  1.1.1.2  christos 
    861  1.1.1.2  christos 	  if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16
    862  1.1.1.2  christos 	      && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2)
    863  1.1.1.2  christos 	    {
    864  1.1.1.2  christos 	      /* As we compact stack-relocs, it is no need for pop operation.
    865  1.1.1.2  christos 		 But break out until here in order to check the imm field.
    866  1.1.1.2  christos 		 May be reloc_num > 1 if implement relax?  */
    867  1.1.1.2  christos 	      ip->reloc_num += reloc_num;
    868  1.1.1.2  christos 	      reloc_type = ip->reloc_info[0].type;
    869  1.1.1.2  christos 
    870  1.1.1.2  christos 	      if (LARCH_opts.relax
    871  1.1.1.2  christos 		    && (BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_type
    872  1.1.1.3  christos 			|| BFD_RELOC_LARCH_TLS_LE_LO12_R == reloc_type
    873  1.1.1.3  christos 			|| BFD_RELOC_LARCH_TLS_LE_HI20 == reloc_type
    874  1.1.1.3  christos 			|| BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_type
    875  1.1.1.3  christos 			|| BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_type
    876  1.1.1.3  christos 			|| BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type
    877  1.1.1.3  christos 			|| BFD_RELOC_LARCH_CALL36 == reloc_type))
    878  1.1.1.2  christos 		{
    879  1.1.1.2  christos 		  ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
    880  1.1.1.2  christos 		  ip->reloc_info[ip->reloc_num].value = const_0;
    881  1.1.1.2  christos 		  ip->reloc_num++;
    882  1.1.1.2  christos 		}
    883  1.1.1.2  christos 
    884  1.1.1.2  christos 	      /* Only one register macros (used in normal code model)
    885  1.1.1.2  christos 		 emit R_LARCH_RELAX.
    886  1.1.1.2  christos 		 LARCH_opts.ase_labs and LARCH_opts.ase_gabs are used
    887  1.1.1.2  christos 		 to generate the code model of absolute addresses, and
    888  1.1.1.2  christos 		 we do not relax this code model.  */
    889  1.1.1.2  christos 	      if (LARCH_opts.relax && (ip->expand_from_macro & 1)
    890  1.1.1.3  christos 		    && !(LARCH_opts.ase_labs | LARCH_opts.ase_gabs)
    891  1.1.1.2  christos 		    && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_type
    892  1.1.1.2  christos 			|| BFD_RELOC_LARCH_PCALA_LO12 == reloc_type
    893  1.1.1.2  christos 			|| BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_type
    894  1.1.1.2  christos 			|| BFD_RELOC_LARCH_GOT_PC_LO12 == reloc_type
    895  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_type
    896  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_type
    897  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_type
    898  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_type
    899  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_DESC_LD == reloc_type
    900  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_DESC_CALL == reloc_type
    901  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_type
    902  1.1.1.2  christos 			|| BFD_RELOC_LARCH_TLS_IE_PC_LO12 == reloc_type))
    903  1.1.1.2  christos 		{
    904  1.1.1.2  christos 		  ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
    905  1.1.1.2  christos 		  ip->reloc_info[ip->reloc_num].value = const_0;
    906  1.1.1.2  christos 		  ip->reloc_num++;
    907  1.1.1.2  christos 		}
    908  1.1.1.2  christos 	      break;
    909  1.1.1.2  christos 	    }
    910      1.1  christos 	  reloc_num++;
    911      1.1  christos 	  ip->reloc_num += reloc_num;
    912      1.1  christos 	  ip->reloc_info[ip->reloc_num - 1].type = reloc_type;
    913      1.1  christos 	  ip->reloc_info[ip->reloc_num - 1].value = const_0;
    914      1.1  christos 	}
    915      1.1  christos       break;
    916      1.1  christos     case 'r':
    917  1.1.1.3  christos       imm = str_hash_find_int (r_htab, arg);
    918  1.1.1.3  christos       ip->match_now = 0 <= imm;
    919  1.1.1.3  christos       ret = imm;
    920  1.1.1.2  christos       if (ip->match_now)
    921  1.1.1.2  christos 	break;
    922  1.1.1.2  christos       /* Handle potential usage of deprecated register aliases.  */
    923  1.1.1.3  christos       imm = str_hash_find_int (r_deprecated_htab, arg);
    924  1.1.1.3  christos       ip->match_now = 0 <= imm;
    925  1.1.1.3  christos       ret = imm;
    926  1.1.1.2  christos       /* !ip->expand_from_macro: avoiding duplicate output warnings,
    927  1.1.1.2  christos 	 only the first macro output warning.  */
    928  1.1.1.2  christos       if (ip->match_now && !ip->expand_from_macro)
    929  1.1.1.2  christos 	as_warn (_("register alias %s is deprecated, use %s instead"),
    930  1.1.1.2  christos 		 arg, r_abi_names[ret]);
    931      1.1  christos       break;
    932      1.1  christos     case 'f':
    933  1.1.1.2  christos       switch (esc_ch2)
    934  1.1.1.2  christos 	{
    935  1.1.1.2  christos 	case 'c':
    936  1.1.1.3  christos 	  imm = str_hash_find_int (fc_htab, arg);
    937  1.1.1.3  christos 	  if (0 > imm)
    938  1.1.1.3  christos 	    imm = str_hash_find_int (fcn_htab, arg);
    939  1.1.1.2  christos 	  break;
    940  1.1.1.2  christos 	default:
    941  1.1.1.3  christos 	  imm = str_hash_find_int (f_htab, arg);
    942  1.1.1.2  christos 	}
    943  1.1.1.3  christos       ip->match_now = 0 <= imm;
    944  1.1.1.3  christos       ret = imm;
    945  1.1.1.2  christos       if (ip->match_now && !ip->expand_from_macro)
    946  1.1.1.2  christos 	break;
    947  1.1.1.2  christos       /* Handle potential usage of deprecated register aliases.  */
    948  1.1.1.3  christos       imm = str_hash_find_int (f_deprecated_htab, arg);
    949  1.1.1.3  christos       ip->match_now = 0 <= imm;
    950  1.1.1.3  christos       ret = imm;
    951  1.1.1.2  christos       if (ip->match_now)
    952  1.1.1.2  christos 	as_warn (_("register alias %s is deprecated, use %s instead"),
    953  1.1.1.2  christos 		 arg, f_abi_names[ret]);
    954      1.1  christos       break;
    955      1.1  christos     case 'c':
    956      1.1  christos       switch (esc_ch2)
    957      1.1  christos 	{
    958      1.1  christos 	case 'r':
    959  1.1.1.3  christos 	  imm = str_hash_find_int (cr_htab, arg);
    960      1.1  christos 	  break;
    961      1.1  christos 	default:
    962  1.1.1.3  christos 	  imm = str_hash_find_int (c_htab, arg);
    963      1.1  christos 	}
    964  1.1.1.3  christos       ip->match_now = 0 <= imm;
    965  1.1.1.3  christos       ret = imm;
    966      1.1  christos       break;
    967      1.1  christos     case 'v':
    968  1.1.1.3  christos       imm = str_hash_find_int (v_htab, arg);
    969  1.1.1.3  christos       ip->match_now = 0 <= imm;
    970  1.1.1.3  christos       ret = imm;
    971      1.1  christos       break;
    972      1.1  christos     case 'x':
    973  1.1.1.3  christos       imm = str_hash_find_int (x_htab, arg);
    974  1.1.1.3  christos       ip->match_now = 0 <= imm;
    975  1.1.1.3  christos       ret = imm;
    976      1.1  christos       break;
    977      1.1  christos     case '\0':
    978      1.1  christos       ip->all_match = ip->match_now;
    979      1.1  christos       ip->insn_length =
    980      1.1  christos 	ip->insn->mask ? loongarch_insn_length (ip->insn->match) : 0;
    981      1.1  christos       /* FIXME: now we have no relax insn.  */
    982      1.1  christos       ip->relax_max_length = ip->insn_length;
    983      1.1  christos       break;
    984      1.1  christos     default:
    985      1.1  christos       as_fatal (_("unknown escape"));
    986      1.1  christos     }
    987      1.1  christos 
    988      1.1  christos   do
    989      1.1  christos     {
    990      1.1  christos       /* Check imm overflow.  */
    991      1.1  christos       int bit_width, bits_needed_s, bits_needed_u;
    992      1.1  christos       char *t;
    993      1.1  christos 
    994      1.1  christos       if (!ip->match_now)
    995      1.1  christos 	break;
    996      1.1  christos 
    997      1.1  christos       if (0 < reloc_num)
    998      1.1  christos 	break;
    999      1.1  christos 
   1000      1.1  christos       bit_width = loongarch_get_bit_field_width (bit_field, &t);
   1001      1.1  christos 
   1002      1.1  christos       if (bit_width == -1)
   1003      1.1  christos 	/* No specify bit width.  */
   1004      1.1  christos 	break;
   1005      1.1  christos 
   1006      1.1  christos       imm = ret;
   1007      1.1  christos       if (t[0] == '<' && t[1] == '<')
   1008      1.1  christos 	{
   1009      1.1  christos 	  int i = strtol (t += 2, &t, 10), j;
   1010      1.1  christos 	  for (j = i; 0 < j; j--, imm >>= 1)
   1011      1.1  christos 	    if (imm & 1)
   1012      1.1  christos 	      as_fatal (_("require imm low %d bit is 0."), i);
   1013      1.1  christos 	}
   1014      1.1  christos 
   1015      1.1  christos       if (*t == '+')
   1016      1.1  christos 	imm -= strtol (t, &t, 10);
   1017      1.1  christos 
   1018      1.1  christos       bits_needed_s = loongarch_bits_imm_needed (imm, 1);
   1019      1.1  christos       bits_needed_u = loongarch_bits_imm_needed (imm, 0);
   1020      1.1  christos 
   1021      1.1  christos       if ((esc_ch1 == 's' && bit_width < bits_needed_s)
   1022      1.1  christos 	  || (esc_ch1 != 's' && bit_width < bits_needed_u))
   1023      1.1  christos 	/* How to do after we detect overflow.  */
   1024      1.1  christos 	as_fatal (_("Immediate overflow.\n"
   1025      1.1  christos 		    "format: %c%c%s\n"
   1026      1.1  christos 		    "arg: %s"),
   1027      1.1  christos 		  esc_ch1, esc_ch2, bit_field, arg);
   1028      1.1  christos     }
   1029      1.1  christos   while (0);
   1030      1.1  christos 
   1031      1.1  christos   if (esc_ch1 != '\0')
   1032      1.1  christos     {
   1033      1.1  christos       ip->args[ip->arg_num] = ret;
   1034      1.1  christos       ip->arg_num++;
   1035      1.1  christos     }
   1036      1.1  christos   return ret;
   1037      1.1  christos }
   1038      1.1  christos 
   1039      1.1  christos static void
   1040      1.1  christos get_loongarch_opcode (struct loongarch_cl_insn *insn)
   1041      1.1  christos {
   1042      1.1  christos   const struct loongarch_opcode *it;
   1043      1.1  christos   struct loongarch_ase *ase;
   1044      1.1  christos   for (ase = loongarch_ASEs; ase->enabled; ase++)
   1045      1.1  christos     {
   1046      1.1  christos       if (!*ase->enabled || (ase->include && !*ase->include)
   1047      1.1  christos 	  || (ase->exclude && *ase->exclude))
   1048      1.1  christos 	continue;
   1049      1.1  christos 
   1050      1.1  christos       if (!ase->name_hash_entry)
   1051      1.1  christos 	{
   1052      1.1  christos 	  ase->name_hash_entry = str_htab_create ();
   1053      1.1  christos 	  for (it = ase->opcodes; it->name; it++)
   1054  1.1.1.2  christos 	    {
   1055  1.1.1.2  christos 	      if ((!it->include || (it->include && *it->include))
   1056  1.1.1.2  christos 		  && (!it->exclude || (it->exclude && !(*it->exclude)))
   1057  1.1.1.2  christos 		  && !(it->pinfo & INSN_DIS_ALIAS))
   1058  1.1.1.3  christos 		str_hash_insert (ase->name_hash_entry, it->name, it, 0);
   1059  1.1.1.2  christos 	    }
   1060      1.1  christos 	}
   1061      1.1  christos 
   1062      1.1  christos       if ((it = str_hash_find (ase->name_hash_entry, insn->name)) == NULL)
   1063      1.1  christos 	continue;
   1064      1.1  christos 
   1065      1.1  christos       do
   1066      1.1  christos 	{
   1067      1.1  christos 	  insn->insn = it;
   1068      1.1  christos 	  insn->match_now = 1;
   1069      1.1  christos 	  insn->all_match = 0;
   1070      1.1  christos 	  insn->arg_num = 0;
   1071      1.1  christos 	  insn->reloc_num = 0;
   1072      1.1  christos 	  insn->insn_bin = (loongarch_foreach_args
   1073      1.1  christos 			    (it->format, insn->arg_strs,
   1074      1.1  christos 			     loongarch_args_parser_can_match_arg_helper,
   1075      1.1  christos 			     insn));
   1076      1.1  christos 	  if (insn->all_match && !(it->include && !*it->include)
   1077      1.1  christos 	      && !(it->exclude && *it->exclude))
   1078      1.1  christos 	    {
   1079      1.1  christos 	      insn->insn_bin |= it->match;
   1080      1.1  christos 	      return;
   1081      1.1  christos 	    }
   1082      1.1  christos 	  it++;
   1083      1.1  christos 	}
   1084      1.1  christos       while (it->name && strcasecmp (it->name, insn->name) == 0);
   1085      1.1  christos     }
   1086      1.1  christos }
   1087      1.1  christos 
   1088      1.1  christos static int
   1089      1.1  christos check_this_insn_before_appending (struct loongarch_cl_insn *ip)
   1090      1.1  christos {
   1091      1.1  christos   int ret = 0;
   1092  1.1.1.2  christos 
   1093  1.1.1.2  christos   if (strncmp (ip->name, "la.abs", 6) == 0)
   1094      1.1  christos     {
   1095      1.1  christos       ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_MARK_LA;
   1096  1.1.1.2  christos       ip->reloc_info[ip->reloc_num].value = const_0;
   1097      1.1  christos       ip->reloc_num++;
   1098      1.1  christos     }
   1099  1.1.1.3  christos   /* check all atomic memory insns */
   1100  1.1.1.3  christos   else if (ip->insn->mask == LARCH_MK_ATOMIC_MEM
   1101  1.1.1.3  christos 	   && LARCH_INSN_ATOMIC_MEM (ip->insn_bin))
   1102      1.1  christos     {
   1103      1.1  christos       /* For AMO insn amswap.[wd], amadd.[wd], etc.  */
   1104      1.1  christos       if (ip->args[0] != 0
   1105      1.1  christos 	  && (ip->args[0] == ip->args[1] || ip->args[0] == ip->args[2]))
   1106  1.1.1.3  christos 	as_bad (_("atomic memory operations insns require rd != rj"
   1107  1.1.1.3  christos 		  " && rd != rk when rd isn't r0"));
   1108      1.1  christos     }
   1109  1.1.1.3  christos   else if ((ip->insn->mask == LARCH_MK_BSTRINS_W
   1110  1.1.1.3  christos 	    /* bstr(ins|pick).w  rd, rj, msbw, lsbw  */
   1111  1.1.1.3  christos 	    && (LARCH_INSN_BSTRINS_W (ip->insn_bin)
   1112  1.1.1.3  christos 		|| LARCH_INSN_BSTRPICK_W (ip->insn_bin)))
   1113  1.1.1.3  christos 	   || (ip->insn->mask == LARCH_MK_BSTRINS_D
   1114  1.1.1.3  christos 	       /* bstr(ins|pick).d  rd, rj, msbd, lsbd  */
   1115  1.1.1.3  christos 	       && (LARCH_INSN_BSTRINS_D (ip->insn_bin)
   1116  1.1.1.3  christos 		   || LARCH_INSN_BSTRPICK_D (ip->insn_bin))))
   1117      1.1  christos     {
   1118      1.1  christos       /* For bstr(ins|pick).[wd].  */
   1119      1.1  christos       if (ip->args[2] < ip->args[3])
   1120  1.1.1.3  christos 	as_bad (_("bstr(ins|pick).[wd] require msbd >= lsbd"));
   1121      1.1  christos     }
   1122  1.1.1.3  christos   else if (ip->insn->mask != 0
   1123  1.1.1.3  christos 	   && (LARCH_INSN_CSRXCHG (ip->insn_bin)
   1124  1.1.1.3  christos 	       || LARCH_INSN_GCSRXCHG (ip->insn_bin))
   1125  1.1.1.3  christos 	   && (LARCH_GET_RJ (ip->insn_bin) == 0
   1126  1.1.1.3  christos 	       || LARCH_GET_RJ (ip->insn_bin) == 1)
   1127      1.1  christos 	   /* csrxchg  rd, rj, csr_num  */
   1128  1.1.1.3  christos 	   && (strcmp ("csrxchg", ip->name) == 0
   1129  1.1.1.3  christos 	       || strcmp ("gcsrxchg", ip->name) == 0))
   1130  1.1.1.3  christos     as_bad (_("g?csrxchg require rj != r0 && rj != r1"));
   1131      1.1  christos 
   1132      1.1  christos   return ret;
   1133      1.1  christos }
   1134      1.1  christos 
   1135      1.1  christos static void
   1136      1.1  christos install_insn (const struct loongarch_cl_insn *insn)
   1137      1.1  christos {
   1138      1.1  christos   char *f = insn->frag->fr_literal + insn->where;
   1139      1.1  christos   if (0 < insn->insn_length)
   1140      1.1  christos     md_number_to_chars (f, insn->insn_bin, insn->insn_length);
   1141      1.1  christos }
   1142      1.1  christos 
   1143      1.1  christos static void
   1144      1.1  christos move_insn (struct loongarch_cl_insn *insn, fragS *frag, long where)
   1145      1.1  christos {
   1146      1.1  christos   size_t i;
   1147      1.1  christos   insn->frag = frag;
   1148      1.1  christos   insn->where = where;
   1149      1.1  christos   for (i = 0; i < insn->reloc_num; i++)
   1150      1.1  christos     {
   1151  1.1.1.2  christos       if (insn->fixp[i])
   1152  1.1.1.2  christos 	{
   1153  1.1.1.2  christos 	  insn->fixp[i]->fx_frag = frag;
   1154  1.1.1.2  christos 	  insn->fixp[i]->fx_where = where;
   1155  1.1.1.2  christos 	}
   1156      1.1  christos     }
   1157      1.1  christos   install_insn (insn);
   1158      1.1  christos }
   1159      1.1  christos 
   1160      1.1  christos /* Add INSN to the end of the output.  */
   1161      1.1  christos static void
   1162      1.1  christos append_fixed_insn (struct loongarch_cl_insn *insn)
   1163      1.1  christos {
   1164  1.1.1.2  christos   /* Ensure the jirl is emitted to the same frag as the pcaddu18i.  */
   1165  1.1.1.2  christos   if (BFD_RELOC_LARCH_CALL36 == insn->reloc_info[0].type)
   1166  1.1.1.2  christos     frag_grow (8);
   1167  1.1.1.2  christos 
   1168      1.1  christos   char *f = frag_more (insn->insn_length);
   1169      1.1  christos   move_insn (insn, frag_now, f - frag_now->fr_literal);
   1170  1.1.1.3  christos 
   1171  1.1.1.3  christos   if (call36)
   1172  1.1.1.3  christos     {
   1173  1.1.1.3  christos       if (strcmp (insn->name, "jirl") == 0)
   1174  1.1.1.3  christos 	{
   1175  1.1.1.3  christos 	  /* See comment at end of append_fixp_and_insn.  */
   1176  1.1.1.3  christos 	  frag_wane (frag_now);
   1177  1.1.1.3  christos 	  frag_new (0);
   1178  1.1.1.3  christos 	}
   1179  1.1.1.3  christos       call36 = 0;
   1180  1.1.1.3  christos     }
   1181  1.1.1.3  christos 
   1182  1.1.1.3  christos   if (BFD_RELOC_LARCH_CALL36 == insn->reloc_info[0].type)
   1183  1.1.1.3  christos     call36 = 1;
   1184      1.1  christos }
   1185      1.1  christos 
   1186  1.1.1.2  christos /* Add instructions based on the worst-case scenario firstly.  */
   1187  1.1.1.2  christos static void
   1188  1.1.1.2  christos append_relaxed_branch_insn (struct loongarch_cl_insn *insn, int max_chars,
   1189  1.1.1.2  christos 	    int var, relax_substateT subtype, symbolS *symbol, offsetT offset)
   1190  1.1.1.2  christos {
   1191  1.1.1.2  christos   frag_grow (max_chars);
   1192  1.1.1.2  christos   move_insn (insn, frag_now, frag_more (0) - frag_now->fr_literal);
   1193  1.1.1.2  christos   frag_var (rs_machine_dependent, max_chars, var,
   1194  1.1.1.2  christos 	    subtype, symbol, offset, NULL);
   1195  1.1.1.2  christos }
   1196  1.1.1.2  christos 
   1197      1.1  christos static void
   1198      1.1  christos append_fixp_and_insn (struct loongarch_cl_insn *ip)
   1199      1.1  christos {
   1200      1.1  christos   reloc_howto_type *howto;
   1201  1.1.1.2  christos   bfd_reloc_code_real_type r_type;
   1202      1.1  christos   struct reloc_info *reloc_info = ip->reloc_info;
   1203      1.1  christos   size_t i;
   1204      1.1  christos 
   1205      1.1  christos   dwarf2_emit_insn (0);
   1206      1.1  christos 
   1207      1.1  christos   for (i = 0; i < ip->reloc_num; i++)
   1208      1.1  christos     {
   1209  1.1.1.2  christos       r_type = reloc_info[i].type;
   1210  1.1.1.2  christos 
   1211  1.1.1.2  christos       if (r_type != BFD_RELOC_UNUSED)
   1212  1.1.1.2  christos 	{
   1213  1.1.1.2  christos 
   1214  1.1.1.2  christos 	  gas_assert (&(reloc_info[i].value));
   1215  1.1.1.2  christos 	  if (BFD_RELOC_LARCH_B16 == r_type || BFD_RELOC_LARCH_B21 == r_type)
   1216  1.1.1.2  christos 	    {
   1217  1.1.1.2  christos 	      int min_bytes = 4; /* One branch instruction.  */
   1218  1.1.1.2  christos 	      unsigned max_bytes = 8; /* Branch and jump instructions.  */
   1219  1.1.1.2  christos 
   1220  1.1.1.2  christos 	      if (now_seg == absolute_section)
   1221  1.1.1.2  christos 		{
   1222  1.1.1.2  christos 		  as_bad (_("relaxable branches not supported in absolute section"));
   1223  1.1.1.2  christos 		  return;
   1224  1.1.1.2  christos 		}
   1225  1.1.1.2  christos 
   1226  1.1.1.2  christos 	      append_relaxed_branch_insn (ip, max_bytes, min_bytes,
   1227  1.1.1.2  christos 					  RELAX_BRANCH_ENCODE (r_type),
   1228  1.1.1.2  christos 					  reloc_info[i].value.X_add_symbol,
   1229  1.1.1.2  christos 					  reloc_info[i].value.X_add_number);
   1230  1.1.1.2  christos 	      return;
   1231  1.1.1.2  christos 	    }
   1232  1.1.1.2  christos 	  else
   1233  1.1.1.2  christos 	    {
   1234  1.1.1.2  christos 	      howto = bfd_reloc_type_lookup (stdoutput, r_type);
   1235  1.1.1.2  christos 	      if (howto == NULL)
   1236  1.1.1.2  christos 		as_fatal (_("no HOWTO loong relocation number %d"), r_type);
   1237  1.1.1.2  christos 
   1238  1.1.1.2  christos 	      ip->fixp[i] = fix_new_exp (ip->frag, ip->where,
   1239  1.1.1.2  christos 					 bfd_get_reloc_size (howto),
   1240  1.1.1.2  christos 					 &reloc_info[i].value, FALSE, r_type);
   1241  1.1.1.2  christos 	    }
   1242  1.1.1.3  christos 	  /* Allow LoongArch 64 to use 64-bit addends.  */
   1243  1.1.1.3  christos 	  if (LARCH_opts.ase_lp64)
   1244  1.1.1.3  christos 	    ip->fixp[i]->fx_no_overflow = 1;
   1245  1.1.1.2  christos 	}
   1246      1.1  christos     }
   1247      1.1  christos 
   1248      1.1  christos   if (ip->insn_length < ip->relax_max_length)
   1249      1.1  christos     as_fatal (_("Internal error: not support relax now"));
   1250      1.1  christos   else
   1251      1.1  christos     append_fixed_insn (ip);
   1252  1.1.1.2  christos 
   1253  1.1.1.2  christos   /* We need to start a new frag after any instruction that can be
   1254  1.1.1.2  christos      optimized away or compressed by the linker during relaxation, to prevent
   1255  1.1.1.2  christos      the assembler from computing static offsets across such an instruction.
   1256  1.1.1.2  christos 
   1257  1.1.1.2  christos      This is necessary to get correct .eh_frame FDE DW_CFA_advance_loc info.
   1258  1.1.1.2  christos      If one cfi_insn_data's two symbols are not in the same frag, it will
   1259  1.1.1.2  christos      generate ADD and SUB relocations pairs to calculate DW_CFA_advance_loc.
   1260  1.1.1.2  christos      (gas/dw2gencfi.c: output_cfi_insn:
   1261  1.1.1.2  christos      if (symbol_get_frag (to) == symbol_get_frag (from)))
   1262  1.1.1.2  christos 
   1263  1.1.1.2  christos      For macro instructions, only the first instruction expanded from macro
   1264  1.1.1.3  christos      need to start a new frag.
   1265  1.1.1.3  christos      Since the relocations of the normal code model and the extreme code model
   1266  1.1.1.3  christos      of the old LE instruction sequence are the same, it is impossible to
   1267  1.1.1.3  christos      distinguish which code model it is based on relocation alone, so the
   1268  1.1.1.3  christos      extreme code model has to be relaxed.  */
   1269  1.1.1.2  christos   if (LARCH_opts.relax
   1270  1.1.1.2  christos       && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_info[0].type
   1271  1.1.1.2  christos 	  || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type
   1272  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_info[0].type
   1273  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_LE_ADD_R == reloc_info[0].type
   1274  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_info[0].type
   1275  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_info[0].type
   1276  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_info[0].type
   1277  1.1.1.2  christos 	  || BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_info[0].type
   1278  1.1.1.3  christos 	  || BFD_RELOC_LARCH_TLS_LE_HI20 == reloc_info[0].type
   1279  1.1.1.3  christos 	  || BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_info[0].type
   1280  1.1.1.3  christos 	  || BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_info[0].type
   1281  1.1.1.3  christos 	  || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_info[0].type))
   1282  1.1.1.2  christos     {
   1283  1.1.1.2  christos       frag_wane (frag_now);
   1284  1.1.1.2  christos       frag_new (0);
   1285  1.1.1.2  christos     }
   1286      1.1  christos }
   1287      1.1  christos 
   1288      1.1  christos /* Ask helper for returning a malloced c_str or NULL.  */
   1289      1.1  christos static char *
   1290      1.1  christos assember_macro_helper (const char *const args[], void *context_ptr)
   1291      1.1  christos {
   1292      1.1  christos   struct loongarch_cl_insn *insn = context_ptr;
   1293      1.1  christos   char *ret = NULL;
   1294      1.1  christos   if ( strcmp (insn->name, "li.w") == 0 || strcmp (insn->name, "li.d") == 0)
   1295      1.1  christos     {
   1296      1.1  christos       char args_buf[50], insns_buf[200];
   1297      1.1  christos       const char *arg_strs[6];
   1298      1.1  christos       uint32_t hi32, lo32;
   1299      1.1  christos 
   1300      1.1  christos       /* We pay attention to sign extend beacause it is chance of reduce insn.
   1301      1.1  christos 	 The exception is 12-bit and hi-12-bit unsigned,
   1302      1.1  christos 	 we need a 'ori' or a 'lu52i.d' accordingly.  */
   1303      1.1  christos       char all0_bit_vec, sign_bit_vec, allf_bit_vec, paritial_is_sext_of_prev;
   1304      1.1  christos 
   1305      1.1  christos       lo32 = insn->args[1] & 0xffffffff;
   1306      1.1  christos       hi32 = insn->args[1] >> 32;
   1307      1.1  christos 
   1308      1.1  christos       if (strcmp (insn->name, "li.w") == 0)
   1309      1.1  christos 	{
   1310      1.1  christos 	  if (hi32 != 0 && hi32 != 0xffffffff)
   1311      1.1  christos 	    as_fatal (_("li overflow: hi32:0x%x lo32:0x%x"), hi32, lo32);
   1312      1.1  christos 	  hi32 = lo32 & 0x80000000 ? 0xffffffff : 0;
   1313      1.1  christos 	}
   1314      1.1  christos 
   1315      1.1  christos       if (strcmp (insn->name, "li.d") == 0 && !LARCH_opts.ase_lp64)
   1316      1.1  christos 	as_fatal (_("we can't li.d on 32bit-arch"));
   1317      1.1  christos 
   1318      1.1  christos       snprintf (args_buf, sizeof (args_buf), "0x%x,0x%x,0x%x,0x%x,%s",
   1319      1.1  christos 		(hi32 >> 20) & 0xfff, hi32 & 0xfffff, (lo32 >> 12) & 0xfffff,
   1320      1.1  christos 		lo32 & 0xfff, args[0]);
   1321      1.1  christos       loongarch_split_args_by_comma (args_buf, arg_strs);
   1322      1.1  christos 
   1323      1.1  christos       all0_bit_vec =
   1324      1.1  christos 	((((hi32 & 0xfff00000) == 0) << 3) | (((hi32 & 0x000fffff) == 0) << 2)
   1325      1.1  christos 	 | (((lo32 & 0xfffff000) == 0) << 1) | ((lo32 & 0x00000fff) == 0));
   1326      1.1  christos       sign_bit_vec =
   1327      1.1  christos 	((((hi32 & 0x80000000) != 0) << 3) | (((hi32 & 0x00080000) != 0) << 2)
   1328      1.1  christos 	 | (((lo32 & 0x80000000) != 0) << 1) | ((lo32 & 0x00000800) != 0));
   1329      1.1  christos       allf_bit_vec =
   1330      1.1  christos 	((((hi32 & 0xfff00000) == 0xfff00000) << 3)
   1331      1.1  christos 	 | (((hi32 & 0x000fffff) == 0x000fffff) << 2)
   1332      1.1  christos 	 | (((lo32 & 0xfffff000) == 0xfffff000) << 1)
   1333      1.1  christos 	 | ((lo32 & 0x00000fff) == 0x00000fff));
   1334      1.1  christos       paritial_is_sext_of_prev =
   1335      1.1  christos 	(all0_bit_vec ^ allf_bit_vec) & (all0_bit_vec ^ (sign_bit_vec << 1));
   1336      1.1  christos 
   1337      1.1  christos       static const char *const li_32bit[] =
   1338      1.1  christos 	{
   1339      1.1  christos 	  "lu12i.w %5,%3&0x80000?%3-0x100000:%3;ori %5,%5,%4;",
   1340      1.1  christos 	  "lu12i.w %5,%3&0x80000?%3-0x100000:%3;",
   1341      1.1  christos 	  "addi.w %5,$r0,%4&0x800?%4-0x1000:%4;",
   1342      1.1  christos 	  "or %5,$r0,$r0;",
   1343      1.1  christos 	};
   1344      1.1  christos       static const char *const li_hi_32bit[] =
   1345      1.1  christos 	{
   1346      1.1  christos 	  "lu32i.d %5,%2&0x80000?%2-0x100000:%2;"
   1347      1.1  christos 	  "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;",
   1348      1.1  christos 	  "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;",
   1349      1.1  christos 	  "lu32i.d %5,%2&0x80000?%2-0x100000:%2;",
   1350      1.1  christos 	  "",
   1351      1.1  christos 	};
   1352      1.1  christos       do
   1353      1.1  christos 	{
   1354      1.1  christos 	  insns_buf[0] = '\0';
   1355      1.1  christos 	  if (paritial_is_sext_of_prev == 0x7)
   1356      1.1  christos 	    {
   1357      1.1  christos 	      strcat (insns_buf, "lu52i.d %5,$r0,%1&0x800?%1-0x1000:%1;");
   1358      1.1  christos 	      break;
   1359      1.1  christos 	    }
   1360      1.1  christos 	  if ((all0_bit_vec & 0x3) == 0x2)
   1361      1.1  christos 	    strcat (insns_buf, "ori %5,$r0,%4;");
   1362      1.1  christos 	  else
   1363      1.1  christos 	    strcat (insns_buf, li_32bit[paritial_is_sext_of_prev & 0x3]);
   1364      1.1  christos 	  strcat (insns_buf, li_hi_32bit[paritial_is_sext_of_prev >> 2]);
   1365      1.1  christos 	}
   1366      1.1  christos       while (0);
   1367      1.1  christos 
   1368      1.1  christos       ret = loongarch_expand_macro (insns_buf, arg_strs, NULL, NULL,
   1369      1.1  christos 				    sizeof (args_buf));
   1370      1.1  christos     }
   1371  1.1.1.2  christos 
   1372      1.1  christos   return ret;
   1373      1.1  christos }
   1374      1.1  christos 
   1375      1.1  christos /* Accept instructions separated by ';'
   1376      1.1  christos  * assuming 'not starting with space and not ending with space' or pass in
   1377      1.1  christos  * empty c_str.  */
   1378      1.1  christos static void
   1379  1.1.1.2  christos loongarch_assemble_INSNs (char *str, unsigned int expand_from_macro)
   1380      1.1  christos {
   1381      1.1  christos   char *rest;
   1382      1.1  christos   size_t len_str = strlen(str);
   1383      1.1  christos 
   1384      1.1  christos   for (rest = str; *rest != ';' && *rest != '\0'; rest++);
   1385      1.1  christos   if (*rest == ';')
   1386      1.1  christos     *rest++ = '\0';
   1387      1.1  christos 
   1388      1.1  christos   if (*str == ':')
   1389      1.1  christos     {
   1390      1.1  christos       str++;
   1391      1.1  christos       setup_internal_label_here (strtol (str, &str, 10));
   1392      1.1  christos       str++;
   1393      1.1  christos     }
   1394      1.1  christos 
   1395      1.1  christos   do
   1396      1.1  christos     {
   1397      1.1  christos       if (*str == '\0')
   1398      1.1  christos 	break;
   1399      1.1  christos 
   1400  1.1.1.3  christos       struct loongarch_cl_insn the_one;
   1401  1.1.1.3  christos       memset (&the_one, 0, sizeof (the_one));
   1402      1.1  christos       the_one.name = str;
   1403  1.1.1.2  christos       the_one.expand_from_macro = expand_from_macro;
   1404      1.1  christos 
   1405  1.1.1.3  christos       for (; *str && !is_whitespace (*str); str++)
   1406      1.1  christos 	;
   1407  1.1.1.3  christos       if (is_whitespace (*str))
   1408      1.1  christos 	*str++ = '\0';
   1409      1.1  christos 
   1410      1.1  christos       loongarch_split_args_by_comma (str, the_one.arg_strs);
   1411      1.1  christos       get_loongarch_opcode (&the_one);
   1412      1.1  christos 
   1413      1.1  christos       if (!the_one.all_match)
   1414      1.1  christos 	{
   1415      1.1  christos 	  char *ss = loongarch_cat_splited_strs (the_one.arg_strs);
   1416      1.1  christos 	  as_bad (_("no match insn: %s\t%s"), the_one.name, ss ? ss : "");
   1417      1.1  christos 	  free(ss);
   1418      1.1  christos 	  return;
   1419      1.1  christos 	}
   1420      1.1  christos 
   1421      1.1  christos       if (check_this_insn_before_appending (&the_one) != 0)
   1422      1.1  christos 	break;
   1423      1.1  christos 
   1424      1.1  christos       append_fixp_and_insn (&the_one);
   1425  1.1.1.2  christos 
   1426  1.1.1.2  christos       /* Expanding macro instructions.  */
   1427      1.1  christos       if (the_one.insn_length == 0 && the_one.insn->macro)
   1428      1.1  christos 	{
   1429  1.1.1.2  christos 	  unsigned int new_expand_from_macro = 0;
   1430  1.1.1.2  christos 	  if (2 == the_one.arg_num)
   1431  1.1.1.2  christos 	    new_expand_from_macro |= 1;
   1432  1.1.1.2  christos 	  else if (3 == the_one.arg_num)
   1433  1.1.1.2  christos 	    new_expand_from_macro |= 2;
   1434  1.1.1.2  christos 
   1435      1.1  christos 	  char *c_str = loongarch_expand_macro (the_one.insn->macro,
   1436      1.1  christos 						the_one.arg_strs,
   1437      1.1  christos 						assember_macro_helper,
   1438      1.1  christos 						&the_one, len_str);
   1439  1.1.1.2  christos 	  /* The first instruction expanded from macro.  */
   1440  1.1.1.2  christos 	  loongarch_assemble_INSNs (c_str, new_expand_from_macro);
   1441      1.1  christos 	  free (c_str);
   1442      1.1  christos 	}
   1443      1.1  christos     }
   1444      1.1  christos   while (0);
   1445      1.1  christos 
   1446  1.1.1.2  christos   /* The rest instructions expanded from macro, split by semicolon(;),
   1447  1.1.1.2  christos      assembly one by one.  */
   1448      1.1  christos   if (*rest != '\0')
   1449  1.1.1.2  christos     loongarch_assemble_INSNs (rest, expand_from_macro);
   1450      1.1  christos }
   1451      1.1  christos 
   1452      1.1  christos void
   1453      1.1  christos md_assemble (char *str)
   1454      1.1  christos {
   1455  1.1.1.2  christos   loongarch_assemble_INSNs (str, 0);
   1456      1.1  christos }
   1457      1.1  christos 
   1458      1.1  christos const char *
   1459      1.1  christos md_atof (int type, char *litP, int *sizeP)
   1460      1.1  christos {
   1461      1.1  christos   return ieee_md_atof (type, litP, sizeP, FALSE);
   1462      1.1  christos }
   1463      1.1  christos 
   1464      1.1  christos void
   1465      1.1  christos md_number_to_chars (char *buf, valueT val, int n)
   1466      1.1  christos {
   1467      1.1  christos   number_to_chars_littleendian (buf, val, n);
   1468      1.1  christos }
   1469      1.1  christos 
   1470      1.1  christos /* The location from which a PC relative jump should be calculated,
   1471      1.1  christos    given a PC relative reloc.  */
   1472      1.1  christos long
   1473      1.1  christos md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
   1474      1.1  christos {
   1475      1.1  christos   return 0;
   1476      1.1  christos }
   1477      1.1  christos 
   1478  1.1.1.3  christos /* Return 1 if the relocation must be forced, and 0 if the relocation
   1479  1.1.1.3  christos    should never be forced.  */
   1480  1.1.1.3  christos int
   1481  1.1.1.3  christos loongarch_force_relocation (struct fix *fixp)
   1482  1.1.1.3  christos {
   1483  1.1.1.3  christos   /* Ensure we emit a relocation for every reference to the global
   1484  1.1.1.3  christos      offset table.  */
   1485  1.1.1.3  christos   switch (fixp->fx_r_type)
   1486  1.1.1.3  christos     {
   1487  1.1.1.3  christos       case BFD_RELOC_LARCH_GOT_PC_HI20:
   1488  1.1.1.3  christos       case BFD_RELOC_LARCH_GOT_PC_LO12:
   1489  1.1.1.3  christos       case BFD_RELOC_LARCH_GOT64_PC_LO20:
   1490  1.1.1.3  christos       case BFD_RELOC_LARCH_GOT64_PC_HI12:
   1491  1.1.1.3  christos       case BFD_RELOC_LARCH_GOT_HI20:
   1492  1.1.1.3  christos       case BFD_RELOC_LARCH_GOT_LO12:
   1493  1.1.1.3  christos       case BFD_RELOC_LARCH_GOT64_LO20:
   1494  1.1.1.3  christos       case BFD_RELOC_LARCH_GOT64_HI12:
   1495  1.1.1.3  christos 	return 1;
   1496  1.1.1.3  christos       default:
   1497  1.1.1.3  christos 	break;
   1498  1.1.1.3  christos     }
   1499  1.1.1.3  christos   return generic_force_reloc (fixp);
   1500  1.1.1.3  christos }
   1501  1.1.1.3  christos 
   1502  1.1.1.3  christos /* If subsy of BFD_RELOC32/64 and PC in same segment, and without relax
   1503  1.1.1.3  christos    or PC at start of subsy or with relax but sub_symbol_segment not in
   1504  1.1.1.3  christos    SEC_CODE, we generate 32/64_PCREL.  */
   1505  1.1.1.3  christos bool
   1506  1.1.1.3  christos loongarch_force_relocation_sub_local (fixS *fixp, segT sec ATTRIBUTE_UNUSED)
   1507  1.1.1.3  christos {
   1508  1.1.1.3  christos   return !(LARCH_opts.thin_add_sub
   1509  1.1.1.3  christos 	   && (fixp->fx_r_type == BFD_RELOC_32
   1510  1.1.1.3  christos 	       || fixp->fx_r_type == BFD_RELOC_64)
   1511  1.1.1.3  christos 	   && (!LARCH_opts.relax
   1512  1.1.1.3  christos 	       || (S_GET_VALUE (fixp->fx_subsy)
   1513  1.1.1.3  christos 		   == fixp->fx_frag->fr_address + fixp->fx_where)
   1514  1.1.1.3  christos 	       || (S_GET_SEGMENT (fixp->fx_subsy)->flags & SEC_CODE) == 0));
   1515  1.1.1.3  christos }
   1516  1.1.1.3  christos 
   1517  1.1.1.3  christos /* Postpone text-section label subtraction calculation until linking, since
   1518  1.1.1.3  christos    linker relaxations might change the deltas.  */
   1519  1.1.1.3  christos bool
   1520  1.1.1.3  christos loongarch_force_relocation_sub_same(fixS *fixp ATTRIBUTE_UNUSED, segT sec)
   1521  1.1.1.3  christos {
   1522  1.1.1.3  christos   return LARCH_opts.relax && (sec->flags & SEC_CODE) != 0;
   1523  1.1.1.3  christos }
   1524  1.1.1.3  christos 
   1525      1.1  christos static void fix_reloc_insn (fixS *fixP, bfd_vma reloc_val, char *buf)
   1526      1.1  christos {
   1527      1.1  christos   reloc_howto_type *howto;
   1528      1.1  christos   insn_t insn;
   1529      1.1  christos   howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
   1530      1.1  christos 
   1531      1.1  christos   insn = bfd_getl32 (buf);
   1532      1.1  christos 
   1533  1.1.1.2  christos   if (!loongarch_adjust_reloc_bitsfield (NULL, howto, &reloc_val))
   1534  1.1.1.2  christos     as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
   1535      1.1  christos 
   1536      1.1  christos   insn = (insn & (insn_t)howto->src_mask)
   1537      1.1  christos     | ((insn & (~(insn_t)howto->dst_mask)) | reloc_val);
   1538      1.1  christos 
   1539      1.1  christos   bfd_putl32 (insn, buf);
   1540      1.1  christos }
   1541      1.1  christos 
   1542      1.1  christos void
   1543      1.1  christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   1544      1.1  christos {
   1545      1.1  christos   static int64_t stack_top;
   1546      1.1  christos   static int last_reloc_is_sop_push_pcrel_1 = 0;
   1547      1.1  christos   int last_reloc_is_sop_push_pcrel = last_reloc_is_sop_push_pcrel_1;
   1548  1.1.1.2  christos   segT sub_segment;
   1549      1.1  christos   last_reloc_is_sop_push_pcrel_1 = 0;
   1550      1.1  christos 
   1551      1.1  christos   char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
   1552      1.1  christos   switch (fixP->fx_r_type)
   1553      1.1  christos     {
   1554      1.1  christos     case BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL:
   1555      1.1  christos     case BFD_RELOC_LARCH_SOP_PUSH_TLS_GD:
   1556      1.1  christos     case BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT:
   1557  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LE_HI20:
   1558  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LE_LO12:
   1559  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LE64_LO20:
   1560  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LE64_HI12:
   1561  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE_PC_HI20:
   1562  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE_PC_LO12:
   1563  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE64_PC_LO20:
   1564  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE64_PC_HI12:
   1565  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE_HI20:
   1566  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE_LO12:
   1567  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE64_LO20:
   1568  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_IE64_HI12:
   1569  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LD_PC_HI20:
   1570  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_LD_HI20:
   1571  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_GD_PC_HI20:
   1572  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_GD_HI20:
   1573  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_PC_HI20:
   1574  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_PC_LO12:
   1575  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC64_PC_LO20:
   1576  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC64_PC_HI12:
   1577  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_HI20:
   1578  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_LO12:
   1579  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC64_LO20:
   1580  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC64_HI12:
   1581  1.1.1.3  christos     case BFD_RELOC_LARCH_TLS_LE_ADD_R:
   1582  1.1.1.3  christos     case BFD_RELOC_LARCH_TLS_LE_HI20_R:
   1583  1.1.1.3  christos     case BFD_RELOC_LARCH_TLS_LE_LO12_R:
   1584  1.1.1.2  christos       /* Add tls lo (got_lo reloc type).  */
   1585  1.1.1.2  christos       if (fixP->fx_addsy == NULL)
   1586  1.1.1.2  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
   1587  1.1.1.2  christos 		      _("Relocation against a constant"));
   1588  1.1.1.2  christos       S_SET_THREAD_LOCAL (fixP->fx_addsy);
   1589  1.1.1.2  christos       break;
   1590  1.1.1.2  christos 
   1591      1.1  christos     case BFD_RELOC_LARCH_SOP_PUSH_PCREL:
   1592      1.1  christos       if (fixP->fx_addsy == NULL)
   1593      1.1  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
   1594      1.1  christos 		      _("Relocation against a constant"));
   1595      1.1  christos 
   1596  1.1.1.2  christos       last_reloc_is_sop_push_pcrel_1 = 1;
   1597  1.1.1.2  christos       if (S_GET_SEGMENT (fixP->fx_addsy) == seg)
   1598  1.1.1.2  christos 	stack_top = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
   1599  1.1.1.2  christos 		     - (fixP->fx_where + fixP->fx_frag->fr_address));
   1600  1.1.1.2  christos       else
   1601  1.1.1.2  christos 	stack_top = 0;
   1602  1.1.1.2  christos       break;
   1603  1.1.1.2  christos 
   1604  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_LD:
   1605  1.1.1.2  christos     case BFD_RELOC_LARCH_TLS_DESC_CALL:
   1606      1.1  christos       break;
   1607      1.1  christos 
   1608      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_10_5:
   1609      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_10_12:
   1610      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_U_10_12:
   1611      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_10_16:
   1612      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2:
   1613      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_5_20:
   1614      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_U:
   1615      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2:
   1616      1.1  christos     case BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2:
   1617      1.1  christos       if (!last_reloc_is_sop_push_pcrel)
   1618      1.1  christos 	break;
   1619      1.1  christos 
   1620      1.1  christos       fix_reloc_insn (fixP, (bfd_vma)stack_top, buf);
   1621      1.1  christos       break;
   1622      1.1  christos 
   1623  1.1.1.2  christos     /* LARCH only has R_LARCH_64/32, not has R_LARCH_24/16/8.
   1624  1.1.1.2  christos        For BFD_RELOC_64/32, if fx_addsy and fx_subsy not null, wer need
   1625  1.1.1.2  christos        generate BFD_RELOC_LARCH_ADD64/32 and BFD_RELOC_LARCH_SUB64/32 here.
   1626  1.1.1.2  christos        Then will parse howto table bfd_reloc_code_real_type to generate
   1627  1.1.1.2  christos        R_LARCH_ADD64/32 and R_LARCH_SUB64/32 reloc at tc_gen_reloc function.
   1628  1.1.1.2  christos        If only fx_addsy not null, skip here directly, then generate
   1629  1.1.1.2  christos        R_LARCH_64/32.
   1630  1.1.1.2  christos 
   1631  1.1.1.2  christos        For BFD_RELOC_24/16/8, if fx_addsy and fx_subsy not null, wer need
   1632  1.1.1.2  christos        generate BFD_RELOC_LARCH_ADD24/16/8 and BFD_RELOC_LARCH_SUB24/16/8 here.
   1633  1.1.1.2  christos        Then will parse howto table bfd_reloc_code_real_type to generate
   1634  1.1.1.2  christos        R_LARCH_ADD24/16/8 and R_LARCH_SUB24/16/8 reloc at tc_gen_reloc
   1635  1.1.1.2  christos        function. If only fx_addsy not null, we generate
   1636  1.1.1.2  christos        BFD_RELOC_LARCH_ADD24/16/8 only, then generate R_LARCH_24/16/8.
   1637  1.1.1.2  christos        To avoid R_LARCH_ADDxx add extra value, we write 0 first
   1638  1.1.1.2  christos        (use md_number_to_chars (buf, 0, fixP->fx_size)).  */
   1639      1.1  christos     case BFD_RELOC_64:
   1640      1.1  christos     case BFD_RELOC_32:
   1641  1.1.1.2  christos       if (fixP->fx_pcrel)
   1642  1.1.1.2  christos 	{
   1643  1.1.1.2  christos 	  switch (fixP->fx_r_type)
   1644  1.1.1.2  christos 	    {
   1645  1.1.1.2  christos 	    case BFD_RELOC_64:
   1646  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_64_PCREL;
   1647  1.1.1.2  christos 	      break;
   1648  1.1.1.2  christos 	    case BFD_RELOC_32:
   1649  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL;
   1650  1.1.1.2  christos 	      break;
   1651  1.1.1.2  christos 	    default:
   1652  1.1.1.2  christos 	      break;
   1653  1.1.1.2  christos 	    }
   1654  1.1.1.2  christos 	}
   1655  1.1.1.2  christos 
   1656  1.1.1.2  christos       /* If symbol in .eh_frame the address may be adjusted, and contents of
   1657  1.1.1.2  christos 	 .eh_frame will be adjusted, so use pc-relative relocation for FDE
   1658  1.1.1.2  christos 	 initial location.
   1659  1.1.1.2  christos 	 The Option of mthin-add-sub does not affect the generation of
   1660  1.1.1.2  christos 	 R_LARCH_32_PCREL relocation in .eh_frame.  */
   1661  1.1.1.2  christos       if (fixP->fx_r_type == BFD_RELOC_32
   1662  1.1.1.2  christos 	  && fixP->fx_addsy && fixP->fx_subsy
   1663  1.1.1.2  christos 	  && (sub_segment = S_GET_SEGMENT (fixP->fx_subsy))
   1664  1.1.1.2  christos 	  && strcmp (sub_segment->name, ".eh_frame") == 0
   1665  1.1.1.2  christos 	  && S_GET_VALUE (fixP->fx_subsy)
   1666  1.1.1.2  christos 	  == fixP->fx_frag->fr_address + fixP->fx_where)
   1667  1.1.1.2  christos 	{
   1668  1.1.1.2  christos 	  fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL;
   1669  1.1.1.2  christos 	  fixP->fx_subsy = NULL;
   1670  1.1.1.2  christos 	  break;
   1671  1.1.1.2  christos 	}
   1672  1.1.1.2  christos 
   1673  1.1.1.2  christos       if (fixP->fx_addsy && fixP->fx_subsy)
   1674      1.1  christos 	{
   1675      1.1  christos 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
   1676      1.1  christos 	  fixP->fx_next->fx_addsy = fixP->fx_subsy;
   1677      1.1  christos 	  fixP->fx_next->fx_subsy = NULL;
   1678      1.1  christos 	  fixP->fx_next->fx_offset = 0;
   1679      1.1  christos 	  fixP->fx_subsy = NULL;
   1680      1.1  christos 
   1681      1.1  christos 	  switch (fixP->fx_r_type)
   1682      1.1  christos 	    {
   1683      1.1  christos 	    case BFD_RELOC_64:
   1684      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD64;
   1685      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB64;
   1686      1.1  christos 	      break;
   1687      1.1  christos 	    case BFD_RELOC_32:
   1688      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD32;
   1689      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB32;
   1690      1.1  christos 	      break;
   1691  1.1.1.2  christos 	    default:
   1692  1.1.1.2  christos 	      break;
   1693  1.1.1.2  christos 	    }
   1694  1.1.1.2  christos 
   1695  1.1.1.2  christos 	  md_number_to_chars (buf, 0, fixP->fx_size);
   1696  1.1.1.2  christos 	}
   1697  1.1.1.2  christos 
   1698  1.1.1.2  christos       if (fixP->fx_addsy == NULL)
   1699  1.1.1.2  christos 	{
   1700  1.1.1.2  christos 	  fixP->fx_done = 1;
   1701  1.1.1.2  christos 	  md_number_to_chars (buf, *valP, fixP->fx_size);
   1702  1.1.1.2  christos 	}
   1703  1.1.1.2  christos       break;
   1704  1.1.1.2  christos 
   1705  1.1.1.2  christos     case BFD_RELOC_24:
   1706  1.1.1.2  christos     case BFD_RELOC_16:
   1707  1.1.1.2  christos     case BFD_RELOC_8:
   1708  1.1.1.2  christos       if (fixP->fx_addsy)
   1709  1.1.1.2  christos 	{
   1710  1.1.1.2  christos 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
   1711  1.1.1.2  christos 	  fixP->fx_next->fx_addsy = fixP->fx_subsy;
   1712  1.1.1.2  christos 	  fixP->fx_next->fx_subsy = NULL;
   1713  1.1.1.2  christos 	  fixP->fx_next->fx_offset = 0;
   1714  1.1.1.2  christos 	  fixP->fx_subsy = NULL;
   1715  1.1.1.2  christos 
   1716  1.1.1.2  christos 	  switch (fixP->fx_r_type)
   1717  1.1.1.2  christos 	    {
   1718      1.1  christos 	    case BFD_RELOC_24:
   1719      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD24;
   1720      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB24;
   1721      1.1  christos 	      break;
   1722      1.1  christos 	    case BFD_RELOC_16:
   1723      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD16;
   1724      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16;
   1725      1.1  christos 	      break;
   1726      1.1  christos 	    case BFD_RELOC_8:
   1727      1.1  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD8;
   1728      1.1  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8;
   1729      1.1  christos 	      break;
   1730      1.1  christos 	    default:
   1731      1.1  christos 	      break;
   1732      1.1  christos 	    }
   1733  1.1.1.2  christos 
   1734      1.1  christos 	  md_number_to_chars (buf, 0, fixP->fx_size);
   1735  1.1.1.2  christos 
   1736      1.1  christos 	  if (fixP->fx_next->fx_addsy == NULL)
   1737      1.1  christos 	    fixP->fx_next->fx_done = 1;
   1738      1.1  christos 	}
   1739  1.1.1.2  christos 
   1740      1.1  christos       if (fixP->fx_addsy == NULL)
   1741      1.1  christos 	{
   1742      1.1  christos 	  fixP->fx_done = 1;
   1743      1.1  christos 	  md_number_to_chars (buf, *valP, fixP->fx_size);
   1744      1.1  christos 	}
   1745      1.1  christos       break;
   1746      1.1  christos 
   1747  1.1.1.2  christos     case BFD_RELOC_LARCH_CFA:
   1748  1.1.1.2  christos       if (fixP->fx_addsy && fixP->fx_subsy)
   1749  1.1.1.2  christos 	{
   1750  1.1.1.2  christos 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
   1751  1.1.1.2  christos 	  fixP->fx_next->fx_addsy = fixP->fx_subsy;
   1752  1.1.1.2  christos 	  fixP->fx_next->fx_subsy = NULL;
   1753  1.1.1.2  christos 	  fixP->fx_next->fx_offset = 0;
   1754  1.1.1.2  christos 	  fixP->fx_subsy = NULL;
   1755  1.1.1.2  christos 
   1756  1.1.1.2  christos 	  unsigned int subtype;
   1757  1.1.1.2  christos 	  offsetT loc;
   1758  1.1.1.3  christos 	  fragS *opfrag = (fragS *) fixP->fx_frag->fr_opcode;
   1759  1.1.1.3  christos 	  subtype = bfd_get_8 (NULL, opfrag->fr_literal + fixP->fx_where);
   1760  1.1.1.2  christos 	  loc = fixP->fx_frag->fr_fix - (subtype & 7);
   1761  1.1.1.2  christos 	  switch (subtype)
   1762  1.1.1.2  christos 	    {
   1763  1.1.1.2  christos 	    case DW_CFA_advance_loc1:
   1764  1.1.1.2  christos 	      fixP->fx_where = loc + 1;
   1765  1.1.1.2  christos 	      fixP->fx_next->fx_where = loc + 1;
   1766  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD8;
   1767  1.1.1.2  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8;
   1768  1.1.1.2  christos 	      md_number_to_chars (buf+1, 0, fixP->fx_size);
   1769  1.1.1.2  christos 	      break;
   1770  1.1.1.2  christos 
   1771  1.1.1.2  christos 	    case DW_CFA_advance_loc2:
   1772  1.1.1.2  christos 	      fixP->fx_size = 2;
   1773  1.1.1.2  christos 	      fixP->fx_next->fx_size = 2;
   1774  1.1.1.2  christos 	      fixP->fx_where = loc + 1;
   1775  1.1.1.2  christos 	      fixP->fx_next->fx_where = loc + 1;
   1776  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD16;
   1777  1.1.1.2  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16;
   1778  1.1.1.2  christos 	      md_number_to_chars (buf+1, 0, fixP->fx_size);
   1779  1.1.1.2  christos 	      break;
   1780  1.1.1.2  christos 
   1781  1.1.1.2  christos 	    case DW_CFA_advance_loc4:
   1782  1.1.1.2  christos 	      fixP->fx_size = 4;
   1783  1.1.1.2  christos 	      fixP->fx_next->fx_size = 4;
   1784  1.1.1.2  christos 	      fixP->fx_where = loc;
   1785  1.1.1.2  christos 	      fixP->fx_next->fx_where = loc;
   1786  1.1.1.2  christos 	      fixP->fx_r_type = BFD_RELOC_LARCH_ADD32;
   1787  1.1.1.2  christos 	      fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB32;
   1788  1.1.1.2  christos 	      md_number_to_chars (buf+1, 0, fixP->fx_size);
   1789  1.1.1.2  christos 	      break;
   1790  1.1.1.2  christos 
   1791  1.1.1.2  christos 	    default:
   1792  1.1.1.2  christos 	      if (subtype < 0x80 && (subtype & 0x40))
   1793  1.1.1.2  christos 		{
   1794  1.1.1.2  christos 		  /* DW_CFA_advance_loc.  */
   1795  1.1.1.3  christos 		  fixP->fx_frag = opfrag;
   1796  1.1.1.2  christos 		  fixP->fx_next->fx_frag = fixP->fx_frag;
   1797  1.1.1.2  christos 		  fixP->fx_r_type = BFD_RELOC_LARCH_ADD6;
   1798  1.1.1.2  christos 		  fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB6;
   1799  1.1.1.2  christos 		  md_number_to_chars (buf, 0x40, fixP->fx_size);
   1800  1.1.1.2  christos 		  }
   1801  1.1.1.2  christos 	      else
   1802  1.1.1.2  christos 		as_fatal (_("internal: bad CFA value #%d"), subtype);
   1803  1.1.1.2  christos 	      break;
   1804  1.1.1.2  christos 	    }
   1805  1.1.1.2  christos 	}
   1806  1.1.1.2  christos       break;
   1807  1.1.1.2  christos 
   1808  1.1.1.2  christos     case BFD_RELOC_LARCH_B16:
   1809  1.1.1.2  christos     case BFD_RELOC_LARCH_B21:
   1810  1.1.1.2  christos     case BFD_RELOC_LARCH_B26:
   1811  1.1.1.2  christos       if (fixP->fx_addsy == NULL)
   1812  1.1.1.2  christos 	{
   1813  1.1.1.2  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   1814  1.1.1.2  christos 			_ ("Relocation against a constant."));
   1815  1.1.1.2  christos 	}
   1816  1.1.1.2  christos       if (S_GET_SEGMENT (fixP->fx_addsy) == seg
   1817  1.1.1.2  christos 	  && !S_FORCE_RELOC (fixP->fx_addsy, 1))
   1818  1.1.1.2  christos 	{
   1819  1.1.1.2  christos 	  int64_t sym_addend = S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset;
   1820  1.1.1.2  christos 	  int64_t pc = fixP->fx_where + fixP->fx_frag->fr_address;
   1821  1.1.1.2  christos 	  fix_reloc_insn (fixP, sym_addend - pc, buf);
   1822  1.1.1.2  christos 
   1823  1.1.1.2  christos 	  /* If relax, symbol value may change at link time, so reloc need to
   1824  1.1.1.2  christos 	     be saved.  */
   1825  1.1.1.2  christos 	  if (!LARCH_opts.relax)
   1826  1.1.1.2  christos 	    fixP->fx_done = 1;
   1827  1.1.1.2  christos 	}
   1828  1.1.1.2  christos       break;
   1829  1.1.1.2  christos 
   1830  1.1.1.2  christos     /* Because ADD_ULEB128/SUB_ULEB128 always occur in pairs.
   1831  1.1.1.2  christos        So just deal with one is ok.
   1832  1.1.1.2  christos     case BFD_RELOC_LARCH_ADD_ULEB128:  */
   1833  1.1.1.2  christos     case BFD_RELOC_LARCH_SUB_ULEB128:
   1834  1.1.1.2  christos       {
   1835  1.1.1.2  christos 	unsigned int len = 0;
   1836  1.1.1.2  christos 	len = loongarch_get_uleb128_length ((bfd_byte *)buf);
   1837  1.1.1.2  christos 	bfd_byte *endp = (bfd_byte*) buf + len -1;
   1838  1.1.1.2  christos 	/* Clean the uleb128 value to 0. Do not reduce the length.  */
   1839  1.1.1.2  christos 	memset (buf, 0x80, len - 1);
   1840  1.1.1.2  christos 	*endp = 0;
   1841  1.1.1.2  christos 	break;
   1842  1.1.1.2  christos       }
   1843  1.1.1.2  christos 
   1844      1.1  christos     default:
   1845      1.1  christos       break;
   1846      1.1  christos     }
   1847      1.1  christos }
   1848      1.1  christos 
   1849  1.1.1.3  christos /* Estimate the size of a frag before relaxing.  */
   1850  1.1.1.3  christos 
   1851      1.1  christos int
   1852  1.1.1.3  christos md_estimate_size_before_relax (fragS *fragp, asection *sec)
   1853      1.1  christos {
   1854  1.1.1.3  christos   /* align pseudo instunctions.  */
   1855  1.1.1.3  christos   if (rs_align_code == fragp->fr_subtype)
   1856  1.1.1.3  christos     {
   1857  1.1.1.3  christos       offsetT nop_bytes;
   1858  1.1.1.3  christos       if (NULL == fragp->fr_symbol)
   1859  1.1.1.3  christos 	nop_bytes = fragp->fr_offset;
   1860  1.1.1.3  christos       else
   1861  1.1.1.3  christos 	nop_bytes = ALIGN_MAX_NOP_BYTES (fragp->fr_offset);
   1862  1.1.1.3  christos 
   1863  1.1.1.3  christos       /* Normally, nop_bytes should be >= 4.  */
   1864  1.1.1.3  christos       gas_assert (nop_bytes > 0);
   1865  1.1.1.3  christos 
   1866  1.1.1.3  christos       if (FRAG_AT_START_OF_SECTION (fragp)
   1867  1.1.1.3  christos 	  && 0 == ((1 << sec->alignment_power) % (nop_bytes + 4)))
   1868  1.1.1.3  christos 	return (fragp->fr_var = 0);
   1869  1.1.1.3  christos       else
   1870  1.1.1.3  christos 	  return (fragp->fr_var = nop_bytes);
   1871  1.1.1.3  christos     }
   1872  1.1.1.3  christos 
   1873  1.1.1.3  christos   /* branch instructions and other instructions.
   1874  1.1.1.3  christos      branch instructions may become 8 bytes after relaxing.  */
   1875  1.1.1.2  christos   return (fragp->fr_var = 4);
   1876      1.1  christos }
   1877      1.1  christos 
   1878      1.1  christos /* Translate internal representation of relocation info to BFD target
   1879      1.1  christos    format.  */
   1880      1.1  christos arelent *
   1881      1.1  christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
   1882      1.1  christos {
   1883  1.1.1.3  christos   arelent *reloc;
   1884      1.1  christos 
   1885  1.1.1.3  christos   reloc = notes_alloc (sizeof (arelent));
   1886  1.1.1.3  christos   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
   1887      1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   1888      1.1  christos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   1889      1.1  christos   reloc->addend = fixp->fx_offset;
   1890      1.1  christos 
   1891      1.1  christos   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   1892      1.1  christos   if (reloc->howto == NULL)
   1893      1.1  christos     {
   1894      1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
   1895      1.1  christos 		    _("cannot represent %s relocation in object file"),
   1896      1.1  christos 		    bfd_get_reloc_code_name (fixp->fx_r_type));
   1897      1.1  christos       return NULL;
   1898      1.1  christos     }
   1899      1.1  christos 
   1900      1.1  christos   return reloc;
   1901      1.1  christos }
   1902      1.1  christos 
   1903      1.1  christos /* Standard calling conventions leave the CFA at SP on entry.  */
   1904      1.1  christos void
   1905      1.1  christos loongarch_cfi_frame_initial_instructions (void)
   1906      1.1  christos {
   1907      1.1  christos   cfi_add_CFA_def_cfa_register (3 /* $sp */);
   1908      1.1  christos }
   1909      1.1  christos 
   1910  1.1.1.3  christos /* Convert REGNAME to a DWARF register number.  */
   1911  1.1.1.3  christos int
   1912  1.1.1.3  christos tc_loongarch_regname_to_dw2regnum (char *regname)
   1913  1.1.1.3  christos {
   1914  1.1.1.3  christos   int reg;
   1915  1.1.1.3  christos 
   1916  1.1.1.3  christos   /* Look up in the general purpose register table.  */
   1917  1.1.1.3  christos   if ((reg = str_hash_find_int (cfi_r_htab, regname)) >= 0)
   1918  1.1.1.3  christos     return reg;
   1919  1.1.1.3  christos 
   1920  1.1.1.3  christos   /* Look up in the floating point register table.  */
   1921  1.1.1.3  christos   if ((reg = str_hash_find_int (cfi_f_htab, regname)) >= 0)
   1922  1.1.1.3  christos     return reg + 32;
   1923  1.1.1.3  christos 
   1924  1.1.1.3  christos   as_bad (_("unknown register `%s`"), regname);
   1925  1.1.1.3  christos   return -1;
   1926  1.1.1.3  christos }
   1927  1.1.1.3  christos 
   1928  1.1.1.3  christos /* Derived from tc_parse_to_dw2regnum, but excluding the case where
   1929  1.1.1.3  christos    the prefix '%'.  */
   1930  1.1.1.3  christos void
   1931  1.1.1.3  christos tc_loongarch_parse_to_dw2regnum (expressionS *exp)
   1932  1.1.1.3  christos {
   1933  1.1.1.3  christos   SKIP_WHITESPACE ();
   1934  1.1.1.3  christos   if (is_name_beginner (*input_line_pointer))
   1935  1.1.1.3  christos     {
   1936  1.1.1.3  christos       char *name, c;
   1937  1.1.1.3  christos 
   1938  1.1.1.3  christos       c = get_symbol_name (& name);
   1939  1.1.1.3  christos 
   1940  1.1.1.3  christos       exp->X_op = O_constant;
   1941  1.1.1.3  christos       exp->X_add_number = tc_loongarch_regname_to_dw2regnum (name);
   1942  1.1.1.3  christos 
   1943  1.1.1.3  christos       restore_line_pointer (c);
   1944  1.1.1.3  christos     }
   1945  1.1.1.3  christos   else
   1946  1.1.1.3  christos     expression_and_evaluate (exp);
   1947  1.1.1.3  christos }
   1948  1.1.1.3  christos 
   1949  1.1.1.3  christos 
   1950  1.1.1.2  christos void
   1951  1.1.1.2  christos loongarch_pre_output_hook (void)
   1952      1.1  christos {
   1953  1.1.1.2  christos   const frchainS *frch;
   1954  1.1.1.2  christos   segT s;
   1955  1.1.1.2  christos 
   1956  1.1.1.2  christos   if (!LARCH_opts.relax)
   1957  1.1.1.2  christos     return;
   1958  1.1.1.2  christos 
   1959  1.1.1.2  christos   /* Save the current segment info.  */
   1960  1.1.1.2  christos   segT seg = now_seg;
   1961  1.1.1.2  christos   subsegT subseg = now_subseg;
   1962  1.1.1.2  christos 
   1963  1.1.1.2  christos   for (s = stdoutput->sections; s; s = s->next)
   1964  1.1.1.2  christos     for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next)
   1965  1.1.1.2  christos       {
   1966  1.1.1.2  christos 	fragS *frag;
   1967  1.1.1.2  christos 
   1968  1.1.1.2  christos 	for (frag = frch->frch_root; frag; frag = frag->fr_next)
   1969  1.1.1.2  christos 	  {
   1970  1.1.1.2  christos 	    if (frag->fr_type == rs_cfa)
   1971  1.1.1.2  christos 	      {
   1972  1.1.1.2  christos 		expressionS exp;
   1973  1.1.1.2  christos 		expressionS *symval;
   1974  1.1.1.2  christos 
   1975  1.1.1.2  christos 		symval = symbol_get_value_expression (frag->fr_symbol);
   1976  1.1.1.2  christos 		exp.X_op = O_subtract;
   1977  1.1.1.2  christos 		exp.X_add_symbol = symval->X_add_symbol;
   1978  1.1.1.2  christos 		exp.X_add_number = 0;
   1979  1.1.1.2  christos 		exp.X_op_symbol = symval->X_op_symbol;
   1980  1.1.1.2  christos 
   1981  1.1.1.2  christos 		/* We must set the segment before creating a frag after all
   1982  1.1.1.2  christos 		   frag chains have been chained together.  */
   1983  1.1.1.2  christos 		subseg_set (s, frch->frch_subseg);
   1984  1.1.1.2  christos 
   1985  1.1.1.2  christos 		fix_new_exp (frag, (int) frag->fr_offset, 1, &exp, 0,
   1986  1.1.1.2  christos 			     BFD_RELOC_LARCH_CFA);
   1987  1.1.1.2  christos 	      }
   1988  1.1.1.2  christos 	  }
   1989  1.1.1.2  christos       }
   1990  1.1.1.2  christos 
   1991  1.1.1.2  christos   /* Restore the original segment info.  */
   1992  1.1.1.2  christos   subseg_set (seg, subseg);
   1993      1.1  christos }
   1994      1.1  christos 
   1995      1.1  christos void
   1996      1.1  christos md_show_usage (FILE *stream)
   1997      1.1  christos {
   1998      1.1  christos   fprintf (stream, _("LARCH options:\n"));
   1999      1.1  christos   /* FIXME */
   2000  1.1.1.2  christos   fprintf (stream, _("\
   2001  1.1.1.2  christos   -mthin-add-sub	  Convert a pair of R_LARCH_ADD32/64 and R_LARCH_SUB32/64 to\n\
   2002  1.1.1.2  christos 			  R_LARCH_32/64_PCREL as much as possible\n\
   2003  1.1.1.2  christos 			  The option does not affect the generation of R_LARCH_32_PCREL\n\
   2004  1.1.1.3  christos 			  relocations in .eh_frame\n\
   2005  1.1.1.3  christos   -mignore-start-align	  Ignore .align if it is at the start of a section. This option\n\
   2006  1.1.1.3  christos 			  can't be used when partial linking (ld -r).\n"));
   2007  1.1.1.2  christos }
   2008  1.1.1.2  christos 
   2009  1.1.1.2  christos static void
   2010  1.1.1.2  christos loongarch_make_nops (char *buf, bfd_vma bytes)
   2011  1.1.1.2  christos {
   2012  1.1.1.2  christos   bfd_vma i = 0;
   2013  1.1.1.2  christos 
   2014  1.1.1.2  christos   /* Fill with 4-byte NOPs.  */
   2015  1.1.1.2  christos   for ( ; i < bytes; i += 4)
   2016  1.1.1.2  christos     number_to_chars_littleendian (buf + i, LARCH_NOP, 4);
   2017  1.1.1.2  christos }
   2018  1.1.1.2  christos 
   2019  1.1.1.2  christos /* Called from md_do_align.  Used to create an alignment frag in a
   2020  1.1.1.2  christos    code section by emitting a worst-case NOP sequence that the linker
   2021  1.1.1.2  christos    will later relax to the correct number of NOPs.  We can't compute
   2022  1.1.1.2  christos    the correct alignment now because of other linker relaxations.  */
   2023  1.1.1.2  christos 
   2024  1.1.1.2  christos bool
   2025  1.1.1.2  christos loongarch_frag_align_code (int n, int max)
   2026  1.1.1.2  christos {
   2027  1.1.1.2  christos   char *nops;
   2028  1.1.1.2  christos   expressionS ex;
   2029  1.1.1.3  christos   symbolS *s = NULL;
   2030  1.1.1.2  christos 
   2031  1.1.1.3  christos   /* When not relaxing, loongarch_handle_align handles code alignment.  */
   2032  1.1.1.3  christos   if (!LARCH_opts.relax)
   2033  1.1.1.3  christos     return false;
   2034  1.1.1.3  christos 
   2035  1.1.1.3  christos   bfd_vma align_bytes = (bfd_vma) 1 << n;
   2036  1.1.1.3  christos   bfd_vma worst_case_bytes = align_bytes - 4;
   2037  1.1.1.3  christos   bfd_vma addend = worst_case_bytes;
   2038  1.1.1.3  christos   bool align_max = max > 0 && (bfd_vma) max < worst_case_bytes;
   2039  1.1.1.2  christos 
   2040  1.1.1.2  christos   /* If we are moving to a smaller alignment than the instruction size, then no
   2041  1.1.1.2  christos      alignment is required.  */
   2042  1.1.1.3  christos   if (align_bytes <= 4)
   2043  1.1.1.2  christos     return true;
   2044  1.1.1.2  christos 
   2045  1.1.1.3  christos   /* If max <= 0, ignore max.
   2046  1.1.1.3  christos      If max >= worst_case_bytes, max has no effect.
   2047  1.1.1.3  christos      Similar to gas/write.c relax_segment function rs_align_code case:
   2048  1.1.1.3  christos      if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype).  */
   2049  1.1.1.3  christos   if (align_max)
   2050  1.1.1.3  christos     {
   2051  1.1.1.3  christos       s = get_align_symbol (now_seg);
   2052  1.1.1.3  christos       if (!s)
   2053  1.1.1.3  christos 	as_fatal (_("internal error: cannot get align symbol"));
   2054  1.1.1.3  christos       addend = ALIGN_MAX_ADDEND (n, max);
   2055  1.1.1.3  christos     }
   2056  1.1.1.3  christos 
   2057  1.1.1.3  christos   if (LARCH_opts.ignore_start_align)
   2058  1.1.1.3  christos     {
   2059  1.1.1.3  christos       frag_grow (worst_case_bytes);
   2060  1.1.1.3  christos       /* Use relaxable frag for .align.
   2061  1.1.1.3  christos 	 If .align at the start of section, do nothing. Section alignment can
   2062  1.1.1.3  christos 	 ensure correct alignment.
   2063  1.1.1.3  christos 	 If .align is not at the start of a section, reserve NOP instructions
   2064  1.1.1.3  christos 	 and R_LARCH_ALIGN relocation.  */
   2065  1.1.1.3  christos       nops = frag_var (rs_machine_dependent, worst_case_bytes, worst_case_bytes,
   2066  1.1.1.3  christos 		       rs_align_code, s, addend, NULL);
   2067  1.1.1.3  christos     }
   2068  1.1.1.3  christos   else
   2069  1.1.1.3  christos     {
   2070  1.1.1.3  christos       nops = frag_more (worst_case_bytes);
   2071  1.1.1.3  christos       if (align_max)
   2072  1.1.1.3  christos 	{
   2073  1.1.1.3  christos 	  ex.X_add_symbol = s;
   2074  1.1.1.3  christos 	  ex.X_op = O_symbol;
   2075  1.1.1.3  christos 	}
   2076  1.1.1.3  christos       else
   2077  1.1.1.3  christos 	  ex.X_op = O_constant;
   2078  1.1.1.2  christos 
   2079  1.1.1.3  christos       ex.X_add_number = addend;
   2080  1.1.1.2  christos 
   2081  1.1.1.3  christos       fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
   2082  1.1.1.3  christos 		   &ex, false, BFD_RELOC_LARCH_ALIGN);
   2083  1.1.1.3  christos     }
   2084  1.1.1.2  christos 
   2085  1.1.1.3  christos   /* Default write NOP for aligned bytes.  */
   2086  1.1.1.2  christos   loongarch_make_nops (nops, worst_case_bytes);
   2087  1.1.1.2  christos 
   2088  1.1.1.2  christos   /* We need to start a new frag after the alignment which may be removed by
   2089  1.1.1.2  christos      the linker, to prevent the assembler from computing static offsets.
   2090  1.1.1.2  christos      This is necessary to get correct EH info.  */
   2091  1.1.1.2  christos   frag_wane (frag_now);
   2092  1.1.1.2  christos   frag_new (0);
   2093  1.1.1.2  christos 
   2094  1.1.1.2  christos   return true;
   2095      1.1  christos }
   2096      1.1  christos 
   2097      1.1  christos /* Fill in an rs_align_code fragment.  We want to fill 'andi $r0,$r0,0'.  */
   2098      1.1  christos void
   2099      1.1  christos loongarch_handle_align (fragS *fragp)
   2100      1.1  christos {
   2101      1.1  christos   /* char nop_opcode; */
   2102      1.1  christos   char *p;
   2103      1.1  christos   int bytes, size, excess;
   2104      1.1  christos   valueT opcode;
   2105      1.1  christos 
   2106      1.1  christos   if (fragp->fr_type != rs_align_code)
   2107      1.1  christos     return;
   2108      1.1  christos 
   2109      1.1  christos   struct loongarch_cl_insn nop =
   2110      1.1  christos     { .name = "andi", .arg_strs = { "$r0", "$r0", "0", NULL } };
   2111      1.1  christos 
   2112      1.1  christos   get_loongarch_opcode (&nop);
   2113      1.1  christos   gas_assert (nop.all_match);
   2114      1.1  christos 
   2115      1.1  christos   p = fragp->fr_literal + fragp->fr_fix;
   2116      1.1  christos   opcode = nop.insn_bin;
   2117      1.1  christos   size = 4;
   2118      1.1  christos 
   2119      1.1  christos   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   2120      1.1  christos   excess = bytes % size;
   2121      1.1  christos 
   2122      1.1  christos   gas_assert (excess < 4);
   2123      1.1  christos   fragp->fr_fix += excess;
   2124      1.1  christos 
   2125      1.1  christos   while (excess-- != 0)
   2126      1.1  christos     *p++ = 0;
   2127      1.1  christos 
   2128      1.1  christos   md_number_to_chars (p, opcode, size);
   2129      1.1  christos   fragp->fr_var = size;
   2130      1.1  christos }
   2131      1.1  christos 
   2132  1.1.1.2  christos /* Scan uleb128 subtraction expressions and insert fixups for them.
   2133  1.1.1.2  christos    e.g., .uleb128 .L1 - .L0
   2134  1.1.1.2  christos    Because relaxation may change the value of the subtraction, we
   2135  1.1.1.2  christos    must resolve them at link-time.  */
   2136  1.1.1.2  christos 
   2137  1.1.1.2  christos static void
   2138  1.1.1.2  christos loongarch_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
   2139  1.1.1.2  christos 		      asection *sec, void *xxx ATTRIBUTE_UNUSED)
   2140  1.1.1.2  christos {
   2141  1.1.1.2  christos   segment_info_type *seginfo = seg_info (sec);
   2142  1.1.1.2  christos   struct frag *fragP;
   2143  1.1.1.2  christos 
   2144  1.1.1.2  christos   subseg_set (sec, 0);
   2145  1.1.1.2  christos 
   2146  1.1.1.2  christos   for (fragP = seginfo->frchainP->frch_root;
   2147  1.1.1.2  christos        fragP; fragP = fragP->fr_next)
   2148  1.1.1.2  christos     {
   2149  1.1.1.2  christos       expressionS *exp, *exp_dup;
   2150  1.1.1.2  christos 
   2151  1.1.1.2  christos       if (fragP->fr_type != rs_leb128  || fragP->fr_symbol == NULL)
   2152  1.1.1.2  christos 	continue;
   2153  1.1.1.2  christos 
   2154  1.1.1.2  christos       exp = symbol_get_value_expression (fragP->fr_symbol);
   2155  1.1.1.2  christos 
   2156  1.1.1.2  christos       if (exp->X_op != O_subtract)
   2157  1.1.1.2  christos 	continue;
   2158  1.1.1.2  christos 
   2159  1.1.1.2  christos       /* FIXME: Skip for .sleb128.  */
   2160  1.1.1.2  christos       if (fragP->fr_subtype != 0)
   2161  1.1.1.2  christos 	continue;
   2162  1.1.1.2  christos 
   2163  1.1.1.2  christos       exp_dup = xmemdup (exp, sizeof (*exp), sizeof (*exp));
   2164  1.1.1.2  christos       exp_dup->X_op = O_symbol;
   2165  1.1.1.2  christos       exp_dup->X_op_symbol = NULL;
   2166  1.1.1.2  christos 
   2167  1.1.1.2  christos       exp_dup->X_add_symbol = exp->X_add_symbol;
   2168  1.1.1.2  christos       fix_new_exp (fragP, fragP->fr_fix, 0,
   2169  1.1.1.2  christos 		   exp_dup, 0, BFD_RELOC_LARCH_ADD_ULEB128);
   2170  1.1.1.2  christos 
   2171  1.1.1.2  christos       /* From binutils/testsuite/binutils-all/dw5.S
   2172  1.1.1.2  christos 	 section .debug_rnglists
   2173  1.1.1.2  christos 	 .uleb128 .Letext0-.Ltext0    Range length (*.LLRL2)
   2174  1.1.1.2  christos     Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
   2175  1.1.1.2  christos 0000000000000015  0000000200000079 R_LARCH_ADD_ULEB128    0000000000000000 .text + 2
   2176  1.1.1.2  christos 0000000000000015  000000020000007a R_LARCH_SUB_ULEB128    0000000000000000 .text + 0.  */
   2177  1.1.1.2  christos 
   2178  1.1.1.2  christos       /* Only the ADD_ULEB128 has X_add_number (Addend)?  */
   2179  1.1.1.2  christos       exp_dup->X_add_number = 0;
   2180  1.1.1.2  christos       exp_dup->X_add_symbol = exp->X_op_symbol;
   2181  1.1.1.2  christos       fix_new_exp (fragP, fragP->fr_fix, 0,
   2182  1.1.1.2  christos 		   exp_dup, 0, BFD_RELOC_LARCH_SUB_ULEB128);
   2183  1.1.1.2  christos     }
   2184  1.1.1.2  christos }
   2185  1.1.1.2  christos 
   2186  1.1.1.2  christos void
   2187  1.1.1.2  christos loongarch_md_finish (void)
   2188  1.1.1.2  christos {
   2189  1.1.1.2  christos   /* Insert relocations for uleb128 directives, so the values can be recomputed
   2190  1.1.1.2  christos      at link time.  */
   2191  1.1.1.2  christos   if (LARCH_opts.relax)
   2192  1.1.1.2  christos     bfd_map_over_sections (stdoutput, loongarch_insert_uleb128_fixes, NULL);
   2193  1.1.1.2  christos }
   2194  1.1.1.2  christos 
   2195      1.1  christos void
   2196      1.1  christos loongarch_elf_final_processing (void)
   2197      1.1  christos {
   2198      1.1  christos   elf_elfheader (stdoutput)->e_flags = LARCH_opts.ase_abi;
   2199      1.1  christos }
   2200  1.1.1.2  christos 
   2201  1.1.1.2  christos /* Compute the length of a branch sequence, and adjust the stored length
   2202  1.1.1.2  christos    accordingly.  If FRAGP is NULL, the worst-case length is returned.  */
   2203  1.1.1.2  christos static unsigned
   2204  1.1.1.2  christos loongarch_relaxed_branch_length (fragS *fragp, asection *sec, int update)
   2205  1.1.1.2  christos {
   2206  1.1.1.2  christos   int length = 4;
   2207  1.1.1.2  christos 
   2208  1.1.1.2  christos   if (!fragp)
   2209  1.1.1.2  christos     return 8;
   2210  1.1.1.2  christos 
   2211  1.1.1.2  christos   if (fragp->fr_symbol != NULL
   2212  1.1.1.2  christos       && S_IS_DEFINED (fragp->fr_symbol)
   2213  1.1.1.2  christos       && !S_IS_WEAK (fragp->fr_symbol)
   2214  1.1.1.2  christos       && sec == S_GET_SEGMENT (fragp->fr_symbol))
   2215  1.1.1.2  christos     {
   2216  1.1.1.2  christos       offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
   2217  1.1.1.2  christos 
   2218  1.1.1.2  christos       val -= fragp->fr_address + fragp->fr_fix;
   2219  1.1.1.2  christos 
   2220  1.1.1.2  christos       if (RELAX_BRANCH_16 == fragp->fr_subtype
   2221  1.1.1.2  christos 	  && OUT_OF_RANGE (val, 16, 2))
   2222  1.1.1.2  christos 	{
   2223  1.1.1.2  christos 	  length = 8;
   2224  1.1.1.2  christos 	  if (update)
   2225  1.1.1.2  christos 	    fragp->fr_subtype = RELAX_BRANCH_26;
   2226  1.1.1.2  christos 	}
   2227  1.1.1.2  christos 
   2228  1.1.1.2  christos       if (RELAX_BRANCH_21 == fragp->fr_subtype
   2229  1.1.1.2  christos 	  && OUT_OF_RANGE (val, 21, 2))
   2230  1.1.1.2  christos 	{
   2231  1.1.1.2  christos 	  length = 8;
   2232  1.1.1.2  christos 	  if (update)
   2233  1.1.1.2  christos 	    fragp->fr_subtype = RELAX_BRANCH_26;
   2234  1.1.1.2  christos 	}
   2235  1.1.1.2  christos 
   2236  1.1.1.2  christos       if (RELAX_BRANCH_26 == fragp->fr_subtype)
   2237  1.1.1.2  christos 	length = 8;
   2238  1.1.1.2  christos     }
   2239  1.1.1.2  christos 
   2240  1.1.1.2  christos   return length;
   2241  1.1.1.2  christos }
   2242  1.1.1.2  christos 
   2243  1.1.1.2  christos int
   2244  1.1.1.3  christos loongarch_relax_frag (asection *sec, fragS *fragp,
   2245  1.1.1.2  christos 		      long stretch ATTRIBUTE_UNUSED)
   2246  1.1.1.2  christos {
   2247  1.1.1.2  christos   if (RELAX_BRANCH (fragp->fr_subtype))
   2248  1.1.1.2  christos     {
   2249  1.1.1.2  christos       offsetT old_var = fragp->fr_var;
   2250  1.1.1.2  christos       fragp->fr_var = loongarch_relaxed_branch_length (fragp, sec, true);
   2251  1.1.1.2  christos       return fragp->fr_var - old_var;
   2252  1.1.1.2  christos     }
   2253  1.1.1.3  christos   else if (rs_align_code == fragp->fr_subtype)
   2254  1.1.1.3  christos     {
   2255  1.1.1.3  christos       offsetT nop_bytes;
   2256  1.1.1.3  christos       if (NULL == fragp->fr_symbol)
   2257  1.1.1.3  christos 	nop_bytes = fragp->fr_offset;
   2258  1.1.1.3  christos       else
   2259  1.1.1.3  christos 	nop_bytes = ALIGN_MAX_NOP_BYTES (fragp->fr_offset);
   2260  1.1.1.3  christos 
   2261  1.1.1.3  christos       /* Normally, nop_bytes should be >= 4.  */
   2262  1.1.1.3  christos       gas_assert (nop_bytes > 0);
   2263  1.1.1.3  christos 
   2264  1.1.1.3  christos       offsetT old_var = fragp->fr_var;
   2265  1.1.1.3  christos       /* If .align at the start of a section, do nothing. Section alignment
   2266  1.1.1.3  christos        * can ensure correct alignment.  */
   2267  1.1.1.3  christos       if (FRAG_AT_START_OF_SECTION (fragp)
   2268  1.1.1.3  christos 	  && 0 == ((1 << sec->alignment_power) % (nop_bytes + 4)))
   2269  1.1.1.3  christos 	fragp->fr_var = 0;
   2270  1.1.1.3  christos       else
   2271  1.1.1.3  christos 	fragp->fr_var = nop_bytes;
   2272  1.1.1.3  christos       return fragp->fr_var - old_var;
   2273  1.1.1.3  christos     }
   2274  1.1.1.2  christos   return 0;
   2275  1.1.1.2  christos }
   2276  1.1.1.2  christos 
   2277  1.1.1.2  christos /* Expand far branches to multi-instruction sequences.
   2278  1.1.1.2  christos    Branch instructions:
   2279  1.1.1.2  christos    beq, bne, blt, bgt, bltz, bgtz, ble, bge, blez, bgez
   2280  1.1.1.2  christos    bltu, bgtu, bleu, bgeu
   2281  1.1.1.2  christos    beqz, bnez, bceqz, bcnez.  */
   2282  1.1.1.2  christos 
   2283  1.1.1.2  christos static void
   2284  1.1.1.2  christos loongarch_convert_frag_branch (fragS *fragp)
   2285  1.1.1.2  christos {
   2286  1.1.1.3  christos   char *buf;
   2287  1.1.1.2  christos   expressionS exp;
   2288  1.1.1.2  christos   fixS *fixp;
   2289  1.1.1.2  christos   insn_t insn;
   2290  1.1.1.2  christos 
   2291  1.1.1.3  christos   buf = fragp->fr_literal + fragp->fr_fix;
   2292  1.1.1.2  christos 
   2293  1.1.1.2  christos   exp.X_op = O_symbol;
   2294  1.1.1.2  christos   exp.X_add_symbol = fragp->fr_symbol;
   2295  1.1.1.2  christos   exp.X_add_number = fragp->fr_offset;
   2296  1.1.1.2  christos 
   2297  1.1.1.2  christos   gas_assert ((fragp->fr_subtype & 0xf) == fragp->fr_var);
   2298  1.1.1.2  christos 
   2299  1.1.1.2  christos   /* blt $t0, $t1, .L1
   2300  1.1.1.2  christos      nop
   2301  1.1.1.2  christos      change to:
   2302  1.1.1.2  christos      bge $t0, $t1, .L2
   2303  1.1.1.2  christos      b .L1
   2304  1.1.1.2  christos    .L2:
   2305  1.1.1.2  christos      nop  */
   2306  1.1.1.2  christos   switch (fragp->fr_subtype)
   2307  1.1.1.2  christos     {
   2308  1.1.1.2  christos     case RELAX_BRANCH_26:
   2309  1.1.1.2  christos       insn = bfd_getl32 (buf);
   2310  1.1.1.2  christos       /* Invert the branch condition.  */
   2311  1.1.1.3  christos       if (LARCH_INSN_FLOAT_BRANCH (insn))
   2312  1.1.1.2  christos 	insn ^= LARCH_FLOAT_BRANCH_INVERT_BIT;
   2313  1.1.1.2  christos       else
   2314  1.1.1.2  christos 	insn ^= LARCH_BRANCH_INVERT_BIT;
   2315  1.1.1.2  christos       insn |= ENCODE_BRANCH16_IMM (8);  /* Set target to PC + 8.  */
   2316  1.1.1.2  christos       bfd_putl32 (insn, buf);
   2317  1.1.1.2  christos       buf += 4;
   2318  1.1.1.2  christos 
   2319  1.1.1.2  christos       /* Add the B instruction and jump to the original target.  */
   2320  1.1.1.2  christos       bfd_putl32 (LARCH_B, buf);
   2321  1.1.1.3  christos       fixp = fix_new_exp (fragp, buf - fragp->fr_literal,
   2322  1.1.1.2  christos 			  4, &exp, false, BFD_RELOC_LARCH_B26);
   2323  1.1.1.2  christos       buf += 4;
   2324  1.1.1.2  christos       break;
   2325  1.1.1.2  christos     case RELAX_BRANCH_21:
   2326  1.1.1.3  christos       fixp = fix_new_exp (fragp, buf - fragp->fr_literal,
   2327  1.1.1.2  christos 			  4, &exp, false, BFD_RELOC_LARCH_B21);
   2328  1.1.1.2  christos       buf += 4;
   2329  1.1.1.2  christos       break;
   2330  1.1.1.2  christos     case RELAX_BRANCH_16:
   2331  1.1.1.3  christos       fixp = fix_new_exp (fragp, buf - fragp->fr_literal,
   2332  1.1.1.2  christos 			  4, &exp, false, BFD_RELOC_LARCH_B16);
   2333  1.1.1.2  christos       buf += 4;
   2334  1.1.1.2  christos       break;
   2335  1.1.1.2  christos 
   2336  1.1.1.2  christos     default:
   2337  1.1.1.2  christos       abort();
   2338  1.1.1.2  christos     }
   2339  1.1.1.2  christos 
   2340  1.1.1.2  christos   fixp->fx_file = fragp->fr_file;
   2341  1.1.1.2  christos   fixp->fx_line = fragp->fr_line;
   2342  1.1.1.2  christos 
   2343  1.1.1.3  christos   gas_assert (buf == fragp->fr_literal + fragp->fr_fix + fragp->fr_var);
   2344  1.1.1.3  christos 
   2345  1.1.1.3  christos   fragp->fr_fix += fragp->fr_var;
   2346  1.1.1.3  christos }
   2347  1.1.1.3  christos 
   2348  1.1.1.3  christos /*  Relax .align frag.  */
   2349  1.1.1.3  christos 
   2350  1.1.1.3  christos static void
   2351  1.1.1.3  christos loongarch_convert_frag_align (fragS *fragp, asection *sec)
   2352  1.1.1.3  christos {
   2353  1.1.1.3  christos   char *buf = fragp->fr_literal + fragp->fr_fix;
   2354  1.1.1.3  christos 
   2355  1.1.1.3  christos   offsetT nop_bytes;
   2356  1.1.1.3  christos   if (NULL == fragp->fr_symbol)
   2357  1.1.1.3  christos     nop_bytes = fragp->fr_offset;
   2358  1.1.1.3  christos   else
   2359  1.1.1.3  christos     nop_bytes = ALIGN_MAX_NOP_BYTES (fragp->fr_offset);
   2360  1.1.1.3  christos 
   2361  1.1.1.3  christos   /* Normally, nop_bytes should be >= 4.  */
   2362  1.1.1.3  christos   gas_assert (nop_bytes > 0);
   2363  1.1.1.3  christos 
   2364  1.1.1.3  christos   if (!(FRAG_AT_START_OF_SECTION (fragp)
   2365  1.1.1.3  christos 	&& 0 == ((1 << sec->alignment_power) % (nop_bytes + 4))))
   2366  1.1.1.3  christos     {
   2367  1.1.1.3  christos       expressionS exp;
   2368  1.1.1.3  christos       exp.X_op = O_symbol;
   2369  1.1.1.3  christos       exp.X_add_symbol = fragp->fr_symbol;
   2370  1.1.1.3  christos       exp.X_add_number = fragp->fr_offset;
   2371  1.1.1.3  christos 
   2372  1.1.1.3  christos       fixS *fixp = fix_new_exp (fragp, buf - fragp->fr_literal,
   2373  1.1.1.3  christos 				nop_bytes, &exp, false, BFD_RELOC_LARCH_ALIGN);
   2374  1.1.1.3  christos       fixp->fx_file = fragp->fr_file;
   2375  1.1.1.3  christos       fixp->fx_line = fragp->fr_line;
   2376  1.1.1.3  christos 
   2377  1.1.1.3  christos       buf += nop_bytes;
   2378  1.1.1.3  christos     }
   2379  1.1.1.3  christos 
   2380  1.1.1.3  christos   gas_assert (buf == fragp->fr_literal + fragp->fr_fix + fragp->fr_var);
   2381  1.1.1.2  christos 
   2382  1.1.1.2  christos   fragp->fr_fix += fragp->fr_var;
   2383  1.1.1.2  christos }
   2384  1.1.1.2  christos 
   2385  1.1.1.3  christos /* Relax a machine dependent frag.  */
   2386  1.1.1.2  christos 
   2387  1.1.1.2  christos void
   2388  1.1.1.3  christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
   2389  1.1.1.2  christos {
   2390  1.1.1.3  christos   gas_assert (RELAX_BRANCH (fragp->fr_subtype)
   2391  1.1.1.3  christos 	      || rs_align_code == fragp->fr_subtype);
   2392  1.1.1.3  christos   if (RELAX_BRANCH (fragp->fr_subtype))
   2393  1.1.1.3  christos     loongarch_convert_frag_branch (fragp);
   2394  1.1.1.3  christos   else if (rs_align_code == fragp->fr_subtype)
   2395  1.1.1.3  christos     loongarch_convert_frag_align (fragp, asec);
   2396  1.1.1.2  christos }
   2397