Home | History | Annotate | Line # | Download | only in loongarch
loongarch.cc revision 1.1.1.1
      1 /* Subroutines used for LoongArch code generation.
      2    Copyright (C) 2021-2022 Free Software Foundation, Inc.
      3    Contributed by Loongson Ltd.
      4    Based on MIPS and RISC-V target for GNU compiler.
      5 
      6 This file is part of GCC.
      7 
      8 GCC 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, or (at your option)
     11 any later version.
     12 
     13 GCC 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 GCC; see the file COPYING3.  If not see
     20 <http://www.gnu.org/licenses/>.  */
     21 
     22 #define IN_TARGET_CODE 1
     23 
     24 #include "config.h"
     25 #include "system.h"
     26 #include "coretypes.h"
     27 #include "backend.h"
     28 #include "target.h"
     29 #include "rtl.h"
     30 #include "tree.h"
     31 #include "memmodel.h"
     32 #include "gimple.h"
     33 #include "cfghooks.h"
     34 #include "df.h"
     35 #include "tm_p.h"
     36 #include "stringpool.h"
     37 #include "attribs.h"
     38 #include "optabs.h"
     39 #include "regs.h"
     40 #include "emit-rtl.h"
     41 #include "recog.h"
     42 #include "cgraph.h"
     43 #include "diagnostic.h"
     44 #include "insn-attr.h"
     45 #include "output.h"
     46 #include "alias.h"
     47 #include "fold-const.h"
     48 #include "varasm.h"
     49 #include "stor-layout.h"
     50 #include "calls.h"
     51 #include "explow.h"
     52 #include "expr.h"
     53 #include "libfuncs.h"
     54 #include "reload.h"
     55 #include "common/common-target.h"
     56 #include "langhooks.h"
     57 #include "cfgrtl.h"
     58 #include "cfganal.h"
     59 #include "sched-int.h"
     60 #include "gimplify.h"
     61 #include "target-globals.h"
     62 #include "tree-pass.h"
     63 #include "context.h"
     64 #include "builtins.h"
     65 #include "rtl-iter.h"
     66 
     67 /* This file should be included last.  */
     68 #include "target-def.h"
     69 
     70 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF.  */
     71 #define UNSPEC_ADDRESS_P(X)					\
     72   (GET_CODE (X) == UNSPEC					\
     73    && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST			\
     74    && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
     75 
     76 /* Extract the symbol or label from UNSPEC wrapper X.  */
     77 #define UNSPEC_ADDRESS(X) XVECEXP (X, 0, 0)
     78 
     79 /* Extract the symbol type from UNSPEC wrapper X.  */
     80 #define UNSPEC_ADDRESS_TYPE(X) \
     81   ((enum loongarch_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
     82 
     83 /* True if INSN is a loongarch.md pattern or asm statement.  */
     84 /* ???	This test exists through the compiler, perhaps it should be
     85    moved to rtl.h.  */
     86 #define USEFUL_INSN_P(INSN)						\
     87   (NONDEBUG_INSN_P (INSN)						\
     88    && GET_CODE (PATTERN (INSN)) != USE					\
     89    && GET_CODE (PATTERN (INSN)) != CLOBBER)
     90 
     91 /* True if bit BIT is set in VALUE.  */
     92 #define BITSET_P(VALUE, BIT) (((VALUE) & (1 << (BIT))) != 0)
     93 
     94 /* Classifies an address.
     95 
     96    ADDRESS_REG
     97        A natural register + offset address.  The register satisfies
     98        loongarch_valid_base_register_p and the offset is a const_arith_operand.
     99 
    100    ADDRESS_REG_REG
    101        A base register indexed by (optionally scaled) register.
    102 
    103    ADDRESS_CONST_INT
    104        A signed 16-bit constant address.
    105 
    106    ADDRESS_SYMBOLIC:
    107        A constant symbolic address.  */
    108 enum loongarch_address_type
    109 {
    110   ADDRESS_REG,
    111   ADDRESS_REG_REG,
    112   ADDRESS_CONST_INT,
    113   ADDRESS_SYMBOLIC
    114 };
    115 
    116 
    117 /* Information about an address described by loongarch_address_type.
    118 
    119    ADDRESS_CONST_INT
    120        No fields are used.
    121 
    122    ADDRESS_REG
    123        REG is the base register and OFFSET is the constant offset.
    124 
    125    ADDRESS_REG_REG
    126        A base register indexed by (optionally scaled) register.
    127 
    128    ADDRESS_SYMBOLIC
    129        SYMBOL_TYPE is the type of symbol that the address references.  */
    130 struct loongarch_address_info
    131 {
    132   enum loongarch_address_type type;
    133   rtx reg;
    134   rtx offset;
    135   enum loongarch_symbol_type symbol_type;
    136 };
    137 
    138 /* Method of loading instant numbers:
    139 
    140    METHOD_NORMAL:
    141      Load 0-31 bit of the immediate number.
    142 
    143    METHOD_LU32I:
    144      Load 32-51 bit of the immediate number.
    145 
    146    METHOD_LU52I:
    147      Load 52-63 bit of the immediate number.
    148 
    149    METHOD_INSV:
    150      immediate like 0xfff00000fffffxxx
    151    */
    152 enum loongarch_load_imm_method
    153 {
    154   METHOD_NORMAL,
    155   METHOD_LU32I,
    156   METHOD_LU52I,
    157   METHOD_INSV
    158 };
    159 
    160 struct loongarch_integer_op
    161 {
    162   enum rtx_code code;
    163   HOST_WIDE_INT value;
    164   enum loongarch_load_imm_method method;
    165 };
    166 
    167 /* The largest number of operations needed to load an integer constant.
    168    The worst accepted case for 64-bit constants is LU12I.W,LU32I.D,LU52I.D,ORI
    169    or LU12I.W,LU32I.D,LU52I.D,ADDI.D DECL_ASSEMBLER_NAME.  */
    170 #define LARCH_MAX_INTEGER_OPS 4
    171 
    172 /* Arrays that map GCC register numbers to debugger register numbers.  */
    173 int loongarch_dwarf_regno[FIRST_PSEUDO_REGISTER];
    174 
    175 /* Index [M][R] is true if register R is allowed to hold a value of mode M.  */
    176 static bool loongarch_hard_regno_mode_ok_p[MAX_MACHINE_MODE]
    177 					  [FIRST_PSEUDO_REGISTER];
    178 
    179 /* Index C is true if character C is a valid PRINT_OPERAND punctation
    180    character.  */
    181 static bool loongarch_print_operand_punct[256];
    182 
    183 /* Cached value of can_issue_more.  This is cached in loongarch_variable_issue
    184    hook and returned from loongarch_sched_reorder2.  */
    185 static int cached_can_issue_more;
    186 
    187 /* Index R is the smallest register class that contains register R.  */
    188 const enum reg_class loongarch_regno_to_class[FIRST_PSEUDO_REGISTER] = {
    189     GR_REGS,	     GR_REGS,	      GR_REGS,	       GR_REGS,
    190     JIRL_REGS,       JIRL_REGS,       JIRL_REGS,       JIRL_REGS,
    191     JIRL_REGS,       JIRL_REGS,       JIRL_REGS,       JIRL_REGS,
    192     SIBCALL_REGS,    JIRL_REGS,       SIBCALL_REGS,    SIBCALL_REGS,
    193     SIBCALL_REGS,    SIBCALL_REGS,    SIBCALL_REGS,    SIBCALL_REGS,
    194     SIBCALL_REGS,    GR_REGS,	      GR_REGS,	       JIRL_REGS,
    195     JIRL_REGS,       JIRL_REGS,       JIRL_REGS,       JIRL_REGS,
    196     JIRL_REGS,       JIRL_REGS,       JIRL_REGS,       JIRL_REGS,
    197 
    198     FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    199     FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    200     FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    201     FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    202     FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    203     FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    204     FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    205     FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    206     FCC_REGS,	FCC_REGS,	FCC_REGS,	FCC_REGS,
    207     FCC_REGS,	FCC_REGS,	FCC_REGS,	FCC_REGS,
    208     FRAME_REGS,	FRAME_REGS
    209 };
    210 
    211 /* Which cost information to use.  */
    212 static const struct loongarch_rtx_cost_data *loongarch_cost;
    213 
    214 /* Information about a single argument.  */
    215 struct loongarch_arg_info
    216 {
    217   /* True if the argument is at least partially passed on the stack.  */
    218   bool stack_p;
    219 
    220   /* The number of integer registers allocated to this argument.  */
    221   unsigned int num_gprs;
    222 
    223   /* The offset of the first register used, provided num_gprs is nonzero.
    224      If passed entirely on the stack, the value is MAX_ARGS_IN_REGISTERS.  */
    225   unsigned int gpr_offset;
    226 
    227   /* The number of floating-point registers allocated to this argument.  */
    228   unsigned int num_fprs;
    229 
    230   /* The offset of the first register used, provided num_fprs is nonzero.  */
    231   unsigned int fpr_offset;
    232 };
    233 
    234 /* Invoke MACRO (COND) for each fcmp.cond.{s/d} condition.  */
    235 #define LARCH_FP_CONDITIONS(MACRO) \
    236   MACRO (f),	\
    237   MACRO (un),	\
    238   MACRO (eq),	\
    239   MACRO (ueq),	\
    240   MACRO (olt),	\
    241   MACRO (ult),	\
    242   MACRO (ole),	\
    243   MACRO (ule),	\
    244   MACRO (sf),	\
    245   MACRO (ngle),	\
    246   MACRO (seq),	\
    247   MACRO (ngl),	\
    248   MACRO (lt),	\
    249   MACRO (nge),	\
    250   MACRO (le),	\
    251   MACRO (ngt)
    252 
    253 /* Enumerates the codes above as LARCH_FP_COND_<X>.  */
    254 #define DECLARE_LARCH_COND(X) LARCH_FP_COND_##X
    255 enum loongarch_fp_condition
    256 {
    257   LARCH_FP_CONDITIONS (DECLARE_LARCH_COND)
    258 };
    259 #undef DECLARE_LARCH_COND
    260 
    261 /* Index X provides the string representation of LARCH_FP_COND_<X>.  */
    262 #define STRINGIFY(X) #X
    263 const char *const
    264 loongarch_fp_conditions[16]= {LARCH_FP_CONDITIONS (STRINGIFY)};
    265 #undef STRINGIFY
    266 
    267 /* Implement TARGET_FUNCTION_ARG_BOUNDARY.  Every parameter gets at
    268    least PARM_BOUNDARY bits of alignment, but will be given anything up
    269    to PREFERRED_STACK_BOUNDARY bits if the type requires it.  */
    270 
    271 static unsigned int
    272 loongarch_function_arg_boundary (machine_mode mode, const_tree type)
    273 {
    274   unsigned int alignment;
    275 
    276   /* Use natural alignment if the type is not aggregate data.  */
    277   if (type && !AGGREGATE_TYPE_P (type))
    278     alignment = TYPE_ALIGN (TYPE_MAIN_VARIANT (type));
    279   else
    280     alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
    281 
    282   return MIN (PREFERRED_STACK_BOUNDARY, MAX (PARM_BOUNDARY, alignment));
    283 }
    284 
    285 /* If MODE represents an argument that can be passed or returned in
    286    floating-point registers, return the number of registers, else 0.  */
    287 
    288 static unsigned
    289 loongarch_pass_mode_in_fpr_p (machine_mode mode)
    290 {
    291   if (GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FP_ARG)
    292     {
    293       if (GET_MODE_CLASS (mode) == MODE_FLOAT)
    294 	return 1;
    295 
    296       if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
    297 	return 2;
    298     }
    299 
    300   return 0;
    301 }
    302 
    303 typedef struct
    304 {
    305   const_tree type;
    306   HOST_WIDE_INT offset;
    307 } loongarch_aggregate_field;
    308 
    309 /* Identify subfields of aggregates that are candidates for passing in
    310    floating-point registers.  */
    311 
    312 static int
    313 loongarch_flatten_aggregate_field (const_tree type,
    314 				   loongarch_aggregate_field fields[2], int n,
    315 				   HOST_WIDE_INT offset)
    316 {
    317   switch (TREE_CODE (type))
    318     {
    319     case RECORD_TYPE:
    320       /* Can't handle incomplete types nor sizes that are not fixed.  */
    321       if (!COMPLETE_TYPE_P (type)
    322 	  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
    323 	  || !tree_fits_uhwi_p (TYPE_SIZE (type)))
    324 	return -1;
    325 
    326       for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
    327 	if (TREE_CODE (f) == FIELD_DECL)
    328 	  {
    329 	    if (!TYPE_P (TREE_TYPE (f)))
    330 	      return -1;
    331 
    332 	    if (DECL_SIZE (f) && integer_zerop (DECL_SIZE (f)))
    333 	      continue;
    334 
    335 	    HOST_WIDE_INT pos = offset + int_byte_position (f);
    336 	    n = loongarch_flatten_aggregate_field (TREE_TYPE (f), fields, n,
    337 						   pos);
    338 	    if (n < 0)
    339 	      return -1;
    340 	  }
    341       return n;
    342 
    343     case ARRAY_TYPE:
    344       {
    345 	HOST_WIDE_INT n_elts;
    346 	loongarch_aggregate_field subfields[2];
    347 	tree index = TYPE_DOMAIN (type);
    348 	tree elt_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
    349 	int n_subfields = loongarch_flatten_aggregate_field (TREE_TYPE (type),
    350 							     subfields, 0,
    351 							     offset);
    352 
    353 	/* Can't handle incomplete types nor sizes that are not fixed.  */
    354 	if (n_subfields <= 0
    355 	    || !COMPLETE_TYPE_P (type)
    356 	    || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
    357 	    || !index
    358 	    || !TYPE_MAX_VALUE (index)
    359 	    || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index))
    360 	    || !TYPE_MIN_VALUE (index)
    361 	    || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index))
    362 	    || !tree_fits_uhwi_p (elt_size))
    363 	  return -1;
    364 
    365 	n_elts = 1 + tree_to_uhwi (TYPE_MAX_VALUE (index))
    366 		 - tree_to_uhwi (TYPE_MIN_VALUE (index));
    367 	gcc_assert (n_elts >= 0);
    368 
    369 	for (HOST_WIDE_INT i = 0; i < n_elts; i++)
    370 	  for (int j = 0; j < n_subfields; j++)
    371 	    {
    372 	      if (n >= 2)
    373 		return -1;
    374 
    375 	      fields[n] = subfields[j];
    376 	      fields[n++].offset += i * tree_to_uhwi (elt_size);
    377 	    }
    378 
    379 	return n;
    380       }
    381 
    382     case COMPLEX_TYPE:
    383       {
    384 	/* Complex type need consume 2 field, so n must be 0.  */
    385 	if (n != 0)
    386 	  return -1;
    387 
    388 	HOST_WIDE_INT elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)));
    389 
    390 	if (elt_size <= UNITS_PER_FP_ARG)
    391 	  {
    392 	    fields[0].type = TREE_TYPE (type);
    393 	    fields[0].offset = offset;
    394 	    fields[1].type = TREE_TYPE (type);
    395 	    fields[1].offset = offset + elt_size;
    396 
    397 	    return 2;
    398 	  }
    399 
    400 	return -1;
    401       }
    402 
    403     default:
    404       if (n < 2
    405 	  && ((SCALAR_FLOAT_TYPE_P (type)
    406 	       && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FP_ARG)
    407 	      || (INTEGRAL_TYPE_P (type)
    408 		  && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD)))
    409 	{
    410 	  fields[n].type = type;
    411 	  fields[n].offset = offset;
    412 	  return n + 1;
    413 	}
    414       else
    415 	return -1;
    416     }
    417 }
    418 
    419 /* Identify candidate aggregates for passing in floating-point registers.
    420    Candidates have at most two fields after flattening.  */
    421 
    422 static int
    423 loongarch_flatten_aggregate_argument (const_tree type,
    424 				      loongarch_aggregate_field fields[2])
    425 {
    426   if (!type || TREE_CODE (type) != RECORD_TYPE)
    427     return -1;
    428 
    429   return loongarch_flatten_aggregate_field (type, fields, 0, 0);
    430 }
    431 
    432 /* See whether TYPE is a record whose fields should be returned in one or
    433    two floating-point registers.  If so, populate FIELDS accordingly.  */
    434 
    435 static unsigned
    436 loongarch_pass_aggregate_num_fpr (const_tree type,
    437 					loongarch_aggregate_field fields[2])
    438 {
    439   int n = loongarch_flatten_aggregate_argument (type, fields);
    440 
    441   for (int i = 0; i < n; i++)
    442     if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
    443       return 0;
    444 
    445   return n > 0 ? n : 0;
    446 }
    447 
    448 /* See whether TYPE is a record whose fields should be returned in one
    449    floating-point register and one integer register.  If so, populate
    450    FIELDS accordingly.  */
    451 
    452 static bool
    453 loongarch_pass_aggregate_in_fpr_and_gpr_p (const_tree type,
    454 					   loongarch_aggregate_field fields[2])
    455 {
    456   unsigned num_int = 0, num_float = 0;
    457   int n = loongarch_flatten_aggregate_argument (type, fields);
    458 
    459   for (int i = 0; i < n; i++)
    460     {
    461       num_float += SCALAR_FLOAT_TYPE_P (fields[i].type);
    462       num_int += INTEGRAL_TYPE_P (fields[i].type);
    463     }
    464 
    465   return num_int == 1 && num_float == 1;
    466 }
    467 
    468 /* Return the representation of an argument passed or returned in an FPR
    469    when the value has mode VALUE_MODE and the type has TYPE_MODE.  The
    470    two modes may be different for structures like:
    471 
    472    struct __attribute__((packed)) foo { float f; }
    473 
    474    where the SFmode value "f" is passed in REGNO but the struct itself
    475    has mode BLKmode.  */
    476 
    477 static rtx
    478 loongarch_pass_fpr_single (machine_mode type_mode, unsigned regno,
    479 			   machine_mode value_mode,
    480 			   HOST_WIDE_INT offset)
    481 {
    482   rtx x = gen_rtx_REG (value_mode, regno);
    483 
    484   if (type_mode != value_mode)
    485     {
    486       x = gen_rtx_EXPR_LIST (VOIDmode, x, GEN_INT (offset));
    487       x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x));
    488     }
    489   return x;
    490 }
    491 
    492 /* Pass or return a composite value in the FPR pair REGNO and REGNO + 1.
    493    MODE is the mode of the composite.  MODE1 and OFFSET1 are the mode and
    494    byte offset for the first value, likewise MODE2 and OFFSET2 for the
    495    second value.  */
    496 
    497 static rtx
    498 loongarch_pass_fpr_pair (machine_mode mode, unsigned regno1,
    499 			 machine_mode mode1, HOST_WIDE_INT offset1,
    500 			 unsigned regno2, machine_mode mode2,
    501 			 HOST_WIDE_INT offset2)
    502 {
    503   return gen_rtx_PARALLEL (
    504     mode, gen_rtvec (2,
    505 		     gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (mode1, regno1),
    506 					GEN_INT (offset1)),
    507 		     gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (mode2, regno2),
    508 					GEN_INT (offset2))));
    509 }
    510 
    511 /* Fill INFO with information about a single argument, and return an
    512    RTL pattern to pass or return the argument.  CUM is the cumulative
    513    state for earlier arguments.  MODE is the mode of this argument and
    514    TYPE is its type (if known).  NAMED is true if this is a named
    515    (fixed) argument rather than a variable one.  RETURN_P is true if
    516    returning the argument, or false if passing the argument.  */
    517 
    518 static rtx
    519 loongarch_get_arg_info (struct loongarch_arg_info *info,
    520 			const CUMULATIVE_ARGS *cum, machine_mode mode,
    521 			const_tree type, bool named, bool return_p)
    522 {
    523   unsigned num_bytes, num_words;
    524   unsigned fpr_base = return_p ? FP_RETURN : FP_ARG_FIRST;
    525   unsigned gpr_base = return_p ? GP_RETURN : GP_ARG_FIRST;
    526   unsigned alignment = loongarch_function_arg_boundary (mode, type);
    527 
    528   memset (info, 0, sizeof (*info));
    529   info->gpr_offset = cum->num_gprs;
    530   info->fpr_offset = cum->num_fprs;
    531 
    532   if (named)
    533     {
    534       loongarch_aggregate_field fields[2];
    535       unsigned fregno = fpr_base + info->fpr_offset;
    536       unsigned gregno = gpr_base + info->gpr_offset;
    537 
    538       /* Pass one- or two-element floating-point aggregates in FPRs.  */
    539       if ((info->num_fprs
    540 	   = loongarch_pass_aggregate_num_fpr (type, fields))
    541 	  && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
    542 	switch (info->num_fprs)
    543 	  {
    544 	  case 1:
    545 	    return loongarch_pass_fpr_single (mode, fregno,
    546 					      TYPE_MODE (fields[0].type),
    547 					      fields[0].offset);
    548 
    549 	  case 2:
    550 	    return loongarch_pass_fpr_pair (mode, fregno,
    551 					    TYPE_MODE (fields[0].type),
    552 					    fields[0].offset,
    553 					    fregno + 1,
    554 					    TYPE_MODE (fields[1].type),
    555 					    fields[1].offset);
    556 
    557 	  default:
    558 	    gcc_unreachable ();
    559 	  }
    560 
    561       /* Pass real and complex floating-point numbers in FPRs.  */
    562       if ((info->num_fprs = loongarch_pass_mode_in_fpr_p (mode))
    563 	  && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
    564 	switch (GET_MODE_CLASS (mode))
    565 	  {
    566 	  case MODE_FLOAT:
    567 	    return gen_rtx_REG (mode, fregno);
    568 
    569 	  case MODE_COMPLEX_FLOAT:
    570 	    return loongarch_pass_fpr_pair (mode, fregno,
    571 					    GET_MODE_INNER (mode), 0,
    572 					    fregno + 1, GET_MODE_INNER (mode),
    573 					    GET_MODE_UNIT_SIZE (mode));
    574 
    575 	  default:
    576 	    gcc_unreachable ();
    577 	  }
    578 
    579       /* Pass structs with one float and one integer in an FPR and a GPR.  */
    580       if (loongarch_pass_aggregate_in_fpr_and_gpr_p (type, fields)
    581 	  && info->gpr_offset < MAX_ARGS_IN_REGISTERS
    582 	  && info->fpr_offset < MAX_ARGS_IN_REGISTERS)
    583 	{
    584 	  info->num_gprs = 1;
    585 	  info->num_fprs = 1;
    586 
    587 	  if (!SCALAR_FLOAT_TYPE_P (fields[0].type))
    588 	    std::swap (fregno, gregno);
    589 
    590 	  return loongarch_pass_fpr_pair (mode, fregno,
    591 					  TYPE_MODE (fields[0].type),
    592 					  fields[0].offset, gregno,
    593 					  TYPE_MODE (fields[1].type),
    594 					  fields[1].offset);
    595 	}
    596     }
    597 
    598   /* Work out the size of the argument.  */
    599   num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
    600   num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
    601 
    602   /* Doubleword-aligned varargs start on an even register boundary.  */
    603   if (!named && num_bytes != 0 && alignment > BITS_PER_WORD)
    604     info->gpr_offset += info->gpr_offset & 1;
    605 
    606   /* Partition the argument between registers and stack.  */
    607   info->num_fprs = 0;
    608   info->num_gprs = MIN (num_words, MAX_ARGS_IN_REGISTERS - info->gpr_offset);
    609   info->stack_p = (num_words - info->num_gprs) != 0;
    610 
    611   if (info->num_gprs || return_p)
    612     return gen_rtx_REG (mode, gpr_base + info->gpr_offset);
    613 
    614   return NULL_RTX;
    615 }
    616 
    617 /* Implement TARGET_FUNCTION_ARG.  */
    618 
    619 static rtx
    620 loongarch_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
    621 {
    622   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    623   struct loongarch_arg_info info;
    624 
    625   if (arg.end_marker_p ())
    626     return NULL;
    627 
    628   return loongarch_get_arg_info (&info, cum, arg.mode, arg.type, arg.named,
    629 				 false);
    630 }
    631 
    632 /* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
    633 
    634 static void
    635 loongarch_function_arg_advance (cumulative_args_t cum_v,
    636 				const function_arg_info &arg)
    637 {
    638   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    639   struct loongarch_arg_info info;
    640 
    641   loongarch_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
    642 
    643   /* Advance the register count.  This has the effect of setting
    644      num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
    645      argument required us to skip the final GPR and pass the whole
    646      argument on the stack.  */
    647   cum->num_fprs = info.fpr_offset + info.num_fprs;
    648   cum->num_gprs = info.gpr_offset + info.num_gprs;
    649 }
    650 
    651 /* Implement TARGET_ARG_PARTIAL_BYTES.  */
    652 
    653 static int
    654 loongarch_arg_partial_bytes (cumulative_args_t cum,
    655 			     const function_arg_info &generic_arg)
    656 {
    657   struct loongarch_arg_info arg;
    658 
    659   loongarch_get_arg_info (&arg, get_cumulative_args (cum), generic_arg.mode,
    660 			  generic_arg.type, generic_arg.named, false);
    661   return arg.stack_p ? arg.num_gprs * UNITS_PER_WORD : 0;
    662 }
    663 
    664 /* Implement FUNCTION_VALUE and LIBCALL_VALUE.  For normal calls,
    665    VALTYPE is the return type and MODE is VOIDmode.  For libcalls,
    666    VALTYPE is null and MODE is the mode of the return value.  */
    667 
    668 static rtx
    669 loongarch_function_value_1 (const_tree type, const_tree func,
    670 			    machine_mode mode)
    671 {
    672   struct loongarch_arg_info info;
    673   CUMULATIVE_ARGS args;
    674 
    675   if (type)
    676     {
    677       int unsigned_p = TYPE_UNSIGNED (type);
    678 
    679       mode = TYPE_MODE (type);
    680 
    681       /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
    682 	 return values, promote the mode here too.  */
    683       mode = promote_function_mode (type, mode, &unsigned_p, func, 1);
    684     }
    685 
    686   memset (&args, 0, sizeof (args));
    687   return loongarch_get_arg_info (&info, &args, mode, type, true, true);
    688 }
    689 
    690 
    691 /* Implement TARGET_FUNCTION_VALUE.  */
    692 
    693 static rtx
    694 loongarch_function_value (const_tree valtype, const_tree fn_decl_or_type,
    695 			  bool outgoing ATTRIBUTE_UNUSED)
    696 {
    697   return loongarch_function_value_1 (valtype, fn_decl_or_type, VOIDmode);
    698 }
    699 
    700 /* Implement TARGET_LIBCALL_VALUE.  */
    701 
    702 static rtx
    703 loongarch_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
    704 {
    705   return loongarch_function_value_1 (NULL_TREE, NULL_TREE, mode);
    706 }
    707 
    708 
    709 /* Implement TARGET_PASS_BY_REFERENCE.  */
    710 
    711 static bool
    712 loongarch_pass_by_reference (cumulative_args_t cum_v,
    713 			     const function_arg_info &arg)
    714 {
    715   HOST_WIDE_INT size = arg.type_size_in_bytes ();
    716   struct loongarch_arg_info info;
    717   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    718 
    719   /* ??? std_gimplify_va_arg_expr passes NULL for cum.  Fortunately, we
    720      never pass variadic arguments in floating-point registers, so we can
    721      avoid the call to loongarch_get_arg_info in this case.  */
    722   if (cum != NULL)
    723     {
    724       /* Don't pass by reference if we can use a floating-point register.  */
    725       loongarch_get_arg_info (&info, cum, arg.mode, arg.type, arg.named,
    726 			      false);
    727       if (info.num_fprs)
    728 	return false;
    729     }
    730 
    731   /* Pass by reference if the data do not fit in two integer registers.  */
    732   return !IN_RANGE (size, 0, 2 * UNITS_PER_WORD);
    733 }
    734 
    735 /* Implement TARGET_RETURN_IN_MEMORY.  */
    736 
    737 static bool
    738 loongarch_return_in_memory (const_tree type,
    739 			    const_tree fndecl ATTRIBUTE_UNUSED)
    740 {
    741   CUMULATIVE_ARGS args;
    742   cumulative_args_t cum = pack_cumulative_args (&args);
    743 
    744   /* The rules for returning in memory are the same as for passing the
    745      first named argument by reference.  */
    746   memset (&args, 0, sizeof (args));
    747   function_arg_info arg (const_cast<tree> (type), /*named=*/true);
    748   return loongarch_pass_by_reference (cum, arg);
    749 }
    750 
    751 /* Implement TARGET_SETUP_INCOMING_VARARGS.  */
    752 
    753 static void
    754 loongarch_setup_incoming_varargs (cumulative_args_t cum,
    755 				  const function_arg_info &arg,
    756 				  int *pretend_size ATTRIBUTE_UNUSED,
    757 				  int no_rtl)
    758 {
    759   CUMULATIVE_ARGS local_cum;
    760   int gp_saved;
    761 
    762   /* The caller has advanced CUM up to, but not beyond, the last named
    763      argument.  Advance a local copy of CUM past the last "real" named
    764      argument, to find out how many registers are left over.  */
    765   local_cum = *get_cumulative_args (cum);
    766   loongarch_function_arg_advance (pack_cumulative_args (&local_cum), arg);
    767 
    768   /* Found out how many registers we need to save.  */
    769   gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
    770 
    771   if (!no_rtl && gp_saved > 0)
    772     {
    773       rtx ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
    774 			       REG_PARM_STACK_SPACE (cfun->decl)
    775 				 - gp_saved * UNITS_PER_WORD);
    776       rtx mem = gen_frame_mem (BLKmode, ptr);
    777       set_mem_alias_set (mem, get_varargs_alias_set ());
    778 
    779       move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST, mem, gp_saved);
    780     }
    781   if (REG_PARM_STACK_SPACE (cfun->decl) == 0)
    782     cfun->machine->varargs_size = gp_saved * UNITS_PER_WORD;
    783 }
    784 
    785 /* Make the last instruction frame-related and note that it performs
    786    the operation described by FRAME_PATTERN.  */
    787 
    788 static void
    789 loongarch_set_frame_expr (rtx frame_pattern)
    790 {
    791   rtx insn;
    792 
    793   insn = get_last_insn ();
    794   RTX_FRAME_RELATED_P (insn) = 1;
    795   REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR, frame_pattern,
    796 				      REG_NOTES (insn));
    797 }
    798 
    799 /* Return a frame-related rtx that stores REG at MEM.
    800    REG must be a single register.  */
    801 
    802 static rtx
    803 loongarch_frame_set (rtx mem, rtx reg)
    804 {
    805   rtx set = gen_rtx_SET (mem, reg);
    806   RTX_FRAME_RELATED_P (set) = 1;
    807   return set;
    808 }
    809 
    810 /* Return true if the current function must save register REGNO.  */
    811 
    812 static bool
    813 loongarch_save_reg_p (unsigned int regno)
    814 {
    815   bool call_saved = !global_regs[regno] && !call_used_regs[regno];
    816   bool might_clobber
    817     = crtl->saves_all_registers || df_regs_ever_live_p (regno);
    818 
    819   if (call_saved && might_clobber)
    820     return true;
    821 
    822   if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
    823     return true;
    824 
    825   if (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return)
    826     return true;
    827 
    828   return false;
    829 }
    830 
    831 /* Determine which GPR save/restore routine to call.  */
    832 
    833 static unsigned
    834 loongarch_save_libcall_count (unsigned mask)
    835 {
    836   for (unsigned n = GP_REG_LAST; n > GP_REG_FIRST; n--)
    837     if (BITSET_P (mask, n))
    838       return CALLEE_SAVED_REG_NUMBER (n) + 1;
    839   abort ();
    840 }
    841 
    842 /* Populate the current function's loongarch_frame_info structure.
    843 
    844    LoongArch stack frames grown downward.  High addresses are at the top.
    845 
    846      +-------------------------------+
    847      |				     |
    848      |  incoming stack arguments     |
    849      |				     |
    850      +-------------------------------+ <-- incoming stack pointer
    851      |				     |
    852      |  callee-allocated save area   |
    853      |  for arguments that are       |
    854      |  split between registers and  |
    855      |  the stack		     |
    856      |				     |
    857      +-------------------------------+ <-- arg_pointer_rtx (virtual)
    858      |				     |
    859      |  callee-allocated save area   |
    860      |  for register varargs	     |
    861      |				     |
    862      +-------------------------------+ <-- hard_frame_pointer_rtx;
    863      |				     |     stack_pointer_rtx + gp_sp_offset
    864      |  GPR save area		     |       + UNITS_PER_WORD
    865      |				     |
    866      +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
    867      |				     |       + UNITS_PER_HWVALUE
    868      |  FPR save area		     |
    869      |				     |
    870      +-------------------------------+ <-- frame_pointer_rtx (virtual)
    871      |				     |
    872      |  local variables		     |
    873      |				     |
    874    P +-------------------------------+
    875      |				     |
    876      |  outgoing stack arguments     |
    877      |				     |
    878      +-------------------------------+ <-- stack_pointer_rtx
    879 
    880    Dynamic stack allocations such as alloca insert data at point P.
    881    They decrease stack_pointer_rtx but leave frame_pointer_rtx and
    882    hard_frame_pointer_rtx unchanged.  */
    883 
    884 static void
    885 loongarch_compute_frame_info (void)
    886 {
    887   struct loongarch_frame_info *frame;
    888   HOST_WIDE_INT offset;
    889   unsigned int regno, i, num_x_saved = 0, num_f_saved = 0;
    890 
    891   frame = &cfun->machine->frame;
    892   memset (frame, 0, sizeof (*frame));
    893 
    894   /* Find out which GPRs we need to save.  */
    895   for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
    896     if (loongarch_save_reg_p (regno))
    897       frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
    898 
    899   /* If this function calls eh_return, we must also save and restore the
    900      EH data registers.  */
    901   if (crtl->calls_eh_return)
    902     for (i = 0; (regno = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
    903       frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
    904 
    905   /* Find out which FPRs we need to save.  This loop must iterate over
    906      the same space as its companion in loongarch_for_each_saved_reg.  */
    907   if (TARGET_HARD_FLOAT)
    908     for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
    909       if (loongarch_save_reg_p (regno))
    910 	frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++;
    911 
    912   /* At the bottom of the frame are any outgoing stack arguments.  */
    913   offset = LARCH_STACK_ALIGN (crtl->outgoing_args_size);
    914   /* Next are local stack variables.  */
    915   offset += LARCH_STACK_ALIGN (get_frame_size ());
    916   /* The virtual frame pointer points above the local variables.  */
    917   frame->frame_pointer_offset = offset;
    918   /* Next are the callee-saved FPRs.  */
    919   if (frame->fmask)
    920     {
    921       offset += LARCH_STACK_ALIGN (num_f_saved * UNITS_PER_FP_REG);
    922       frame->fp_sp_offset = offset - UNITS_PER_FP_REG;
    923     }
    924   else
    925     frame->fp_sp_offset = offset;
    926   /* Next are the callee-saved GPRs.  */
    927   if (frame->mask)
    928     {
    929       unsigned x_save_size = LARCH_STACK_ALIGN (num_x_saved * UNITS_PER_WORD);
    930       unsigned num_save_restore
    931 	= 1 + loongarch_save_libcall_count (frame->mask);
    932 
    933       /* Only use save/restore routines if they don't alter the stack size.  */
    934       if (LARCH_STACK_ALIGN (num_save_restore * UNITS_PER_WORD) == x_save_size)
    935 	frame->save_libcall_adjustment = x_save_size;
    936 
    937       offset += x_save_size;
    938       frame->gp_sp_offset = offset - UNITS_PER_WORD;
    939     }
    940   else
    941     frame->gp_sp_offset = offset;
    942   /* The hard frame pointer points above the callee-saved GPRs.  */
    943   frame->hard_frame_pointer_offset = offset;
    944   /* Above the hard frame pointer is the callee-allocated varags save area.  */
    945   offset += LARCH_STACK_ALIGN (cfun->machine->varargs_size);
    946   /* Next is the callee-allocated area for pretend stack arguments.  */
    947   offset += LARCH_STACK_ALIGN (crtl->args.pretend_args_size);
    948   /* Arg pointer must be below pretend args, but must be above alignment
    949      padding.  */
    950   frame->arg_pointer_offset = offset - crtl->args.pretend_args_size;
    951   frame->total_size = offset;
    952   /* Next points the incoming stack pointer and any incoming arguments.  */
    953 
    954   /* Only use save/restore routines when the GPRs are atop the frame.  */
    955   if (frame->hard_frame_pointer_offset != frame->total_size)
    956     frame->save_libcall_adjustment = 0;
    957 }
    958 
    959 /* Implement INITIAL_ELIMINATION_OFFSET.  FROM is either the frame pointer
    960    or argument pointer.  TO is either the stack pointer or hard frame
    961    pointer.  */
    962 
    963 HOST_WIDE_INT
    964 loongarch_initial_elimination_offset (int from, int to)
    965 {
    966   HOST_WIDE_INT src, dest;
    967 
    968   loongarch_compute_frame_info ();
    969 
    970   if (to == HARD_FRAME_POINTER_REGNUM)
    971     dest = cfun->machine->frame.hard_frame_pointer_offset;
    972   else if (to == STACK_POINTER_REGNUM)
    973     dest = 0; /* The stack pointer is the base of all offsets, hence 0.  */
    974   else
    975     gcc_unreachable ();
    976 
    977   if (from == FRAME_POINTER_REGNUM)
    978     src = cfun->machine->frame.frame_pointer_offset;
    979   else if (from == ARG_POINTER_REGNUM)
    980     src = cfun->machine->frame.arg_pointer_offset;
    981   else
    982     gcc_unreachable ();
    983 
    984   return src - dest;
    985 }
    986 
    987 /* A function to save or store a register.  The first argument is the
    988    register and the second is the stack slot.  */
    989 typedef void (*loongarch_save_restore_fn) (rtx, rtx);
    990 
    991 /* Use FN to save or restore register REGNO.  MODE is the register's
    992    mode and OFFSET is the offset of its save slot from the current
    993    stack pointer.  */
    994 
    995 static void
    996 loongarch_save_restore_reg (machine_mode mode, int regno, HOST_WIDE_INT offset,
    997 			    loongarch_save_restore_fn fn)
    998 {
    999   rtx mem;
   1000 
   1001   mem = gen_frame_mem (mode, plus_constant (Pmode, stack_pointer_rtx, offset));
   1002   fn (gen_rtx_REG (mode, regno), mem);
   1003 }
   1004 
   1005 /* Call FN for each register that is saved by the current function.
   1006    SP_OFFSET is the offset of the current stack pointer from the start
   1007    of the frame.  */
   1008 
   1009 static void
   1010 loongarch_for_each_saved_reg (HOST_WIDE_INT sp_offset,
   1011 			      loongarch_save_restore_fn fn,
   1012 			      bool skip_eh_data_regs_p)
   1013 {
   1014   HOST_WIDE_INT offset;
   1015 
   1016   /* Save the link register and s-registers.  */
   1017   offset = cfun->machine->frame.gp_sp_offset - sp_offset;
   1018   for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
   1019     if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
   1020       {
   1021 	/* Special care needs to be taken for $r4-$r7 (EH_RETURN_DATA_REGNO)
   1022 	   when returning normally from a function that calls
   1023 	   __builtin_eh_return.  In this case, these registers are saved but
   1024 	   should not be restored, or the return value may be clobbered.  */
   1025 
   1026 	if (!(skip_eh_data_regs_p
   1027 	      && GP_ARG_FIRST <= regno && regno < GP_ARG_FIRST + 4))
   1028 	  loongarch_save_restore_reg (word_mode, regno, offset, fn);
   1029 
   1030 	offset -= UNITS_PER_WORD;
   1031       }
   1032 
   1033   /* This loop must iterate over the same space as its companion in
   1034      loongarch_compute_frame_info.  */
   1035   offset = cfun->machine->frame.fp_sp_offset - sp_offset;
   1036   for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
   1037     if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
   1038       {
   1039 	machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
   1040 
   1041 	loongarch_save_restore_reg (mode, regno, offset, fn);
   1042 	offset -= GET_MODE_SIZE (mode);
   1043       }
   1044 }
   1045 
   1046 /* Emit a move from SRC to DEST.  Assume that the move expanders can
   1047    handle all moves if !can_create_pseudo_p ().  The distinction is
   1048    important because, unlike emit_move_insn, the move expanders know
   1049    how to force Pmode objects into the constant pool even when the
   1050    constant pool address is not itself legitimate.  */
   1051 
   1052 rtx
   1053 loongarch_emit_move (rtx dest, rtx src)
   1054 {
   1055   return (can_create_pseudo_p () ? emit_move_insn (dest, src)
   1056 				 : emit_move_insn_1 (dest, src));
   1057 }
   1058 
   1059 /* Save register REG to MEM.  Make the instruction frame-related.  */
   1060 
   1061 static void
   1062 loongarch_save_reg (rtx reg, rtx mem)
   1063 {
   1064   loongarch_emit_move (mem, reg);
   1065   loongarch_set_frame_expr (loongarch_frame_set (mem, reg));
   1066 }
   1067 
   1068 /* Restore register REG from MEM.  */
   1069 
   1070 static void
   1071 loongarch_restore_reg (rtx reg, rtx mem)
   1072 {
   1073   rtx insn = loongarch_emit_move (reg, mem);
   1074   rtx dwarf = NULL_RTX;
   1075   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
   1076   REG_NOTES (insn) = dwarf;
   1077 
   1078   RTX_FRAME_RELATED_P (insn) = 1;
   1079 }
   1080 
   1081 /* For stack frames that can't be allocated with a single ADDI instruction,
   1082    compute the best value to initially allocate.  It must at a minimum
   1083    allocate enough space to spill the callee-saved registers.  */
   1084 
   1085 static HOST_WIDE_INT
   1086 loongarch_first_stack_step (struct loongarch_frame_info *frame)
   1087 {
   1088   if (IMM12_OPERAND (frame->total_size))
   1089     return frame->total_size;
   1090 
   1091   HOST_WIDE_INT min_first_step
   1092     = LARCH_STACK_ALIGN (frame->total_size - frame->fp_sp_offset);
   1093   HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8;
   1094   HOST_WIDE_INT min_second_step = frame->total_size - max_first_step;
   1095   gcc_assert (min_first_step <= max_first_step);
   1096 
   1097   /* As an optimization, use the least-significant bits of the total frame
   1098      size, so that the second adjustment step is just LU12I + ADD.  */
   1099   if (!IMM12_OPERAND (min_second_step)
   1100       && frame->total_size % IMM_REACH < IMM_REACH / 2
   1101       && frame->total_size % IMM_REACH >= min_first_step)
   1102     return frame->total_size % IMM_REACH;
   1103 
   1104   return max_first_step;
   1105 }
   1106 
   1107 static void
   1108 loongarch_emit_stack_tie (void)
   1109 {
   1110   emit_insn (gen_stack_tie (Pmode, stack_pointer_rtx,
   1111 			    frame_pointer_needed ? hard_frame_pointer_rtx
   1112 			    : stack_pointer_rtx));
   1113 }
   1114 
   1115 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
   1116 
   1117 #if PROBE_INTERVAL > 16384
   1118 #error Cannot use indexed addressing mode for stack probing
   1119 #endif
   1120 
   1121 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
   1122    inclusive.  These are offsets from the current stack pointer.  */
   1123 
   1124 static void
   1125 loongarch_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
   1126 {
   1127   /* See if we have a constant small number of probes to generate.  If so,
   1128      that's the easy case.  */
   1129   if ((TARGET_64BIT && (first + size <= 32768))
   1130       || (!TARGET_64BIT && (first + size <= 2048)))
   1131     {
   1132       HOST_WIDE_INT i;
   1133 
   1134       /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
   1135 	 it exceeds SIZE.  If only one probe is needed, this will not
   1136 	 generate any code.  Then probe at FIRST + SIZE.  */
   1137       for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
   1138 	emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
   1139 					 -(first + i)));
   1140 
   1141       emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
   1142 				       -(first + size)));
   1143     }
   1144 
   1145   /* Otherwise, do the same as above, but in a loop.  Note that we must be
   1146      extra careful with variables wrapping around because we might be at
   1147      the very top (or the very bottom) of the address space and we have
   1148      to be able to handle this case properly; in particular, we use an
   1149      equality test for the loop condition.  */
   1150   else
   1151     {
   1152       HOST_WIDE_INT rounded_size;
   1153       rtx r13 = LARCH_PROLOGUE_TEMP (Pmode);
   1154       rtx r12 = LARCH_PROLOGUE_TEMP2 (Pmode);
   1155       rtx r14 = LARCH_PROLOGUE_TEMP3 (Pmode);
   1156 
   1157       /* Sanity check for the addressing mode we're going to use.  */
   1158       gcc_assert (first <= 16384);
   1159 
   1160 
   1161       /* Step 1: round SIZE to the previous multiple of the interval.  */
   1162 
   1163       rounded_size = ROUND_DOWN (size, PROBE_INTERVAL);
   1164 
   1165       /* TEST_ADDR = SP + FIRST */
   1166       if (first != 0)
   1167 	{
   1168 	  emit_move_insn (r14, GEN_INT (first));
   1169 	  emit_insn (gen_rtx_SET (r13, gen_rtx_MINUS (Pmode,
   1170 						      stack_pointer_rtx,
   1171 						      r14)));
   1172 	}
   1173       else
   1174 	emit_move_insn (r13, stack_pointer_rtx);
   1175 
   1176       /* Step 2: compute initial and final value of the loop counter.  */
   1177 
   1178       emit_move_insn (r14, GEN_INT (PROBE_INTERVAL));
   1179       /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE.  */
   1180       if (rounded_size == 0)
   1181 	emit_move_insn (r12, r13);
   1182       else
   1183 	{
   1184 	  emit_move_insn (r12, GEN_INT (rounded_size));
   1185 	  emit_insn (gen_rtx_SET (r12, gen_rtx_MINUS (Pmode, r13, r12)));
   1186 	  /* Step 3: the loop
   1187 
   1188 	     do
   1189 	     {
   1190 	     TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
   1191 	     probe at TEST_ADDR
   1192 	     }
   1193 	     while (TEST_ADDR != LAST_ADDR)
   1194 
   1195 	     probes at FIRST + N * PROBE_INTERVAL for values of N from 1
   1196 	     until it is equal to ROUNDED_SIZE.  */
   1197 
   1198 	  emit_insn (gen_probe_stack_range (Pmode, r13, r13, r12, r14));
   1199 	}
   1200 
   1201       /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
   1202 	 that SIZE is equal to ROUNDED_SIZE.  */
   1203 
   1204       if (size != rounded_size)
   1205 	{
   1206 	  if (TARGET_64BIT)
   1207 	    emit_stack_probe (plus_constant (Pmode, r12, rounded_size - size));
   1208 	  else
   1209 	    {
   1210 	      HOST_WIDE_INT i;
   1211 	      for (i = 2048; i < (size - rounded_size); i += 2048)
   1212 		{
   1213 		  emit_stack_probe (plus_constant (Pmode, r12, -i));
   1214 		  emit_insn (gen_rtx_SET (r12,
   1215 					  plus_constant (Pmode, r12, -2048)));
   1216 		}
   1217 	      rtx r1 = plus_constant (Pmode, r12,
   1218 				      -(size - rounded_size - i + 2048));
   1219 	      emit_stack_probe (r1);
   1220 	    }
   1221 	}
   1222     }
   1223 
   1224   /* Make sure nothing is scheduled before we are done.  */
   1225   emit_insn (gen_blockage ());
   1226 }
   1227 
   1228 /* Probe a range of stack addresses from REG1 to REG2 inclusive.  These are
   1229    absolute addresses.  */
   1230 const char *
   1231 loongarch_output_probe_stack_range (rtx reg1, rtx reg2, rtx reg3)
   1232 {
   1233   static int labelno = 0;
   1234   char loop_lab[32], tmp[64];
   1235   rtx xops[3];
   1236 
   1237   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
   1238 
   1239   /* Loop.  */
   1240   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
   1241 
   1242   /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL.  */
   1243   xops[0] = reg1;
   1244   xops[1] = GEN_INT (-PROBE_INTERVAL);
   1245   xops[2] = reg3;
   1246   if (TARGET_64BIT)
   1247     output_asm_insn ("sub.d\t%0,%0,%2", xops);
   1248   else
   1249     output_asm_insn ("sub.w\t%0,%0,%2", xops);
   1250 
   1251   /* Probe at TEST_ADDR, test if TEST_ADDR == LAST_ADDR and branch.  */
   1252   xops[1] = reg2;
   1253   strcpy (tmp, "bne\t%0,%1,");
   1254   if (TARGET_64BIT)
   1255     output_asm_insn ("st.d\t$r0,%0,0", xops);
   1256   else
   1257     output_asm_insn ("st.w\t$r0,%0,0", xops);
   1258   output_asm_insn (strcat (tmp, &loop_lab[1]), xops);
   1259 
   1260   return "";
   1261 }
   1262 
   1263 /* Expand the "prologue" pattern.  */
   1264 
   1265 void
   1266 loongarch_expand_prologue (void)
   1267 {
   1268   struct loongarch_frame_info *frame = &cfun->machine->frame;
   1269   HOST_WIDE_INT size = frame->total_size;
   1270   HOST_WIDE_INT tmp;
   1271   rtx insn;
   1272 
   1273   if (flag_stack_usage_info)
   1274     current_function_static_stack_size = size;
   1275 
   1276   if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
   1277       || flag_stack_clash_protection)
   1278     {
   1279       if (crtl->is_leaf && !cfun->calls_alloca)
   1280 	{
   1281 	  if (size > PROBE_INTERVAL && size > get_stack_check_protect ())
   1282 	    {
   1283 	      tmp = size - get_stack_check_protect ();
   1284 	      loongarch_emit_probe_stack_range (get_stack_check_protect (),
   1285 						tmp);
   1286 	    }
   1287 	}
   1288       else if (size > 0)
   1289 	loongarch_emit_probe_stack_range (get_stack_check_protect (), size);
   1290     }
   1291 
   1292   /* Save the registers.  */
   1293   if ((frame->mask | frame->fmask) != 0)
   1294     {
   1295       HOST_WIDE_INT step1 = MIN (size, loongarch_first_stack_step (frame));
   1296 
   1297       insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
   1298 			    GEN_INT (-step1));
   1299       RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
   1300       size -= step1;
   1301       loongarch_for_each_saved_reg (size, loongarch_save_reg, false);
   1302     }
   1303 
   1304 
   1305   /* Set up the frame pointer, if we're using one.  */
   1306   if (frame_pointer_needed)
   1307     {
   1308       insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
   1309 			    GEN_INT (frame->hard_frame_pointer_offset - size));
   1310       RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
   1311 
   1312       loongarch_emit_stack_tie ();
   1313     }
   1314 
   1315   /* Allocate the rest of the frame.  */
   1316   if (size > 0)
   1317     {
   1318       if (IMM12_OPERAND (-size))
   1319 	{
   1320 	  insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
   1321 				GEN_INT (-size));
   1322 	  RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
   1323 	}
   1324       else
   1325 	{
   1326 	  loongarch_emit_move (LARCH_PROLOGUE_TEMP (Pmode), GEN_INT (-size));
   1327 	  emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
   1328 				    LARCH_PROLOGUE_TEMP (Pmode)));
   1329 
   1330 	  /* Describe the effect of the previous instructions.  */
   1331 	  insn = plus_constant (Pmode, stack_pointer_rtx, -size);
   1332 	  insn = gen_rtx_SET (stack_pointer_rtx, insn);
   1333 	  loongarch_set_frame_expr (insn);
   1334 	}
   1335     }
   1336 }
   1337 
   1338 /* Return nonzero if this function is known to have a null epilogue.
   1339    This allows the optimizer to omit jumps to jumps if no stack
   1340    was created.  */
   1341 
   1342 bool
   1343 loongarch_can_use_return_insn (void)
   1344 {
   1345   return reload_completed && cfun->machine->frame.total_size == 0;
   1346 }
   1347 
   1348 /* Expand function epilogue using the following insn patterns:
   1349    "epilogue"	      (style == NORMAL_RETURN)
   1350    "sibcall_epilogue" (style == SIBCALL_RETURN)
   1351    "eh_return"	      (style == EXCEPTION_RETURN) */
   1352 
   1353 void
   1354 loongarch_expand_epilogue (int style)
   1355 {
   1356   /* Split the frame into two.  STEP1 is the amount of stack we should
   1357      deallocate before restoring the registers.  STEP2 is the amount we
   1358      should deallocate afterwards.
   1359 
   1360      Start off by assuming that no registers need to be restored.  */
   1361   struct loongarch_frame_info *frame = &cfun->machine->frame;
   1362   HOST_WIDE_INT step1 = frame->total_size;
   1363   HOST_WIDE_INT step2 = 0;
   1364   rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
   1365   rtx insn;
   1366 
   1367   /* We need to add memory barrier to prevent read from deallocated stack.  */
   1368   bool need_barrier_p
   1369     = (get_frame_size () + cfun->machine->frame.arg_pointer_offset) != 0;
   1370 
   1371   /* Handle simple returns.  */
   1372   if (style == NORMAL_RETURN && loongarch_can_use_return_insn ())
   1373     {
   1374       emit_jump_insn (gen_return ());
   1375       return;
   1376     }
   1377 
   1378   /* Move past any dynamic stack allocations.  */
   1379   if (cfun->calls_alloca)
   1380     {
   1381       /* Emit a barrier to prevent loads from a deallocated stack.  */
   1382       loongarch_emit_stack_tie ();
   1383       need_barrier_p = false;
   1384 
   1385       rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset);
   1386       if (!IMM12_OPERAND (INTVAL (adjust)))
   1387 	{
   1388 	  loongarch_emit_move (LARCH_PROLOGUE_TEMP (Pmode), adjust);
   1389 	  adjust = LARCH_PROLOGUE_TEMP (Pmode);
   1390 	}
   1391 
   1392       insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
   1393 				       hard_frame_pointer_rtx,
   1394 				       adjust));
   1395 
   1396       rtx dwarf = NULL_RTX;
   1397       rtx minus_offset = GEN_INT (-frame->hard_frame_pointer_offset);
   1398       rtx cfa_adjust_value = gen_rtx_PLUS (Pmode,
   1399 					   hard_frame_pointer_rtx,
   1400 					   minus_offset);
   1401 
   1402       rtx cfa_adjust_rtx = gen_rtx_SET (stack_pointer_rtx, cfa_adjust_value);
   1403       dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, cfa_adjust_rtx, dwarf);
   1404       RTX_FRAME_RELATED_P (insn) = 1;
   1405 
   1406       REG_NOTES (insn) = dwarf;
   1407     }
   1408 
   1409   /* If we need to restore registers, deallocate as much stack as
   1410      possible in the second step without going out of range.  */
   1411   if ((frame->mask | frame->fmask) != 0)
   1412     {
   1413       step2 = loongarch_first_stack_step (frame);
   1414       step1 -= step2;
   1415     }
   1416 
   1417   /* Set TARGET to BASE + STEP1.  */
   1418   if (step1 > 0)
   1419     {
   1420       /* Emit a barrier to prevent loads from a deallocated stack.  */
   1421       loongarch_emit_stack_tie ();
   1422       need_barrier_p = false;
   1423 
   1424       /* Get an rtx for STEP1 that we can add to BASE.  */
   1425       rtx adjust = GEN_INT (step1);
   1426       if (!IMM12_OPERAND (step1))
   1427 	{
   1428 	  loongarch_emit_move (LARCH_PROLOGUE_TEMP (Pmode), adjust);
   1429 	  adjust = LARCH_PROLOGUE_TEMP (Pmode);
   1430 	}
   1431 
   1432       insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
   1433 				       stack_pointer_rtx,
   1434 				       adjust));
   1435 
   1436       rtx dwarf = NULL_RTX;
   1437       rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   1438 					 GEN_INT (step2));
   1439 
   1440       dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
   1441       RTX_FRAME_RELATED_P (insn) = 1;
   1442 
   1443       REG_NOTES (insn) = dwarf;
   1444     }
   1445 
   1446   /* Restore the registers.  */
   1447   loongarch_for_each_saved_reg (frame->total_size - step2,
   1448 				loongarch_restore_reg,
   1449 				crtl->calls_eh_return
   1450 				&& style != EXCEPTION_RETURN);
   1451 
   1452   if (need_barrier_p)
   1453     loongarch_emit_stack_tie ();
   1454 
   1455   /* Deallocate the final bit of the frame.  */
   1456   if (step2 > 0)
   1457     {
   1458       insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
   1459 				       stack_pointer_rtx,
   1460 				       GEN_INT (step2)));
   1461 
   1462       rtx dwarf = NULL_RTX;
   1463       rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx, const0_rtx);
   1464       dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
   1465       RTX_FRAME_RELATED_P (insn) = 1;
   1466 
   1467       REG_NOTES (insn) = dwarf;
   1468     }
   1469 
   1470   /* Add in the __builtin_eh_return stack adjustment.  */
   1471   if (crtl->calls_eh_return && style == EXCEPTION_RETURN)
   1472     emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
   1473 			      EH_RETURN_STACKADJ_RTX));
   1474 
   1475   /* Emit return unless doing sibcall.  */
   1476   if (style != SIBCALL_RETURN)
   1477     emit_jump_insn (gen_simple_return_internal (ra));
   1478 }
   1479 
   1480 #define LU32I_B (0xfffffULL << 32)
   1481 #define LU52I_B (0xfffULL << 52)
   1482 
   1483 /* Fill CODES with a sequence of rtl operations to load VALUE.
   1484    Return the number of operations needed.  */
   1485 
   1486 static unsigned int
   1487 loongarch_build_integer (struct loongarch_integer_op *codes,
   1488 			 HOST_WIDE_INT value)
   1489 
   1490 {
   1491   unsigned int cost = 0;
   1492 
   1493   /* Get the lower 32 bits of the value.  */
   1494   HOST_WIDE_INT low_part = (int32_t)value;
   1495 
   1496   if (IMM12_OPERAND (low_part) || IMM12_OPERAND_UNSIGNED (low_part))
   1497     {
   1498       /* The value of the lower 32 bit be loaded with one instruction.
   1499 	 lu12i.w.  */
   1500       codes[0].code = UNKNOWN;
   1501       codes[0].method = METHOD_NORMAL;
   1502       codes[0].value = low_part;
   1503       cost++;
   1504     }
   1505   else
   1506     {
   1507       /* lu12i.w + ior.  */
   1508       codes[0].code = UNKNOWN;
   1509       codes[0].method = METHOD_NORMAL;
   1510       codes[0].value = low_part & ~(IMM_REACH - 1);
   1511       cost++;
   1512       HOST_WIDE_INT iorv = low_part & (IMM_REACH - 1);
   1513       if (iorv != 0)
   1514 	{
   1515 	  codes[1].code = IOR;
   1516 	  codes[1].method = METHOD_NORMAL;
   1517 	  codes[1].value = iorv;
   1518 	  cost++;
   1519 	}
   1520     }
   1521 
   1522   if (TARGET_64BIT)
   1523     {
   1524       bool lu32i[2] = {(value & LU32I_B) == 0, (value & LU32I_B) == LU32I_B};
   1525       bool lu52i[2] = {(value & LU52I_B) == 0, (value & LU52I_B) == LU52I_B};
   1526 
   1527       int sign31 = (value & (HOST_WIDE_INT_1U << 31)) >> 31;
   1528       int sign51 = (value & (HOST_WIDE_INT_1U << 51)) >> 51;
   1529       /* Determine whether the upper 32 bits are sign-extended from the lower
   1530 	 32 bits. If it is, the instructions to load the high order can be
   1531 	 ommitted.  */
   1532       if (lu32i[sign31] && lu52i[sign31])
   1533 	return cost;
   1534       /* Determine whether bits 32-51 are sign-extended from the lower 32
   1535 	 bits. If so, directly load 52-63 bits.  */
   1536       else if (lu32i[sign31])
   1537 	{
   1538 	  codes[cost].method = METHOD_LU52I;
   1539 	  codes[cost].value = value & LU52I_B;
   1540 	  return cost + 1;
   1541 	}
   1542 
   1543       codes[cost].method = METHOD_LU32I;
   1544       codes[cost].value = (value & LU32I_B) | (sign51 ? LU52I_B : 0);
   1545       cost++;
   1546 
   1547       /* Determine whether the 52-61 bits are sign-extended from the low order,
   1548 	 and if not, load the 52-61 bits.  */
   1549       if (!lu52i[(value & (HOST_WIDE_INT_1U << 51)) >> 51])
   1550 	{
   1551 	  codes[cost].method = METHOD_LU52I;
   1552 	  codes[cost].value = value & LU52I_B;
   1553 	  cost++;
   1554 	}
   1555     }
   1556 
   1557   gcc_assert (cost <= LARCH_MAX_INTEGER_OPS);
   1558 
   1559   return cost;
   1560 }
   1561 
   1562 /* Fill CODES with a sequence of rtl operations to load VALUE.
   1563    Return the number of operations needed.
   1564    Split interger in loongarch_output_move.  */
   1565 
   1566 static unsigned int
   1567 loongarch_integer_cost (HOST_WIDE_INT value)
   1568 {
   1569   struct loongarch_integer_op codes[LARCH_MAX_INTEGER_OPS];
   1570   return loongarch_build_integer (codes, value);
   1571 }
   1572 
   1573 /* Implement TARGET_LEGITIMATE_CONSTANT_P.  */
   1574 
   1575 static bool
   1576 loongarch_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
   1577 {
   1578   return loongarch_const_insns (x) > 0;
   1579 }
   1580 
   1581 /* Return true if X is a thread-local symbol.  */
   1582 
   1583 static bool
   1584 loongarch_tls_symbol_p (rtx x)
   1585 {
   1586   return SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0;
   1587 }
   1588 
   1589 /* Return true if SYMBOL_REF X is associated with a global symbol
   1590    (in the STB_GLOBAL sense).  */
   1591 
   1592 bool
   1593 loongarch_global_symbol_p (const_rtx x)
   1594 {
   1595   if (LABEL_REF_P (x))
   1596     return false;
   1597 
   1598   const_tree decl = SYMBOL_REF_DECL (x);
   1599 
   1600   if (!decl)
   1601     return !SYMBOL_REF_LOCAL_P (x) || SYMBOL_REF_EXTERNAL_P (x);
   1602 
   1603   /* Weakref symbols are not TREE_PUBLIC, but their targets are global
   1604      or weak symbols.  Relocations in the object file will be against
   1605      the target symbol, so it's that symbol's binding that matters here.  */
   1606   return DECL_P (decl) && (TREE_PUBLIC (decl) || DECL_WEAK (decl));
   1607 }
   1608 
   1609 bool
   1610 loongarch_global_symbol_noweak_p (const_rtx x)
   1611 {
   1612   if (LABEL_REF_P (x))
   1613     return false;
   1614 
   1615   const_tree decl = SYMBOL_REF_DECL (x);
   1616 
   1617   if (!decl)
   1618     return !SYMBOL_REF_LOCAL_P (x) || SYMBOL_REF_EXTERNAL_P (x);
   1619 
   1620   return DECL_P (decl) && TREE_PUBLIC (decl);
   1621 }
   1622 
   1623 bool
   1624 loongarch_weak_symbol_p (const_rtx x)
   1625 {
   1626   const_tree decl;
   1627   if (LABEL_REF_P (x) || !(decl = SYMBOL_REF_DECL (x)))
   1628     return false;
   1629   return DECL_P (decl) && DECL_WEAK (decl);
   1630 }
   1631 
   1632 /* Return true if SYMBOL_REF X binds locally.  */
   1633 
   1634 bool
   1635 loongarch_symbol_binds_local_p (const_rtx x)
   1636 {
   1637   if (LABEL_REF_P (x))
   1638     return false;
   1639 
   1640   return (SYMBOL_REF_DECL (x) ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
   1641 			      : SYMBOL_REF_LOCAL_P (x));
   1642 }
   1643 
   1644 /* Return true if rtx constants of mode MODE should be put into a small
   1645    data section.  */
   1646 
   1647 static bool
   1648 loongarch_rtx_constant_in_small_data_p (machine_mode mode)
   1649 {
   1650   return (GET_MODE_SIZE (mode) <= g_switch_value);
   1651 }
   1652 
   1653 /* Return the method that should be used to access SYMBOL_REF or
   1654    LABEL_REF X.  */
   1655 
   1656 static enum loongarch_symbol_type
   1657 loongarch_classify_symbol (const_rtx x)
   1658 {
   1659   if (LABEL_REF_P (x))
   1660     return SYMBOL_GOT_DISP;
   1661 
   1662   gcc_assert (SYMBOL_REF_P (x));
   1663 
   1664   if (SYMBOL_REF_TLS_MODEL (x))
   1665     return SYMBOL_TLS;
   1666 
   1667   if (SYMBOL_REF_P (x))
   1668     return SYMBOL_GOT_DISP;
   1669 
   1670   return SYMBOL_GOT_DISP;
   1671 }
   1672 
   1673 /* Return true if X is a symbolic constant.  If it is,
   1674    store the type of the symbol in *SYMBOL_TYPE.  */
   1675 
   1676 bool
   1677 loongarch_symbolic_constant_p (rtx x, enum loongarch_symbol_type *symbol_type)
   1678 {
   1679   rtx offset;
   1680 
   1681   split_const (x, &x, &offset);
   1682   if (UNSPEC_ADDRESS_P (x))
   1683     {
   1684       *symbol_type = UNSPEC_ADDRESS_TYPE (x);
   1685       x = UNSPEC_ADDRESS (x);
   1686     }
   1687   else if (SYMBOL_REF_P (x) || LABEL_REF_P (x))
   1688     {
   1689       *symbol_type = loongarch_classify_symbol (x);
   1690       if (*symbol_type == SYMBOL_TLS)
   1691 	return true;
   1692     }
   1693   else
   1694     return false;
   1695 
   1696   if (offset == const0_rtx)
   1697     return true;
   1698 
   1699   /* Check whether a nonzero offset is valid for the underlying
   1700      relocations.  */
   1701   switch (*symbol_type)
   1702     {
   1703     case SYMBOL_GOT_DISP:
   1704     case SYMBOL_TLSGD:
   1705     case SYMBOL_TLSLDM:
   1706     case SYMBOL_TLS:
   1707       return false;
   1708     }
   1709   gcc_unreachable ();
   1710 }
   1711 
   1712 /* Returns the number of instructions necessary to reference a symbol.  */
   1713 
   1714 static int
   1715 loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode)
   1716 {
   1717   switch (type)
   1718     {
   1719     case SYMBOL_GOT_DISP:
   1720       /* The constant will have to be loaded from the GOT before it
   1721 	 is used in an address.  */
   1722       if (mode != MAX_MACHINE_MODE)
   1723 	return 0;
   1724 
   1725       return 3;
   1726 
   1727     case SYMBOL_TLSGD:
   1728     case SYMBOL_TLSLDM:
   1729       return 1;
   1730 
   1731     case SYMBOL_TLS:
   1732       /* We don't treat a bare TLS symbol as a constant.  */
   1733       return 0;
   1734     }
   1735   gcc_unreachable ();
   1736 }
   1737 
   1738 /* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */
   1739 
   1740 static bool
   1741 loongarch_cannot_force_const_mem (machine_mode mode, rtx x)
   1742 {
   1743   enum loongarch_symbol_type type;
   1744   rtx base, offset;
   1745 
   1746   /* As an optimization, reject constants that loongarch_legitimize_move
   1747      can expand inline.
   1748 
   1749      Suppose we have a multi-instruction sequence that loads constant C
   1750      into register R.  If R does not get allocated a hard register, and
   1751      R is used in an operand that allows both registers and memory
   1752      references, reload will consider forcing C into memory and using
   1753      one of the instruction's memory alternatives.  Returning false
   1754      here will force it to use an input reload instead.  */
   1755   if (CONST_INT_P (x) && loongarch_legitimate_constant_p (mode, x))
   1756     return true;
   1757 
   1758   split_const (x, &base, &offset);
   1759   if (loongarch_symbolic_constant_p (base, &type))
   1760     {
   1761       /* The same optimization as for CONST_INT.  */
   1762       if (IMM12_INT (offset)
   1763 	  && loongarch_symbol_insns (type, MAX_MACHINE_MODE) > 0)
   1764 	return true;
   1765     }
   1766 
   1767   /* TLS symbols must be computed by loongarch_legitimize_move.  */
   1768   if (tls_referenced_p (x))
   1769     return true;
   1770 
   1771   return false;
   1772 }
   1773 
   1774 /* Return true if register REGNO is a valid base register for mode MODE.
   1775    STRICT_P is true if REG_OK_STRICT is in effect.  */
   1776 
   1777 int
   1778 loongarch_regno_mode_ok_for_base_p (int regno,
   1779 				    machine_mode mode ATTRIBUTE_UNUSED,
   1780 				    bool strict_p)
   1781 {
   1782   if (!HARD_REGISTER_NUM_P (regno))
   1783     {
   1784       if (!strict_p)
   1785 	return true;
   1786       regno = reg_renumber[regno];
   1787     }
   1788 
   1789   /* These fake registers will be eliminated to either the stack or
   1790      hard frame pointer, both of which are usually valid base registers.
   1791      Reload deals with the cases where the eliminated form isn't valid.  */
   1792   if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
   1793     return true;
   1794 
   1795   return GP_REG_P (regno);
   1796 }
   1797 
   1798 /* Return true if X is a valid base register for mode MODE.
   1799    STRICT_P is true if REG_OK_STRICT is in effect.  */
   1800 
   1801 static bool
   1802 loongarch_valid_base_register_p (rtx x, machine_mode mode, bool strict_p)
   1803 {
   1804   if (!strict_p && SUBREG_P (x))
   1805     x = SUBREG_REG (x);
   1806 
   1807   return (REG_P (x)
   1808 	  && loongarch_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p));
   1809 }
   1810 
   1811 /* Return true if, for every base register BASE_REG, (plus BASE_REG X)
   1812    can address a value of mode MODE.  */
   1813 
   1814 static bool
   1815 loongarch_valid_offset_p (rtx x, machine_mode mode)
   1816 {
   1817   /* Check that X is a signed 12-bit number,
   1818      or check that X is a signed 16-bit number
   1819      and offset 4 byte aligned.  */
   1820   if (!(const_arith_operand (x, Pmode)
   1821 	|| ((mode == E_SImode || mode == E_DImode)
   1822 	    && const_imm16_operand (x, Pmode)
   1823 	    && (loongarch_signed_immediate_p (INTVAL (x), 14, 2)))))
   1824     return false;
   1825 
   1826   /* We may need to split multiword moves, so make sure that every word
   1827      is accessible.  */
   1828   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
   1829       && !IMM12_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
   1830     return false;
   1831 
   1832   return true;
   1833 }
   1834 
   1835 static bool
   1836 loongarch_valid_index_p (struct loongarch_address_info *info, rtx x,
   1837 			  machine_mode mode, bool strict_p)
   1838 {
   1839   rtx index;
   1840 
   1841   if ((REG_P (x) || SUBREG_P (x))
   1842       && GET_MODE (x) == Pmode)
   1843     {
   1844       index = x;
   1845     }
   1846   else
   1847     return false;
   1848 
   1849   if (!strict_p
   1850       && SUBREG_P (index)
   1851       && contains_reg_of_mode[GENERAL_REGS][GET_MODE (SUBREG_REG (index))])
   1852     index = SUBREG_REG (index);
   1853 
   1854   if (loongarch_valid_base_register_p (index, mode, strict_p))
   1855     {
   1856       info->type = ADDRESS_REG_REG;
   1857       info->offset = index;
   1858       return true;
   1859     }
   1860 
   1861   return false;
   1862 }
   1863 
   1864 /* Return true if X is a valid address for machine mode MODE.  If it is,
   1865    fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
   1866    effect.  */
   1867 
   1868 static bool
   1869 loongarch_classify_address (struct loongarch_address_info *info, rtx x,
   1870 			    machine_mode mode, bool strict_p)
   1871 {
   1872   switch (GET_CODE (x))
   1873     {
   1874     case REG:
   1875     case SUBREG:
   1876       info->type = ADDRESS_REG;
   1877       info->reg = x;
   1878       info->offset = const0_rtx;
   1879       return loongarch_valid_base_register_p (info->reg, mode, strict_p);
   1880 
   1881     case PLUS:
   1882       if (loongarch_valid_base_register_p (XEXP (x, 0), mode, strict_p)
   1883 	  && loongarch_valid_index_p (info, XEXP (x, 1), mode, strict_p))
   1884 	{
   1885 	  info->reg = XEXP (x, 0);
   1886 	  return true;
   1887 	}
   1888 
   1889       if (loongarch_valid_base_register_p (XEXP (x, 1), mode, strict_p)
   1890 	 && loongarch_valid_index_p (info, XEXP (x, 0), mode, strict_p))
   1891 	{
   1892 	  info->reg = XEXP (x, 1);
   1893 	  return true;
   1894 	}
   1895 
   1896       info->type = ADDRESS_REG;
   1897       info->reg = XEXP (x, 0);
   1898       info->offset = XEXP (x, 1);
   1899       return (loongarch_valid_base_register_p (info->reg, mode, strict_p)
   1900 	      && loongarch_valid_offset_p (info->offset, mode));
   1901     default:
   1902       return false;
   1903     }
   1904 }
   1905 
   1906 /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
   1907 
   1908 static bool
   1909 loongarch_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
   1910 {
   1911   struct loongarch_address_info addr;
   1912 
   1913   return loongarch_classify_address (&addr, x, mode, strict_p);
   1914 }
   1915 
   1916 /* Return true if ADDR matches the pattern for the indexed address
   1917    instruction.  */
   1918 
   1919 static bool
   1920 loongarch_index_address_p (rtx addr, machine_mode mode ATTRIBUTE_UNUSED)
   1921 {
   1922   if (GET_CODE (addr) != PLUS
   1923       || !REG_P (XEXP (addr, 0))
   1924       || !REG_P (XEXP (addr, 1)))
   1925     return false;
   1926   return true;
   1927 }
   1928 
   1929 /* Return the number of instructions needed to load or store a value
   1930    of mode MODE at address X.  Return 0 if X isn't valid for MODE.
   1931    Assume that multiword moves may need to be split into word moves
   1932    if MIGHT_SPLIT_P, otherwise assume that a single load or store is
   1933    enough.  */
   1934 
   1935 int
   1936 loongarch_address_insns (rtx x, machine_mode mode, bool might_split_p)
   1937 {
   1938   struct loongarch_address_info addr;
   1939   int factor;
   1940 
   1941   if (!loongarch_classify_address (&addr, x, mode, false))
   1942     return 0;
   1943 
   1944   /* BLKmode is used for single unaligned loads and stores and should
   1945      not count as a multiword mode.  (GET_MODE_SIZE (BLKmode) is pretty
   1946      meaningless, so we have to single it out as a special case one way
   1947      or the other.)  */
   1948   if (mode != BLKmode && might_split_p)
   1949     factor = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
   1950   else
   1951     factor = 1;
   1952 
   1953   if (loongarch_classify_address (&addr, x, mode, false))
   1954     switch (addr.type)
   1955       {
   1956       case ADDRESS_REG:
   1957 	return factor;
   1958 
   1959       case ADDRESS_REG_REG:
   1960 	return factor;
   1961 
   1962       case ADDRESS_CONST_INT:
   1963 	return factor;
   1964 
   1965       case ADDRESS_SYMBOLIC:
   1966 	return factor * loongarch_symbol_insns (addr.symbol_type, mode);
   1967       }
   1968   return 0;
   1969 }
   1970 
   1971 /* Return true if X fits within an unsigned field of BITS bits that is
   1972    shifted left SHIFT bits before being used.  */
   1973 
   1974 bool
   1975 loongarch_unsigned_immediate_p (unsigned HOST_WIDE_INT x, int bits,
   1976 				int shift = 0)
   1977 {
   1978   return (x & ((1 << shift) - 1)) == 0 && x < ((unsigned) 1 << (shift + bits));
   1979 }
   1980 
   1981 /* Return true if X fits within a signed field of BITS bits that is
   1982    shifted left SHIFT bits before being used.  */
   1983 
   1984 bool
   1985 loongarch_signed_immediate_p (unsigned HOST_WIDE_INT x, int bits,
   1986 			      int shift = 0)
   1987 {
   1988   x += 1 << (bits + shift - 1);
   1989   return loongarch_unsigned_immediate_p (x, bits, shift);
   1990 }
   1991 
   1992 /* Return true if X is a legitimate address with a 12-bit offset.
   1993    MODE is the mode of the value being accessed.  */
   1994 
   1995 bool
   1996 loongarch_12bit_offset_address_p (rtx x, machine_mode mode)
   1997 {
   1998   struct loongarch_address_info addr;
   1999 
   2000   return (loongarch_classify_address (&addr, x, mode, false)
   2001 	  && addr.type == ADDRESS_REG
   2002 	  && CONST_INT_P (addr.offset)
   2003 	  && LARCH_U12BIT_OFFSET_P (INTVAL (addr.offset)));
   2004 }
   2005 
   2006 /* Return true if X is a legitimate address with a 14-bit offset shifted 2.
   2007    MODE is the mode of the value being accessed.  */
   2008 
   2009 bool
   2010 loongarch_14bit_shifted_offset_address_p (rtx x, machine_mode mode)
   2011 {
   2012   struct loongarch_address_info addr;
   2013 
   2014   return (loongarch_classify_address (&addr, x, mode, false)
   2015 	  && addr.type == ADDRESS_REG
   2016 	  && CONST_INT_P (addr.offset)
   2017 	  && LARCH_16BIT_OFFSET_P (INTVAL (addr.offset))
   2018 	  && LARCH_SHIFT_2_OFFSET_P (INTVAL (addr.offset)));
   2019 }
   2020 
   2021 bool
   2022 loongarch_base_index_address_p (rtx x, machine_mode mode)
   2023 {
   2024   struct loongarch_address_info addr;
   2025 
   2026   return (loongarch_classify_address (&addr, x, mode, false)
   2027 	  && addr.type == ADDRESS_REG_REG
   2028 	  && REG_P (addr.offset));
   2029 }
   2030 
   2031 /* Return the number of instructions needed to load constant X,
   2032    Return 0 if X isn't a valid constant.  */
   2033 
   2034 int
   2035 loongarch_const_insns (rtx x)
   2036 {
   2037   enum loongarch_symbol_type symbol_type;
   2038   rtx offset;
   2039 
   2040   switch (GET_CODE (x))
   2041     {
   2042     case CONST_INT:
   2043       return loongarch_integer_cost (INTVAL (x));
   2044 
   2045     case CONST_VECTOR:
   2046       /* Fall through.  */
   2047     case CONST_DOUBLE:
   2048       return x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;
   2049 
   2050     case CONST:
   2051       /* See if we can refer to X directly.  */
   2052       if (loongarch_symbolic_constant_p (x, &symbol_type))
   2053 	return loongarch_symbol_insns (symbol_type, MAX_MACHINE_MODE);
   2054 
   2055       /* Otherwise try splitting the constant into a base and offset.
   2056 	 If the offset is a 12-bit value, we can load the base address
   2057 	 into a register and then use ADDI.{W/D} to add in the offset.
   2058 	 If the offset is larger, we can load the base and offset
   2059 	 into separate registers and add them together with ADD.{W/D}.
   2060 	 However, the latter is only possible before reload; during
   2061 	 and after reload, we must have the option of forcing the
   2062 	 constant into the pool instead.  */
   2063       split_const (x, &x, &offset);
   2064       if (offset != 0)
   2065 	{
   2066 	  int n = loongarch_const_insns (x);
   2067 	  if (n != 0)
   2068 	    {
   2069 	      if (IMM12_INT (offset))
   2070 		return n + 1;
   2071 	      else if (!targetm.cannot_force_const_mem (GET_MODE (x), x))
   2072 		return n + 1 + loongarch_integer_cost (INTVAL (offset));
   2073 	    }
   2074 	}
   2075       return 0;
   2076 
   2077     case SYMBOL_REF:
   2078     case LABEL_REF:
   2079       return loongarch_symbol_insns (
   2080 	loongarch_classify_symbol (x), MAX_MACHINE_MODE);
   2081 
   2082     default:
   2083       return 0;
   2084     }
   2085 }
   2086 
   2087 /* X is a doubleword constant that can be handled by splitting it into
   2088    two words and loading each word separately.  Return the number of
   2089    instructions required to do this.  */
   2090 
   2091 int
   2092 loongarch_split_const_insns (rtx x)
   2093 {
   2094   unsigned int low, high;
   2095 
   2096   low = loongarch_const_insns (loongarch_subword (x, false));
   2097   high = loongarch_const_insns (loongarch_subword (x, true));
   2098   gcc_assert (low > 0 && high > 0);
   2099   return low + high;
   2100 }
   2101 
   2102 /* Return the number of instructions needed to implement INSN,
   2103    given that it loads from or stores to MEM.  */
   2104 
   2105 int
   2106 loongarch_load_store_insns (rtx mem, rtx_insn *insn)
   2107 {
   2108   machine_mode mode;
   2109   bool might_split_p;
   2110   rtx set;
   2111 
   2112   gcc_assert (MEM_P (mem));
   2113   mode = GET_MODE (mem);
   2114 
   2115   /* Try to prove that INSN does not need to be split.  */
   2116   might_split_p = GET_MODE_SIZE (mode) > UNITS_PER_WORD;
   2117   if (might_split_p)
   2118     {
   2119       set = single_set (insn);
   2120       if (set
   2121 	  && !loongarch_split_move_insn_p (SET_DEST (set), SET_SRC (set)))
   2122 	might_split_p = false;
   2123     }
   2124 
   2125   return loongarch_address_insns (XEXP (mem, 0), mode, might_split_p);
   2126 }
   2127 
   2128 /* Return true if we need to trap on division by zero.  */
   2129 
   2130 static bool
   2131 loongarch_check_zero_div_p (void)
   2132 {
   2133   /* if -m[no-]check-zero-division is given explicitly.  */
   2134   if (target_flags_explicit & MASK_CHECK_ZERO_DIV)
   2135     return TARGET_CHECK_ZERO_DIV;
   2136 
   2137   /* if not, don't trap for optimized code except -Og.  */
   2138   return !optimize || optimize_debug;
   2139 }
   2140 
   2141 /* Return the number of instructions needed for an integer division.  */
   2142 
   2143 int
   2144 loongarch_idiv_insns (machine_mode mode ATTRIBUTE_UNUSED)
   2145 {
   2146   int count;
   2147 
   2148   count = 1;
   2149   if (loongarch_check_zero_div_p ())
   2150     count += 2;
   2151 
   2152   return count;
   2153 }
   2154 
   2155 /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)).  */
   2156 
   2157 void
   2158 loongarch_emit_binary (enum rtx_code code, rtx target, rtx op0, rtx op1)
   2159 {
   2160   emit_insn (gen_rtx_SET (target, gen_rtx_fmt_ee (code, GET_MODE (target),
   2161 						  op0, op1)));
   2162 }
   2163 
   2164 /* Compute (CODE OP0 OP1) and store the result in a new register
   2165    of mode MODE.  Return that new register.  */
   2166 
   2167 static rtx
   2168 loongarch_force_binary (machine_mode mode, enum rtx_code code, rtx op0,
   2169 			rtx op1)
   2170 {
   2171   rtx reg;
   2172 
   2173   reg = gen_reg_rtx (mode);
   2174   loongarch_emit_binary (code, reg, op0, op1);
   2175   return reg;
   2176 }
   2177 
   2178 /* Copy VALUE to a register and return that register.  If new pseudos
   2179    are allowed, copy it into a new register, otherwise use DEST.  */
   2180 
   2181 static rtx
   2182 loongarch_force_temporary (rtx dest, rtx value)
   2183 {
   2184   if (can_create_pseudo_p ())
   2185     return force_reg (Pmode, value);
   2186   else
   2187     {
   2188       loongarch_emit_move (dest, value);
   2189       return dest;
   2190     }
   2191 }
   2192 
   2193 /* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
   2194    then add CONST_INT OFFSET to the result.  */
   2195 
   2196 static rtx
   2197 loongarch_unspec_address_offset (rtx base, rtx offset,
   2198 				 enum loongarch_symbol_type symbol_type)
   2199 {
   2200   base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
   2201 			 UNSPEC_ADDRESS_FIRST + symbol_type);
   2202   if (offset != const0_rtx)
   2203     base = gen_rtx_PLUS (Pmode, base, offset);
   2204   return gen_rtx_CONST (Pmode, base);
   2205 }
   2206 
   2207 /* Return an UNSPEC address with underlying address ADDRESS and symbol
   2208    type SYMBOL_TYPE.  */
   2209 
   2210 rtx
   2211 loongarch_unspec_address (rtx address, enum loongarch_symbol_type symbol_type)
   2212 {
   2213   rtx base, offset;
   2214 
   2215   split_const (address, &base, &offset);
   2216   return loongarch_unspec_address_offset (base, offset, symbol_type);
   2217 }
   2218 
   2219 /* If OP is an UNSPEC address, return the address to which it refers,
   2220    otherwise return OP itself.  */
   2221 
   2222 rtx
   2223 loongarch_strip_unspec_address (rtx op)
   2224 {
   2225   rtx base, offset;
   2226 
   2227   split_const (op, &base, &offset);
   2228   if (UNSPEC_ADDRESS_P (base))
   2229     op = plus_constant (Pmode, UNSPEC_ADDRESS (base), INTVAL (offset));
   2230   return op;
   2231 }
   2232 
   2233 /* Return a legitimate address for REG + OFFSET.  TEMP is as for
   2234    loongarch_force_temporary; it is only needed when OFFSET is not a
   2235    IMM12_OPERAND.  */
   2236 
   2237 static rtx
   2238 loongarch_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
   2239 {
   2240   if (!IMM12_OPERAND (offset))
   2241     {
   2242       rtx high;
   2243 
   2244       /* Leave OFFSET as a 12-bit offset and put the excess in HIGH.
   2245 	 The addition inside the macro CONST_HIGH_PART may cause an
   2246 	 overflow, so we need to force a sign-extension check.  */
   2247       high = gen_int_mode (CONST_HIGH_PART (offset), Pmode);
   2248       offset = CONST_LOW_PART (offset);
   2249       high = loongarch_force_temporary (temp, high);
   2250       reg = loongarch_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg));
   2251     }
   2252   return plus_constant (Pmode, reg, offset);
   2253 }
   2254 
   2255 /* The __tls_get_attr symbol.  */
   2256 static GTY (()) rtx loongarch_tls_symbol;
   2257 
   2258 /* Load an entry from the GOT for a TLS GD access.  */
   2259 
   2260 static rtx
   2261 loongarch_got_load_tls_gd (rtx dest, rtx sym)
   2262 {
   2263   return gen_got_load_tls_gd (Pmode, dest, sym);
   2264 }
   2265 
   2266 /* Load an entry from the GOT for a TLS LD access.  */
   2267 
   2268 static rtx
   2269 loongarch_got_load_tls_ld (rtx dest, rtx sym)
   2270 {
   2271   return gen_got_load_tls_ld (Pmode, dest, sym);
   2272 }
   2273 
   2274 /* Load an entry from the GOT for a TLS IE access.  */
   2275 
   2276 static rtx
   2277 loongarch_got_load_tls_ie (rtx dest, rtx sym)
   2278 {
   2279   return gen_got_load_tls_ie (Pmode, dest, sym);
   2280 }
   2281 
   2282 /* Add in the thread pointer for a TLS LE access.  */
   2283 
   2284 static rtx
   2285 loongarch_got_load_tls_le (rtx dest, rtx sym)
   2286 {
   2287   return gen_got_load_tls_le (Pmode, dest, sym);
   2288 }
   2289 
   2290 /* Return an instruction sequence that calls __tls_get_addr.  SYM is
   2291    the TLS symbol we are referencing and TYPE is the symbol type to use
   2292    (either global dynamic or local dynamic).  V0 is an RTX for the
   2293    return value location.  */
   2294 
   2295 static rtx_insn *
   2296 loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
   2297 {
   2298   rtx loc, a0;
   2299   rtx_insn *insn;
   2300 
   2301   a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
   2302 
   2303   if (!loongarch_tls_symbol)
   2304     loongarch_tls_symbol = init_one_libfunc ("__tls_get_addr");
   2305 
   2306   loc = loongarch_unspec_address (sym, type);
   2307 
   2308   start_sequence ();
   2309 
   2310   if (type == SYMBOL_TLSLDM)
   2311     emit_insn (loongarch_got_load_tls_ld (a0, loc));
   2312   else if (type == SYMBOL_TLSGD)
   2313     emit_insn (loongarch_got_load_tls_gd (a0, loc));
   2314   else
   2315     gcc_unreachable ();
   2316 
   2317   insn = emit_call_insn (gen_call_value_internal (v0, loongarch_tls_symbol,
   2318 						  const0_rtx));
   2319   RTL_CONST_CALL_P (insn) = 1;
   2320   use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
   2321   insn = get_insns ();
   2322 
   2323   end_sequence ();
   2324 
   2325   return insn;
   2326 }
   2327 
   2328 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
   2329    its address.  The return value will be both a valid address and a valid
   2330    SET_SRC (either a REG or a LO_SUM).  */
   2331 
   2332 static rtx
   2333 loongarch_legitimize_tls_address (rtx loc)
   2334 {
   2335   rtx dest, tp, tmp;
   2336   enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
   2337   rtx_insn *insn;
   2338 
   2339   switch (model)
   2340     {
   2341     case TLS_MODEL_LOCAL_DYNAMIC:
   2342       tmp = gen_rtx_REG (Pmode, GP_RETURN);
   2343       dest = gen_reg_rtx (Pmode);
   2344       insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSLDM, tmp);
   2345       emit_libcall_block (insn, dest, tmp, loc);
   2346       break;
   2347 
   2348     case TLS_MODEL_GLOBAL_DYNAMIC:
   2349       tmp = gen_rtx_REG (Pmode, GP_RETURN);
   2350       dest = gen_reg_rtx (Pmode);
   2351       insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSGD, tmp);
   2352       emit_libcall_block (insn, dest, tmp, loc);
   2353       break;
   2354 
   2355     case TLS_MODEL_INITIAL_EXEC:
   2356       /* la.tls.ie; tp-relative add  */
   2357       tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
   2358       tmp = gen_reg_rtx (Pmode);
   2359       emit_insn (loongarch_got_load_tls_ie (tmp, loc));
   2360       dest = gen_reg_rtx (Pmode);
   2361       emit_insn (gen_add3_insn (dest, tmp, tp));
   2362       break;
   2363 
   2364     case TLS_MODEL_LOCAL_EXEC:
   2365       /* la.tls.le; tp-relative add  */
   2366       tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
   2367       tmp = gen_reg_rtx (Pmode);
   2368       emit_insn (loongarch_got_load_tls_le (tmp, loc));
   2369       dest = gen_reg_rtx (Pmode);
   2370       emit_insn (gen_add3_insn (dest, tmp, tp));
   2371       break;
   2372 
   2373     default:
   2374       gcc_unreachable ();
   2375     }
   2376   return dest;
   2377 }
   2378 
   2379 rtx
   2380 loongarch_legitimize_call_address (rtx addr)
   2381 {
   2382   if (!call_insn_operand (addr, VOIDmode))
   2383     {
   2384       rtx reg = gen_reg_rtx (Pmode);
   2385       loongarch_emit_move (reg, addr);
   2386       return reg;
   2387     }
   2388   return addr;
   2389 }
   2390 
   2391 /* If X is a PLUS of a CONST_INT, return the two terms in *BASE_PTR
   2392    and *OFFSET_PTR.  Return X in *BASE_PTR and 0 in *OFFSET_PTR otherwise.  */
   2393 
   2394 static void
   2395 loongarch_split_plus (rtx x, rtx *base_ptr, HOST_WIDE_INT *offset_ptr)
   2396 {
   2397   if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
   2398     {
   2399       *base_ptr = XEXP (x, 0);
   2400       *offset_ptr = INTVAL (XEXP (x, 1));
   2401     }
   2402   else
   2403     {
   2404       *base_ptr = x;
   2405       *offset_ptr = 0;
   2406     }
   2407 }
   2408 
   2409 /* If X is not a valid address for mode MODE, force it into a register.  */
   2410 
   2411 static rtx
   2412 loongarch_force_address (rtx x, machine_mode mode)
   2413 {
   2414   if (!loongarch_legitimate_address_p (mode, x, false))
   2415     x = force_reg (Pmode, x);
   2416   return x;
   2417 }
   2418 
   2419 /* This function is used to implement LEGITIMIZE_ADDRESS.  If X can
   2420    be legitimized in a way that the generic machinery might not expect,
   2421    return a new address, otherwise return NULL.  MODE is the mode of
   2422    the memory being accessed.  */
   2423 
   2424 static rtx
   2425 loongarch_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
   2426 			      machine_mode mode)
   2427 {
   2428   rtx base, addr;
   2429   HOST_WIDE_INT offset;
   2430 
   2431   if (loongarch_tls_symbol_p (x))
   2432     return loongarch_legitimize_tls_address (x);
   2433 
   2434   /* Handle BASE + OFFSET using loongarch_add_offset.  */
   2435   loongarch_split_plus (x, &base, &offset);
   2436   if (offset != 0)
   2437     {
   2438       if (!loongarch_valid_base_register_p (base, mode, false))
   2439 	base = copy_to_mode_reg (Pmode, base);
   2440       addr = loongarch_add_offset (NULL, base, offset);
   2441       return loongarch_force_address (addr, mode);
   2442     }
   2443 
   2444   return x;
   2445 }
   2446 
   2447 /* Load VALUE into DEST.  TEMP is as for loongarch_force_temporary.  */
   2448 
   2449 void
   2450 loongarch_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value)
   2451 {
   2452   struct loongarch_integer_op codes[LARCH_MAX_INTEGER_OPS];
   2453   machine_mode mode;
   2454   unsigned int i, num_ops;
   2455   rtx x;
   2456 
   2457   mode = GET_MODE (dest);
   2458   num_ops = loongarch_build_integer (codes, value);
   2459 
   2460   /* Apply each binary operation to X.  Invariant: X is a legitimate
   2461      source operand for a SET pattern.  */
   2462   x = GEN_INT (codes[0].value);
   2463   for (i = 1; i < num_ops; i++)
   2464     {
   2465       if (!can_create_pseudo_p ())
   2466 	{
   2467 	  emit_insn (gen_rtx_SET (temp, x));
   2468 	  x = temp;
   2469 	}
   2470       else
   2471 	x = force_reg (mode, x);
   2472 
   2473       switch (codes[i].method)
   2474 	{
   2475 	case METHOD_NORMAL:
   2476 	  x = gen_rtx_fmt_ee (codes[i].code, mode, x,
   2477 			      GEN_INT (codes[i].value));
   2478 	  break;
   2479 	case METHOD_LU32I:
   2480 	  emit_insn (
   2481 	    gen_rtx_SET (x,
   2482 			 gen_rtx_IOR (DImode,
   2483 				      gen_rtx_ZERO_EXTEND (
   2484 					DImode, gen_rtx_SUBREG (SImode, x, 0)),
   2485 				      GEN_INT (codes[i].value))));
   2486 	  break;
   2487 	case METHOD_LU52I:
   2488 	  emit_insn (gen_lu52i_d (x, x, GEN_INT (0xfffffffffffff),
   2489 				  GEN_INT (codes[i].value)));
   2490 	  break;
   2491 	case METHOD_INSV:
   2492 	  emit_insn (
   2493 	    gen_rtx_SET (gen_rtx_ZERO_EXTRACT (DImode, x, GEN_INT (20),
   2494 					       GEN_INT (32)),
   2495 			 gen_rtx_REG (DImode, 0)));
   2496 	  break;
   2497 	default:
   2498 	  gcc_unreachable ();
   2499 	}
   2500     }
   2501 
   2502   emit_insn (gen_rtx_SET (dest, x));
   2503 }
   2504 
   2505 /* Subroutine of loongarch_legitimize_move.  Move constant SRC into register
   2506    DEST given that SRC satisfies immediate_operand but doesn't satisfy
   2507    move_operand.  */
   2508 
   2509 static void
   2510 loongarch_legitimize_const_move (machine_mode mode, rtx dest, rtx src)
   2511 {
   2512   rtx base, offset;
   2513 
   2514   /* Split moves of big integers into smaller pieces.  */
   2515   if (splittable_const_int_operand (src, mode))
   2516     {
   2517       loongarch_move_integer (dest, dest, INTVAL (src));
   2518       return;
   2519     }
   2520 
   2521   /* Generate the appropriate access sequences for TLS symbols.  */
   2522   if (loongarch_tls_symbol_p (src))
   2523     {
   2524       loongarch_emit_move (dest, loongarch_legitimize_tls_address (src));
   2525       return;
   2526     }
   2527 
   2528   /* If we have (const (plus symbol offset)), and that expression cannot
   2529      be forced into memory, load the symbol first and add in the offset.
   2530      prefer to do this even if the constant _can_ be forced into memory,
   2531      as it usually produces better code.  */
   2532   split_const (src, &base, &offset);
   2533   if (offset != const0_rtx
   2534       && (targetm.cannot_force_const_mem (mode, src)
   2535 	  || (can_create_pseudo_p ())))
   2536     {
   2537       base = loongarch_force_temporary (dest, base);
   2538       loongarch_emit_move (dest,
   2539 			   loongarch_add_offset (NULL, base, INTVAL (offset)));
   2540       return;
   2541     }
   2542 
   2543   src = force_const_mem (mode, src);
   2544 
   2545   loongarch_emit_move (dest, src);
   2546 }
   2547 
   2548 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
   2549    sequence that is valid.  */
   2550 
   2551 bool
   2552 loongarch_legitimize_move (machine_mode mode, rtx dest, rtx src)
   2553 {
   2554   if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
   2555     {
   2556       loongarch_emit_move (dest, force_reg (mode, src));
   2557       return true;
   2558     }
   2559 
   2560   /* Both src and dest are non-registers;  one special case is supported where
   2561      the source is (const_int 0) and the store can source the zero register.
   2562      */
   2563   if (!register_operand (dest, mode) && !register_operand (src, mode)
   2564       && !const_0_operand (src, mode))
   2565     {
   2566       loongarch_emit_move (dest, force_reg (mode, src));
   2567       return true;
   2568     }
   2569 
   2570   /* We need to deal with constants that would be legitimate
   2571      immediate_operands but aren't legitimate move_operands.  */
   2572   if (CONSTANT_P (src) && !move_operand (src, mode))
   2573     {
   2574       loongarch_legitimize_const_move (mode, dest, src);
   2575       set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
   2576       return true;
   2577     }
   2578 
   2579   return false;
   2580 }
   2581 
   2582 /* Return true if OP refers to small data symbols directly.  */
   2583 
   2584 static int
   2585 loongarch_small_data_pattern_1 (rtx x)
   2586 {
   2587   subrtx_var_iterator::array_type array;
   2588   FOR_EACH_SUBRTX_VAR (iter, array, x, ALL)
   2589     {
   2590       rtx x = *iter;
   2591 
   2592       /* We make no particular guarantee about which symbolic constants are
   2593 	 acceptable as asm operands versus which must be forced into a GPR.  */
   2594       if (GET_CODE (x) == ASM_OPERANDS)
   2595 	iter.skip_subrtxes ();
   2596       else if (MEM_P (x))
   2597 	{
   2598 	  if (loongarch_small_data_pattern_1 (XEXP (x, 0)))
   2599 	    return true;
   2600 	  iter.skip_subrtxes ();
   2601 	}
   2602     }
   2603   return false;
   2604 }
   2605 
   2606 /* Return true if OP refers to small data symbols directly.  */
   2607 
   2608 bool
   2609 loongarch_small_data_pattern_p (rtx op)
   2610 {
   2611   return loongarch_small_data_pattern_1 (op);
   2612 }
   2613 
   2614 /* Rewrite *LOC so that it refers to small data using explicit
   2615    relocations.  */
   2616 
   2617 static void
   2618 loongarch_rewrite_small_data_1 (rtx *loc)
   2619 {
   2620   subrtx_ptr_iterator::array_type array;
   2621   FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
   2622     {
   2623       rtx *loc = *iter;
   2624       if (MEM_P (*loc))
   2625 	{
   2626 	  loongarch_rewrite_small_data_1 (&XEXP (*loc, 0));
   2627 	  iter.skip_subrtxes ();
   2628 	}
   2629     }
   2630 }
   2631 
   2632 /* Rewrite instruction pattern PATTERN so that it refers to small data
   2633    using explicit relocations.  */
   2634 
   2635 rtx
   2636 loongarch_rewrite_small_data (rtx pattern)
   2637 {
   2638   pattern = copy_insn (pattern);
   2639   loongarch_rewrite_small_data_1 (&pattern);
   2640   return pattern;
   2641 }
   2642 
   2643 /* The cost of loading values from the constant pool.  It should be
   2644    larger than the cost of any constant we want to synthesize inline.  */
   2645 #define CONSTANT_POOL_COST COSTS_N_INSNS (8)
   2646 
   2647 /* Return true if there is a instruction that implements CODE
   2648    and if that instruction accepts X as an immediate operand.  */
   2649 
   2650 static int
   2651 loongarch_immediate_operand_p (int code, HOST_WIDE_INT x)
   2652 {
   2653   switch (code)
   2654     {
   2655     case ASHIFT:
   2656     case ASHIFTRT:
   2657     case LSHIFTRT:
   2658       /* All shift counts are truncated to a valid constant.  */
   2659       return true;
   2660 
   2661     case ROTATE:
   2662     case ROTATERT:
   2663       return true;
   2664 
   2665     case AND:
   2666     case IOR:
   2667     case XOR:
   2668       /* These instructions take 12-bit unsigned immediates.  */
   2669       return IMM12_OPERAND_UNSIGNED (x);
   2670 
   2671     case PLUS:
   2672     case LT:
   2673     case LTU:
   2674       /* These instructions take 12-bit signed immediates.  */
   2675       return IMM12_OPERAND (x);
   2676 
   2677     case EQ:
   2678     case NE:
   2679     case GT:
   2680     case GTU:
   2681       /* The "immediate" forms of these instructions are really
   2682 	 implemented as comparisons with register 0.  */
   2683       return x == 0;
   2684 
   2685     case GE:
   2686     case GEU:
   2687       /* Likewise, meaning that the only valid immediate operand is 1.  */
   2688       return x == 1;
   2689 
   2690     case LE:
   2691       /* We add 1 to the immediate and use SLT.  */
   2692       return IMM12_OPERAND (x + 1);
   2693 
   2694     case LEU:
   2695       /* Likewise SLTU, but reject the always-true case.  */
   2696       return IMM12_OPERAND (x + 1) && x + 1 != 0;
   2697 
   2698     case SIGN_EXTRACT:
   2699     case ZERO_EXTRACT:
   2700       /* The bit position and size are immediate operands.  */
   2701       return 1;
   2702 
   2703     default:
   2704       /* By default assume that $0 can be used for 0.  */
   2705       return x == 0;
   2706     }
   2707 }
   2708 
   2709 /* Return the cost of binary operation X, given that the instruction
   2710    sequence for a word-sized or smaller operation has cost SINGLE_COST
   2711    and that the sequence of a double-word operation has cost DOUBLE_COST.
   2712    If SPEED is true, optimize for speed otherwise optimize for size.  */
   2713 
   2714 static int
   2715 loongarch_binary_cost (rtx x, int single_cost, int double_cost, bool speed)
   2716 {
   2717   int cost;
   2718 
   2719   if (GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD * 2)
   2720     cost = double_cost;
   2721   else
   2722     cost = single_cost;
   2723   return (cost
   2724 	  + set_src_cost (XEXP (x, 0), GET_MODE (x), speed)
   2725 	  + rtx_cost (XEXP (x, 1), GET_MODE (x), GET_CODE (x), 1, speed));
   2726 }
   2727 
   2728 /* Return the cost of floating-point multiplications of mode MODE.  */
   2729 
   2730 static int
   2731 loongarch_fp_mult_cost (machine_mode mode)
   2732 {
   2733   return mode == DFmode ? loongarch_cost->fp_mult_df
   2734 			: loongarch_cost->fp_mult_sf;
   2735 }
   2736 
   2737 /* Return the cost of floating-point divisions of mode MODE.  */
   2738 
   2739 static int
   2740 loongarch_fp_div_cost (machine_mode mode)
   2741 {
   2742   return mode == DFmode ? loongarch_cost->fp_div_df
   2743 			: loongarch_cost->fp_div_sf;
   2744 }
   2745 
   2746 /* Return the cost of sign-extending OP to mode MODE, not including the
   2747    cost of OP itself.  */
   2748 
   2749 static int
   2750 loongarch_sign_extend_cost (rtx op)
   2751 {
   2752   if (MEM_P (op))
   2753     /* Extended loads are as cheap as unextended ones.  */
   2754     return 0;
   2755 
   2756   return COSTS_N_INSNS (1);
   2757 }
   2758 
   2759 /* Return the cost of zero-extending OP to mode MODE, not including the
   2760    cost of OP itself.  */
   2761 
   2762 static int
   2763 loongarch_zero_extend_cost (rtx op)
   2764 {
   2765   if (MEM_P (op))
   2766     /* Extended loads are as cheap as unextended ones.  */
   2767     return 0;
   2768 
   2769   /* We can use ANDI.  */
   2770   return COSTS_N_INSNS (1);
   2771 }
   2772 
   2773 /* Return the cost of moving between two registers of mode MODE,
   2774    assuming that the move will be in pieces of at most UNITS bytes.  */
   2775 
   2776 static int
   2777 loongarch_set_reg_reg_piece_cost (machine_mode mode, unsigned int units)
   2778 {
   2779   return COSTS_N_INSNS ((GET_MODE_SIZE (mode) + units - 1) / units);
   2780 }
   2781 
   2782 /* Return the cost of moving between two registers of mode MODE.  */
   2783 
   2784 static int
   2785 loongarch_set_reg_reg_cost (machine_mode mode)
   2786 {
   2787   switch (GET_MODE_CLASS (mode))
   2788     {
   2789     case MODE_CC:
   2790       return loongarch_set_reg_reg_piece_cost (mode, GET_MODE_SIZE (CCmode));
   2791 
   2792     case MODE_FLOAT:
   2793     case MODE_COMPLEX_FLOAT:
   2794     case MODE_VECTOR_FLOAT:
   2795       if (TARGET_HARD_FLOAT)
   2796 	return loongarch_set_reg_reg_piece_cost (mode, UNITS_PER_HWFPVALUE);
   2797       /* Fall through.  */
   2798 
   2799     default:
   2800       return loongarch_set_reg_reg_piece_cost (mode, UNITS_PER_WORD);
   2801     }
   2802 }
   2803 
   2804 /* Implement TARGET_RTX_COSTS.  */
   2805 
   2806 static bool
   2807 loongarch_rtx_costs (rtx x, machine_mode mode, int outer_code,
   2808 		     int opno ATTRIBUTE_UNUSED, int *total, bool speed)
   2809 {
   2810   int code = GET_CODE (x);
   2811   bool float_mode_p = FLOAT_MODE_P (mode);
   2812   int cost;
   2813   rtx addr;
   2814 
   2815   if (outer_code == COMPARE)
   2816     {
   2817       gcc_assert (CONSTANT_P (x));
   2818       *total = 0;
   2819       return true;
   2820     }
   2821 
   2822   switch (code)
   2823     {
   2824     case CONST_INT:
   2825       if (TARGET_64BIT && outer_code == AND && UINTVAL (x) == 0xffffffff)
   2826 	{
   2827 	  *total = 0;
   2828 	  return true;
   2829 	}
   2830 
   2831       /* When not optimizing for size, we care more about the cost
   2832 	 of hot code, and hot code is often in a loop.  If a constant
   2833 	 operand needs to be forced into a register, we will often be
   2834 	 able to hoist the constant load out of the loop, so the load
   2835 	 should not contribute to the cost.  */
   2836       if (speed || loongarch_immediate_operand_p (outer_code, INTVAL (x)))
   2837 	{
   2838 	  *total = 0;
   2839 	  return true;
   2840 	}
   2841       /* Fall through.  */
   2842 
   2843     case CONST:
   2844     case SYMBOL_REF:
   2845     case LABEL_REF:
   2846     case CONST_DOUBLE:
   2847       cost = loongarch_const_insns (x);
   2848       if (cost > 0)
   2849 	{
   2850 	  if (cost == 1 && outer_code == SET
   2851 	      && !(float_mode_p && TARGET_HARD_FLOAT))
   2852 	    cost = 0;
   2853 	  else if ((outer_code == SET || GET_MODE (x) == VOIDmode))
   2854 	    cost = 1;
   2855 	  *total = COSTS_N_INSNS (cost);
   2856 	  return true;
   2857 	}
   2858       /* The value will need to be fetched from the constant pool.  */
   2859       *total = CONSTANT_POOL_COST;
   2860       return true;
   2861 
   2862     case MEM:
   2863       /* If the address is legitimate, return the number of
   2864 	 instructions it needs.  */
   2865       addr = XEXP (x, 0);
   2866       /* Check for a scaled indexed address.  */
   2867       if (loongarch_index_address_p (addr, mode))
   2868 	{
   2869 	  *total = COSTS_N_INSNS (2);
   2870 	  return true;
   2871 	}
   2872       cost = loongarch_address_insns (addr, mode, true);
   2873       if (cost > 0)
   2874 	{
   2875 	  *total = COSTS_N_INSNS (cost + 1);
   2876 	  return true;
   2877 	}
   2878       /* Otherwise use the default handling.  */
   2879       return false;
   2880 
   2881     case FFS:
   2882       *total = COSTS_N_INSNS (6);
   2883       return false;
   2884 
   2885     case NOT:
   2886       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1);
   2887       return false;
   2888 
   2889     case AND:
   2890       /* Check for a *clear_upper32 pattern and treat it like a zero
   2891 	 extension.  See the pattern's comment for details.  */
   2892       if (TARGET_64BIT && mode == DImode && CONST_INT_P (XEXP (x, 1))
   2893 	  && UINTVAL (XEXP (x, 1)) == 0xffffffff)
   2894 	{
   2895 	  *total = (loongarch_zero_extend_cost (XEXP (x, 0))
   2896 		    + set_src_cost (XEXP (x, 0), mode, speed));
   2897 	  return true;
   2898 	}
   2899       /* (AND (NOT op0) (NOT op1) is a nor operation that can be done in
   2900 	 a single instruction.  */
   2901       if (GET_CODE (XEXP (x, 0)) == NOT && GET_CODE (XEXP (x, 1)) == NOT)
   2902 	{
   2903 	  cost = GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1;
   2904 	  *total = (COSTS_N_INSNS (cost)
   2905 		    + set_src_cost (XEXP (XEXP (x, 0), 0), mode, speed)
   2906 		    + set_src_cost (XEXP (XEXP (x, 1), 0), mode, speed));
   2907 	  return true;
   2908 	}
   2909 
   2910       /* Fall through.  */
   2911 
   2912     case IOR:
   2913     case XOR:
   2914       /* Double-word operations use two single-word operations.  */
   2915       *total = loongarch_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (2),
   2916 				      speed);
   2917       return true;
   2918 
   2919     case ASHIFT:
   2920     case ASHIFTRT:
   2921     case LSHIFTRT:
   2922     case ROTATE:
   2923     case ROTATERT:
   2924       if (CONSTANT_P (XEXP (x, 1)))
   2925 	*total = loongarch_binary_cost (x, COSTS_N_INSNS (1),
   2926 					COSTS_N_INSNS (4), speed);
   2927       else
   2928 	*total = loongarch_binary_cost (x, COSTS_N_INSNS (1),
   2929 					COSTS_N_INSNS (12), speed);
   2930       return true;
   2931 
   2932     case ABS:
   2933       if (float_mode_p)
   2934 	*total = loongarch_cost->fp_add;
   2935       else
   2936 	*total = COSTS_N_INSNS (4);
   2937       return false;
   2938 
   2939     case LT:
   2940     case LTU:
   2941     case LE:
   2942     case LEU:
   2943     case GT:
   2944     case GTU:
   2945     case GE:
   2946     case GEU:
   2947     case EQ:
   2948     case NE:
   2949     case UNORDERED:
   2950     case LTGT:
   2951     case UNGE:
   2952     case UNGT:
   2953     case UNLE:
   2954     case UNLT:
   2955       /* Branch comparisons have VOIDmode, so use the first operand's
   2956 	 mode instead.  */
   2957       mode = GET_MODE (XEXP (x, 0));
   2958       if (FLOAT_MODE_P (mode))
   2959 	{
   2960 	  *total = loongarch_cost->fp_add;
   2961 	  return false;
   2962 	}
   2963       *total = loongarch_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (4),
   2964 				      speed);
   2965       return true;
   2966 
   2967     case MINUS:
   2968     case PLUS:
   2969       if (float_mode_p)
   2970 	{
   2971 	  *total = loongarch_cost->fp_add;
   2972 	  return false;
   2973 	}
   2974 
   2975       /* If it's an add + mult (which is equivalent to shift left) and
   2976 	 it's immediate operand satisfies const_immalsl_operand predicate.  */
   2977       if ((mode == SImode || (TARGET_64BIT && mode == DImode))
   2978 	  && GET_CODE (XEXP (x, 0)) == MULT)
   2979 	{
   2980 	  rtx op2 = XEXP (XEXP (x, 0), 1);
   2981 	  if (const_immalsl_operand (op2, mode))
   2982 	    {
   2983 	      *total = (COSTS_N_INSNS (1)
   2984 			+ set_src_cost (XEXP (XEXP (x, 0), 0), mode, speed)
   2985 			+ set_src_cost (XEXP (x, 1), mode, speed));
   2986 	      return true;
   2987 	    }
   2988 	}
   2989 
   2990       /* Double-word operations require three single-word operations and
   2991 	 an SLTU.  */
   2992       *total = loongarch_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (4),
   2993 				      speed);
   2994       return true;
   2995 
   2996     case NEG:
   2997       if (float_mode_p)
   2998 	*total = loongarch_cost->fp_add;
   2999       else
   3000 	*total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1);
   3001       return false;
   3002 
   3003     case FMA:
   3004       *total = loongarch_fp_mult_cost (mode);
   3005       return false;
   3006 
   3007     case MULT:
   3008       if (float_mode_p)
   3009 	*total = loongarch_fp_mult_cost (mode);
   3010       else if (mode == DImode && !TARGET_64BIT)
   3011 	*total = (speed
   3012 		  ? loongarch_cost->int_mult_si * 3 + 6
   3013 		  : COSTS_N_INSNS (7));
   3014       else if (!speed)
   3015 	*total = COSTS_N_INSNS (1) + 1;
   3016       else if (mode == DImode)
   3017 	*total = loongarch_cost->int_mult_di;
   3018       else
   3019 	*total = loongarch_cost->int_mult_si;
   3020       return false;
   3021 
   3022     case DIV:
   3023       /* Check for a reciprocal.  */
   3024       if (float_mode_p
   3025 	  && flag_unsafe_math_optimizations
   3026 	  && XEXP (x, 0) == CONST1_RTX (mode))
   3027 	{
   3028 	  if (outer_code == SQRT || GET_CODE (XEXP (x, 1)) == SQRT)
   3029 	    /* An rsqrt<mode>a or rsqrt<mode>b pattern.  Count the
   3030 	       division as being free.  */
   3031 	    *total = set_src_cost (XEXP (x, 1), mode, speed);
   3032 	  else
   3033 	    *total = (loongarch_fp_div_cost (mode)
   3034 		      + set_src_cost (XEXP (x, 1), mode, speed));
   3035 	  return true;
   3036 	}
   3037       /* Fall through.  */
   3038 
   3039     case SQRT:
   3040     case MOD:
   3041       if (float_mode_p)
   3042 	{
   3043 	  *total = loongarch_fp_div_cost (mode);
   3044 	  return false;
   3045 	}
   3046       /* Fall through.  */
   3047 
   3048     case UDIV:
   3049     case UMOD:
   3050       if (!speed)
   3051 	{
   3052 	  *total = COSTS_N_INSNS (loongarch_idiv_insns (mode));
   3053 	}
   3054       else if (mode == DImode)
   3055 	*total = loongarch_cost->int_div_di;
   3056       else
   3057 	*total = loongarch_cost->int_div_si;
   3058       return false;
   3059 
   3060     case SIGN_EXTEND:
   3061       *total = loongarch_sign_extend_cost (XEXP (x, 0));
   3062       return false;
   3063 
   3064     case ZERO_EXTEND:
   3065       *total = loongarch_zero_extend_cost (XEXP (x, 0));
   3066       return false;
   3067     case TRUNCATE:
   3068       /* Costings for highpart multiplies.  Matching patterns of the form:
   3069 
   3070 	 (lshiftrt:DI (mult:DI (sign_extend:DI (...)
   3071 			       (sign_extend:DI (...))
   3072 		      (const_int 32)
   3073       */
   3074       if ((GET_CODE (XEXP (x, 0)) == ASHIFTRT
   3075 	   || GET_CODE (XEXP (x, 0)) == LSHIFTRT)
   3076 	  && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   3077 	  && ((INTVAL (XEXP (XEXP (x, 0), 1)) == 32
   3078 	       && GET_MODE (XEXP (x, 0)) == DImode)
   3079 	      || (TARGET_64BIT
   3080 		  && INTVAL (XEXP (XEXP (x, 0), 1)) == 64
   3081 		  && GET_MODE (XEXP (x, 0)) == TImode))
   3082 	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
   3083 	  && ((GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND
   3084 	       && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == SIGN_EXTEND)
   3085 	      || (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND
   3086 		  && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1))
   3087 		      == ZERO_EXTEND))))
   3088 	{
   3089 	  if (!speed)
   3090 	    *total = COSTS_N_INSNS (1) + 1;
   3091 	  else if (mode == DImode)
   3092 	    *total = loongarch_cost->int_mult_di;
   3093 	  else
   3094 	    *total = loongarch_cost->int_mult_si;
   3095 
   3096 	  /* Sign extension is free, zero extension costs for DImode when
   3097 	     on a 64bit core / when DMUL is present.  */
   3098 	  for (int i = 0; i < 2; ++i)
   3099 	    {
   3100 	      rtx op = XEXP (XEXP (XEXP (x, 0), 0), i);
   3101 	      if (TARGET_64BIT
   3102 		  && GET_CODE (op) == ZERO_EXTEND
   3103 		  && GET_MODE (op) == DImode)
   3104 		*total += rtx_cost (op, DImode, MULT, i, speed);
   3105 	      else
   3106 		*total += rtx_cost (XEXP (op, 0), VOIDmode, GET_CODE (op), 0,
   3107 				    speed);
   3108 	    }
   3109 
   3110 	  return true;
   3111 	}
   3112       return false;
   3113 
   3114     case FLOAT:
   3115     case UNSIGNED_FLOAT:
   3116     case FIX:
   3117     case FLOAT_EXTEND:
   3118     case FLOAT_TRUNCATE:
   3119       *total = loongarch_cost->fp_add;
   3120       return false;
   3121 
   3122     case SET:
   3123       if (register_operand (SET_DEST (x), VOIDmode)
   3124 	  && reg_or_0_operand (SET_SRC (x), VOIDmode))
   3125 	{
   3126 	  *total = loongarch_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
   3127 	  return true;
   3128 	}
   3129       return false;
   3130 
   3131     default:
   3132       return false;
   3133     }
   3134 }
   3135 
   3136 /* Implement TARGET_ADDRESS_COST.  */
   3137 
   3138 static int
   3139 loongarch_address_cost (rtx addr, machine_mode mode,
   3140 			addr_space_t as ATTRIBUTE_UNUSED,
   3141 			bool speed ATTRIBUTE_UNUSED)
   3142 {
   3143   return loongarch_address_insns (addr, mode, false);
   3144 }
   3145 
   3146 /* Return one word of double-word value OP, taking into account the fixed
   3147    endianness of certain registers.  HIGH_P is true to select the high part,
   3148    false to select the low part.  */
   3149 
   3150 rtx
   3151 loongarch_subword (rtx op, bool high_p)
   3152 {
   3153   unsigned int byte;
   3154   machine_mode mode;
   3155 
   3156   byte = high_p ? UNITS_PER_WORD : 0;
   3157   mode = GET_MODE (op);
   3158   if (mode == VOIDmode)
   3159     mode = TARGET_64BIT ? TImode : DImode;
   3160 
   3161   if (FP_REG_RTX_P (op))
   3162     return gen_rtx_REG (word_mode, REGNO (op) + high_p);
   3163 
   3164   if (MEM_P (op))
   3165     return loongarch_rewrite_small_data (adjust_address (op, word_mode, byte));
   3166 
   3167   return simplify_gen_subreg (word_mode, op, mode, byte);
   3168 }
   3169 
   3170 /* Return true if a move from SRC to DEST should be split into two.
   3171    SPLIT_TYPE describes the split condition.  */
   3172 
   3173 bool
   3174 loongarch_split_move_p (rtx dest, rtx src)
   3175 {
   3176   /* FPR-to-FPR moves can be done in a single instruction, if they're
   3177      allowed at all.  */
   3178   unsigned int size = GET_MODE_SIZE (GET_MODE (dest));
   3179   if (size == 8 && FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
   3180     return false;
   3181 
   3182   /* Check for floating-point loads and stores.  */
   3183   if (size == 8)
   3184     {
   3185       if (FP_REG_RTX_P (dest) && MEM_P (src))
   3186 	return false;
   3187       if (FP_REG_RTX_P (src) && MEM_P (dest))
   3188 	return false;
   3189     }
   3190   /* Otherwise split all multiword moves.  */
   3191   return size > UNITS_PER_WORD;
   3192 }
   3193 
   3194 /* Split a move from SRC to DEST, given that loongarch_split_move_p holds.
   3195    SPLIT_TYPE describes the split condition.  */
   3196 
   3197 void
   3198 loongarch_split_move (rtx dest, rtx src, rtx insn_)
   3199 {
   3200   rtx low_dest;
   3201 
   3202   gcc_checking_assert (loongarch_split_move_p (dest, src));
   3203   if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src))
   3204     {
   3205       if (!TARGET_64BIT && GET_MODE (dest) == DImode)
   3206 	emit_insn (gen_move_doubleword_fprdi (dest, src));
   3207       else if (!TARGET_64BIT && GET_MODE (dest) == DFmode)
   3208 	emit_insn (gen_move_doubleword_fprdf (dest, src));
   3209       else if (TARGET_64BIT && GET_MODE (dest) == TFmode)
   3210 	emit_insn (gen_move_doubleword_fprtf (dest, src));
   3211       else
   3212 	gcc_unreachable ();
   3213     }
   3214   else
   3215     {
   3216       /* The operation can be split into two normal moves.  Decide in
   3217 	 which order to do them.  */
   3218       low_dest = loongarch_subword (dest, false);
   3219       if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src))
   3220 	{
   3221 	  loongarch_emit_move (loongarch_subword (dest, true),
   3222 			       loongarch_subword (src, true));
   3223 	  loongarch_emit_move (low_dest, loongarch_subword (src, false));
   3224 	}
   3225       else
   3226 	{
   3227 	  loongarch_emit_move (low_dest, loongarch_subword (src, false));
   3228 	  loongarch_emit_move (loongarch_subword (dest, true),
   3229 			       loongarch_subword (src, true));
   3230 	}
   3231     }
   3232 
   3233   /* This is a hack.  See if the next insn uses DEST and if so, see if we
   3234      can forward SRC for DEST.  This is most useful if the next insn is a
   3235      simple store.  */
   3236   rtx_insn *insn = (rtx_insn *) insn_;
   3237   struct loongarch_address_info addr = {};
   3238   if (insn)
   3239     {
   3240       rtx_insn *next = next_nonnote_nondebug_insn_bb (insn);
   3241       if (next)
   3242 	{
   3243 	  rtx set = single_set (next);
   3244 	  if (set && SET_SRC (set) == dest)
   3245 	    {
   3246 	      if (MEM_P (src))
   3247 		{
   3248 		  rtx tmp = XEXP (src, 0);
   3249 		  loongarch_classify_address (&addr, tmp, GET_MODE (tmp),
   3250 					      true);
   3251 		  if (addr.reg && !reg_overlap_mentioned_p (dest, addr.reg))
   3252 		    validate_change (next, &SET_SRC (set), src, false);
   3253 		}
   3254 	      else
   3255 		validate_change (next, &SET_SRC (set), src, false);
   3256 	    }
   3257 	}
   3258     }
   3259 }
   3260 
   3261 /* Return true if a move from SRC to DEST in INSN should be split.  */
   3262 
   3263 bool
   3264 loongarch_split_move_insn_p (rtx dest, rtx src)
   3265 {
   3266   return loongarch_split_move_p (dest, src);
   3267 }
   3268 
   3269 /* Split a move from SRC to DEST in INSN, given that
   3270    loongarch_split_move_insn_p holds.  */
   3271 
   3272 void
   3273 loongarch_split_move_insn (rtx dest, rtx src, rtx insn)
   3274 {
   3275   loongarch_split_move (dest, src, insn);
   3276 }
   3277 
   3278 /* Implement TARGET_CONSTANT_ALIGNMENT.  */
   3279 
   3280 static HOST_WIDE_INT
   3281 loongarch_constant_alignment (const_tree exp, HOST_WIDE_INT align)
   3282 {
   3283   if (TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
   3284     return MAX (align, BITS_PER_WORD);
   3285   return align;
   3286 }
   3287 
   3288 const char *
   3289 loongarch_output_move_index (rtx x, machine_mode mode, bool ldr)
   3290 {
   3291   int index = exact_log2 (GET_MODE_SIZE (mode));
   3292   if (!IN_RANGE (index, 0, 3))
   3293     return NULL;
   3294 
   3295   struct loongarch_address_info info;
   3296   if ((loongarch_classify_address (&info, x, mode, false)
   3297        && !(info.type == ADDRESS_REG_REG))
   3298       || !loongarch_legitimate_address_p (mode, x, false))
   3299     return NULL;
   3300 
   3301   const char *const insn[][4] =
   3302     {
   3303       {
   3304 	"stx.b\t%z1,%0",
   3305 	"stx.h\t%z1,%0",
   3306 	"stx.w\t%z1,%0",
   3307 	"stx.d\t%z1,%0",
   3308       },
   3309       {
   3310 	"ldx.bu\t%0,%1",
   3311 	"ldx.hu\t%0,%1",
   3312 	"ldx.w\t%0,%1",
   3313 	"ldx.d\t%0,%1",
   3314       }
   3315     };
   3316 
   3317   return insn[ldr][index];
   3318 }
   3319 
   3320 const char *
   3321 loongarch_output_move_index_float (rtx x, machine_mode mode, bool ldr)
   3322 {
   3323   int index = exact_log2 (GET_MODE_SIZE (mode));
   3324   if (!IN_RANGE (index, 2, 3))
   3325     return NULL;
   3326 
   3327   struct loongarch_address_info info;
   3328   if ((loongarch_classify_address (&info, x, mode, false)
   3329        && !(info.type == ADDRESS_REG_REG))
   3330       || !loongarch_legitimate_address_p (mode, x, false))
   3331     return NULL;
   3332 
   3333   const char *const insn[][2] =
   3334     {
   3335 	{
   3336 	  "fstx.s\t%1,%0",
   3337 	  "fstx.d\t%1,%0"
   3338 	},
   3339 	{
   3340 	  "fldx.s\t%0,%1",
   3341 	  "fldx.d\t%0,%1"
   3342 	},
   3343     };
   3344 
   3345   return insn[ldr][index-2];
   3346 }
   3347 
   3348 /* Return the appropriate instructions to move SRC into DEST.  Assume
   3349    that SRC is operand 1 and DEST is operand 0.  */
   3350 
   3351 const char *
   3352 loongarch_output_move (rtx dest, rtx src)
   3353 {
   3354   enum rtx_code dest_code = GET_CODE (dest);
   3355   enum rtx_code src_code = GET_CODE (src);
   3356   machine_mode mode = GET_MODE (dest);
   3357   bool dbl_p = (GET_MODE_SIZE (mode) == 8);
   3358 
   3359   if (loongarch_split_move_p (dest, src))
   3360     return "#";
   3361 
   3362   if ((src_code == REG && GP_REG_P (REGNO (src)))
   3363       || (src == CONST0_RTX (mode)))
   3364     {
   3365       if (dest_code == REG)
   3366 	{
   3367 	  if (GP_REG_P (REGNO (dest)))
   3368 	    return "or\t%0,%z1,$r0";
   3369 
   3370 	  if (FP_REG_P (REGNO (dest)))
   3371 	    return dbl_p ? "movgr2fr.d\t%0,%z1" : "movgr2fr.w\t%0,%z1";
   3372 	}
   3373       if (dest_code == MEM)
   3374 	{
   3375 	  const char *insn = NULL;
   3376 	  insn = loongarch_output_move_index (XEXP (dest, 0), GET_MODE (dest),
   3377 					      false);
   3378 	  if (insn)
   3379 	    return insn;
   3380 
   3381 	  rtx offset = XEXP (dest, 0);
   3382 	  if (GET_CODE (offset) == PLUS)
   3383 	    offset = XEXP (offset, 1);
   3384 	  switch (GET_MODE_SIZE (mode))
   3385 	    {
   3386 	    case 1:
   3387 	      return "st.b\t%z1,%0";
   3388 	    case 2:
   3389 	      return "st.h\t%z1,%0";
   3390 	    case 4:
   3391 	      if (const_arith_operand (offset, Pmode))
   3392 		return "st.w\t%z1,%0";
   3393 	      else
   3394 		return "stptr.w\t%z1,%0";
   3395 	    case 8:
   3396 	      if (const_arith_operand (offset, Pmode))
   3397 		return "st.d\t%z1,%0";
   3398 	      else
   3399 		return "stptr.d\t%z1,%0";
   3400 	    default:
   3401 	      gcc_unreachable ();
   3402 	    }
   3403 	}
   3404     }
   3405   if (dest_code == REG && GP_REG_P (REGNO (dest)))
   3406     {
   3407       if (src_code == REG)
   3408 	if (FP_REG_P (REGNO (src)))
   3409 	  return dbl_p ? "movfr2gr.d\t%0,%1" : "movfr2gr.s\t%0,%1";
   3410 
   3411       if (src_code == MEM)
   3412 	{
   3413 	  const char *insn = NULL;
   3414 	  insn = loongarch_output_move_index (XEXP (src, 0), GET_MODE (src),
   3415 					      true);
   3416 	  if (insn)
   3417 	    return insn;
   3418 
   3419 	  rtx offset = XEXP (src, 0);
   3420 	  if (GET_CODE (offset) == PLUS)
   3421 	    offset = XEXP (offset, 1);
   3422 	  switch (GET_MODE_SIZE (mode))
   3423 	    {
   3424 	    case 1:
   3425 	      return "ld.bu\t%0,%1";
   3426 	    case 2:
   3427 	      return "ld.hu\t%0,%1";
   3428 	    case 4:
   3429 	      if (const_arith_operand (offset, Pmode))
   3430 		return "ld.w\t%0,%1";
   3431 	      else
   3432 		return "ldptr.w\t%0,%1";
   3433 	    case 8:
   3434 	      if (const_arith_operand (offset, Pmode))
   3435 		return "ld.d\t%0,%1";
   3436 	      else
   3437 		return "ldptr.d\t%0,%1";
   3438 	    default:
   3439 	      gcc_unreachable ();
   3440 	    }
   3441 	}
   3442 
   3443       if (src_code == CONST_INT)
   3444 	{
   3445 	  if (LU12I_INT (src))
   3446 	    return "lu12i.w\t%0,%1>>12\t\t\t# %X1";
   3447 	  else if (IMM12_INT (src))
   3448 	    return "addi.w\t%0,$r0,%1\t\t\t# %X1";
   3449 	  else if (IMM12_INT_UNSIGNED (src))
   3450 	    return "ori\t%0,$r0,%1\t\t\t# %X1";
   3451 	  else if (LU52I_INT (src))
   3452 	    return "lu52i.d\t%0,$r0,%X1>>52\t\t\t# %1";
   3453 	  else
   3454 	    gcc_unreachable ();
   3455 	}
   3456 
   3457       if (symbolic_operand (src, VOIDmode))
   3458 	{
   3459 	  if ((TARGET_CMODEL_TINY && (!loongarch_global_symbol_p (src)
   3460 				      || loongarch_symbol_binds_local_p (src)))
   3461 	      || (TARGET_CMODEL_TINY_STATIC && !loongarch_weak_symbol_p (src)))
   3462 	    {
   3463 	      /* The symbol must be aligned to 4 byte.  */
   3464 	      unsigned int align;
   3465 
   3466 	      if (LABEL_REF_P (src))
   3467 		align = 32 /* Whatever.  */;
   3468 	      else if (CONSTANT_POOL_ADDRESS_P (src))
   3469 		align = GET_MODE_ALIGNMENT (get_pool_mode (src));
   3470 	      else if (TREE_CONSTANT_POOL_ADDRESS_P (src))
   3471 		{
   3472 		  tree exp = SYMBOL_REF_DECL (src);
   3473 		  align = TYPE_ALIGN (TREE_TYPE (exp));
   3474 		  align = loongarch_constant_alignment (exp, align);
   3475 		}
   3476 	      else if (SYMBOL_REF_DECL (src))
   3477 		align = DECL_ALIGN (SYMBOL_REF_DECL (src));
   3478 	      else if (SYMBOL_REF_HAS_BLOCK_INFO_P (src)
   3479 		       && SYMBOL_REF_BLOCK (src) != NULL)
   3480 		align = SYMBOL_REF_BLOCK (src)->alignment;
   3481 	      else
   3482 		align = BITS_PER_UNIT;
   3483 
   3484 	      if (align % (4 * 8) == 0)
   3485 		return "pcaddi\t%0,%%pcrel(%1)>>2";
   3486 	    }
   3487 	  if (TARGET_CMODEL_TINY
   3488 	      || TARGET_CMODEL_TINY_STATIC
   3489 	      || TARGET_CMODEL_NORMAL
   3490 	      || TARGET_CMODEL_LARGE)
   3491 	    {
   3492 	      if (!loongarch_global_symbol_p (src)
   3493 		  || loongarch_symbol_binds_local_p (src))
   3494 		return "la.local\t%0,%1";
   3495 	      else
   3496 		return "la.global\t%0,%1";
   3497 	    }
   3498 	  if (TARGET_CMODEL_EXTREME)
   3499 	    {
   3500 	      sorry ("Normal symbol loading not implemented in extreme mode.");
   3501 	      gcc_unreachable ();
   3502 	    }
   3503 
   3504 	}
   3505     }
   3506   if (src_code == REG && FP_REG_P (REGNO (src)))
   3507     {
   3508       if (dest_code == REG && FP_REG_P (REGNO (dest)))
   3509 	return dbl_p ? "fmov.d\t%0,%1" : "fmov.s\t%0,%1";
   3510 
   3511       if (dest_code == MEM)
   3512 	{
   3513 	  const char *insn = NULL;
   3514 	  insn = loongarch_output_move_index_float (XEXP (dest, 0),
   3515 						    GET_MODE (dest),
   3516 						    false);
   3517 	  if (insn)
   3518 	    return insn;
   3519 
   3520 	  return dbl_p ? "fst.d\t%1,%0" : "fst.s\t%1,%0";
   3521 	}
   3522     }
   3523   if (dest_code == REG && FP_REG_P (REGNO (dest)))
   3524     {
   3525       if (src_code == MEM)
   3526 	{
   3527 	  const char *insn = NULL;
   3528 	  insn = loongarch_output_move_index_float (XEXP (src, 0),
   3529 						    GET_MODE (src),
   3530 						    true);
   3531 	  if (insn)
   3532 	    return insn;
   3533 
   3534 	  return dbl_p ? "fld.d\t%0,%1" : "fld.s\t%0,%1";
   3535 	}
   3536     }
   3537   gcc_unreachable ();
   3538 }
   3539 
   3540 /* Return true if CMP1 is a suitable second operand for integer ordering
   3541    test CODE.  */
   3542 
   3543 static bool
   3544 loongarch_int_order_operand_ok_p (enum rtx_code code, rtx cmp1)
   3545 {
   3546   switch (code)
   3547     {
   3548     case GT:
   3549     case GTU:
   3550       return reg_or_0_operand (cmp1, VOIDmode);
   3551 
   3552     case GE:
   3553     case GEU:
   3554       return cmp1 == const1_rtx;
   3555 
   3556     case LT:
   3557     case LTU:
   3558       return arith_operand (cmp1, VOIDmode);
   3559 
   3560     case LE:
   3561       return sle_operand (cmp1, VOIDmode);
   3562 
   3563     case LEU:
   3564       return sleu_operand (cmp1, VOIDmode);
   3565 
   3566     default:
   3567       gcc_unreachable ();
   3568     }
   3569 }
   3570 
   3571 /* Return true if *CMP1 (of mode MODE) is a valid second operand for
   3572    integer ordering test *CODE, or if an equivalent combination can
   3573    be formed by adjusting *CODE and *CMP1.  When returning true, update
   3574    *CODE and *CMP1 with the chosen code and operand, otherwise leave
   3575    them alone.  */
   3576 
   3577 static bool
   3578 loongarch_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1,
   3579 				       machine_mode mode)
   3580 {
   3581   HOST_WIDE_INT plus_one;
   3582 
   3583   if (loongarch_int_order_operand_ok_p (*code, *cmp1))
   3584     return true;
   3585 
   3586   if (CONST_INT_P (*cmp1))
   3587     switch (*code)
   3588       {
   3589       case LE:
   3590 	plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
   3591 	if (INTVAL (*cmp1) < plus_one)
   3592 	  {
   3593 	    *code = LT;
   3594 	    *cmp1 = force_reg (mode, GEN_INT (plus_one));
   3595 	    return true;
   3596 	  }
   3597 	break;
   3598 
   3599       case LEU:
   3600 	plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
   3601 	if (plus_one != 0)
   3602 	  {
   3603 	    *code = LTU;
   3604 	    *cmp1 = force_reg (mode, GEN_INT (plus_one));
   3605 	    return true;
   3606 	  }
   3607 	break;
   3608 
   3609       default:
   3610 	break;
   3611       }
   3612   return false;
   3613 }
   3614 
   3615 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
   3616    in TARGET.  CMP0 and TARGET are register_operands.  If INVERT_PTR
   3617    is nonnull, it's OK to set TARGET to the inverse of the result and
   3618    flip *INVERT_PTR instead.  */
   3619 
   3620 static void
   3621 loongarch_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
   3622 			       rtx target, rtx cmp0, rtx cmp1)
   3623 {
   3624   machine_mode mode;
   3625 
   3626   /* First see if there is a LoongArch instruction that can do this operation.
   3627      If not, try doing the same for the inverse operation.  If that also
   3628      fails, force CMP1 into a register and try again.  */
   3629   mode = GET_MODE (cmp0);
   3630   if (loongarch_canonicalize_int_order_test (&code, &cmp1, mode))
   3631     loongarch_emit_binary (code, target, cmp0, cmp1);
   3632   else
   3633     {
   3634       enum rtx_code inv_code = reverse_condition (code);
   3635       if (!loongarch_canonicalize_int_order_test (&inv_code, &cmp1, mode))
   3636 	{
   3637 	  cmp1 = force_reg (mode, cmp1);
   3638 	  loongarch_emit_int_order_test (code, invert_ptr, target, cmp0, cmp1);
   3639 	}
   3640       else if (invert_ptr == 0)
   3641 	{
   3642 	  rtx inv_target;
   3643 
   3644 	  inv_target = loongarch_force_binary (GET_MODE (target),
   3645 					       inv_code, cmp0, cmp1);
   3646 	  loongarch_emit_binary (XOR, target, inv_target, const1_rtx);
   3647 	}
   3648       else
   3649 	{
   3650 	  *invert_ptr = !*invert_ptr;
   3651 	  loongarch_emit_binary (inv_code, target, cmp0, cmp1);
   3652 	}
   3653     }
   3654 }
   3655 
   3656 /* Return a register that is zero if CMP0 and CMP1 are equal.
   3657    The register will have the same mode as CMP0.  */
   3658 
   3659 static rtx
   3660 loongarch_zero_if_equal (rtx cmp0, rtx cmp1)
   3661 {
   3662   if (cmp1 == const0_rtx)
   3663     return cmp0;
   3664 
   3665   if (uns_arith_operand (cmp1, VOIDmode))
   3666     return expand_binop (GET_MODE (cmp0), xor_optab, cmp0, cmp1, 0, 0,
   3667 			 OPTAB_DIRECT);
   3668 
   3669   return expand_binop (GET_MODE (cmp0), sub_optab, cmp0, cmp1, 0, 0,
   3670 		       OPTAB_DIRECT);
   3671 }
   3672 
   3673 /* Allocate a floating-point condition-code register of mode MODE.  */
   3674 
   3675 static rtx
   3676 loongarch_allocate_fcc (machine_mode mode)
   3677 {
   3678   unsigned int regno, count;
   3679 
   3680   gcc_assert (TARGET_HARD_FLOAT);
   3681 
   3682   if (mode == FCCmode)
   3683     count = 1;
   3684   else
   3685     gcc_unreachable ();
   3686 
   3687   cfun->machine->next_fcc += -cfun->machine->next_fcc & (count - 1);
   3688   if (cfun->machine->next_fcc > FCC_REG_LAST - FCC_REG_FIRST)
   3689     cfun->machine->next_fcc = 0;
   3690 
   3691   regno = FCC_REG_FIRST + cfun->machine->next_fcc;
   3692   cfun->machine->next_fcc += count;
   3693   return gen_rtx_REG (mode, regno);
   3694 }
   3695 
   3696 /* Sign- or zero-extend OP0 and OP1 for integer comparisons.  */
   3697 
   3698 static void
   3699 loongarch_extend_comparands (rtx_code code, rtx *op0, rtx *op1)
   3700 {
   3701   /* Comparisons consider all XLEN bits, so extend sub-XLEN values.  */
   3702   if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0)))
   3703     {
   3704       /* TODO: checkout It is more profitable to zero-extend QImode values.  */
   3705       if (unsigned_condition (code) == code && GET_MODE (*op0) == QImode)
   3706 	{
   3707 	  *op0 = gen_rtx_ZERO_EXTEND (word_mode, *op0);
   3708 	  if (CONST_INT_P (*op1))
   3709 	    *op1 = GEN_INT ((uint8_t) INTVAL (*op1));
   3710 	  else
   3711 	    *op1 = gen_rtx_ZERO_EXTEND (word_mode, *op1);
   3712 	}
   3713       else
   3714 	{
   3715 	  *op0 = gen_rtx_SIGN_EXTEND (word_mode, *op0);
   3716 	  if (*op1 != const0_rtx)
   3717 	    *op1 = gen_rtx_SIGN_EXTEND (word_mode, *op1);
   3718 	}
   3719     }
   3720 }
   3721 
   3722 /* Convert a comparison into something that can be used in a branch.  On
   3723    entry, *OP0 and *OP1 are the values being compared and *CODE is the code
   3724    used to compare them.  Update them to describe the final comparison.  */
   3725 
   3726 static void
   3727 loongarch_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1)
   3728 {
   3729   static const enum rtx_code
   3730   mag_comparisons[][2] = {{LEU, LTU}, {GTU, GEU}, {LE, LT}, {GT, GE}};
   3731 
   3732   if (splittable_const_int_operand (*op1, VOIDmode))
   3733     {
   3734       HOST_WIDE_INT rhs = INTVAL (*op1);
   3735 
   3736       if (*code == EQ || *code == NE)
   3737 	{
   3738 	  /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0.  */
   3739 	  if (IMM12_OPERAND (-rhs))
   3740 	    {
   3741 	      *op0 = loongarch_force_binary (GET_MODE (*op0), PLUS, *op0,
   3742 					     GEN_INT (-rhs));
   3743 	      *op1 = const0_rtx;
   3744 	    }
   3745 	}
   3746       else
   3747 	{
   3748 	  /* Convert e.g. (OP0 <= 0xFFF) into (OP0 < 0x1000).  */
   3749 	  for (size_t i = 0; i < ARRAY_SIZE (mag_comparisons); i++)
   3750 	    {
   3751 	      HOST_WIDE_INT new_rhs;
   3752 	      bool increment = *code == mag_comparisons[i][0];
   3753 	      bool decrement = *code == mag_comparisons[i][1];
   3754 	      if (!increment && !decrement)
   3755 		continue;
   3756 
   3757 	      new_rhs = rhs + (increment ? 1 : -1);
   3758 	      if (loongarch_integer_cost (new_rhs)
   3759 		    < loongarch_integer_cost (rhs)
   3760 		  && (rhs < 0) == (new_rhs < 0))
   3761 		{
   3762 		  *op1 = GEN_INT (new_rhs);
   3763 		  *code = mag_comparisons[i][increment];
   3764 		}
   3765 	      break;
   3766 	    }
   3767 	}
   3768     }
   3769 
   3770   loongarch_extend_comparands (*code, op0, op1);
   3771 
   3772   *op0 = force_reg (word_mode, *op0);
   3773   if (*op1 != const0_rtx)
   3774     *op1 = force_reg (word_mode, *op1);
   3775 }
   3776 
   3777 /* Like loongarch_emit_int_compare, but for floating-point comparisons.  */
   3778 
   3779 static void
   3780 loongarch_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
   3781 {
   3782   rtx cmp_op0 = *op0;
   3783   rtx cmp_op1 = *op1;
   3784 
   3785   /* Floating-point tests use a separate FCMP.cond.fmt
   3786      comparison to set a register.  The branch or conditional move will
   3787      then compare that register against zero.
   3788 
   3789      Set CMP_CODE to the code of the comparison instruction and
   3790      *CODE to the code that the branch or move should use.  */
   3791   enum rtx_code cmp_code = *code;
   3792   /* Three FP conditions cannot be implemented by reversing the
   3793      operands for FCMP.cond.fmt, instead a reversed condition code is
   3794      required and a test for false.  */
   3795   *code = NE;
   3796   *op0 = loongarch_allocate_fcc (FCCmode);
   3797 
   3798   *op1 = const0_rtx;
   3799   loongarch_emit_binary (cmp_code, *op0, cmp_op0, cmp_op1);
   3800 }
   3801 
   3802 /* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
   3803    and OPERAND[3].  Store the result in OPERANDS[0].
   3804 
   3805    On 64-bit targets, the mode of the comparison and target will always be
   3806    SImode, thus possibly narrower than that of the comparison's operands.  */
   3807 
   3808 void
   3809 loongarch_expand_scc (rtx operands[])
   3810 {
   3811   rtx target = operands[0];
   3812   enum rtx_code code = GET_CODE (operands[1]);
   3813   rtx op0 = operands[2];
   3814   rtx op1 = operands[3];
   3815 
   3816   loongarch_extend_comparands (code, &op0, &op1);
   3817   op0 = force_reg (word_mode, op0);
   3818 
   3819   gcc_assert (GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT);
   3820 
   3821   if (code == EQ || code == NE)
   3822     {
   3823       rtx zie = loongarch_zero_if_equal (op0, op1);
   3824       loongarch_emit_binary (code, target, zie, const0_rtx);
   3825     }
   3826   else
   3827     loongarch_emit_int_order_test (code, 0, target, op0, op1);
   3828 }
   3829 
   3830 /* Compare OPERANDS[1] with OPERANDS[2] using comparison code
   3831    CODE and jump to OPERANDS[3] if the condition holds.  */
   3832 
   3833 void
   3834 loongarch_expand_conditional_branch (rtx *operands)
   3835 {
   3836   enum rtx_code code = GET_CODE (operands[0]);
   3837   rtx op0 = operands[1];
   3838   rtx op1 = operands[2];
   3839   rtx condition;
   3840 
   3841   if (FLOAT_MODE_P (GET_MODE (op1)))
   3842     loongarch_emit_float_compare (&code, &op0, &op1);
   3843   else
   3844     loongarch_emit_int_compare (&code, &op0, &op1);
   3845 
   3846   condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
   3847   emit_jump_insn (gen_condjump (condition, operands[3]));
   3848 }
   3849 
   3850 /* Perform the comparison in OPERANDS[1].  Move OPERANDS[2] into OPERANDS[0]
   3851    if the condition holds, otherwise move OPERANDS[3] into OPERANDS[0].  */
   3852 
   3853 void
   3854 loongarch_expand_conditional_move (rtx *operands)
   3855 {
   3856   enum rtx_code code = GET_CODE (operands[1]);
   3857   rtx op0 = XEXP (operands[1], 0);
   3858   rtx op1 = XEXP (operands[1], 1);
   3859 
   3860   if (FLOAT_MODE_P (GET_MODE (op1)))
   3861     loongarch_emit_float_compare (&code, &op0, &op1);
   3862   else
   3863     {
   3864       loongarch_extend_comparands (code, &op0, &op1);
   3865 
   3866       op0 = force_reg (word_mode, op0);
   3867 
   3868       if (code == EQ || code == NE)
   3869 	{
   3870 	  op0 = loongarch_zero_if_equal (op0, op1);
   3871 	  op1 = const0_rtx;
   3872 	}
   3873       else
   3874 	{
   3875 	  /* The comparison needs a separate scc instruction.  Store the
   3876 	     result of the scc in *OP0 and compare it against zero.  */
   3877 	  bool invert = false;
   3878 	  rtx target = gen_reg_rtx (GET_MODE (op0));
   3879 	  loongarch_emit_int_order_test (code, &invert, target, op0, op1);
   3880 	  code = invert ? EQ : NE;
   3881 	  op0 = target;
   3882 	  op1 = const0_rtx;
   3883 	}
   3884     }
   3885 
   3886   rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
   3887   /* There is no direct support for general conditional GP move involving
   3888      two registers using SEL.  */
   3889   if (INTEGRAL_MODE_P (GET_MODE (operands[2]))
   3890       && register_operand (operands[2], VOIDmode)
   3891       && register_operand (operands[3], VOIDmode))
   3892     {
   3893       machine_mode mode = GET_MODE (operands[0]);
   3894       rtx temp = gen_reg_rtx (mode);
   3895       rtx temp2 = gen_reg_rtx (mode);
   3896 
   3897       emit_insn (gen_rtx_SET (temp,
   3898 			      gen_rtx_IF_THEN_ELSE (mode, cond,
   3899 						    operands[2], const0_rtx)));
   3900 
   3901       /* Flip the test for the second operand.  */
   3902       cond = gen_rtx_fmt_ee ((code == EQ) ? NE : EQ, GET_MODE (op0), op0, op1);
   3903 
   3904       emit_insn (gen_rtx_SET (temp2,
   3905 			      gen_rtx_IF_THEN_ELSE (mode, cond,
   3906 						    operands[3], const0_rtx)));
   3907 
   3908       /* Merge the two results, at least one is guaranteed to be zero.  */
   3909       emit_insn (gen_rtx_SET (operands[0], gen_rtx_IOR (mode, temp, temp2)));
   3910     }
   3911   else
   3912     emit_insn (gen_rtx_SET (operands[0],
   3913 			    gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), cond,
   3914 						  operands[2], operands[3])));
   3915 }
   3916 
   3917 /* Implement TARGET_EXPAND_BUILTIN_VA_START.  */
   3918 
   3919 static void
   3920 loongarch_va_start (tree valist, rtx nextarg)
   3921 {
   3922   nextarg = plus_constant (Pmode, nextarg, -cfun->machine->varargs_size);
   3923   std_expand_builtin_va_start (valist, nextarg);
   3924 }
   3925 
   3926 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL.  */
   3927 
   3928 static bool
   3929 loongarch_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
   3930 				   tree exp ATTRIBUTE_UNUSED)
   3931 {
   3932   /* Always OK.  */
   3933   return true;
   3934 }
   3935 
   3936 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
   3937    Assume that the areas do not overlap.  */
   3938 
   3939 static void
   3940 loongarch_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
   3941 {
   3942   HOST_WIDE_INT offset, delta;
   3943   unsigned HOST_WIDE_INT bits;
   3944   int i;
   3945   machine_mode mode;
   3946   rtx *regs;
   3947 
   3948   bits = MIN (BITS_PER_WORD, MIN (MEM_ALIGN (src), MEM_ALIGN (dest)));
   3949 
   3950   mode = int_mode_for_size (bits, 0).require ();
   3951   delta = bits / BITS_PER_UNIT;
   3952 
   3953   /* Allocate a buffer for the temporary registers.  */
   3954   regs = XALLOCAVEC (rtx, length / delta);
   3955 
   3956   /* Load as many BITS-sized chunks as possible.  Use a normal load if
   3957      the source has enough alignment, otherwise use left/right pairs.  */
   3958   for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
   3959     {
   3960       regs[i] = gen_reg_rtx (mode);
   3961       loongarch_emit_move (regs[i], adjust_address (src, mode, offset));
   3962     }
   3963 
   3964   for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
   3965     loongarch_emit_move (adjust_address (dest, mode, offset), regs[i]);
   3966 
   3967   /* Mop up any left-over bytes.  */
   3968   if (offset < length)
   3969     {
   3970       src = adjust_address (src, BLKmode, offset);
   3971       dest = adjust_address (dest, BLKmode, offset);
   3972       move_by_pieces (dest, src, length - offset,
   3973 		      MIN (MEM_ALIGN (src), MEM_ALIGN (dest)),
   3974 		      (enum memop_ret) 0);
   3975     }
   3976 }
   3977 
   3978 /* Helper function for doing a loop-based block operation on memory
   3979    reference MEM.  Each iteration of the loop will operate on LENGTH
   3980    bytes of MEM.
   3981 
   3982    Create a new base register for use within the loop and point it to
   3983    the start of MEM.  Create a new memory reference that uses this
   3984    register.  Store them in *LOOP_REG and *LOOP_MEM respectively.  */
   3985 
   3986 static void
   3987 loongarch_adjust_block_mem (rtx mem, HOST_WIDE_INT length, rtx *loop_reg,
   3988 			    rtx *loop_mem)
   3989 {
   3990   *loop_reg = copy_addr_to_reg (XEXP (mem, 0));
   3991 
   3992   /* Although the new mem does not refer to a known location,
   3993      it does keep up to LENGTH bytes of alignment.  */
   3994   *loop_mem = change_address (mem, BLKmode, *loop_reg);
   3995   set_mem_align (*loop_mem, MIN (MEM_ALIGN (mem), length * BITS_PER_UNIT));
   3996 }
   3997 
   3998 /* Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER
   3999    bytes at a time.  LENGTH must be at least BYTES_PER_ITER.  Assume that
   4000    the memory regions do not overlap.  */
   4001 
   4002 static void
   4003 loongarch_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
   4004 			   HOST_WIDE_INT bytes_per_iter)
   4005 {
   4006   rtx_code_label *label;
   4007   rtx src_reg, dest_reg, final_src, test;
   4008   HOST_WIDE_INT leftover;
   4009 
   4010   leftover = length % bytes_per_iter;
   4011   length -= leftover;
   4012 
   4013   /* Create registers and memory references for use within the loop.  */
   4014   loongarch_adjust_block_mem (src, bytes_per_iter, &src_reg, &src);
   4015   loongarch_adjust_block_mem (dest, bytes_per_iter, &dest_reg, &dest);
   4016 
   4017   /* Calculate the value that SRC_REG should have after the last iteration
   4018      of the loop.  */
   4019   final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length), 0,
   4020 				   0, OPTAB_WIDEN);
   4021 
   4022   /* Emit the start of the loop.  */
   4023   label = gen_label_rtx ();
   4024   emit_label (label);
   4025 
   4026   /* Emit the loop body.  */
   4027   loongarch_block_move_straight (dest, src, bytes_per_iter);
   4028 
   4029   /* Move on to the next block.  */
   4030   loongarch_emit_move (src_reg,
   4031 		       plus_constant (Pmode, src_reg, bytes_per_iter));
   4032   loongarch_emit_move (dest_reg,
   4033 		       plus_constant (Pmode, dest_reg, bytes_per_iter));
   4034 
   4035   /* Emit the loop condition.  */
   4036   test = gen_rtx_NE (VOIDmode, src_reg, final_src);
   4037   if (Pmode == DImode)
   4038     emit_jump_insn (gen_cbranchdi4 (test, src_reg, final_src, label));
   4039   else
   4040     emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label));
   4041 
   4042   /* Mop up any left-over bytes.  */
   4043   if (leftover)
   4044     loongarch_block_move_straight (dest, src, leftover);
   4045   else
   4046     /* Temporary fix for PR79150.  */
   4047     emit_insn (gen_nop ());
   4048 }
   4049 
   4050 /* Expand a cpymemsi instruction, which copies LENGTH bytes from
   4051    memory reference SRC to memory reference DEST.  */
   4052 
   4053 bool
   4054 loongarch_expand_block_move (rtx dest, rtx src, rtx length)
   4055 {
   4056   int max_move_bytes = LARCH_MAX_MOVE_BYTES_STRAIGHT;
   4057 
   4058   if (CONST_INT_P (length)
   4059       && INTVAL (length) <= loongarch_max_inline_memcpy_size)
   4060     {
   4061       if (INTVAL (length) <= max_move_bytes)
   4062 	{
   4063 	  loongarch_block_move_straight (dest, src, INTVAL (length));
   4064 	  return true;
   4065 	}
   4066       else if (optimize)
   4067 	{
   4068 	  loongarch_block_move_loop (dest, src, INTVAL (length),
   4069 				     LARCH_MAX_MOVE_BYTES_PER_LOOP_ITER);
   4070 	  return true;
   4071 	}
   4072     }
   4073   return false;
   4074 }
   4075 
   4076 /* Return true if loongarch_expand_block_move is the preferred
   4077    implementation of the 'cpymemsi' template.  */
   4078 
   4079 bool
   4080 loongarch_do_optimize_block_move_p (void)
   4081 {
   4082   /* if -m[no-]memcpy is given explicitly.  */
   4083   if (target_flags_explicit & MASK_MEMCPY)
   4084     return !TARGET_MEMCPY;
   4085 
   4086   /* if not, don't optimize under -Os.  */
   4087   return !optimize_size;
   4088 }
   4089 
   4090 /* Expand a QI or HI mode atomic memory operation.
   4091 
   4092    GENERATOR contains a pointer to the gen_* function that generates
   4093    the SI mode underlying atomic operation using masks that we
   4094    calculate.
   4095 
   4096    RESULT is the return register for the operation.  Its value is NULL
   4097    if unused.
   4098 
   4099    MEM is the location of the atomic access.
   4100 
   4101    OLDVAL is the first operand for the operation.
   4102 
   4103    NEWVAL is the optional second operand for the operation.  Its value
   4104    is NULL if unused.  */
   4105 
   4106 void
   4107 loongarch_expand_atomic_qihi (union loongarch_gen_fn_ptrs generator,
   4108 			      rtx result, rtx mem, rtx oldval, rtx newval,
   4109 			      rtx model)
   4110 {
   4111   rtx orig_addr, memsi_addr, memsi, shift, shiftsi, unshifted_mask;
   4112   rtx unshifted_mask_reg, mask, inverted_mask, si_op;
   4113   rtx res = NULL;
   4114   machine_mode mode;
   4115 
   4116   mode = GET_MODE (mem);
   4117 
   4118   /* Compute the address of the containing SImode value.  */
   4119   orig_addr = force_reg (Pmode, XEXP (mem, 0));
   4120   memsi_addr = loongarch_force_binary (Pmode, AND, orig_addr,
   4121 				       force_reg (Pmode, GEN_INT (-4)));
   4122 
   4123   /* Create a memory reference for it.  */
   4124   memsi = gen_rtx_MEM (SImode, memsi_addr);
   4125   set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
   4126   MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
   4127 
   4128   /* Work out the byte offset of the QImode or HImode value,
   4129      counting from the least significant byte.  */
   4130   shift = loongarch_force_binary (Pmode, AND, orig_addr, GEN_INT (3));
   4131   /* Multiply by eight to convert the shift value from bytes to bits.  */
   4132   loongarch_emit_binary (ASHIFT, shift, shift, GEN_INT (3));
   4133 
   4134   /* Make the final shift an SImode value, so that it can be used in
   4135      SImode operations.  */
   4136   shiftsi = force_reg (SImode, gen_lowpart (SImode, shift));
   4137 
   4138   /* Set MASK to an inclusive mask of the QImode or HImode value.  */
   4139   unshifted_mask = GEN_INT (GET_MODE_MASK (mode));
   4140   unshifted_mask_reg = force_reg (SImode, unshifted_mask);
   4141   mask = loongarch_force_binary (SImode, ASHIFT, unshifted_mask_reg, shiftsi);
   4142 
   4143   /* Compute the equivalent exclusive mask.  */
   4144   inverted_mask = gen_reg_rtx (SImode);
   4145   emit_insn (gen_rtx_SET (inverted_mask, gen_rtx_NOT (SImode, mask)));
   4146 
   4147   /* Shift the old value into place.  */
   4148   if (oldval != const0_rtx)
   4149     {
   4150       oldval = convert_modes (SImode, mode, oldval, true);
   4151       oldval = force_reg (SImode, oldval);
   4152       oldval = loongarch_force_binary (SImode, ASHIFT, oldval, shiftsi);
   4153     }
   4154 
   4155   /* Do the same for the new value.  */
   4156   if (newval && newval != const0_rtx)
   4157     {
   4158       newval = convert_modes (SImode, mode, newval, true);
   4159       newval = force_reg (SImode, newval);
   4160       newval = loongarch_force_binary (SImode, ASHIFT, newval, shiftsi);
   4161     }
   4162 
   4163   /* Do the SImode atomic access.  */
   4164   if (result)
   4165     res = gen_reg_rtx (SImode);
   4166 
   4167   if (newval)
   4168     si_op = generator.fn_7 (res, memsi, mask, inverted_mask, oldval, newval,
   4169 			    model);
   4170   else if (result)
   4171     si_op = generator.fn_6 (res, memsi, mask, inverted_mask, oldval, model);
   4172   else
   4173     si_op = generator.fn_5 (memsi, mask, inverted_mask, oldval, model);
   4174 
   4175   emit_insn (si_op);
   4176 
   4177   if (result)
   4178     {
   4179       /* Shift and convert the result.  */
   4180       loongarch_emit_binary (AND, res, res, mask);
   4181       loongarch_emit_binary (LSHIFTRT, res, res, shiftsi);
   4182       loongarch_emit_move (result, gen_lowpart (GET_MODE (result), res));
   4183     }
   4184 }
   4185 
   4186 /* Return true if (zero_extract OP WIDTH BITPOS) can be used as the
   4187    source of an "ext" instruction or the destination of an "ins"
   4188    instruction.  OP must be a register operand and the following
   4189    conditions must hold:
   4190 
   4191    0 <= BITPOS < GET_MODE_BITSIZE (GET_MODE (op))
   4192    0 < WIDTH <= GET_MODE_BITSIZE (GET_MODE (op))
   4193    0 < BITPOS + WIDTH <= GET_MODE_BITSIZE (GET_MODE (op))
   4194 
   4195    Also reject lengths equal to a word as they are better handled
   4196    by the move patterns.  */
   4197 
   4198 bool
   4199 loongarch_use_ins_ext_p (rtx op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos)
   4200 {
   4201   if (!register_operand (op, VOIDmode)
   4202       || GET_MODE_BITSIZE (GET_MODE (op)) > BITS_PER_WORD)
   4203     return false;
   4204 
   4205   if (!IN_RANGE (width, 1, GET_MODE_BITSIZE (GET_MODE (op)) - 1))
   4206     return false;
   4207 
   4208   if (bitpos < 0 || bitpos + width > GET_MODE_BITSIZE (GET_MODE (op)))
   4209     return false;
   4210 
   4211   return true;
   4212 }
   4213 
   4214 /* Print the text for PRINT_OPERAND punctation character CH to FILE.
   4215    The punctuation characters are:
   4216 
   4217    '.'	Print the name of the register with a hard-wired zero (zero or $r0).
   4218    '$'	Print the name of the stack pointer register (sp or $r3).
   4219 
   4220    See also loongarch_init_print_operand_punct.  */
   4221 
   4222 static void
   4223 loongarch_print_operand_punctuation (FILE *file, int ch)
   4224 {
   4225   switch (ch)
   4226     {
   4227     case '.':
   4228       fputs (reg_names[GP_REG_FIRST + 0], file);
   4229       break;
   4230 
   4231     case '$':
   4232       fputs (reg_names[STACK_POINTER_REGNUM], file);
   4233       break;
   4234 
   4235     default:
   4236       gcc_unreachable ();
   4237       break;
   4238     }
   4239 }
   4240 
   4241 /* Initialize loongarch_print_operand_punct.  */
   4242 
   4243 static void
   4244 loongarch_init_print_operand_punct (void)
   4245 {
   4246   const char *p;
   4247 
   4248   for (p = ".$"; *p; p++)
   4249     loongarch_print_operand_punct[(unsigned char) *p] = true;
   4250 }
   4251 
   4252 /* PRINT_OPERAND prefix LETTER refers to the integer branch instruction
   4253    associated with condition CODE.  Print the condition part of the
   4254    opcode to FILE.  */
   4255 
   4256 static void
   4257 loongarch_print_int_branch_condition (FILE *file, enum rtx_code code,
   4258 				      int letter)
   4259 {
   4260   switch (code)
   4261     {
   4262     case EQ:
   4263     case NE:
   4264     case GT:
   4265     case GE:
   4266     case LT:
   4267     case LE:
   4268     case GTU:
   4269     case GEU:
   4270     case LTU:
   4271     case LEU:
   4272       /* Conveniently, the LoongArch names for these conditions are the same
   4273 	 as their RTL equivalents.  */
   4274       fputs (GET_RTX_NAME (code), file);
   4275       break;
   4276 
   4277     default:
   4278       output_operand_lossage ("'%%%c' is not a valid operand prefix", letter);
   4279       break;
   4280     }
   4281 }
   4282 
   4283 /* Likewise floating-point branches.  */
   4284 
   4285 static void
   4286 loongarch_print_float_branch_condition (FILE *file, enum rtx_code code,
   4287 					int letter)
   4288 {
   4289   switch (code)
   4290     {
   4291     case EQ:
   4292       fputs ("ceqz", file);
   4293       break;
   4294 
   4295     case NE:
   4296       fputs ("cnez", file);
   4297       break;
   4298 
   4299     default:
   4300       output_operand_lossage ("'%%%c' is not a valid operand prefix", letter);
   4301       break;
   4302     }
   4303 }
   4304 
   4305 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P.  */
   4306 
   4307 static bool
   4308 loongarch_print_operand_punct_valid_p (unsigned char code)
   4309 {
   4310   return loongarch_print_operand_punct[code];
   4311 }
   4312 
   4313 /* Return true if a FENCE should be emitted to before a memory access to
   4314    implement the release portion of memory model MODEL.  */
   4315 
   4316 static bool
   4317 loongarch_memmodel_needs_rel_acq_fence (enum memmodel model)
   4318 {
   4319   switch (model)
   4320     {
   4321       case MEMMODEL_ACQ_REL:
   4322       case MEMMODEL_SEQ_CST:
   4323       case MEMMODEL_SYNC_SEQ_CST:
   4324       case MEMMODEL_RELEASE:
   4325       case MEMMODEL_SYNC_RELEASE:
   4326       case MEMMODEL_ACQUIRE:
   4327       case MEMMODEL_CONSUME:
   4328       case MEMMODEL_SYNC_ACQUIRE:
   4329 	return true;
   4330 
   4331       case MEMMODEL_RELAXED:
   4332 	return false;
   4333 
   4334       default:
   4335 	gcc_unreachable ();
   4336     }
   4337 }
   4338 
   4339 /* Return true if a FENCE should be emitted after a failed CAS to
   4340    implement the acquire semantic of failure_memorder.  */
   4341 
   4342 static bool
   4343 loongarch_cas_failure_memorder_needs_acquire (enum memmodel model)
   4344 {
   4345   switch (memmodel_base (model))
   4346     {
   4347     case MEMMODEL_ACQUIRE:
   4348     case MEMMODEL_ACQ_REL:
   4349     case MEMMODEL_SEQ_CST:
   4350       return true;
   4351 
   4352     case MEMMODEL_RELAXED:
   4353     case MEMMODEL_RELEASE:
   4354       return false;
   4355 
   4356     /* MEMMODEL_CONSUME is deliberately not handled because it's always
   4357        replaced by MEMMODEL_ACQUIRE as at now.  If you see an ICE caused by
   4358        MEMMODEL_CONSUME, read the change (re)introducing it carefully and
   4359        decide what to do.  See PR 59448 and get_memmodel in builtins.cc.  */
   4360     default:
   4361       gcc_unreachable ();
   4362     }
   4363 }
   4364 
   4365 /* Implement TARGET_PRINT_OPERAND.  The LoongArch-specific operand codes are:
   4366 
   4367    'X'	Print CONST_INT OP in hexadecimal format.
   4368    'x'	Print the low 16 bits of CONST_INT OP in hexadecimal format.
   4369    'd'	Print CONST_INT OP in decimal.
   4370    'm'	Print one less than CONST_INT OP in decimal.
   4371    'y'	Print exact log2 of CONST_INT OP in decimal.
   4372    'C'	Print the integer branch condition for comparison OP.
   4373    'N'	Print the inverse of the integer branch condition for comparison OP.
   4374    'F'	Print the FPU branch condition for comparison OP.
   4375    'W'	Print the inverse of the FPU branch condition for comparison OP.
   4376    'T'	Print 'f' for (eq:CC ...), 't' for (ne:CC ...),
   4377 	      'z' for (eq:?I ...), 'n' for (ne:?I ...).
   4378    't'	Like 'T', but with the EQ/NE cases reversed
   4379    'Y'	Print loongarch_fp_conditions[INTVAL (OP)]
   4380    'Z'	Print OP and a comma for 8CC, otherwise print nothing.
   4381    'z'	Print $0 if OP is zero, otherwise print OP normally.
   4382    'b'	Print the address of a memory operand, without offset.
   4383    'V'	Print exact log2 of CONST_INT OP element 0 of a replicated
   4384 	  CONST_VECTOR in decimal.
   4385    'A'	Print a _DB suffix if the memory model requires a release.
   4386    'G'	Print a DBAR insn for CAS failure (with an acquire semantic if
   4387 	needed, otherwise a simple load-load barrier).
   4388    'i'	Print i if the operand is not a register.  */
   4389 
   4390 static void
   4391 loongarch_print_operand (FILE *file, rtx op, int letter)
   4392 {
   4393   enum rtx_code code;
   4394 
   4395   if (loongarch_print_operand_punct_valid_p (letter))
   4396     {
   4397       loongarch_print_operand_punctuation (file, letter);
   4398       return;
   4399     }
   4400 
   4401   gcc_assert (op);
   4402   code = GET_CODE (op);
   4403 
   4404   switch (letter)
   4405     {
   4406     case 'X':
   4407       if (CONST_INT_P (op))
   4408 	fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op));
   4409       else
   4410 	output_operand_lossage ("invalid use of '%%%c'", letter);
   4411       break;
   4412 
   4413     case 'x':
   4414       if (CONST_INT_P (op))
   4415 	fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op) & 0xffff);
   4416       else
   4417 	output_operand_lossage ("invalid use of '%%%c'", letter);
   4418       break;
   4419 
   4420     case 'd':
   4421       if (CONST_INT_P (op))
   4422 	fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op));
   4423       else
   4424 	output_operand_lossage ("invalid use of '%%%c'", letter);
   4425       break;
   4426 
   4427     case 'm':
   4428       if (CONST_INT_P (op))
   4429 	fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1);
   4430       else
   4431 	output_operand_lossage ("invalid use of '%%%c'", letter);
   4432       break;
   4433 
   4434     case 'y':
   4435       if (CONST_INT_P (op))
   4436 	{
   4437 	  int val = exact_log2 (INTVAL (op));
   4438 	  if (val != -1)
   4439 	    fprintf (file, "%d", val);
   4440 	  else
   4441 	    output_operand_lossage ("invalid use of '%%%c'", letter);
   4442 	}
   4443       else
   4444 	output_operand_lossage ("invalid use of '%%%c'", letter);
   4445       break;
   4446 
   4447     case 'V':
   4448       if (CONST_VECTOR_P (op))
   4449 	{
   4450 	  machine_mode mode = GET_MODE_INNER (GET_MODE (op));
   4451 	  unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (op, 0));
   4452 	  int vlog2 = exact_log2 (val & GET_MODE_MASK (mode));
   4453 	  if (vlog2 != -1)
   4454 	    fprintf (file, "%d", vlog2);
   4455 	  else
   4456 	    output_operand_lossage ("invalid use of '%%%c'", letter);
   4457 	}
   4458       else
   4459 	output_operand_lossage ("invalid use of '%%%c'", letter);
   4460       break;
   4461 
   4462     case 'C':
   4463       loongarch_print_int_branch_condition (file, code, letter);
   4464       break;
   4465 
   4466     case 'N':
   4467       loongarch_print_int_branch_condition (file, reverse_condition (code),
   4468 					    letter);
   4469       break;
   4470 
   4471     case 'F':
   4472       loongarch_print_float_branch_condition (file, code, letter);
   4473       break;
   4474 
   4475     case 'W':
   4476       loongarch_print_float_branch_condition (file, reverse_condition (code),
   4477 					      letter);
   4478       break;
   4479 
   4480     case 'T':
   4481     case 't':
   4482       {
   4483 	int truth = (code == NE) == (letter == 'T');
   4484 	fputc ("zfnt"[truth * 2 + FCC_REG_P (REGNO (XEXP (op, 0)))], file);
   4485       }
   4486       break;
   4487 
   4488     case 'Y':
   4489       if (code == CONST_INT
   4490 	  && UINTVAL (op) < ARRAY_SIZE (loongarch_fp_conditions))
   4491 	fputs (loongarch_fp_conditions[UINTVAL (op)], file);
   4492       else
   4493 	output_operand_lossage ("'%%%c' is not a valid operand prefix",
   4494 				letter);
   4495       break;
   4496 
   4497     case 'Z':
   4498       loongarch_print_operand (file, op, 0);
   4499       fputc (',', file);
   4500       break;
   4501 
   4502     case 'A':
   4503       if (loongarch_memmodel_needs_rel_acq_fence ((enum memmodel) INTVAL (op)))
   4504 	fputs ("_db", file);
   4505       break;
   4506 
   4507     case 'G':
   4508       if (loongarch_cas_failure_memorder_needs_acquire (
   4509 	    memmodel_from_int (INTVAL (op))))
   4510 	fputs ("dbar\t0b10100", file);
   4511       else
   4512 	fputs ("dbar\t0x700", file);
   4513       break;
   4514 
   4515     case 'i':
   4516       if (code != REG)
   4517 	fputs ("i", file);
   4518       break;
   4519 
   4520     default:
   4521       switch (code)
   4522 	{
   4523 	case REG:
   4524 	  {
   4525 	    unsigned int regno = REGNO (op);
   4526 	    if (letter && letter != 'z')
   4527 	      output_operand_lossage ("invalid use of '%%%c'", letter);
   4528 	    fprintf (file, "%s", reg_names[regno]);
   4529 	  }
   4530 	  break;
   4531 
   4532 	case MEM:
   4533 	  if (letter == 'D')
   4534 	    output_address (GET_MODE (op),
   4535 			    plus_constant (Pmode, XEXP (op, 0), 4));
   4536 	  else if (letter == 'b')
   4537 	    {
   4538 	      gcc_assert (REG_P (XEXP (op, 0)));
   4539 	      loongarch_print_operand (file, XEXP (op, 0), 0);
   4540 	    }
   4541 	  else if (letter && letter != 'z')
   4542 	    output_operand_lossage ("invalid use of '%%%c'", letter);
   4543 	  else
   4544 	    output_address (GET_MODE (op), XEXP (op, 0));
   4545 	  break;
   4546 
   4547 	default:
   4548 	  if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
   4549 	    fputs (reg_names[GP_REG_FIRST], file);
   4550 	  else if (letter && letter != 'z')
   4551 	    output_operand_lossage ("invalid use of '%%%c'", letter);
   4552 	  else
   4553 	    output_addr_const (file, loongarch_strip_unspec_address (op));
   4554 	  break;
   4555 	}
   4556     }
   4557 }
   4558 
   4559 /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
   4560 
   4561 static void
   4562 loongarch_print_operand_address (FILE *file, machine_mode /* mode  */, rtx x)
   4563 {
   4564   struct loongarch_address_info addr;
   4565 
   4566   if (loongarch_classify_address (&addr, x, word_mode, true))
   4567     switch (addr.type)
   4568       {
   4569       case ADDRESS_REG:
   4570 	fprintf (file, "%s,", reg_names[REGNO (addr.reg)]);
   4571 	loongarch_print_operand (file, addr.offset, 0);
   4572 	return;
   4573 
   4574       case ADDRESS_REG_REG:
   4575 	fprintf (file, "%s,%s", reg_names[REGNO (addr.reg)],
   4576 				reg_names[REGNO (addr.offset)]);
   4577 	return;
   4578 
   4579       case ADDRESS_CONST_INT:
   4580 	fprintf (file, "%s,", reg_names[GP_REG_FIRST]);
   4581 	output_addr_const (file, x);
   4582 	return;
   4583 
   4584       case ADDRESS_SYMBOLIC:
   4585 	output_addr_const (file, loongarch_strip_unspec_address (x));
   4586 	return;
   4587       }
   4588   if (CONST_INT_P (x))
   4589     output_addr_const (file, x);
   4590   else
   4591     gcc_unreachable ();
   4592 }
   4593 
   4594 /* Implement TARGET_ASM_SELECT_RTX_SECTION.  */
   4595 
   4596 static section *
   4597 loongarch_select_rtx_section (machine_mode mode, rtx x,
   4598 			      unsigned HOST_WIDE_INT align)
   4599 {
   4600   /* ??? Consider using mergeable small data sections.  */
   4601   if (loongarch_rtx_constant_in_small_data_p (mode))
   4602     return get_named_section (NULL, ".sdata", 0);
   4603 
   4604   return default_elf_select_rtx_section (mode, x, align);
   4605 }
   4606 
   4607 /* Implement TARGET_ASM_FUNCTION_RODATA_SECTION.
   4608 
   4609    The complication here is that jump tables will use absolute addresses,
   4610    and should therefore not be included in the read-only part of a DSO.
   4611    Handle such cases by selecting a normal data section instead of a
   4612    read-only one.  The logic apes that in default_function_rodata_section.  */
   4613 
   4614 static section *
   4615 loongarch_function_rodata_section (tree decl, bool)
   4616 {
   4617   return default_function_rodata_section (decl, false);
   4618 }
   4619 
   4620 /* Implement TARGET_IN_SMALL_DATA_P.  */
   4621 
   4622 static bool
   4623 loongarch_in_small_data_p (const_tree decl)
   4624 {
   4625   int size;
   4626 
   4627   if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
   4628     return false;
   4629 
   4630   if (VAR_P (decl) && DECL_SECTION_NAME (decl) != 0)
   4631     {
   4632       const char *name;
   4633 
   4634       /* Reject anything that isn't in a known small-data section.  */
   4635       name = DECL_SECTION_NAME (decl);
   4636       if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
   4637 	return false;
   4638 
   4639       /* If a symbol is defined externally, the assembler will use the
   4640 	 usual -G rules when deciding how to implement macros.  */
   4641       if (!DECL_EXTERNAL (decl))
   4642 	return true;
   4643     }
   4644 
   4645   /* We have traditionally not treated zero-sized objects as small data,
   4646      so this is now effectively part of the ABI.  */
   4647   size = int_size_in_bytes (TREE_TYPE (decl));
   4648   return size > 0 && size <= g_switch_value;
   4649 }
   4650 
   4651 /* The LoongArch debug format wants all automatic variables and arguments
   4652    to be in terms of the virtual frame pointer (stack pointer before
   4653    any adjustment in the function), while the LoongArch linker wants
   4654    the frame pointer to be the stack pointer after the initial
   4655    adjustment.  So, we do the adjustment here.  The arg pointer (which
   4656    is eliminated) points to the virtual frame pointer, while the frame
   4657    pointer (which may be eliminated) points to the stack pointer after
   4658    the initial adjustments.  */
   4659 
   4660 HOST_WIDE_INT
   4661 loongarch_debugger_offset (rtx addr, HOST_WIDE_INT offset)
   4662 {
   4663   rtx offset2 = const0_rtx;
   4664   rtx reg = eliminate_constant_term (addr, &offset2);
   4665 
   4666   if (offset == 0)
   4667     offset = INTVAL (offset2);
   4668 
   4669   if (reg == stack_pointer_rtx
   4670       || reg == frame_pointer_rtx
   4671       || reg == hard_frame_pointer_rtx)
   4672     {
   4673       offset -= cfun->machine->frame.total_size;
   4674       if (reg == hard_frame_pointer_rtx)
   4675 	offset += cfun->machine->frame.hard_frame_pointer_offset;
   4676     }
   4677 
   4678   return offset;
   4679 }
   4680 
   4681 /* Implement ASM_OUTPUT_EXTERNAL.  */
   4682 
   4683 void
   4684 loongarch_output_external (FILE *file, tree decl, const char *name)
   4685 {
   4686   default_elf_asm_output_external (file, decl, name);
   4687 
   4688   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
   4689      set in order to avoid putting out names that are never really
   4690      used.  */
   4691   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
   4692     {
   4693       if (loongarch_in_small_data_p (decl))
   4694 	{
   4695 	  /* When using assembler macros, emit .extern directives for
   4696 	     all small-data externs so that the assembler knows how
   4697 	     big they are.
   4698 
   4699 	     In most cases it would be safe (though pointless) to emit
   4700 	     .externs for other symbols too.  One exception is when an
   4701 	     object is within the -G limit but declared by the user to
   4702 	     be in a section other than .sbss or .sdata.  */
   4703 	  fputs ("\t.extern\t", file);
   4704 	  assemble_name (file, name);
   4705 	  fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC "\n",
   4706 		   int_size_in_bytes (TREE_TYPE (decl)));
   4707 	}
   4708     }
   4709 }
   4710 
   4711 /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL.  */
   4712 
   4713 static void ATTRIBUTE_UNUSED
   4714 loongarch_output_dwarf_dtprel (FILE *file, int size, rtx x)
   4715 {
   4716   switch (size)
   4717     {
   4718     case 4:
   4719       fputs ("\t.dtprelword\t", file);
   4720       break;
   4721 
   4722     case 8:
   4723       fputs ("\t.dtpreldword\t", file);
   4724       break;
   4725 
   4726     default:
   4727       gcc_unreachable ();
   4728     }
   4729   output_addr_const (file, x);
   4730   fputs ("+0x8000", file);
   4731 }
   4732 
   4733 /* Implement ASM_OUTPUT_ASCII.  */
   4734 
   4735 void
   4736 loongarch_output_ascii (FILE *stream, const char *string, size_t len)
   4737 {
   4738   size_t i;
   4739   int cur_pos;
   4740 
   4741   cur_pos = 17;
   4742   fprintf (stream, "\t.ascii\t\"");
   4743   for (i = 0; i < len; i++)
   4744     {
   4745       int c;
   4746 
   4747       c = (unsigned char) string[i];
   4748       if (ISPRINT (c))
   4749 	{
   4750 	  if (c == '\\' || c == '\"')
   4751 	    {
   4752 	      putc ('\\', stream);
   4753 	      cur_pos++;
   4754 	    }
   4755 	  putc (c, stream);
   4756 	  cur_pos++;
   4757 	}
   4758       else
   4759 	{
   4760 	  fprintf (stream, "\\%03o", c);
   4761 	  cur_pos += 4;
   4762 	}
   4763 
   4764       if (cur_pos > 72 && i + 1 < len)
   4765 	{
   4766 	  cur_pos = 17;
   4767 	  fprintf (stream, "\"\n\t.ascii\t\"");
   4768 	}
   4769     }
   4770   fprintf (stream, "\"\n");
   4771 }
   4772 
   4773 /* Implement TARGET_FRAME_POINTER_REQUIRED.  */
   4774 
   4775 static bool
   4776 loongarch_frame_pointer_required (void)
   4777 {
   4778   /* If the function contains dynamic stack allocations, we need to
   4779      use the frame pointer to access the static parts of the frame.  */
   4780   if (cfun->calls_alloca)
   4781     return true;
   4782 
   4783   return false;
   4784 }
   4785 
   4786 /* Implement TARGET_CAN_ELIMINATE.  Make sure that we're not trying
   4787    to eliminate to the wrong hard frame pointer.  */
   4788 
   4789 static bool
   4790 loongarch_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
   4791 {
   4792   return (to == HARD_FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM);
   4793 }
   4794 
   4795 /* Implement RETURN_ADDR_RTX.  We do not support moving back to a
   4796    previous frame.  */
   4797 
   4798 rtx
   4799 loongarch_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
   4800 {
   4801   if (count != 0)
   4802     return const0_rtx;
   4803 
   4804   return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
   4805 }
   4806 
   4807 /* Emit code to change the current function's return address to
   4808    ADDRESS.  SCRATCH is available as a scratch register, if needed.
   4809    ADDRESS and SCRATCH are both word-mode GPRs.  */
   4810 
   4811 void
   4812 loongarch_set_return_address (rtx address, rtx scratch)
   4813 {
   4814   rtx slot_address;
   4815 
   4816   gcc_assert (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM));
   4817 
   4818   if (frame_pointer_needed)
   4819     slot_address = loongarch_add_offset (scratch, hard_frame_pointer_rtx,
   4820 					 -UNITS_PER_WORD);
   4821   else
   4822     slot_address = loongarch_add_offset (scratch, stack_pointer_rtx,
   4823 					 cfun->machine->frame.gp_sp_offset);
   4824 
   4825   loongarch_emit_move (gen_frame_mem (GET_MODE (address), slot_address),
   4826 		       address);
   4827 }
   4828 
   4829 /* Return true if register REGNO can store a value of mode MODE.
   4830    The result of this function is cached in loongarch_hard_regno_mode_ok.  */
   4831 
   4832 static bool
   4833 loongarch_hard_regno_mode_ok_uncached (unsigned int regno, machine_mode mode)
   4834 {
   4835   unsigned int size;
   4836   enum mode_class mclass;
   4837 
   4838   if (mode == FCCmode)
   4839     return FCC_REG_P (regno);
   4840 
   4841   size = GET_MODE_SIZE (mode);
   4842   mclass = GET_MODE_CLASS (mode);
   4843 
   4844   if (GP_REG_P (regno))
   4845     return ((regno - GP_REG_FIRST) & 1) == 0 || size <= UNITS_PER_WORD;
   4846 
   4847   if (FP_REG_P (regno))
   4848     {
   4849       if (mclass == MODE_FLOAT
   4850 	  || mclass == MODE_COMPLEX_FLOAT
   4851 	  || mclass == MODE_VECTOR_FLOAT)
   4852 	return size <= UNITS_PER_FPVALUE;
   4853 
   4854       /* Allow integer modes that fit into a single register.  We need
   4855 	 to put integers into FPRs when using instructions like CVT
   4856 	 and TRUNC.  There's no point allowing sizes smaller than a word,
   4857 	 because the FPU has no appropriate load/store instructions.  */
   4858       if (mclass == MODE_INT)
   4859 	return size >= MIN_UNITS_PER_WORD && size <= UNITS_PER_FPREG;
   4860     }
   4861 
   4862   return false;
   4863 }
   4864 
   4865 /* Implement TARGET_HARD_REGNO_MODE_OK.  */
   4866 
   4867 static bool
   4868 loongarch_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
   4869 {
   4870   return loongarch_hard_regno_mode_ok_p[mode][regno];
   4871 }
   4872 
   4873 /* Implement TARGET_HARD_REGNO_NREGS.  */
   4874 
   4875 static unsigned int
   4876 loongarch_hard_regno_nregs (unsigned int regno, machine_mode mode)
   4877 {
   4878   if (FCC_REG_P (regno))
   4879     /* The size of FP status registers is always 4, because they only hold
   4880        FCCmode values, and FCCmode is always considered to be 4 bytes wide.  */
   4881     return (GET_MODE_SIZE (mode) + 3) / 4;
   4882 
   4883   if (FP_REG_P (regno))
   4884     return (GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG;
   4885 
   4886   /* All other registers are word-sized.  */
   4887   return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
   4888 }
   4889 
   4890 /* Implement CLASS_MAX_NREGS, taking the maximum of the cases
   4891    in loongarch_hard_regno_nregs.  */
   4892 
   4893 int
   4894 loongarch_class_max_nregs (enum reg_class rclass, machine_mode mode)
   4895 {
   4896   int size;
   4897   HARD_REG_SET left;
   4898 
   4899   size = 0x8000;
   4900   left = reg_class_contents[rclass];
   4901   if (hard_reg_set_intersect_p (left, reg_class_contents[(int) FCC_REGS]))
   4902     {
   4903       if (loongarch_hard_regno_mode_ok (FCC_REG_FIRST, mode))
   4904 	size = MIN (size, 4);
   4905 
   4906       left &= ~reg_class_contents[FCC_REGS];
   4907     }
   4908   if (hard_reg_set_intersect_p (left, reg_class_contents[(int) FP_REGS]))
   4909     {
   4910       if (loongarch_hard_regno_mode_ok (FP_REG_FIRST, mode))
   4911 	size = MIN (size, UNITS_PER_FPREG);
   4912 
   4913       left &= ~reg_class_contents[FP_REGS];
   4914     }
   4915   if (!hard_reg_set_empty_p (left))
   4916     size = MIN (size, UNITS_PER_WORD);
   4917   return (GET_MODE_SIZE (mode) + size - 1) / size;
   4918 }
   4919 
   4920 /* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */
   4921 
   4922 static bool
   4923 loongarch_can_change_mode_class (machine_mode, machine_mode,
   4924 				 reg_class_t rclass)
   4925 {
   4926   return !reg_classes_intersect_p (FP_REGS, rclass);
   4927 }
   4928 
   4929 /* Return true if moves in mode MODE can use the FPU's fmov.fmt instruction,
   4930 */
   4931 
   4932 static bool
   4933 loongarch_mode_ok_for_mov_fmt_p (machine_mode mode)
   4934 {
   4935   switch (mode)
   4936     {
   4937     case E_FCCmode:
   4938     case E_SFmode:
   4939       return TARGET_HARD_FLOAT;
   4940 
   4941     case E_DFmode:
   4942       return TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT;
   4943 
   4944     default:
   4945       return 0;
   4946     }
   4947 }
   4948 
   4949 /* Implement TARGET_MODES_TIEABLE_P.  */
   4950 
   4951 static bool
   4952 loongarch_modes_tieable_p (machine_mode mode1, machine_mode mode2)
   4953 {
   4954   /* FPRs allow no mode punning, so it's not worth tying modes if we'd
   4955      prefer to put one of them in FPRs.  */
   4956   return (mode1 == mode2
   4957 	  || (!loongarch_mode_ok_for_mov_fmt_p (mode1)
   4958 	      && !loongarch_mode_ok_for_mov_fmt_p (mode2)));
   4959 }
   4960 
   4961 /* Implement TARGET_PREFERRED_RELOAD_CLASS.  */
   4962 
   4963 static reg_class_t
   4964 loongarch_preferred_reload_class (rtx x, reg_class_t rclass)
   4965 {
   4966   if (reg_class_subset_p (FP_REGS, rclass)
   4967       && loongarch_mode_ok_for_mov_fmt_p (GET_MODE (x)))
   4968     return FP_REGS;
   4969 
   4970   if (reg_class_subset_p (GR_REGS, rclass))
   4971     rclass = GR_REGS;
   4972 
   4973   return rclass;
   4974 }
   4975 
   4976 /* RCLASS is a class involved in a REGISTER_MOVE_COST calculation.
   4977    Return a "canonical" class to represent it in later calculations.  */
   4978 
   4979 static reg_class_t
   4980 loongarch_canonicalize_move_class (reg_class_t rclass)
   4981 {
   4982   if (reg_class_subset_p (rclass, GENERAL_REGS))
   4983     rclass = GENERAL_REGS;
   4984 
   4985   return rclass;
   4986 }
   4987 
   4988 /* Return the cost of moving a value from a register of class FROM to a GPR.
   4989    Return 0 for classes that are unions of other classes handled by this
   4990    function.  */
   4991 
   4992 static int
   4993 loongarch_move_to_gpr_cost (reg_class_t from)
   4994 {
   4995   switch (from)
   4996     {
   4997     case GENERAL_REGS:
   4998       /* MOVE macro.  */
   4999       return 2;
   5000 
   5001     case FP_REGS:
   5002       /* MOVFR2GR, etc.  */
   5003       return 4;
   5004 
   5005     default:
   5006       return 0;
   5007     }
   5008 }
   5009 
   5010 /* Return the cost of moving a value from a GPR to a register of class TO.
   5011    Return 0 for classes that are unions of other classes handled by this
   5012    function.  */
   5013 
   5014 static int
   5015 loongarch_move_from_gpr_cost (reg_class_t to)
   5016 {
   5017   switch (to)
   5018     {
   5019     case GENERAL_REGS:
   5020       /*MOVE macro.  */
   5021       return 2;
   5022 
   5023     case FP_REGS:
   5024       /* MOVGR2FR, etc.  */
   5025       return 4;
   5026 
   5027     default:
   5028       return 0;
   5029     }
   5030 }
   5031 
   5032 /* Implement TARGET_REGISTER_MOVE_COST.  Return 0 for classes that are the
   5033    maximum of the move costs for subclasses; regclass will work out
   5034    the maximum for us.  */
   5035 
   5036 static int
   5037 loongarch_register_move_cost (machine_mode mode, reg_class_t from,
   5038 			      reg_class_t to)
   5039 {
   5040   reg_class_t dregs;
   5041   int cost1, cost2;
   5042 
   5043   from = loongarch_canonicalize_move_class (from);
   5044   to = loongarch_canonicalize_move_class (to);
   5045 
   5046   /* Handle moves that can be done without using general-purpose registers.  */
   5047   if (from == FP_REGS)
   5048     {
   5049       if (to == FP_REGS && loongarch_mode_ok_for_mov_fmt_p (mode))
   5050 	/* FMOV.FMT.  */
   5051 	return 4;
   5052     }
   5053 
   5054   /* Handle cases in which only one class deviates from the ideal.  */
   5055   dregs = GENERAL_REGS;
   5056   if (from == dregs)
   5057     return loongarch_move_from_gpr_cost (to);
   5058   if (to == dregs)
   5059     return loongarch_move_to_gpr_cost (from);
   5060 
   5061   /* Handles cases that require a GPR temporary.  */
   5062   cost1 = loongarch_move_to_gpr_cost (from);
   5063   if (cost1 != 0)
   5064     {
   5065       cost2 = loongarch_move_from_gpr_cost (to);
   5066       if (cost2 != 0)
   5067 	return cost1 + cost2;
   5068     }
   5069 
   5070   return 0;
   5071 }
   5072 
   5073 /* Implement TARGET_MEMORY_MOVE_COST.  */
   5074 
   5075 static int
   5076 loongarch_memory_move_cost (machine_mode mode, reg_class_t rclass, bool in)
   5077 {
   5078   return (loongarch_cost->memory_latency
   5079 	  + memory_move_secondary_cost (mode, rclass, in));
   5080 }
   5081 
   5082 /* Return the register class required for a secondary register when
   5083    copying between one of the registers in RCLASS and value X, which
   5084    has mode MODE.  X is the source of the move if IN_P, otherwise it
   5085    is the destination.  Return NO_REGS if no secondary register is
   5086    needed.  */
   5087 
   5088 static reg_class_t
   5089 loongarch_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x,
   5090 			    reg_class_t rclass, machine_mode mode,
   5091 			    secondary_reload_info *sri ATTRIBUTE_UNUSED)
   5092 {
   5093   int regno;
   5094 
   5095   regno = true_regnum (x);
   5096 
   5097   if (reg_class_subset_p (rclass, FP_REGS))
   5098     {
   5099       if (regno < 0
   5100 	  || (MEM_P (x)
   5101 	      && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)))
   5102 	/* In this case we can use fld.s, fst.s, fld.d or fst.d.  */
   5103 	return NO_REGS;
   5104 
   5105       if (GP_REG_P (regno) || x == CONST0_RTX (mode))
   5106 	/* In this case we can use movgr2fr.s, movfr2gr.s, movgr2fr.d or
   5107 	 * movfr2gr.d.  */
   5108 	return NO_REGS;
   5109 
   5110       if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (mode, x))
   5111 	/* We can force the constant to memory and use fld.s
   5112 	   and fld.d.  As above, we will use pairs of lwc1s if
   5113 	   ldc1 is not supported.  */
   5114 	return NO_REGS;
   5115 
   5116       if (FP_REG_P (regno) && loongarch_mode_ok_for_mov_fmt_p (mode))
   5117 	/* In this case we can use fmov.{s/d}.  */
   5118 	return NO_REGS;
   5119 
   5120       /* Otherwise, we need to reload through an integer register.  */
   5121       return GR_REGS;
   5122     }
   5123   if (FP_REG_P (regno))
   5124     return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS;
   5125 
   5126   return NO_REGS;
   5127 }
   5128 
   5129 /* Implement TARGET_VALID_POINTER_MODE.  */
   5130 
   5131 static bool
   5132 loongarch_valid_pointer_mode (scalar_int_mode mode)
   5133 {
   5134   return mode == SImode || (TARGET_64BIT && mode == DImode);
   5135 }
   5136 
   5137 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P.  */
   5138 
   5139 static bool
   5140 loongarch_scalar_mode_supported_p (scalar_mode mode)
   5141 {
   5142   if (ALL_FIXED_POINT_MODE_P (mode)
   5143       && GET_MODE_PRECISION (mode) <= 2 * BITS_PER_WORD)
   5144     return true;
   5145 
   5146   return default_scalar_mode_supported_p (mode);
   5147 }
   5148 
   5149 /* Return the assembly code for INSN, which has the operands given by
   5150    OPERANDS, and which branches to OPERANDS[0] if some condition is true.
   5151    BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[0]
   5152    is in range of a direct branch.  BRANCH_IF_FALSE is an inverted
   5153    version of BRANCH_IF_TRUE.  */
   5154 
   5155 const char *
   5156 loongarch_output_conditional_branch (rtx_insn *insn, rtx *operands,
   5157 				     const char *branch_if_true,
   5158 				     const char *branch_if_false)
   5159 {
   5160   unsigned int length;
   5161   rtx taken;
   5162 
   5163   gcc_assert (LABEL_P (operands[0]));
   5164 
   5165   length = get_attr_length (insn);
   5166   if (length <= 4)
   5167     {
   5168       return branch_if_true;
   5169     }
   5170 
   5171   /* Generate a reversed branch around a direct jump.  */
   5172   rtx_code_label *not_taken = gen_label_rtx ();
   5173   taken = operands[0];
   5174 
   5175   /* Generate the reversed branch to NOT_TAKEN.  */
   5176   operands[0] = not_taken;
   5177   output_asm_insn (branch_if_false, operands);
   5178 
   5179   output_asm_insn ("b\t%0", &taken);
   5180 
   5181   /* Output NOT_TAKEN.  */
   5182   targetm.asm_out.internal_label (asm_out_file, "L",
   5183 				  CODE_LABEL_NUMBER (not_taken));
   5184   return "";
   5185 }
   5186 
   5187 /* Return the assembly code for INSN, which branches to OPERANDS[0]
   5188    if some equality condition is true.  The condition is given by
   5189    OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
   5190    OPERANDS[1].  OPERANDS[2] is the comparison's first operand;
   5191    OPERANDS[3] is the second operand and may be zero or a register.  */
   5192 
   5193 const char *
   5194 loongarch_output_equal_conditional_branch (rtx_insn *insn, rtx *operands,
   5195 					   bool inverted_p)
   5196 {
   5197   const char *branch[2];
   5198   if (operands[3] == const0_rtx)
   5199     {
   5200       branch[!inverted_p] = LARCH_BRANCH ("b%C1z", "%2,%0");
   5201       branch[inverted_p] = LARCH_BRANCH ("b%N1z", "%2,%0");
   5202     }
   5203   else
   5204     {
   5205       branch[!inverted_p] = LARCH_BRANCH ("b%C1", "%2,%z3,%0");
   5206       branch[inverted_p] = LARCH_BRANCH ("b%N1", "%2,%z3,%0");
   5207     }
   5208 
   5209   return loongarch_output_conditional_branch (insn, operands, branch[1],
   5210 					      branch[0]);
   5211 }
   5212 
   5213 /* Return the assembly code for INSN, which branches to OPERANDS[0]
   5214    if some ordering condition is true.  The condition is given by
   5215    OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
   5216    OPERANDS[1].  OPERANDS[2] is the comparison's first operand;
   5217    OPERANDS[3] is the second operand and may be zero or a register.  */
   5218 
   5219 const char *
   5220 loongarch_output_order_conditional_branch (rtx_insn *insn, rtx *operands,
   5221 					   bool inverted_p)
   5222 {
   5223   const char *branch[2];
   5224 
   5225   /* Make BRANCH[1] branch to OPERANDS[0] when the condition is true.
   5226      Make BRANCH[0] branch on the inverse condition.  */
   5227   if (operands[3] != const0_rtx)
   5228     {
   5229       /* Handle degenerate cases that should not, but do, occur.  */
   5230       if (REGNO (operands[2]) == REGNO (operands[3]))
   5231 	{
   5232 	  switch (GET_CODE (operands[1]))
   5233 	    {
   5234 	    case LT:
   5235 	    case LTU:
   5236 	    case GT:
   5237 	    case GTU:
   5238 	      inverted_p = !inverted_p;
   5239 	      /* Fall through.  */
   5240 	    case LE:
   5241 	    case LEU:
   5242 	    case GE:
   5243 	    case GEU:
   5244 	      branch[!inverted_p] = LARCH_BRANCH ("b", "%0");
   5245 	      branch[inverted_p] = "\t# branch never";
   5246 	      break;
   5247 	    default:
   5248 	      gcc_unreachable ();
   5249 	    }
   5250 	}
   5251       else
   5252 	{
   5253 	  switch (GET_CODE (operands[1]))
   5254 	    {
   5255 	    case LE:
   5256 	    case LEU:
   5257 	    case GT:
   5258 	    case GTU:
   5259 	    case LT:
   5260 	    case LTU:
   5261 	    case GE:
   5262 	    case GEU:
   5263 	      branch[!inverted_p] = LARCH_BRANCH ("b%C1", "%2,%3,%0");
   5264 	      branch[inverted_p] = LARCH_BRANCH ("b%N1", "%2,%3,%0");
   5265 	      break;
   5266 	    default:
   5267 	      gcc_unreachable ();
   5268 	    }
   5269 	}
   5270     }
   5271   else
   5272     {
   5273       switch (GET_CODE (operands[1]))
   5274 	{
   5275 	  /* These cases are equivalent to comparisons against zero.  */
   5276 	case LEU:
   5277 	case GTU:
   5278 	case LTU:
   5279 	case GEU:
   5280 	case LE:
   5281 	case GT:
   5282 	case LT:
   5283 	case GE:
   5284 	  branch[!inverted_p] = LARCH_BRANCH ("b%C1", "%2,$r0,%0");
   5285 	  branch[inverted_p] = LARCH_BRANCH ("b%N1", "%2,$r0,%0");
   5286 	  break;
   5287 	default:
   5288 	  gcc_unreachable ();
   5289 	}
   5290     }
   5291   return loongarch_output_conditional_branch (insn, operands, branch[1],
   5292 					      branch[0]);
   5293 }
   5294 
   5295 /* Return the assembly code for DIV.{W/D} instruction DIVISION, which has
   5296    the operands given by OPERANDS.  Add in a divide-by-zero check if needed.
   5297    */
   5298 
   5299 const char *
   5300 loongarch_output_division (const char *division, rtx *operands)
   5301 {
   5302   const char *s;
   5303 
   5304   s = division;
   5305   if (loongarch_check_zero_div_p ())
   5306     {
   5307       output_asm_insn (s, operands);
   5308       s = "bne\t%2,%.,1f\n\tbreak\t7\n1:";
   5309     }
   5310   return s;
   5311 }
   5312 
   5313 /* Implement TARGET_SCHED_ADJUST_COST.  We assume that anti and output
   5314    dependencies have no cost.  */
   5315 
   5316 static int
   5317 loongarch_adjust_cost (rtx_insn *, int dep_type, rtx_insn *, int cost,
   5318 		       unsigned int)
   5319 {
   5320   if (dep_type != 0 && (dep_type != REG_DEP_OUTPUT))
   5321     return 0;
   5322   return cost;
   5323 }
   5324 
   5325 /* Return the number of instructions that can be issued per cycle.  */
   5326 
   5327 static int
   5328 loongarch_issue_rate (void)
   5329 {
   5330   if ((unsigned long) LARCH_ACTUAL_TUNE < N_TUNE_TYPES)
   5331     return loongarch_cpu_issue_rate[LARCH_ACTUAL_TUNE];
   5332   else
   5333     return 1;
   5334 }
   5335 
   5336 /* Implement TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD.  This should
   5337    be as wide as the scheduling freedom in the DFA.  */
   5338 
   5339 static int
   5340 loongarch_multipass_dfa_lookahead (void)
   5341 {
   5342   if ((unsigned long) LARCH_ACTUAL_TUNE < N_ARCH_TYPES)
   5343     return loongarch_cpu_multipass_dfa_lookahead[LARCH_ACTUAL_TUNE];
   5344   else
   5345     return 0;
   5346 }
   5347 
   5348 /* Implement TARGET_SCHED_REORDER.  */
   5349 
   5350 static int
   5351 loongarch_sched_reorder (FILE *file ATTRIBUTE_UNUSED,
   5352 			 int verbose ATTRIBUTE_UNUSED,
   5353 			 rtx_insn **ready ATTRIBUTE_UNUSED,
   5354 			 int *nreadyp ATTRIBUTE_UNUSED,
   5355 			 int cycle ATTRIBUTE_UNUSED)
   5356 {
   5357   return loongarch_issue_rate ();
   5358 }
   5359 
   5360 /* Implement TARGET_SCHED_REORDER2.  */
   5361 
   5362 static int
   5363 loongarch_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED,
   5364 			  int verbose ATTRIBUTE_UNUSED,
   5365 			  rtx_insn **ready ATTRIBUTE_UNUSED,
   5366 			  int *nreadyp ATTRIBUTE_UNUSED,
   5367 			  int cycle ATTRIBUTE_UNUSED)
   5368 {
   5369   return cached_can_issue_more;
   5370 }
   5371 
   5372 /* Implement TARGET_SCHED_INIT.  */
   5373 
   5374 static void
   5375 loongarch_sched_init (FILE *file ATTRIBUTE_UNUSED,
   5376 		      int verbose ATTRIBUTE_UNUSED,
   5377 		      int max_ready ATTRIBUTE_UNUSED)
   5378 {}
   5379 
   5380 /* Implement TARGET_SCHED_VARIABLE_ISSUE.  */
   5381 
   5382 static int
   5383 loongarch_variable_issue (FILE *file ATTRIBUTE_UNUSED,
   5384 			  int verbose ATTRIBUTE_UNUSED, rtx_insn *insn,
   5385 			  int more)
   5386 {
   5387   /* Ignore USEs and CLOBBERs; don't count them against the issue rate.  */
   5388   if (USEFUL_INSN_P (insn))
   5389     {
   5390       if (get_attr_type (insn) != TYPE_GHOST)
   5391 	more--;
   5392     }
   5393 
   5394   /* Instructions of type 'multi' should all be split before
   5395      the second scheduling pass.  */
   5396   gcc_assert (!reload_completed
   5397 	      || recog_memoized (insn) < 0
   5398 	      || get_attr_type (insn) != TYPE_MULTI);
   5399 
   5400   cached_can_issue_more = more;
   5401   return more;
   5402 }
   5403 
   5404 /* Given that we have an rtx of the form (prefetch ... WRITE LOCALITY),
   5405    return the first operand of the associated PREF or PREFX insn.  */
   5406 
   5407 rtx
   5408 loongarch_prefetch_cookie (rtx write, rtx locality)
   5409 {
   5410   /* store_streamed / load_streamed.  */
   5411   if (INTVAL (locality) <= 0)
   5412     return GEN_INT (INTVAL (write) + 4);
   5413 
   5414   /* store / load.  */
   5415   if (INTVAL (locality) <= 2)
   5416     return write;
   5417 
   5418   /* store_retained / load_retained.  */
   5419   return GEN_INT (INTVAL (write) + 6);
   5420 }
   5421 
   5422 /* Implement TARGET_ASM_OUTPUT_MI_THUNK.  Generate rtl rather than asm text
   5423    in order to avoid duplicating too much logic from elsewhere.  */
   5424 
   5425 static void
   5426 loongarch_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
   5427 			   HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
   5428 			   tree function)
   5429 {
   5430   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   5431   rtx this_rtx, temp1, temp2, fnaddr;
   5432   rtx_insn *insn;
   5433   bool use_sibcall_p;
   5434 
   5435   /* Pretend to be a post-reload pass while generating rtl.  */
   5436   reload_completed = 1;
   5437 
   5438   /* Mark the end of the (empty) prologue.  */
   5439   emit_note (NOTE_INSN_PROLOGUE_END);
   5440 
   5441   /* Determine if we can use a sibcall to call FUNCTION directly.  */
   5442   fnaddr = XEXP (DECL_RTL (function), 0);
   5443   use_sibcall_p = const_call_insn_operand (fnaddr, Pmode);
   5444 
   5445   /* We need two temporary registers in some cases.  */
   5446   temp1 = gen_rtx_REG (Pmode, 12);
   5447   temp2 = gen_rtx_REG (Pmode, 13);
   5448 
   5449   /* Find out which register contains the "this" pointer.  */
   5450   if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
   5451     this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1);
   5452   else
   5453     this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST);
   5454 
   5455   /* Add DELTA to THIS_RTX.  */
   5456   if (delta != 0)
   5457     {
   5458       rtx offset = GEN_INT (delta);
   5459       if (!IMM12_OPERAND (delta))
   5460 	{
   5461 	  loongarch_emit_move (temp1, offset);
   5462 	  offset = temp1;
   5463 	}
   5464       emit_insn (gen_add3_insn (this_rtx, this_rtx, offset));
   5465     }
   5466 
   5467   /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX.  */
   5468   if (vcall_offset != 0)
   5469     {
   5470       rtx addr;
   5471 
   5472       /* Set TEMP1 to *THIS_RTX.  */
   5473       loongarch_emit_move (temp1, gen_rtx_MEM (Pmode, this_rtx));
   5474 
   5475       /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET.  */
   5476       addr = loongarch_add_offset (temp2, temp1, vcall_offset);
   5477 
   5478       /* Load the offset and add it to THIS_RTX.  */
   5479       loongarch_emit_move (temp1, gen_rtx_MEM (Pmode, addr));
   5480       emit_insn (gen_add3_insn (this_rtx, this_rtx, temp1));
   5481     }
   5482 
   5483   /* Jump to the target function.  Use a sibcall if direct jumps are
   5484      allowed, otherwise load the address into a register first.  */
   5485   if (use_sibcall_p)
   5486     {
   5487       insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
   5488       SIBLING_CALL_P (insn) = 1;
   5489     }
   5490   else
   5491     {
   5492       loongarch_emit_move (temp1, fnaddr);
   5493       emit_jump_insn (gen_indirect_jump (temp1));
   5494     }
   5495 
   5496   /* Run just enough of rest_of_compilation.  This sequence was
   5497      "borrowed" from alpha.c.  */
   5498   insn = get_insns ();
   5499   split_all_insns_noflow ();
   5500   shorten_branches (insn);
   5501   assemble_start_function (thunk_fndecl, fnname);
   5502   final_start_function (insn, file, 1);
   5503   final (insn, file, 1);
   5504   final_end_function ();
   5505   assemble_end_function (thunk_fndecl, fnname);
   5506 
   5507   /* Stop pretending to be a post-reload pass.  */
   5508   reload_completed = 0;
   5509 }
   5510 
   5511 /* Allocate a chunk of memory for per-function machine-dependent data.  */
   5512 
   5513 static struct machine_function *
   5514 loongarch_init_machine_status (void)
   5515 {
   5516   return ggc_cleared_alloc<machine_function> ();
   5517 }
   5518 
   5519 static void
   5520 loongarch_option_override_internal (struct gcc_options *opts,
   5521 				    struct gcc_options *opts_set)
   5522 {
   5523   int i, regno, mode;
   5524 
   5525   if (flag_pic)
   5526     g_switch_value = 0;
   5527 
   5528   /* Handle target-specific options: compute defaults/conflicts etc.  */
   5529   loongarch_config_target (&la_target, la_opt_switches,
   5530 			   la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu,
   5531 			   la_opt_abi_base, la_opt_abi_ext, la_opt_cmodel, 0);
   5532 
   5533   loongarch_update_gcc_opt_status (&la_target, opts, opts_set);
   5534 
   5535   if (TARGET_ABI_LP64)
   5536     flag_pcc_struct_return = 0;
   5537 
   5538   /* Decide which rtx_costs structure to use.  */
   5539   if (optimize_size)
   5540     loongarch_cost = &loongarch_rtx_cost_optimize_size;
   5541   else
   5542     loongarch_cost = &loongarch_cpu_rtx_cost_data[LARCH_ACTUAL_TUNE];
   5543 
   5544   /* If the user hasn't specified a branch cost, use the processor's
   5545      default.  */
   5546   if (loongarch_branch_cost == 0)
   5547     loongarch_branch_cost = loongarch_cost->branch_cost;
   5548 
   5549 
   5550   switch (la_target.cmodel)
   5551     {
   5552       case CMODEL_TINY_STATIC:
   5553       case CMODEL_EXTREME:
   5554 	if (opts->x_flag_plt)
   5555 	  error ("code model %qs and %qs not support %s mode",
   5556 		 "tiny-static", "extreme", "plt");
   5557 	break;
   5558 
   5559       case CMODEL_NORMAL:
   5560       case CMODEL_TINY:
   5561       case CMODEL_LARGE:
   5562 	break;
   5563 
   5564       default:
   5565 	gcc_unreachable ();
   5566     }
   5567 
   5568   loongarch_init_print_operand_punct ();
   5569 
   5570   /* Set up array to map GCC register number to debug register number.
   5571      Ignore the special purpose register numbers.  */
   5572 
   5573   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   5574     {
   5575       if (GP_REG_P (i) || FP_REG_P (i))
   5576 	loongarch_dwarf_regno[i] = i;
   5577       else
   5578 	loongarch_dwarf_regno[i] = INVALID_REGNUM;
   5579     }
   5580 
   5581   /* Set up loongarch_hard_regno_mode_ok.  */
   5582   for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
   5583     for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   5584       loongarch_hard_regno_mode_ok_p[mode][regno]
   5585 	= loongarch_hard_regno_mode_ok_uncached (regno, (machine_mode) mode);
   5586 
   5587   /* Function to allocate machine-dependent function status.  */
   5588   init_machine_status = &loongarch_init_machine_status;
   5589 }
   5590 
   5591 
   5592 /* Implement TARGET_OPTION_OVERRIDE.  */
   5593 
   5594 static void
   5595 loongarch_option_override (void)
   5596 {
   5597   loongarch_option_override_internal (&global_options, &global_options_set);
   5598 }
   5599 
   5600 /* Implement TARGET_OPTION_SAVE.  */
   5601 static void
   5602 loongarch_option_save (struct cl_target_option *,
   5603 		       struct gcc_options *opts,
   5604 		       struct gcc_options *opts_set)
   5605 {
   5606   loongarch_update_gcc_opt_status (&la_target, opts, opts_set);
   5607 }
   5608 
   5609 /* Implement TARGET_OPTION_RESTORE.  */
   5610 static void
   5611 loongarch_option_restore (struct gcc_options *,
   5612 			  struct gcc_options *,
   5613 			  struct cl_target_option *ptr)
   5614 {
   5615   la_target.cpu_arch = ptr->x_la_opt_cpu_arch;
   5616   la_target.cpu_tune = ptr->x_la_opt_cpu_tune;
   5617 
   5618   la_target.isa.fpu = ptr->x_la_opt_fpu;
   5619 
   5620   la_target.cmodel = ptr->x_la_opt_cmodel;
   5621 }
   5622 
   5623 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.  */
   5624 
   5625 static void
   5626 loongarch_conditional_register_usage (void)
   5627 {
   5628   if (!TARGET_HARD_FLOAT)
   5629     accessible_reg_set &= ~(reg_class_contents[FP_REGS]
   5630 			    | reg_class_contents[FCC_REGS]);
   5631 }
   5632 
   5633 /* Implement EH_USES.  */
   5634 
   5635 bool
   5636 loongarch_eh_uses (unsigned int regno ATTRIBUTE_UNUSED)
   5637 {
   5638   return false;
   5639 }
   5640 
   5641 /* Implement EPILOGUE_USES.  */
   5642 
   5643 bool
   5644 loongarch_epilogue_uses (unsigned int regno)
   5645 {
   5646   /* Say that the epilogue uses the return address register.  Note that
   5647      in the case of sibcalls, the values "used by the epilogue" are
   5648      considered live at the start of the called function.  */
   5649   if (regno == RETURN_ADDR_REGNUM)
   5650     return true;
   5651 
   5652   return false;
   5653 }
   5654 
   5655 bool
   5656 loongarch_load_store_bonding_p (rtx *operands, machine_mode mode, bool load_p)
   5657 {
   5658   rtx reg1, reg2, mem1, mem2, base1, base2;
   5659   enum reg_class rc1, rc2;
   5660   HOST_WIDE_INT offset1, offset2;
   5661 
   5662   if (load_p)
   5663     {
   5664       reg1 = operands[0];
   5665       reg2 = operands[2];
   5666       mem1 = operands[1];
   5667       mem2 = operands[3];
   5668     }
   5669   else
   5670     {
   5671       reg1 = operands[1];
   5672       reg2 = operands[3];
   5673       mem1 = operands[0];
   5674       mem2 = operands[2];
   5675     }
   5676 
   5677   if (loongarch_address_insns (XEXP (mem1, 0), mode, false) == 0
   5678       || loongarch_address_insns (XEXP (mem2, 0), mode, false) == 0)
   5679     return false;
   5680 
   5681   loongarch_split_plus (XEXP (mem1, 0), &base1, &offset1);
   5682   loongarch_split_plus (XEXP (mem2, 0), &base2, &offset2);
   5683 
   5684   /* Base regs do not match.  */
   5685   if (!REG_P (base1) || !rtx_equal_p (base1, base2))
   5686     return false;
   5687 
   5688   /* Either of the loads is clobbering base register.  It is legitimate to bond
   5689      loads if second load clobbers base register.  However, hardware does not
   5690      support such bonding.  */
   5691   if (load_p
   5692       && (REGNO (reg1) == REGNO (base1) || (REGNO (reg2) == REGNO (base1))))
   5693     return false;
   5694 
   5695   /* Loading in same registers.  */
   5696   if (load_p && REGNO (reg1) == REGNO (reg2))
   5697     return false;
   5698 
   5699   /* The loads/stores are not of same type.  */
   5700   rc1 = REGNO_REG_CLASS (REGNO (reg1));
   5701   rc2 = REGNO_REG_CLASS (REGNO (reg2));
   5702   if (rc1 != rc2 && !reg_class_subset_p (rc1, rc2)
   5703       && !reg_class_subset_p (rc2, rc1))
   5704     return false;
   5705 
   5706   if (abs (offset1 - offset2) != GET_MODE_SIZE (mode))
   5707     return false;
   5708 
   5709   return true;
   5710 }
   5711 
   5712 /* Implement TARGET_TRAMPOLINE_INIT.  */
   5713 
   5714 static void
   5715 loongarch_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   5716 {
   5717   rtx addr, end_addr, mem;
   5718   rtx trampoline[8];
   5719   unsigned int i, j;
   5720   HOST_WIDE_INT end_addr_offset, static_chain_offset, target_function_offset;
   5721 
   5722   /* Work out the offsets of the pointers from the start of the
   5723      trampoline code.  */
   5724   end_addr_offset = TRAMPOLINE_CODE_SIZE;
   5725   static_chain_offset = end_addr_offset;
   5726   target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
   5727 
   5728   /* Get pointers to the beginning and end of the code block.  */
   5729   addr = force_reg (Pmode, XEXP (m_tramp, 0));
   5730   end_addr
   5731     = loongarch_force_binary (Pmode, PLUS, addr, GEN_INT (end_addr_offset));
   5732 
   5733 #define OP(X) gen_int_mode (X, SImode)
   5734 
   5735   /* Build up the code in TRAMPOLINE.  */
   5736   i = 0;
   5737   /*pcaddi $static_chain,0
   5738     ld.[dw] $tmp,$static_chain,target_function_offset
   5739     ld.[dw] $static_chain,$static_chain,static_chain_offset
   5740     jirl $r0,$tmp,0  */
   5741   trampoline[i++] = OP (0x18000000 | (STATIC_CHAIN_REGNUM - GP_REG_FIRST));
   5742   trampoline[i++] = OP ((ptr_mode == DImode ? 0x28c00000 : 0x28800000)
   5743 			| 19 /* $t7  */
   5744 			| ((STATIC_CHAIN_REGNUM - GP_REG_FIRST) << 5)
   5745 			| ((target_function_offset & 0xfff) << 10));
   5746   trampoline[i++] = OP ((ptr_mode == DImode ? 0x28c00000 : 0x28800000)
   5747 			| (STATIC_CHAIN_REGNUM - GP_REG_FIRST)
   5748 			| ((STATIC_CHAIN_REGNUM - GP_REG_FIRST) << 5)
   5749 			| ((static_chain_offset & 0xfff) << 10));
   5750   trampoline[i++] = OP (0x4c000000 | (19 << 5));
   5751 #undef OP
   5752 
   5753   for (j = 0; j < i; j++)
   5754    {
   5755      mem = adjust_address (m_tramp, SImode, j * GET_MODE_SIZE (SImode));
   5756      loongarch_emit_move (mem, trampoline[j]);
   5757    }
   5758 
   5759   /* Set up the static chain pointer field.  */
   5760   mem = adjust_address (m_tramp, ptr_mode, static_chain_offset);
   5761   loongarch_emit_move (mem, chain_value);
   5762 
   5763   /* Set up the target function field.  */
   5764   mem = adjust_address (m_tramp, ptr_mode, target_function_offset);
   5765   loongarch_emit_move (mem, XEXP (DECL_RTL (fndecl), 0));
   5766 
   5767   /* Flush the code part of the trampoline.  */
   5768   emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE)));
   5769   emit_insn (gen_clear_cache (addr, end_addr));
   5770 }
   5771 
   5772 /* Implement HARD_REGNO_CALLER_SAVE_MODE.  */
   5773 
   5774 machine_mode
   5775 loongarch_hard_regno_caller_save_mode (unsigned int regno, unsigned int nregs,
   5776 				       machine_mode mode)
   5777 {
   5778   /* For performance, avoid saving/restoring upper parts of a register
   5779      by returning MODE as save mode when the mode is known.  */
   5780   if (mode == VOIDmode)
   5781     return choose_hard_reg_mode (regno, nregs, NULL);
   5782   else
   5783     return mode;
   5784 }
   5785 
   5786 /* Implement TARGET_SPILL_CLASS.  */
   5787 
   5788 static reg_class_t
   5789 loongarch_spill_class (reg_class_t rclass ATTRIBUTE_UNUSED,
   5790 		       machine_mode mode ATTRIBUTE_UNUSED)
   5791 {
   5792   return NO_REGS;
   5793 }
   5794 
   5795 /* Implement TARGET_PROMOTE_FUNCTION_MODE.  */
   5796 
   5797 /* This function is equivalent to default_promote_function_mode_always_promote
   5798    except that it returns a promoted mode even if type is NULL_TREE.  This is
   5799    needed by libcalls which have no type (only a mode) such as fixed conversion
   5800    routines that take a signed or unsigned char/short argument and convert it
   5801    to a fixed type.  */
   5802 
   5803 static machine_mode
   5804 loongarch_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
   5805 				 machine_mode mode,
   5806 				 int *punsignedp ATTRIBUTE_UNUSED,
   5807 				 const_tree fntype ATTRIBUTE_UNUSED,
   5808 				 int for_return ATTRIBUTE_UNUSED)
   5809 {
   5810   int unsignedp;
   5811 
   5812   if (type != NULL_TREE)
   5813     return promote_mode (type, mode, punsignedp);
   5814 
   5815   unsignedp = *punsignedp;
   5816   PROMOTE_MODE (mode, unsignedp, type);
   5817   *punsignedp = unsignedp;
   5818   return mode;
   5819 }
   5820 
   5821 /* Implement TARGET_STARTING_FRAME_OFFSET.  See loongarch_compute_frame_info
   5822    for details about the frame layout.  */
   5823 
   5824 static HOST_WIDE_INT
   5825 loongarch_starting_frame_offset (void)
   5826 {
   5827   if (FRAME_GROWS_DOWNWARD)
   5828     return 0;
   5829   return crtl->outgoing_args_size;
   5830 }
   5831 
   5832 /* Initialize the GCC target structure.  */
   5833 #undef TARGET_ASM_ALIGNED_HI_OP
   5834 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
   5835 #undef TARGET_ASM_ALIGNED_SI_OP
   5836 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
   5837 #undef TARGET_ASM_ALIGNED_DI_OP
   5838 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
   5839 
   5840 #undef TARGET_OPTION_OVERRIDE
   5841 #define TARGET_OPTION_OVERRIDE loongarch_option_override
   5842 #define TARGET_OPTION_SAVE loongarch_option_save
   5843 #undef TARGET_OPTION_RESTORE
   5844 #define TARGET_OPTION_RESTORE loongarch_option_restore
   5845 
   5846 
   5847 #undef TARGET_LEGITIMIZE_ADDRESS
   5848 #define TARGET_LEGITIMIZE_ADDRESS loongarch_legitimize_address
   5849 
   5850 #undef TARGET_ASM_SELECT_RTX_SECTION
   5851 #define TARGET_ASM_SELECT_RTX_SECTION loongarch_select_rtx_section
   5852 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
   5853 #define TARGET_ASM_FUNCTION_RODATA_SECTION loongarch_function_rodata_section
   5854 
   5855 #undef TARGET_SCHED_INIT
   5856 #define TARGET_SCHED_INIT loongarch_sched_init
   5857 #undef TARGET_SCHED_REORDER
   5858 #define TARGET_SCHED_REORDER loongarch_sched_reorder
   5859 #undef TARGET_SCHED_REORDER2
   5860 #define TARGET_SCHED_REORDER2 loongarch_sched_reorder2
   5861 #undef TARGET_SCHED_VARIABLE_ISSUE
   5862 #define TARGET_SCHED_VARIABLE_ISSUE loongarch_variable_issue
   5863 #undef TARGET_SCHED_ADJUST_COST
   5864 #define TARGET_SCHED_ADJUST_COST loongarch_adjust_cost
   5865 #undef TARGET_SCHED_ISSUE_RATE
   5866 #define TARGET_SCHED_ISSUE_RATE loongarch_issue_rate
   5867 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
   5868 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
   5869   loongarch_multipass_dfa_lookahead
   5870 
   5871 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
   5872 #define TARGET_FUNCTION_OK_FOR_SIBCALL loongarch_function_ok_for_sibcall
   5873 
   5874 #undef TARGET_VALID_POINTER_MODE
   5875 #define TARGET_VALID_POINTER_MODE loongarch_valid_pointer_mode
   5876 #undef TARGET_REGISTER_MOVE_COST
   5877 #define TARGET_REGISTER_MOVE_COST loongarch_register_move_cost
   5878 #undef TARGET_MEMORY_MOVE_COST
   5879 #define TARGET_MEMORY_MOVE_COST loongarch_memory_move_cost
   5880 #undef TARGET_RTX_COSTS
   5881 #define TARGET_RTX_COSTS loongarch_rtx_costs
   5882 #undef TARGET_ADDRESS_COST
   5883 #define TARGET_ADDRESS_COST loongarch_address_cost
   5884 
   5885 #undef TARGET_IN_SMALL_DATA_P
   5886 #define TARGET_IN_SMALL_DATA_P loongarch_in_small_data_p
   5887 
   5888 #undef TARGET_PREFERRED_RELOAD_CLASS
   5889 #define TARGET_PREFERRED_RELOAD_CLASS loongarch_preferred_reload_class
   5890 
   5891 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
   5892 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
   5893 
   5894 #undef TARGET_EXPAND_BUILTIN_VA_START
   5895 #define TARGET_EXPAND_BUILTIN_VA_START loongarch_va_start
   5896 
   5897 #undef TARGET_PROMOTE_FUNCTION_MODE
   5898 #define TARGET_PROMOTE_FUNCTION_MODE loongarch_promote_function_mode
   5899 #undef TARGET_RETURN_IN_MEMORY
   5900 #define TARGET_RETURN_IN_MEMORY loongarch_return_in_memory
   5901 
   5902 #undef TARGET_FUNCTION_VALUE
   5903 #define TARGET_FUNCTION_VALUE loongarch_function_value
   5904 #undef TARGET_LIBCALL_VALUE
   5905 #define TARGET_LIBCALL_VALUE loongarch_libcall_value
   5906 
   5907 #undef TARGET_ASM_OUTPUT_MI_THUNK
   5908 #define TARGET_ASM_OUTPUT_MI_THUNK loongarch_output_mi_thunk
   5909 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
   5910 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
   5911   hook_bool_const_tree_hwi_hwi_const_tree_true
   5912 
   5913 #undef TARGET_PRINT_OPERAND
   5914 #define TARGET_PRINT_OPERAND loongarch_print_operand
   5915 #undef TARGET_PRINT_OPERAND_ADDRESS
   5916 #define TARGET_PRINT_OPERAND_ADDRESS loongarch_print_operand_address
   5917 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
   5918 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P \
   5919   loongarch_print_operand_punct_valid_p
   5920 
   5921 #undef TARGET_SETUP_INCOMING_VARARGS
   5922 #define TARGET_SETUP_INCOMING_VARARGS loongarch_setup_incoming_varargs
   5923 #undef TARGET_STRICT_ARGUMENT_NAMING
   5924 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
   5925 #undef TARGET_MUST_PASS_IN_STACK
   5926 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
   5927 #undef TARGET_PASS_BY_REFERENCE
   5928 #define TARGET_PASS_BY_REFERENCE loongarch_pass_by_reference
   5929 #undef TARGET_ARG_PARTIAL_BYTES
   5930 #define TARGET_ARG_PARTIAL_BYTES loongarch_arg_partial_bytes
   5931 #undef TARGET_FUNCTION_ARG
   5932 #define TARGET_FUNCTION_ARG loongarch_function_arg
   5933 #undef TARGET_FUNCTION_ARG_ADVANCE
   5934 #define TARGET_FUNCTION_ARG_ADVANCE loongarch_function_arg_advance
   5935 #undef TARGET_FUNCTION_ARG_BOUNDARY
   5936 #define TARGET_FUNCTION_ARG_BOUNDARY loongarch_function_arg_boundary
   5937 
   5938 #undef TARGET_SCALAR_MODE_SUPPORTED_P
   5939 #define TARGET_SCALAR_MODE_SUPPORTED_P loongarch_scalar_mode_supported_p
   5940 
   5941 #undef TARGET_INIT_BUILTINS
   5942 #define TARGET_INIT_BUILTINS loongarch_init_builtins
   5943 #undef TARGET_BUILTIN_DECL
   5944 #define TARGET_BUILTIN_DECL loongarch_builtin_decl
   5945 #undef TARGET_EXPAND_BUILTIN
   5946 #define TARGET_EXPAND_BUILTIN loongarch_expand_builtin
   5947 
   5948 /* The generic ELF target does not always have TLS support.  */
   5949 #ifdef HAVE_AS_TLS
   5950 #undef TARGET_HAVE_TLS
   5951 #define TARGET_HAVE_TLS HAVE_AS_TLS
   5952 #endif
   5953 
   5954 #undef TARGET_CANNOT_FORCE_CONST_MEM
   5955 #define TARGET_CANNOT_FORCE_CONST_MEM loongarch_cannot_force_const_mem
   5956 
   5957 #undef TARGET_LEGITIMATE_CONSTANT_P
   5958 #define TARGET_LEGITIMATE_CONSTANT_P loongarch_legitimate_constant_p
   5959 
   5960 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
   5961 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
   5962 
   5963 #ifdef HAVE_AS_DTPRELWORD
   5964 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
   5965 #define TARGET_ASM_OUTPUT_DWARF_DTPREL loongarch_output_dwarf_dtprel
   5966 #endif
   5967 
   5968 #undef TARGET_LEGITIMATE_ADDRESS_P
   5969 #define TARGET_LEGITIMATE_ADDRESS_P loongarch_legitimate_address_p
   5970 
   5971 #undef TARGET_FRAME_POINTER_REQUIRED
   5972 #define TARGET_FRAME_POINTER_REQUIRED loongarch_frame_pointer_required
   5973 
   5974 #undef TARGET_CAN_ELIMINATE
   5975 #define TARGET_CAN_ELIMINATE loongarch_can_eliminate
   5976 
   5977 #undef TARGET_CONDITIONAL_REGISTER_USAGE
   5978 #define TARGET_CONDITIONAL_REGISTER_USAGE loongarch_conditional_register_usage
   5979 
   5980 #undef TARGET_TRAMPOLINE_INIT
   5981 #define TARGET_TRAMPOLINE_INIT loongarch_trampoline_init
   5982 
   5983 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
   5984 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV loongarch_atomic_assign_expand_fenv
   5985 
   5986 #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
   5987 #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
   5988 
   5989 #undef TARGET_SPILL_CLASS
   5990 #define TARGET_SPILL_CLASS loongarch_spill_class
   5991 
   5992 #undef TARGET_HARD_REGNO_NREGS
   5993 #define TARGET_HARD_REGNO_NREGS loongarch_hard_regno_nregs
   5994 #undef TARGET_HARD_REGNO_MODE_OK
   5995 #define TARGET_HARD_REGNO_MODE_OK loongarch_hard_regno_mode_ok
   5996 
   5997 #undef TARGET_MODES_TIEABLE_P
   5998 #define TARGET_MODES_TIEABLE_P loongarch_modes_tieable_p
   5999 
   6000 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
   6001 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2
   6002 
   6003 #undef TARGET_CAN_CHANGE_MODE_CLASS
   6004 #define TARGET_CAN_CHANGE_MODE_CLASS loongarch_can_change_mode_class
   6005 
   6006 #undef TARGET_CONSTANT_ALIGNMENT
   6007 #define TARGET_CONSTANT_ALIGNMENT loongarch_constant_alignment
   6008 
   6009 #undef TARGET_STARTING_FRAME_OFFSET
   6010 #define TARGET_STARTING_FRAME_OFFSET loongarch_starting_frame_offset
   6011 
   6012 #undef TARGET_SECONDARY_RELOAD
   6013 #define TARGET_SECONDARY_RELOAD loongarch_secondary_reload
   6014 
   6015 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
   6016 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
   6017 
   6018 struct gcc_target targetm = TARGET_INITIALIZER;
   6019 
   6020 #include "gt-loongarch.h"
   6021