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