1 /* Subroutines used for code generation for RISC-V.
2 Copyright (C) 2011-2021 Free Software Foundation, Inc.
3 Contributed by Andrew Waterman (andrew@sifive.com).
4 Based on MIPS 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 #define INCLUDE_STRING
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "rtl.h"
30 #include "regs.h"
31 #include "insn-config.h"
32 #include "insn-attr.h"
33 #include "recog.h"
34 #include "output.h"
35 #include "alias.h"
36 #include "tree.h"
37 #include "stringpool.h"
38 #include "attribs.h"
39 #include "varasm.h"
40 #include "stor-layout.h"
41 #include "calls.h"
42 #include "function.h"
43 #include "explow.h"
44 #include "memmodel.h"
45 #include "emit-rtl.h"
46 #include "reload.h"
47 #include "tm_p.h"
48 #include "target.h"
49 #include "target-def.h"
50 #include "basic-block.h"
51 #include "expr.h"
52 #include "optabs.h"
53 #include "bitmap.h"
54 #include "df.h"
55 #include "diagnostic.h"
56 #include "builtins.h"
57 #include "predict.h"
58 #include "tree-pass.h"
59
60 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
61 #define UNSPEC_ADDRESS_P(X) \
62 (GET_CODE (X) == UNSPEC \
63 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
64 && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
65
66 /* Extract the symbol or label from UNSPEC wrapper X. */
67 #define UNSPEC_ADDRESS(X) \
68 XVECEXP (X, 0, 0)
69
70 /* Extract the symbol type from UNSPEC wrapper X. */
71 #define UNSPEC_ADDRESS_TYPE(X) \
72 ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
73
74 /* True if bit BIT is set in VALUE. */
75 #define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
76
77 /* Classifies an address.
78
79 ADDRESS_REG
80 A natural register + offset address. The register satisfies
81 riscv_valid_base_register_p and the offset is a const_arith_operand.
82
83 ADDRESS_LO_SUM
84 A LO_SUM rtx. The first operand is a valid base register and
85 the second operand is a symbolic address.
86
87 ADDRESS_CONST_INT
88 A signed 16-bit constant address.
89
90 ADDRESS_SYMBOLIC:
91 A constant symbolic address. */
92 enum riscv_address_type {
93 ADDRESS_REG,
94 ADDRESS_LO_SUM,
95 ADDRESS_CONST_INT,
96 ADDRESS_SYMBOLIC
97 };
98
99 /* Information about a function's frame layout. */
100 struct GTY(()) riscv_frame_info {
101 /* The size of the frame in bytes. */
102 HOST_WIDE_INT total_size;
103
104 /* Bit X is set if the function saves or restores GPR X. */
105 unsigned int mask;
106
107 /* Likewise FPR X. */
108 unsigned int fmask;
109
110 /* How much the GPR save/restore routines adjust sp (or 0 if unused). */
111 unsigned save_libcall_adjustment;
112
113 /* Offsets of fixed-point and floating-point save areas from frame bottom */
114 HOST_WIDE_INT gp_sp_offset;
115 HOST_WIDE_INT fp_sp_offset;
116
117 /* Offset of virtual frame pointer from stack pointer/frame bottom */
118 HOST_WIDE_INT frame_pointer_offset;
119
120 /* Offset of hard frame pointer from stack pointer/frame bottom */
121 HOST_WIDE_INT hard_frame_pointer_offset;
122
123 /* The offset of arg_pointer_rtx from the bottom of the frame. */
124 HOST_WIDE_INT arg_pointer_offset;
125 };
126
127 enum riscv_privilege_levels {
128 UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE
129 };
130
131 struct GTY(()) machine_function {
132 /* The number of extra stack bytes taken up by register varargs.
133 This area is allocated by the callee at the very top of the frame. */
134 int varargs_size;
135
136 /* True if current function is a naked function. */
137 bool naked_p;
138
139 /* True if current function is an interrupt function. */
140 bool interrupt_handler_p;
141 /* For an interrupt handler, indicates the privilege level. */
142 enum riscv_privilege_levels interrupt_mode;
143
144 /* True if attributes on current function have been checked. */
145 bool attributes_checked_p;
146
147 /* The current frame information, calculated by riscv_compute_frame_info. */
148 struct riscv_frame_info frame;
149 };
150
151 /* Information about a single argument. */
152 struct riscv_arg_info {
153 /* True if the argument is at least partially passed on the stack. */
154 bool stack_p;
155
156 /* The number of integer registers allocated to this argument. */
157 unsigned int num_gprs;
158
159 /* The offset of the first register used, provided num_gprs is nonzero.
160 If passed entirely on the stack, the value is MAX_ARGS_IN_REGISTERS. */
161 unsigned int gpr_offset;
162
163 /* The number of floating-point registers allocated to this argument. */
164 unsigned int num_fprs;
165
166 /* The offset of the first register used, provided num_fprs is nonzero. */
167 unsigned int fpr_offset;
168 };
169
170 /* Information about an address described by riscv_address_type.
171
172 ADDRESS_CONST_INT
173 No fields are used.
174
175 ADDRESS_REG
176 REG is the base register and OFFSET is the constant offset.
177
178 ADDRESS_LO_SUM
179 REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
180 is the type of symbol it references.
181
182 ADDRESS_SYMBOLIC
183 SYMBOL_TYPE is the type of symbol that the address references. */
184 struct riscv_address_info {
185 enum riscv_address_type type;
186 rtx reg;
187 rtx offset;
188 enum riscv_symbol_type symbol_type;
189 };
190
191 /* One stage in a constant building sequence. These sequences have
192 the form:
193
194 A = VALUE[0]
195 A = A CODE[1] VALUE[1]
196 A = A CODE[2] VALUE[2]
197 ...
198
199 where A is an accumulator, each CODE[i] is a binary rtl operation
200 and each VALUE[i] is a constant integer. CODE[0] is undefined. */
201 struct riscv_integer_op {
202 enum rtx_code code;
203 unsigned HOST_WIDE_INT value;
204 };
205
206 /* The largest number of operations needed to load an integer constant.
207 The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI. */
208 #define RISCV_MAX_INTEGER_OPS 8
209
210 /* Costs of various operations on the different architectures. */
211
212 struct riscv_tune_param
213 {
214 unsigned short fp_add[2];
215 unsigned short fp_mul[2];
216 unsigned short fp_div[2];
217 unsigned short int_mul[2];
218 unsigned short int_div[2];
219 unsigned short issue_rate;
220 unsigned short branch_cost;
221 unsigned short memory_cost;
222 bool slow_unaligned_access;
223 };
224
225 /* Information about one micro-arch we know about. */
226 struct riscv_tune_info {
227 /* This micro-arch canonical name. */
228 const char *name;
229
230 /* Which automaton to use for tuning. */
231 enum riscv_microarchitecture_type microarchitecture;
232
233 /* Tuning parameters for this micro-arch. */
234 const struct riscv_tune_param *tune_param;
235 };
236
237 /* Global variables for machine-dependent things. */
238
239 /* Whether unaligned accesses execute very slowly. */
240 bool riscv_slow_unaligned_access_p;
241
242 /* Stack alignment to assume/maintain. */
243 unsigned riscv_stack_boundary;
244
245 /* If non-zero, this is an offset to be added to SP to redefine the CFA
246 when restoring the FP register from the stack. Only valid when generating
247 the epilogue. */
248 static int epilogue_cfa_sp_offset;
249
250 /* Which tuning parameters to use. */
251 static const struct riscv_tune_param *tune_param;
252
253 /* Which automaton to use for tuning. */
254 enum riscv_microarchitecture_type riscv_microarchitecture;
255
256 /* Index R is the smallest register class that contains register R. */
257 const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {
258 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
259 GR_REGS, GR_REGS, SIBCALL_REGS, SIBCALL_REGS,
260 JALR_REGS, JALR_REGS, SIBCALL_REGS, SIBCALL_REGS,
261 SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS,
262 SIBCALL_REGS, SIBCALL_REGS, JALR_REGS, JALR_REGS,
263 JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
264 JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
265 SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS,
266 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
267 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
268 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
269 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
270 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
271 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
272 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
273 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
274 FRAME_REGS, FRAME_REGS,
275 };
276
277 /* Costs to use when optimizing for rocket. */
278 static const struct riscv_tune_param rocket_tune_info = {
279 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
280 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
281 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
282 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
283 {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
284 1, /* issue_rate */
285 3, /* branch_cost */
286 5, /* memory_cost */
287 true, /* slow_unaligned_access */
288 };
289
290 /* Costs to use when optimizing for Sifive 7 Series. */
291 static const struct riscv_tune_param sifive_7_tune_info = {
292 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
293 {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
294 {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
295 {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
296 {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
297 2, /* issue_rate */
298 4, /* branch_cost */
299 3, /* memory_cost */
300 true, /* slow_unaligned_access */
301 };
302
303 /* Costs to use when optimizing for size. */
304 static const struct riscv_tune_param optimize_size_tune_info = {
305 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */
306 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_mul */
307 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_div */
308 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_mul */
309 {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_div */
310 1, /* issue_rate */
311 1, /* branch_cost */
312 2, /* memory_cost */
313 false, /* slow_unaligned_access */
314 };
315
316 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
317 static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
318
319 /* Defining target-specific uses of __attribute__. */
320 static const struct attribute_spec riscv_attribute_table[] =
321 {
322 /* Syntax: { name, min_len, max_len, decl_required, type_required,
323 function_type_required, affects_type_identity, handler,
324 exclude } */
325
326 /* The attribute telling no prologue/epilogue. */
327 { "naked", 0, 0, true, false, false, false,
328 riscv_handle_fndecl_attribute, NULL },
329 /* This attribute generates prologue/epilogue for interrupt handlers. */
330 { "interrupt", 0, 1, false, true, true, false,
331 riscv_handle_type_attribute, NULL },
332
333 /* The last attribute spec is set to be NULL. */
334 { NULL, 0, 0, false, false, false, false, NULL, NULL }
335 };
336
337 /* Order for the CLOBBERs/USEs of gpr_save. */
338 static const unsigned gpr_save_reg_order[] = {
339 INVALID_REGNUM, T0_REGNUM, T1_REGNUM, RETURN_ADDR_REGNUM,
340 S0_REGNUM, S1_REGNUM, S2_REGNUM, S3_REGNUM, S4_REGNUM,
341 S5_REGNUM, S6_REGNUM, S7_REGNUM, S8_REGNUM, S9_REGNUM,
342 S10_REGNUM, S11_REGNUM
343 };
344
345 /* A table describing all the processors GCC knows about. */
346 static const struct riscv_tune_info riscv_tune_info_table[] = {
347 { "rocket", generic, &rocket_tune_info },
348 { "sifive-3-series", generic, &rocket_tune_info },
349 { "sifive-5-series", generic, &rocket_tune_info },
350 { "sifive-7-series", sifive_7, &sifive_7_tune_info },
351 { "size", generic, &optimize_size_tune_info },
352 };
353
354 /* Return the riscv_tune_info entry for the given name string. */
355
356 static const struct riscv_tune_info *
riscv_parse_tune(const char * tune_string)357 riscv_parse_tune (const char *tune_string)
358 {
359 const riscv_cpu_info *cpu = riscv_find_cpu (tune_string);
360
361 if (cpu)
362 tune_string = cpu->tune;
363
364 for (unsigned i = 0; i < ARRAY_SIZE (riscv_tune_info_table); i++)
365 if (strcmp (riscv_tune_info_table[i].name, tune_string) == 0)
366 return riscv_tune_info_table + i;
367
368 error ("unknown cpu %qs for %<-mtune%>", tune_string);
369 return riscv_tune_info_table;
370 }
371
372 /* Helper function for riscv_build_integer; arguments are as for
373 riscv_build_integer. */
374
375 static int
riscv_build_integer_1(struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS],HOST_WIDE_INT value,machine_mode mode)376 riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS],
377 HOST_WIDE_INT value, machine_mode mode)
378 {
379 HOST_WIDE_INT low_part = CONST_LOW_PART (value);
380 int cost = RISCV_MAX_INTEGER_OPS + 1, alt_cost;
381 struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
382
383 if (SMALL_OPERAND (value) || LUI_OPERAND (value))
384 {
385 /* Simply ADDI or LUI. */
386 codes[0].code = UNKNOWN;
387 codes[0].value = value;
388 return 1;
389 }
390
391 /* End with ADDI. When constructing HImode constants, do not generate any
392 intermediate value that is not itself a valid HImode constant. The
393 XORI case below will handle those remaining HImode constants. */
394 if (low_part != 0
395 && (mode != HImode
396 || value - low_part <= ((1 << (GET_MODE_BITSIZE (HImode) - 1)) - 1)))
397 {
398 alt_cost = 1 + riscv_build_integer_1 (alt_codes, value - low_part, mode);
399 if (alt_cost < cost)
400 {
401 alt_codes[alt_cost-1].code = PLUS;
402 alt_codes[alt_cost-1].value = low_part;
403 memcpy (codes, alt_codes, sizeof (alt_codes));
404 cost = alt_cost;
405 }
406 }
407
408 /* End with XORI. */
409 if (cost > 2 && (low_part < 0 || mode == HImode))
410 {
411 alt_cost = 1 + riscv_build_integer_1 (alt_codes, value ^ low_part, mode);
412 if (alt_cost < cost)
413 {
414 alt_codes[alt_cost-1].code = XOR;
415 alt_codes[alt_cost-1].value = low_part;
416 memcpy (codes, alt_codes, sizeof (alt_codes));
417 cost = alt_cost;
418 }
419 }
420
421 /* Eliminate trailing zeros and end with SLLI. */
422 if (cost > 2 && (value & 1) == 0)
423 {
424 int shift = ctz_hwi (value);
425 unsigned HOST_WIDE_INT x = value;
426 x = sext_hwi (x >> shift, HOST_BITS_PER_WIDE_INT - shift);
427
428 /* Don't eliminate the lower 12 bits if LUI might apply. */
429 if (shift > IMM_BITS && !SMALL_OPERAND (x) && LUI_OPERAND (x << IMM_BITS))
430 shift -= IMM_BITS, x <<= IMM_BITS;
431
432 alt_cost = 1 + riscv_build_integer_1 (alt_codes, x, mode);
433 if (alt_cost < cost)
434 {
435 alt_codes[alt_cost-1].code = ASHIFT;
436 alt_codes[alt_cost-1].value = shift;
437 memcpy (codes, alt_codes, sizeof (alt_codes));
438 cost = alt_cost;
439 }
440 }
441
442 gcc_assert (cost <= RISCV_MAX_INTEGER_OPS);
443 return cost;
444 }
445
446 /* Fill CODES with a sequence of rtl operations to load VALUE.
447 Return the number of operations needed. */
448
449 static int
riscv_build_integer(struct riscv_integer_op * codes,HOST_WIDE_INT value,machine_mode mode)450 riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value,
451 machine_mode mode)
452 {
453 int cost = riscv_build_integer_1 (codes, value, mode);
454
455 /* Eliminate leading zeros and end with SRLI. */
456 if (value > 0 && cost > 2)
457 {
458 struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
459 int alt_cost, shift = clz_hwi (value);
460 HOST_WIDE_INT shifted_val;
461
462 /* Try filling trailing bits with 1s. */
463 shifted_val = (value << shift) | ((((HOST_WIDE_INT) 1) << shift) - 1);
464 alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
465 if (alt_cost < cost)
466 {
467 alt_codes[alt_cost-1].code = LSHIFTRT;
468 alt_codes[alt_cost-1].value = shift;
469 memcpy (codes, alt_codes, sizeof (alt_codes));
470 cost = alt_cost;
471 }
472
473 /* Try filling trailing bits with 0s. */
474 shifted_val = value << shift;
475 alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
476 if (alt_cost < cost)
477 {
478 alt_codes[alt_cost-1].code = LSHIFTRT;
479 alt_codes[alt_cost-1].value = shift;
480 memcpy (codes, alt_codes, sizeof (alt_codes));
481 cost = alt_cost;
482 }
483 }
484
485 return cost;
486 }
487
488 /* Return the cost of constructing VAL in the event that a scratch
489 register is available. */
490
491 static int
riscv_split_integer_cost(HOST_WIDE_INT val)492 riscv_split_integer_cost (HOST_WIDE_INT val)
493 {
494 int cost;
495 unsigned HOST_WIDE_INT loval = sext_hwi (val, 32);
496 unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32);
497 struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
498
499 cost = 2 + riscv_build_integer (codes, loval, VOIDmode);
500 if (loval != hival)
501 cost += riscv_build_integer (codes, hival, VOIDmode);
502
503 return cost;
504 }
505
506 /* Return the cost of constructing the integer constant VAL. */
507
508 static int
riscv_integer_cost(HOST_WIDE_INT val)509 riscv_integer_cost (HOST_WIDE_INT val)
510 {
511 struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
512 return MIN (riscv_build_integer (codes, val, VOIDmode),
513 riscv_split_integer_cost (val));
514 }
515
516 /* Try to split a 64b integer into 32b parts, then reassemble. */
517
518 static rtx
riscv_split_integer(HOST_WIDE_INT val,machine_mode mode)519 riscv_split_integer (HOST_WIDE_INT val, machine_mode mode)
520 {
521 unsigned HOST_WIDE_INT loval = sext_hwi (val, 32);
522 unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32);
523 rtx hi = gen_reg_rtx (mode), lo = gen_reg_rtx (mode);
524
525 riscv_move_integer (hi, hi, hival, mode, FALSE);
526 riscv_move_integer (lo, lo, loval, mode, FALSE);
527
528 hi = gen_rtx_fmt_ee (ASHIFT, mode, hi, GEN_INT (32));
529 hi = force_reg (mode, hi);
530
531 return gen_rtx_fmt_ee (PLUS, mode, hi, lo);
532 }
533
534 /* Return true if X is a thread-local symbol. */
535
536 static bool
riscv_tls_symbol_p(const_rtx x)537 riscv_tls_symbol_p (const_rtx x)
538 {
539 return SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0;
540 }
541
542 /* Return true if symbol X binds locally. */
543
544 static bool
riscv_symbol_binds_local_p(const_rtx x)545 riscv_symbol_binds_local_p (const_rtx x)
546 {
547 if (SYMBOL_REF_P (x))
548 return (SYMBOL_REF_DECL (x)
549 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
550 : SYMBOL_REF_LOCAL_P (x));
551 else
552 return false;
553 }
554
555 /* Return the method that should be used to access SYMBOL_REF or
556 LABEL_REF X. */
557
558 static enum riscv_symbol_type
riscv_classify_symbol(const_rtx x)559 riscv_classify_symbol (const_rtx x)
560 {
561 if (riscv_tls_symbol_p (x))
562 return SYMBOL_TLS;
563
564 if (GET_CODE (x) == SYMBOL_REF && flag_pic && !riscv_symbol_binds_local_p (x))
565 return SYMBOL_GOT_DISP;
566
567 return riscv_cmodel == CM_MEDLOW ? SYMBOL_ABSOLUTE : SYMBOL_PCREL;
568 }
569
570 /* Classify the base of symbolic expression X. */
571
572 enum riscv_symbol_type
riscv_classify_symbolic_expression(rtx x)573 riscv_classify_symbolic_expression (rtx x)
574 {
575 rtx offset;
576
577 split_const (x, &x, &offset);
578 if (UNSPEC_ADDRESS_P (x))
579 return UNSPEC_ADDRESS_TYPE (x);
580
581 return riscv_classify_symbol (x);
582 }
583
584 /* Return true if X is a symbolic constant. If it is, store the type of
585 the symbol in *SYMBOL_TYPE. */
586
587 bool
riscv_symbolic_constant_p(rtx x,enum riscv_symbol_type * symbol_type)588 riscv_symbolic_constant_p (rtx x, enum riscv_symbol_type *symbol_type)
589 {
590 rtx offset;
591
592 split_const (x, &x, &offset);
593 if (UNSPEC_ADDRESS_P (x))
594 {
595 *symbol_type = UNSPEC_ADDRESS_TYPE (x);
596 x = UNSPEC_ADDRESS (x);
597 }
598 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
599 *symbol_type = riscv_classify_symbol (x);
600 else
601 return false;
602
603 if (offset == const0_rtx)
604 return true;
605
606 /* Nonzero offsets are only valid for references that don't use the GOT. */
607 switch (*symbol_type)
608 {
609 case SYMBOL_ABSOLUTE:
610 case SYMBOL_PCREL:
611 case SYMBOL_TLS_LE:
612 /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */
613 return sext_hwi (INTVAL (offset), 32) == INTVAL (offset);
614
615 default:
616 return false;
617 }
618 }
619
620 /* Returns the number of instructions necessary to reference a symbol. */
621
riscv_symbol_insns(enum riscv_symbol_type type)622 static int riscv_symbol_insns (enum riscv_symbol_type type)
623 {
624 switch (type)
625 {
626 case SYMBOL_TLS: return 0; /* Depends on the TLS model. */
627 case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference. */
628 case SYMBOL_PCREL: return 2; /* AUIPC + the reference. */
629 case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference. */
630 case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference. */
631 default: gcc_unreachable ();
632 }
633 }
634
635 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
636
637 static bool
riscv_legitimate_constant_p(machine_mode mode ATTRIBUTE_UNUSED,rtx x)638 riscv_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
639 {
640 return riscv_const_insns (x) > 0;
641 }
642
643 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
644
645 static bool
riscv_cannot_force_const_mem(machine_mode mode ATTRIBUTE_UNUSED,rtx x)646 riscv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
647 {
648 enum riscv_symbol_type type;
649 rtx base, offset;
650
651 /* There is no assembler syntax for expressing an address-sized
652 high part. */
653 if (GET_CODE (x) == HIGH)
654 return true;
655
656 split_const (x, &base, &offset);
657 if (riscv_symbolic_constant_p (base, &type))
658 {
659 /* As an optimization, don't spill symbolic constants that are as
660 cheap to rematerialize as to access in the constant pool. */
661 if (SMALL_OPERAND (INTVAL (offset)) && riscv_symbol_insns (type) > 0)
662 return true;
663
664 /* As an optimization, avoid needlessly generate dynamic relocations. */
665 if (flag_pic)
666 return true;
667 }
668
669 /* TLS symbols must be computed by riscv_legitimize_move. */
670 if (tls_referenced_p (x))
671 return true;
672
673 return false;
674 }
675
676 /* Return true if register REGNO is a valid base register for mode MODE.
677 STRICT_P is true if REG_OK_STRICT is in effect. */
678
679 int
riscv_regno_mode_ok_for_base_p(int regno,machine_mode mode ATTRIBUTE_UNUSED,bool strict_p)680 riscv_regno_mode_ok_for_base_p (int regno,
681 machine_mode mode ATTRIBUTE_UNUSED,
682 bool strict_p)
683 {
684 if (!HARD_REGISTER_NUM_P (regno))
685 {
686 if (!strict_p)
687 return true;
688 regno = reg_renumber[regno];
689 }
690
691 /* These fake registers will be eliminated to either the stack or
692 hard frame pointer, both of which are usually valid base registers.
693 Reload deals with the cases where the eliminated form isn't valid. */
694 if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
695 return true;
696
697 return GP_REG_P (regno);
698 }
699
700 /* Return true if X is a valid base register for mode MODE.
701 STRICT_P is true if REG_OK_STRICT is in effect. */
702
703 static bool
riscv_valid_base_register_p(rtx x,machine_mode mode,bool strict_p)704 riscv_valid_base_register_p (rtx x, machine_mode mode, bool strict_p)
705 {
706 if (!strict_p && GET_CODE (x) == SUBREG)
707 x = SUBREG_REG (x);
708
709 return (REG_P (x)
710 && riscv_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p));
711 }
712
713 /* Return true if, for every base register BASE_REG, (plus BASE_REG X)
714 can address a value of mode MODE. */
715
716 static bool
riscv_valid_offset_p(rtx x,machine_mode mode)717 riscv_valid_offset_p (rtx x, machine_mode mode)
718 {
719 /* Check that X is a signed 12-bit number. */
720 if (!const_arith_operand (x, Pmode))
721 return false;
722
723 /* We may need to split multiword moves, so make sure that every word
724 is accessible. */
725 if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
726 && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
727 return false;
728
729 return true;
730 }
731
732 /* Should a symbol of type SYMBOL_TYPE should be split in two? */
733
734 bool
riscv_split_symbol_type(enum riscv_symbol_type symbol_type)735 riscv_split_symbol_type (enum riscv_symbol_type symbol_type)
736 {
737 if (symbol_type == SYMBOL_TLS_LE)
738 return true;
739
740 if (!TARGET_EXPLICIT_RELOCS)
741 return false;
742
743 return symbol_type == SYMBOL_ABSOLUTE || symbol_type == SYMBOL_PCREL;
744 }
745
746 /* Return true if a LO_SUM can address a value of mode MODE when the
747 LO_SUM symbol has type SYM_TYPE. X is the LO_SUM second operand, which
748 is used when the mode is BLKmode. */
749
750 static bool
riscv_valid_lo_sum_p(enum riscv_symbol_type sym_type,machine_mode mode,rtx x)751 riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode,
752 rtx x)
753 {
754 int align, size;
755
756 /* Check that symbols of type SYMBOL_TYPE can be used to access values
757 of mode MODE. */
758 if (riscv_symbol_insns (sym_type) == 0)
759 return false;
760
761 /* Check that there is a known low-part relocation. */
762 if (!riscv_split_symbol_type (sym_type))
763 return false;
764
765 /* We can't tell size or alignment when we have BLKmode, so try extracing a
766 decl from the symbol if possible. */
767 if (mode == BLKmode)
768 {
769 rtx offset;
770
771 /* Extract the symbol from the LO_SUM operand, if any. */
772 split_const (x, &x, &offset);
773
774 /* Might be a CODE_LABEL. We can compute align but not size for that,
775 so don't bother trying to handle it. */
776 if (!SYMBOL_REF_P (x))
777 return false;
778
779 /* Use worst case assumptions if we don't have a SYMBOL_REF_DECL. */
780 align = (SYMBOL_REF_DECL (x)
781 ? DECL_ALIGN (SYMBOL_REF_DECL (x))
782 : 1);
783 size = (SYMBOL_REF_DECL (x) && DECL_SIZE (SYMBOL_REF_DECL (x))
784 ? tree_to_uhwi (DECL_SIZE (SYMBOL_REF_DECL (x)))
785 : 2*BITS_PER_WORD);
786 }
787 else
788 {
789 align = GET_MODE_ALIGNMENT (mode);
790 size = GET_MODE_BITSIZE (mode);
791 }
792
793 /* We may need to split multiword moves, so make sure that each word
794 can be accessed without inducing a carry. */
795 if (size > BITS_PER_WORD
796 && (!TARGET_STRICT_ALIGN || size > align))
797 return false;
798
799 return true;
800 }
801
802 /* Return true if X is a valid address for machine mode MODE. If it is,
803 fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
804 effect. */
805
806 static bool
riscv_classify_address(struct riscv_address_info * info,rtx x,machine_mode mode,bool strict_p)807 riscv_classify_address (struct riscv_address_info *info, rtx x,
808 machine_mode mode, bool strict_p)
809 {
810 switch (GET_CODE (x))
811 {
812 case REG:
813 case SUBREG:
814 info->type = ADDRESS_REG;
815 info->reg = x;
816 info->offset = const0_rtx;
817 return riscv_valid_base_register_p (info->reg, mode, strict_p);
818
819 case PLUS:
820 info->type = ADDRESS_REG;
821 info->reg = XEXP (x, 0);
822 info->offset = XEXP (x, 1);
823 return (riscv_valid_base_register_p (info->reg, mode, strict_p)
824 && riscv_valid_offset_p (info->offset, mode));
825
826 case LO_SUM:
827 info->type = ADDRESS_LO_SUM;
828 info->reg = XEXP (x, 0);
829 info->offset = XEXP (x, 1);
830 /* We have to trust the creator of the LO_SUM to do something vaguely
831 sane. Target-independent code that creates a LO_SUM should also
832 create and verify the matching HIGH. Target-independent code that
833 adds an offset to a LO_SUM must prove that the offset will not
834 induce a carry. Failure to do either of these things would be
835 a bug, and we are not required to check for it here. The RISC-V
836 backend itself should only create LO_SUMs for valid symbolic
837 constants, with the high part being either a HIGH or a copy
838 of _gp. */
839 info->symbol_type
840 = riscv_classify_symbolic_expression (info->offset);
841 return (riscv_valid_base_register_p (info->reg, mode, strict_p)
842 && riscv_valid_lo_sum_p (info->symbol_type, mode, info->offset));
843
844 case CONST_INT:
845 /* Small-integer addresses don't occur very often, but they
846 are legitimate if x0 is a valid base register. */
847 info->type = ADDRESS_CONST_INT;
848 return SMALL_OPERAND (INTVAL (x));
849
850 default:
851 return false;
852 }
853 }
854
855 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
856
857 static bool
riscv_legitimate_address_p(machine_mode mode,rtx x,bool strict_p)858 riscv_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
859 {
860 struct riscv_address_info addr;
861
862 return riscv_classify_address (&addr, x, mode, strict_p);
863 }
864
865 /* Return true if hard reg REGNO can be used in compressed instructions. */
866
867 static bool
riscv_compressed_reg_p(int regno)868 riscv_compressed_reg_p (int regno)
869 {
870 /* x8-x15/f8-f15 are compressible registers. */
871 return (TARGET_RVC && (IN_RANGE (regno, GP_REG_FIRST + 8, GP_REG_FIRST + 15)
872 || IN_RANGE (regno, FP_REG_FIRST + 8, FP_REG_FIRST + 15)));
873 }
874
875 /* Return true if x is an unsigned 5-bit immediate scaled by 4. */
876
877 static bool
riscv_compressed_lw_offset_p(rtx x)878 riscv_compressed_lw_offset_p (rtx x)
879 {
880 return (CONST_INT_P (x)
881 && (INTVAL (x) & 3) == 0
882 && IN_RANGE (INTVAL (x), 0, CSW_MAX_OFFSET));
883 }
884
885 /* Return true if load/store from/to address x can be compressed. */
886
887 static bool
riscv_compressed_lw_address_p(rtx x)888 riscv_compressed_lw_address_p (rtx x)
889 {
890 struct riscv_address_info addr;
891 bool result = riscv_classify_address (&addr, x, GET_MODE (x),
892 reload_completed);
893
894 /* Return false if address is not compressed_reg + small_offset. */
895 if (!result
896 || addr.type != ADDRESS_REG
897 /* Before reload, assume all registers are OK. */
898 || (reload_completed
899 && !riscv_compressed_reg_p (REGNO (addr.reg))
900 && addr.reg != stack_pointer_rtx)
901 || !riscv_compressed_lw_offset_p (addr.offset))
902 return false;
903
904 return result;
905 }
906
907 /* Return the number of instructions needed to load or store a value
908 of mode MODE at address X. Return 0 if X isn't valid for MODE.
909 Assume that multiword moves may need to be split into word moves
910 if MIGHT_SPLIT_P, otherwise assume that a single load or store is
911 enough. */
912
913 int
riscv_address_insns(rtx x,machine_mode mode,bool might_split_p)914 riscv_address_insns (rtx x, machine_mode mode, bool might_split_p)
915 {
916 struct riscv_address_info addr = {};
917 int n = 1;
918
919 if (!riscv_classify_address (&addr, x, mode, false))
920 {
921 /* This could be a pattern from the pic.md file. In which case we want
922 this address to always have a cost of 3 to make it as expensive as the
923 most expensive symbol. This prevents constant propagation from
924 preferring symbols over register plus offset. */
925 return 3;
926 }
927
928 /* BLKmode is used for single unaligned loads and stores and should
929 not count as a multiword mode. */
930 if (mode != BLKmode && might_split_p)
931 n += (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
932
933 if (addr.type == ADDRESS_LO_SUM)
934 n += riscv_symbol_insns (addr.symbol_type) - 1;
935
936 return n;
937 }
938
939 /* Return the number of instructions needed to load constant X.
940 Return 0 if X isn't a valid constant. */
941
942 int
riscv_const_insns(rtx x)943 riscv_const_insns (rtx x)
944 {
945 enum riscv_symbol_type symbol_type;
946 rtx offset;
947
948 switch (GET_CODE (x))
949 {
950 case HIGH:
951 if (!riscv_symbolic_constant_p (XEXP (x, 0), &symbol_type)
952 || !riscv_split_symbol_type (symbol_type))
953 return 0;
954
955 /* This is simply an LUI. */
956 return 1;
957
958 case CONST_INT:
959 {
960 int cost = riscv_integer_cost (INTVAL (x));
961 /* Force complicated constants to memory. */
962 return cost < 4 ? cost : 0;
963 }
964
965 case CONST_DOUBLE:
966 case CONST_VECTOR:
967 /* We can use x0 to load floating-point zero. */
968 return x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;
969
970 case CONST:
971 /* See if we can refer to X directly. */
972 if (riscv_symbolic_constant_p (x, &symbol_type))
973 return riscv_symbol_insns (symbol_type);
974
975 /* Otherwise try splitting the constant into a base and offset. */
976 split_const (x, &x, &offset);
977 if (offset != 0)
978 {
979 int n = riscv_const_insns (x);
980 if (n != 0)
981 return n + riscv_integer_cost (INTVAL (offset));
982 }
983 return 0;
984
985 case SYMBOL_REF:
986 case LABEL_REF:
987 return riscv_symbol_insns (riscv_classify_symbol (x));
988
989 default:
990 return 0;
991 }
992 }
993
994 /* X is a doubleword constant that can be handled by splitting it into
995 two words and loading each word separately. Return the number of
996 instructions required to do this. */
997
998 int
riscv_split_const_insns(rtx x)999 riscv_split_const_insns (rtx x)
1000 {
1001 unsigned int low, high;
1002
1003 low = riscv_const_insns (riscv_subword (x, false));
1004 high = riscv_const_insns (riscv_subword (x, true));
1005 gcc_assert (low > 0 && high > 0);
1006 return low + high;
1007 }
1008
1009 /* Return the number of instructions needed to implement INSN,
1010 given that it loads from or stores to MEM. */
1011
1012 int
riscv_load_store_insns(rtx mem,rtx_insn * insn)1013 riscv_load_store_insns (rtx mem, rtx_insn *insn)
1014 {
1015 machine_mode mode;
1016 bool might_split_p;
1017 rtx set;
1018
1019 gcc_assert (MEM_P (mem));
1020 mode = GET_MODE (mem);
1021
1022 /* Try to prove that INSN does not need to be split. */
1023 might_split_p = true;
1024 if (GET_MODE_BITSIZE (mode) <= 32)
1025 might_split_p = false;
1026 else if (GET_MODE_BITSIZE (mode) == 64)
1027 {
1028 set = single_set (insn);
1029 if (set && !riscv_split_64bit_move_p (SET_DEST (set), SET_SRC (set)))
1030 might_split_p = false;
1031 }
1032
1033 return riscv_address_insns (XEXP (mem, 0), mode, might_split_p);
1034 }
1035
1036 /* Emit a move from SRC to DEST. Assume that the move expanders can
1037 handle all moves if !can_create_pseudo_p (). The distinction is
1038 important because, unlike emit_move_insn, the move expanders know
1039 how to force Pmode objects into the constant pool even when the
1040 constant pool address is not itself legitimate. */
1041
1042 rtx
riscv_emit_move(rtx dest,rtx src)1043 riscv_emit_move (rtx dest, rtx src)
1044 {
1045 return (can_create_pseudo_p ()
1046 ? emit_move_insn (dest, src)
1047 : emit_move_insn_1 (dest, src));
1048 }
1049
1050 /* Emit an instruction of the form (set TARGET SRC). */
1051
1052 static rtx
riscv_emit_set(rtx target,rtx src)1053 riscv_emit_set (rtx target, rtx src)
1054 {
1055 emit_insn (gen_rtx_SET (target, src));
1056 return target;
1057 }
1058
1059 /* Emit an instruction of the form (set DEST (CODE X Y)). */
1060
1061 static rtx
riscv_emit_binary(enum rtx_code code,rtx dest,rtx x,rtx y)1062 riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y)
1063 {
1064 return riscv_emit_set (dest, gen_rtx_fmt_ee (code, GET_MODE (dest), x, y));
1065 }
1066
1067 /* Compute (CODE X Y) and store the result in a new register
1068 of mode MODE. Return that new register. */
1069
1070 static rtx
riscv_force_binary(machine_mode mode,enum rtx_code code,rtx x,rtx y)1071 riscv_force_binary (machine_mode mode, enum rtx_code code, rtx x, rtx y)
1072 {
1073 return riscv_emit_binary (code, gen_reg_rtx (mode), x, y);
1074 }
1075
1076 static rtx
riscv_swap_instruction(rtx inst)1077 riscv_swap_instruction (rtx inst)
1078 {
1079 gcc_assert (GET_MODE (inst) == SImode);
1080 if (BYTES_BIG_ENDIAN)
1081 inst = expand_unop (SImode, bswap_optab, inst, gen_reg_rtx (SImode), 1);
1082 return inst;
1083 }
1084
1085 /* Copy VALUE to a register and return that register. If new pseudos
1086 are allowed, copy it into a new register, otherwise use DEST. */
1087
1088 static rtx
riscv_force_temporary(rtx dest,rtx value,bool in_splitter)1089 riscv_force_temporary (rtx dest, rtx value, bool in_splitter)
1090 {
1091 /* We can't call gen_reg_rtx from a splitter, because this might realloc
1092 the regno_reg_rtx array, which would invalidate reg rtx pointers in the
1093 combine undo buffer. */
1094 if (can_create_pseudo_p () && !in_splitter)
1095 return force_reg (Pmode, value);
1096 else
1097 {
1098 riscv_emit_move (dest, value);
1099 return dest;
1100 }
1101 }
1102
1103 /* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
1104 then add CONST_INT OFFSET to the result. */
1105
1106 static rtx
riscv_unspec_address_offset(rtx base,rtx offset,enum riscv_symbol_type symbol_type)1107 riscv_unspec_address_offset (rtx base, rtx offset,
1108 enum riscv_symbol_type symbol_type)
1109 {
1110 base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
1111 UNSPEC_ADDRESS_FIRST + symbol_type);
1112 if (offset != const0_rtx)
1113 base = gen_rtx_PLUS (Pmode, base, offset);
1114 return gen_rtx_CONST (Pmode, base);
1115 }
1116
1117 /* Return an UNSPEC address with underlying address ADDRESS and symbol
1118 type SYMBOL_TYPE. */
1119
1120 rtx
riscv_unspec_address(rtx address,enum riscv_symbol_type symbol_type)1121 riscv_unspec_address (rtx address, enum riscv_symbol_type symbol_type)
1122 {
1123 rtx base, offset;
1124
1125 split_const (address, &base, &offset);
1126 return riscv_unspec_address_offset (base, offset, symbol_type);
1127 }
1128
1129 /* If OP is an UNSPEC address, return the address to which it refers,
1130 otherwise return OP itself. */
1131
1132 static rtx
riscv_strip_unspec_address(rtx op)1133 riscv_strip_unspec_address (rtx op)
1134 {
1135 rtx base, offset;
1136
1137 split_const (op, &base, &offset);
1138 if (UNSPEC_ADDRESS_P (base))
1139 op = plus_constant (Pmode, UNSPEC_ADDRESS (base), INTVAL (offset));
1140 return op;
1141 }
1142
1143 /* If riscv_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
1144 high part to BASE and return the result. Just return BASE otherwise.
1145 TEMP is as for riscv_force_temporary.
1146
1147 The returned expression can be used as the first operand to a LO_SUM. */
1148
1149 static rtx
riscv_unspec_offset_high(rtx temp,rtx addr,enum riscv_symbol_type symbol_type)1150 riscv_unspec_offset_high (rtx temp, rtx addr, enum riscv_symbol_type symbol_type)
1151 {
1152 addr = gen_rtx_HIGH (Pmode, riscv_unspec_address (addr, symbol_type));
1153 return riscv_force_temporary (temp, addr, FALSE);
1154 }
1155
1156 /* Load an entry from the GOT for a TLS GD access. */
1157
riscv_got_load_tls_gd(rtx dest,rtx sym)1158 static rtx riscv_got_load_tls_gd (rtx dest, rtx sym)
1159 {
1160 if (Pmode == DImode)
1161 return gen_got_load_tls_gddi (dest, sym);
1162 else
1163 return gen_got_load_tls_gdsi (dest, sym);
1164 }
1165
1166 /* Load an entry from the GOT for a TLS IE access. */
1167
riscv_got_load_tls_ie(rtx dest,rtx sym)1168 static rtx riscv_got_load_tls_ie (rtx dest, rtx sym)
1169 {
1170 if (Pmode == DImode)
1171 return gen_got_load_tls_iedi (dest, sym);
1172 else
1173 return gen_got_load_tls_iesi (dest, sym);
1174 }
1175
1176 /* Add in the thread pointer for a TLS LE access. */
1177
riscv_tls_add_tp_le(rtx dest,rtx base,rtx sym)1178 static rtx riscv_tls_add_tp_le (rtx dest, rtx base, rtx sym)
1179 {
1180 rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
1181 if (Pmode == DImode)
1182 return gen_tls_add_tp_ledi (dest, base, tp, sym);
1183 else
1184 return gen_tls_add_tp_lesi (dest, base, tp, sym);
1185 }
1186
1187 /* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
1188 it appears in a MEM of that mode. Return true if ADDR is a legitimate
1189 constant in that context and can be split into high and low parts.
1190 If so, and if LOW_OUT is nonnull, emit the high part and store the
1191 low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
1192
1193 TEMP is as for riscv_force_temporary and is used to load the high
1194 part into a register.
1195
1196 When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
1197 a legitimize SET_SRC for an .md pattern, otherwise the low part
1198 is guaranteed to be a legitimate address for mode MODE. */
1199
1200 bool
riscv_split_symbol(rtx temp,rtx addr,machine_mode mode,rtx * low_out,bool in_splitter)1201 riscv_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out,
1202 bool in_splitter)
1203 {
1204 enum riscv_symbol_type symbol_type;
1205
1206 if ((GET_CODE (addr) == HIGH && mode == MAX_MACHINE_MODE)
1207 || !riscv_symbolic_constant_p (addr, &symbol_type)
1208 || riscv_symbol_insns (symbol_type) == 0
1209 || !riscv_split_symbol_type (symbol_type))
1210 return false;
1211
1212 if (low_out)
1213 switch (symbol_type)
1214 {
1215 case SYMBOL_ABSOLUTE:
1216 {
1217 rtx high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
1218 high = riscv_force_temporary (temp, high, in_splitter);
1219 *low_out = gen_rtx_LO_SUM (Pmode, high, addr);
1220 }
1221 break;
1222
1223 case SYMBOL_PCREL:
1224 {
1225 static unsigned seqno;
1226 char buf[32];
1227 rtx label;
1228
1229 ssize_t bytes = snprintf (buf, sizeof (buf), ".LA%u", seqno);
1230 gcc_assert ((size_t) bytes < sizeof (buf));
1231
1232 label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1233 SYMBOL_REF_FLAGS (label) |= SYMBOL_FLAG_LOCAL;
1234 /* ??? Ugly hack to make weak symbols work. May need to change the
1235 RTL for the auipc and/or low patterns to get a better fix for
1236 this. */
1237 if (! nonzero_address_p (addr))
1238 SYMBOL_REF_WEAK (label) = 1;
1239
1240 if (temp == NULL)
1241 temp = gen_reg_rtx (Pmode);
1242
1243 if (Pmode == DImode)
1244 emit_insn (gen_auipcdi (temp, copy_rtx (addr), GEN_INT (seqno)));
1245 else
1246 emit_insn (gen_auipcsi (temp, copy_rtx (addr), GEN_INT (seqno)));
1247
1248 *low_out = gen_rtx_LO_SUM (Pmode, temp, label);
1249
1250 seqno++;
1251 }
1252 break;
1253
1254 default:
1255 gcc_unreachable ();
1256 }
1257
1258 return true;
1259 }
1260
1261 /* Return a legitimate address for REG + OFFSET. TEMP is as for
1262 riscv_force_temporary; it is only needed when OFFSET is not a
1263 SMALL_OPERAND. */
1264
1265 static rtx
riscv_add_offset(rtx temp,rtx reg,HOST_WIDE_INT offset)1266 riscv_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
1267 {
1268 if (!SMALL_OPERAND (offset))
1269 {
1270 rtx high;
1271
1272 /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
1273 The addition inside the macro CONST_HIGH_PART may cause an
1274 overflow, so we need to force a sign-extension check. */
1275 high = gen_int_mode (CONST_HIGH_PART (offset), Pmode);
1276 offset = CONST_LOW_PART (offset);
1277 high = riscv_force_temporary (temp, high, FALSE);
1278 reg = riscv_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg),
1279 FALSE);
1280 }
1281 return plus_constant (Pmode, reg, offset);
1282 }
1283
1284 /* The __tls_get_attr symbol. */
1285 static GTY(()) rtx riscv_tls_symbol;
1286
1287 /* Return an instruction sequence that calls __tls_get_addr. SYM is
1288 the TLS symbol we are referencing and TYPE is the symbol type to use
1289 (either global dynamic or local dynamic). RESULT is an RTX for the
1290 return value location. */
1291
1292 static rtx_insn *
riscv_call_tls_get_addr(rtx sym,rtx result)1293 riscv_call_tls_get_addr (rtx sym, rtx result)
1294 {
1295 rtx a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST), func;
1296 rtx_insn *insn;
1297
1298 if (!riscv_tls_symbol)
1299 riscv_tls_symbol = init_one_libfunc ("__tls_get_addr");
1300 func = gen_rtx_MEM (FUNCTION_MODE, riscv_tls_symbol);
1301
1302 start_sequence ();
1303
1304 emit_insn (riscv_got_load_tls_gd (a0, sym));
1305 insn = emit_call_insn (gen_call_value (result, func, const0_rtx, NULL));
1306 RTL_CONST_CALL_P (insn) = 1;
1307 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
1308 insn = get_insns ();
1309
1310 end_sequence ();
1311
1312 return insn;
1313 }
1314
1315 /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
1316 its address. The return value will be both a valid address and a valid
1317 SET_SRC (either a REG or a LO_SUM). */
1318
1319 static rtx
riscv_legitimize_tls_address(rtx loc)1320 riscv_legitimize_tls_address (rtx loc)
1321 {
1322 rtx dest, tp, tmp;
1323 enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
1324
1325 #if 0
1326 /* TLS copy relocs are now deprecated and should not be used. */
1327 /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE. */
1328 if (!flag_pic)
1329 model = TLS_MODEL_LOCAL_EXEC;
1330 #endif
1331
1332 switch (model)
1333 {
1334 case TLS_MODEL_LOCAL_DYNAMIC:
1335 /* Rely on section anchors for the optimization that LDM TLS
1336 provides. The anchor's address is loaded with GD TLS. */
1337 case TLS_MODEL_GLOBAL_DYNAMIC:
1338 tmp = gen_rtx_REG (Pmode, GP_RETURN);
1339 dest = gen_reg_rtx (Pmode);
1340 emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp, loc);
1341 break;
1342
1343 case TLS_MODEL_INITIAL_EXEC:
1344 /* la.tls.ie; tp-relative add */
1345 tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
1346 tmp = gen_reg_rtx (Pmode);
1347 emit_insn (riscv_got_load_tls_ie (tmp, loc));
1348 dest = gen_reg_rtx (Pmode);
1349 emit_insn (gen_add3_insn (dest, tmp, tp));
1350 break;
1351
1352 case TLS_MODEL_LOCAL_EXEC:
1353 tmp = riscv_unspec_offset_high (NULL, loc, SYMBOL_TLS_LE);
1354 dest = gen_reg_rtx (Pmode);
1355 emit_insn (riscv_tls_add_tp_le (dest, tmp, loc));
1356 dest = gen_rtx_LO_SUM (Pmode, dest,
1357 riscv_unspec_address (loc, SYMBOL_TLS_LE));
1358 break;
1359
1360 default:
1361 gcc_unreachable ();
1362 }
1363 return dest;
1364 }
1365
1366 /* If X is not a valid address for mode MODE, force it into a register. */
1367
1368 static rtx
riscv_force_address(rtx x,machine_mode mode)1369 riscv_force_address (rtx x, machine_mode mode)
1370 {
1371 if (!riscv_legitimate_address_p (mode, x, false))
1372 x = force_reg (Pmode, x);
1373 return x;
1374 }
1375
1376 /* Modify base + offset so that offset fits within a compressed load/store insn
1377 and the excess is added to base. */
1378
1379 static rtx
riscv_shorten_lw_offset(rtx base,HOST_WIDE_INT offset)1380 riscv_shorten_lw_offset (rtx base, HOST_WIDE_INT offset)
1381 {
1382 rtx addr, high;
1383 /* Leave OFFSET as an unsigned 5-bit offset scaled by 4 and put the excess
1384 into HIGH. */
1385 high = GEN_INT (offset & ~CSW_MAX_OFFSET);
1386 offset &= CSW_MAX_OFFSET;
1387 if (!SMALL_OPERAND (INTVAL (high)))
1388 high = force_reg (Pmode, high);
1389 base = force_reg (Pmode, gen_rtx_PLUS (Pmode, high, base));
1390 addr = plus_constant (Pmode, base, offset);
1391 return addr;
1392 }
1393
1394 /* This function is used to implement LEGITIMIZE_ADDRESS. If X can
1395 be legitimized in a way that the generic machinery might not expect,
1396 return a new address, otherwise return NULL. MODE is the mode of
1397 the memory being accessed. */
1398
1399 static rtx
riscv_legitimize_address(rtx x,rtx oldx ATTRIBUTE_UNUSED,machine_mode mode)1400 riscv_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
1401 machine_mode mode)
1402 {
1403 rtx addr;
1404
1405 if (riscv_tls_symbol_p (x))
1406 return riscv_legitimize_tls_address (x);
1407
1408 /* See if the address can split into a high part and a LO_SUM. */
1409 if (riscv_split_symbol (NULL, x, mode, &addr, FALSE))
1410 return riscv_force_address (addr, mode);
1411
1412 /* Handle BASE + OFFSET. */
1413 if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))
1414 && INTVAL (XEXP (x, 1)) != 0)
1415 {
1416 rtx base = XEXP (x, 0);
1417 HOST_WIDE_INT offset = INTVAL (XEXP (x, 1));
1418
1419 if (!riscv_valid_base_register_p (base, mode, false))
1420 base = copy_to_mode_reg (Pmode, base);
1421 if (optimize_function_for_size_p (cfun)
1422 && (strcmp (current_pass->name, "shorten_memrefs") == 0)
1423 && mode == SImode)
1424 /* Convert BASE + LARGE_OFFSET into NEW_BASE + SMALL_OFFSET to allow
1425 possible compressed load/store. */
1426 addr = riscv_shorten_lw_offset (base, offset);
1427 else
1428 addr = riscv_add_offset (NULL, base, offset);
1429 return riscv_force_address (addr, mode);
1430 }
1431
1432 return x;
1433 }
1434
1435 /* Load VALUE into DEST. TEMP is as for riscv_force_temporary. ORIG_MODE
1436 is the original src mode before promotion. */
1437
1438 void
riscv_move_integer(rtx temp,rtx dest,HOST_WIDE_INT value,machine_mode orig_mode,bool in_splitter)1439 riscv_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value,
1440 machine_mode orig_mode, bool in_splitter)
1441 {
1442 struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
1443 machine_mode mode;
1444 int i, num_ops;
1445 rtx x;
1446
1447 /* We can't call gen_reg_rtx from a splitter, because this might realloc
1448 the regno_reg_rtx array, which would invalidate reg rtx pointers in the
1449 combine undo buffer. */
1450 bool can_create_pseudo = can_create_pseudo_p () && ! in_splitter;
1451
1452 mode = GET_MODE (dest);
1453 /* We use the original mode for the riscv_build_integer call, because HImode
1454 values are given special treatment. */
1455 num_ops = riscv_build_integer (codes, value, orig_mode);
1456
1457 if (can_create_pseudo && num_ops > 2 /* not a simple constant */
1458 && num_ops >= riscv_split_integer_cost (value))
1459 x = riscv_split_integer (value, mode);
1460 else
1461 {
1462 /* Apply each binary operation to X. */
1463 x = GEN_INT (codes[0].value);
1464
1465 for (i = 1; i < num_ops; i++)
1466 {
1467 if (!can_create_pseudo)
1468 x = riscv_emit_set (temp, x);
1469 else
1470 x = force_reg (mode, x);
1471
1472 x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
1473 }
1474 }
1475
1476 riscv_emit_set (dest, x);
1477 }
1478
1479 /* Subroutine of riscv_legitimize_move. Move constant SRC into register
1480 DEST given that SRC satisfies immediate_operand but doesn't satisfy
1481 move_operand. */
1482
1483 static void
riscv_legitimize_const_move(machine_mode mode,rtx dest,rtx src)1484 riscv_legitimize_const_move (machine_mode mode, rtx dest, rtx src)
1485 {
1486 rtx base, offset;
1487
1488 /* Split moves of big integers into smaller pieces. */
1489 if (splittable_const_int_operand (src, mode))
1490 {
1491 riscv_move_integer (dest, dest, INTVAL (src), mode, FALSE);
1492 return;
1493 }
1494
1495 /* Split moves of symbolic constants into high/low pairs. */
1496 if (riscv_split_symbol (dest, src, MAX_MACHINE_MODE, &src, FALSE))
1497 {
1498 riscv_emit_set (dest, src);
1499 return;
1500 }
1501
1502 /* Generate the appropriate access sequences for TLS symbols. */
1503 if (riscv_tls_symbol_p (src))
1504 {
1505 riscv_emit_move (dest, riscv_legitimize_tls_address (src));
1506 return;
1507 }
1508
1509 /* If we have (const (plus symbol offset)), and that expression cannot
1510 be forced into memory, load the symbol first and add in the offset. Also
1511 prefer to do this even if the constant _can_ be forced into memory, as it
1512 usually produces better code. */
1513 split_const (src, &base, &offset);
1514 if (offset != const0_rtx
1515 && (targetm.cannot_force_const_mem (mode, src) || can_create_pseudo_p ()))
1516 {
1517 base = riscv_force_temporary (dest, base, FALSE);
1518 riscv_emit_move (dest, riscv_add_offset (NULL, base, INTVAL (offset)));
1519 return;
1520 }
1521
1522 src = force_const_mem (mode, src);
1523
1524 /* When using explicit relocs, constant pool references are sometimes
1525 not legitimate addresses. */
1526 riscv_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0), FALSE);
1527 riscv_emit_move (dest, src);
1528 }
1529
1530 /* If (set DEST SRC) is not a valid move instruction, emit an equivalent
1531 sequence that is valid. */
1532
1533 bool
riscv_legitimize_move(machine_mode mode,rtx dest,rtx src)1534 riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
1535 {
1536 /* Expand
1537 (set (reg:QI target) (mem:QI (address)))
1538 to
1539 (set (reg:DI temp) (zero_extend:DI (mem:QI (address))))
1540 (set (reg:QI target) (subreg:QI (reg:DI temp) 0))
1541 with auto-sign/zero extend. */
1542 if (GET_MODE_CLASS (mode) == MODE_INT
1543 && GET_MODE_SIZE (mode) < UNITS_PER_WORD
1544 && can_create_pseudo_p ()
1545 && MEM_P (src))
1546 {
1547 rtx temp_reg;
1548 int zero_extend_p;
1549
1550 temp_reg = gen_reg_rtx (word_mode);
1551 zero_extend_p = (LOAD_EXTEND_OP (mode) == ZERO_EXTEND);
1552 emit_insn (gen_extend_insn (temp_reg, src, word_mode, mode,
1553 zero_extend_p));
1554 riscv_emit_move (dest, gen_lowpart (mode, temp_reg));
1555 return true;
1556 }
1557
1558 if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
1559 {
1560 rtx reg;
1561
1562 if (GET_CODE (src) == CONST_INT)
1563 {
1564 /* Apply the equivalent of PROMOTE_MODE here for constants to
1565 improve cse. */
1566 machine_mode promoted_mode = mode;
1567 if (GET_MODE_CLASS (mode) == MODE_INT
1568 && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
1569 promoted_mode = word_mode;
1570
1571 if (splittable_const_int_operand (src, mode))
1572 {
1573 reg = gen_reg_rtx (promoted_mode);
1574 riscv_move_integer (reg, reg, INTVAL (src), mode, FALSE);
1575 }
1576 else
1577 reg = force_reg (promoted_mode, src);
1578
1579 if (promoted_mode != mode)
1580 reg = gen_lowpart (mode, reg);
1581 }
1582 else
1583 reg = force_reg (mode, src);
1584 riscv_emit_move (dest, reg);
1585 return true;
1586 }
1587
1588 /* We need to deal with constants that would be legitimate
1589 immediate_operands but aren't legitimate move_operands. */
1590 if (CONSTANT_P (src) && !move_operand (src, mode))
1591 {
1592 riscv_legitimize_const_move (mode, dest, src);
1593 set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
1594 return true;
1595 }
1596
1597 /* RISC-V GCC may generate non-legitimate address due to we provide some
1598 pattern for optimize access PIC local symbol and it's make GCC generate
1599 unrecognizable instruction during optmizing. */
1600
1601 if (MEM_P (dest) && !riscv_legitimate_address_p (mode, XEXP (dest, 0),
1602 reload_completed))
1603 {
1604 XEXP (dest, 0) = riscv_force_address (XEXP (dest, 0), mode);
1605 }
1606
1607 if (MEM_P (src) && !riscv_legitimate_address_p (mode, XEXP (src, 0),
1608 reload_completed))
1609 {
1610 XEXP (src, 0) = riscv_force_address (XEXP (src, 0), mode);
1611 }
1612
1613 return false;
1614 }
1615
1616 /* Return true if there is an instruction that implements CODE and accepts
1617 X as an immediate operand. */
1618
1619 static int
riscv_immediate_operand_p(int code,HOST_WIDE_INT x)1620 riscv_immediate_operand_p (int code, HOST_WIDE_INT x)
1621 {
1622 switch (code)
1623 {
1624 case ASHIFT:
1625 case ASHIFTRT:
1626 case LSHIFTRT:
1627 /* All shift counts are truncated to a valid constant. */
1628 return true;
1629
1630 case AND:
1631 case IOR:
1632 case XOR:
1633 case PLUS:
1634 case LT:
1635 case LTU:
1636 /* These instructions take 12-bit signed immediates. */
1637 return SMALL_OPERAND (x);
1638
1639 case LE:
1640 /* We add 1 to the immediate and use SLT. */
1641 return SMALL_OPERAND (x + 1);
1642
1643 case LEU:
1644 /* Likewise SLTU, but reject the always-true case. */
1645 return SMALL_OPERAND (x + 1) && x + 1 != 0;
1646
1647 case GE:
1648 case GEU:
1649 /* We can emulate an immediate of 1 by using GT/GTU against x0. */
1650 return x == 1;
1651
1652 default:
1653 /* By default assume that x0 can be used for 0. */
1654 return x == 0;
1655 }
1656 }
1657
1658 /* Return the cost of binary operation X, given that the instruction
1659 sequence for a word-sized or smaller operation takes SIGNLE_INSNS
1660 instructions and that the sequence of a double-word operation takes
1661 DOUBLE_INSNS instructions. */
1662
1663 static int
riscv_binary_cost(rtx x,int single_insns,int double_insns)1664 riscv_binary_cost (rtx x, int single_insns, int double_insns)
1665 {
1666 if (GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD * 2)
1667 return COSTS_N_INSNS (double_insns);
1668 return COSTS_N_INSNS (single_insns);
1669 }
1670
1671 /* Return the cost of sign- or zero-extending OP. */
1672
1673 static int
riscv_extend_cost(rtx op,bool unsigned_p)1674 riscv_extend_cost (rtx op, bool unsigned_p)
1675 {
1676 if (MEM_P (op))
1677 return 0;
1678
1679 if (unsigned_p && GET_MODE (op) == QImode)
1680 /* We can use ANDI. */
1681 return COSTS_N_INSNS (1);
1682
1683 if (!unsigned_p && GET_MODE (op) == SImode)
1684 /* We can use SEXT.W. */
1685 return COSTS_N_INSNS (1);
1686
1687 /* We need to use a shift left and a shift right. */
1688 return COSTS_N_INSNS (2);
1689 }
1690
1691 /* Implement TARGET_RTX_COSTS. */
1692
1693 #define SINGLE_SHIFT_COST 1
1694
1695 static bool
riscv_rtx_costs(rtx x,machine_mode mode,int outer_code,int opno ATTRIBUTE_UNUSED,int * total,bool speed)1696 riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED,
1697 int *total, bool speed)
1698 {
1699 bool float_mode_p = FLOAT_MODE_P (mode);
1700 int cost;
1701
1702 switch (GET_CODE (x))
1703 {
1704 case CONST_INT:
1705 if (riscv_immediate_operand_p (outer_code, INTVAL (x)))
1706 {
1707 *total = 0;
1708 return true;
1709 }
1710 /* Fall through. */
1711
1712 case SYMBOL_REF:
1713 case LABEL_REF:
1714 case CONST_DOUBLE:
1715 case CONST:
1716 if ((cost = riscv_const_insns (x)) > 0)
1717 {
1718 /* If the constant is likely to be stored in a GPR, SETs of
1719 single-insn constants are as cheap as register sets; we
1720 never want to CSE them. */
1721 if (cost == 1 && outer_code == SET)
1722 *total = 0;
1723 /* When we load a constant more than once, it usually is better
1724 to duplicate the last operation in the sequence than to CSE
1725 the constant itself. */
1726 else if (outer_code == SET || GET_MODE (x) == VOIDmode)
1727 *total = COSTS_N_INSNS (1);
1728 }
1729 else /* The instruction will be fetched from the constant pool. */
1730 *total = COSTS_N_INSNS (riscv_symbol_insns (SYMBOL_ABSOLUTE));
1731 return true;
1732
1733 case MEM:
1734 /* If the address is legitimate, return the number of
1735 instructions it needs. */
1736 if ((cost = riscv_address_insns (XEXP (x, 0), mode, true)) > 0)
1737 {
1738 /* When optimizing for size, make uncompressible 32-bit addresses
1739 more expensive so that compressible 32-bit addresses are
1740 preferred. */
1741 if (TARGET_RVC && !speed && riscv_mshorten_memrefs && mode == SImode
1742 && !riscv_compressed_lw_address_p (XEXP (x, 0)))
1743 cost++;
1744
1745 *total = COSTS_N_INSNS (cost + tune_param->memory_cost);
1746 return true;
1747 }
1748 /* Otherwise use the default handling. */
1749 return false;
1750
1751 case NOT:
1752 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1);
1753 return false;
1754
1755 case AND:
1756 case IOR:
1757 case XOR:
1758 /* Double-word operations use two single-word operations. */
1759 *total = riscv_binary_cost (x, 1, 2);
1760 return false;
1761
1762 case ZERO_EXTRACT:
1763 /* This is an SImode shift. */
1764 if (outer_code == SET
1765 && CONST_INT_P (XEXP (x, 1))
1766 && CONST_INT_P (XEXP (x, 2))
1767 && (INTVAL (XEXP (x, 2)) > 0)
1768 && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (x, 2)) == 32))
1769 {
1770 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
1771 return true;
1772 }
1773 return false;
1774
1775 case ASHIFT:
1776 case ASHIFTRT:
1777 case LSHIFTRT:
1778 *total = riscv_binary_cost (x, SINGLE_SHIFT_COST,
1779 CONSTANT_P (XEXP (x, 1)) ? 4 : 9);
1780 return false;
1781
1782 case ABS:
1783 *total = COSTS_N_INSNS (float_mode_p ? 1 : 3);
1784 return false;
1785
1786 case LO_SUM:
1787 *total = set_src_cost (XEXP (x, 0), mode, speed);
1788 return true;
1789
1790 case LT:
1791 /* This is an SImode shift. */
1792 if (outer_code == SET && GET_MODE (x) == DImode
1793 && GET_MODE (XEXP (x, 0)) == SImode)
1794 {
1795 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
1796 return true;
1797 }
1798 /* Fall through. */
1799 case LTU:
1800 case LE:
1801 case LEU:
1802 case GT:
1803 case GTU:
1804 case GE:
1805 case GEU:
1806 case EQ:
1807 case NE:
1808 /* Branch comparisons have VOIDmode, so use the first operand's
1809 mode instead. */
1810 mode = GET_MODE (XEXP (x, 0));
1811 if (float_mode_p)
1812 *total = tune_param->fp_add[mode == DFmode];
1813 else
1814 *total = riscv_binary_cost (x, 1, 3);
1815 return false;
1816
1817 case UNORDERED:
1818 case ORDERED:
1819 /* (FEQ(A, A) & FEQ(B, B)) compared against 0. */
1820 mode = GET_MODE (XEXP (x, 0));
1821 *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (2);
1822 return false;
1823
1824 case UNEQ:
1825 /* (FEQ(A, A) & FEQ(B, B)) compared against FEQ(A, B). */
1826 mode = GET_MODE (XEXP (x, 0));
1827 *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (3);
1828 return false;
1829
1830 case LTGT:
1831 /* (FLT(A, A) || FGT(B, B)). */
1832 mode = GET_MODE (XEXP (x, 0));
1833 *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (2);
1834 return false;
1835
1836 case UNGE:
1837 case UNGT:
1838 case UNLE:
1839 case UNLT:
1840 /* FLT or FLE, but guarded by an FFLAGS read and write. */
1841 mode = GET_MODE (XEXP (x, 0));
1842 *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (4);
1843 return false;
1844
1845 case MINUS:
1846 case PLUS:
1847 if (float_mode_p)
1848 *total = tune_param->fp_add[mode == DFmode];
1849 else
1850 *total = riscv_binary_cost (x, 1, 4);
1851 return false;
1852
1853 case NEG:
1854 {
1855 rtx op = XEXP (x, 0);
1856 if (GET_CODE (op) == FMA && !HONOR_SIGNED_ZEROS (mode))
1857 {
1858 *total = (tune_param->fp_mul[mode == DFmode]
1859 + set_src_cost (XEXP (op, 0), mode, speed)
1860 + set_src_cost (XEXP (op, 1), mode, speed)
1861 + set_src_cost (XEXP (op, 2), mode, speed));
1862 return true;
1863 }
1864 }
1865
1866 if (float_mode_p)
1867 *total = tune_param->fp_add[mode == DFmode];
1868 else
1869 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1);
1870 return false;
1871
1872 case MULT:
1873 if (float_mode_p)
1874 *total = tune_param->fp_mul[mode == DFmode];
1875 else if (!TARGET_MUL)
1876 /* Estimate the cost of a library call. */
1877 *total = COSTS_N_INSNS (speed ? 32 : 6);
1878 else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
1879 *total = 3 * tune_param->int_mul[0] + COSTS_N_INSNS (2);
1880 else if (!speed)
1881 *total = COSTS_N_INSNS (1);
1882 else
1883 *total = tune_param->int_mul[mode == DImode];
1884 return false;
1885
1886 case DIV:
1887 case SQRT:
1888 case MOD:
1889 if (float_mode_p)
1890 {
1891 *total = tune_param->fp_div[mode == DFmode];
1892 return false;
1893 }
1894 /* Fall through. */
1895
1896 case UDIV:
1897 case UMOD:
1898 if (!TARGET_DIV)
1899 /* Estimate the cost of a library call. */
1900 *total = COSTS_N_INSNS (speed ? 32 : 6);
1901 else if (speed)
1902 *total = tune_param->int_div[mode == DImode];
1903 else
1904 *total = COSTS_N_INSNS (1);
1905 return false;
1906
1907 case ZERO_EXTEND:
1908 /* This is an SImode shift. */
1909 if (GET_CODE (XEXP (x, 0)) == LSHIFTRT)
1910 {
1911 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
1912 return true;
1913 }
1914 /* Fall through. */
1915 case SIGN_EXTEND:
1916 *total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND);
1917 return false;
1918
1919 case FLOAT:
1920 case UNSIGNED_FLOAT:
1921 case FIX:
1922 case FLOAT_EXTEND:
1923 case FLOAT_TRUNCATE:
1924 *total = tune_param->fp_add[mode == DFmode];
1925 return false;
1926
1927 case FMA:
1928 *total = (tune_param->fp_mul[mode == DFmode]
1929 + set_src_cost (XEXP (x, 0), mode, speed)
1930 + set_src_cost (XEXP (x, 1), mode, speed)
1931 + set_src_cost (XEXP (x, 2), mode, speed));
1932 return true;
1933
1934 case UNSPEC:
1935 if (XINT (x, 1) == UNSPEC_AUIPC)
1936 {
1937 /* Make AUIPC cheap to avoid spilling its result to the stack. */
1938 *total = 1;
1939 return true;
1940 }
1941 return false;
1942
1943 default:
1944 return false;
1945 }
1946 }
1947
1948 /* Implement TARGET_ADDRESS_COST. */
1949
1950 static int
riscv_address_cost(rtx addr,machine_mode mode,addr_space_t as ATTRIBUTE_UNUSED,bool speed ATTRIBUTE_UNUSED)1951 riscv_address_cost (rtx addr, machine_mode mode,
1952 addr_space_t as ATTRIBUTE_UNUSED,
1953 bool speed ATTRIBUTE_UNUSED)
1954 {
1955 /* When optimizing for size, make uncompressible 32-bit addresses more
1956 * expensive so that compressible 32-bit addresses are preferred. */
1957 if (TARGET_RVC && !speed && riscv_mshorten_memrefs && mode == SImode
1958 && !riscv_compressed_lw_address_p (addr))
1959 return riscv_address_insns (addr, mode, false) + 1;
1960 return riscv_address_insns (addr, mode, false);
1961 }
1962
1963 /* Return one word of double-word value OP. HIGH_P is true to select the
1964 high part or false to select the low part. */
1965
1966 rtx
riscv_subword(rtx op,bool high_p)1967 riscv_subword (rtx op, bool high_p)
1968 {
1969 unsigned int byte = (high_p != BYTES_BIG_ENDIAN) ? UNITS_PER_WORD : 0;
1970 machine_mode mode = GET_MODE (op);
1971
1972 if (mode == VOIDmode)
1973 mode = TARGET_64BIT ? TImode : DImode;
1974
1975 if (MEM_P (op))
1976 return adjust_address (op, word_mode, byte);
1977
1978 if (REG_P (op))
1979 gcc_assert (!FP_REG_RTX_P (op));
1980
1981 return simplify_gen_subreg (word_mode, op, mode, byte);
1982 }
1983
1984 /* Return true if a 64-bit move from SRC to DEST should be split into two. */
1985
1986 bool
riscv_split_64bit_move_p(rtx dest,rtx src)1987 riscv_split_64bit_move_p (rtx dest, rtx src)
1988 {
1989 if (TARGET_64BIT)
1990 return false;
1991
1992 /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case
1993 of zeroing an FPR with FCVT.D.W. */
1994 if (TARGET_DOUBLE_FLOAT
1995 && ((FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
1996 || (FP_REG_RTX_P (dest) && MEM_P (src))
1997 || (FP_REG_RTX_P (src) && MEM_P (dest))
1998 || (FP_REG_RTX_P (dest) && src == CONST0_RTX (GET_MODE (src)))))
1999 return false;
2000
2001 return true;
2002 }
2003
2004 /* Split a doubleword move from SRC to DEST. On 32-bit targets,
2005 this function handles 64-bit moves for which riscv_split_64bit_move_p
2006 holds. For 64-bit targets, this function handles 128-bit moves. */
2007
2008 void
riscv_split_doubleword_move(rtx dest,rtx src)2009 riscv_split_doubleword_move (rtx dest, rtx src)
2010 {
2011 rtx low_dest;
2012
2013 /* The operation can be split into two normal moves. Decide in
2014 which order to do them. */
2015 low_dest = riscv_subword (dest, false);
2016 if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src))
2017 {
2018 riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
2019 riscv_emit_move (low_dest, riscv_subword (src, false));
2020 }
2021 else
2022 {
2023 riscv_emit_move (low_dest, riscv_subword (src, false));
2024 riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
2025 }
2026 }
2027
2028 /* Return the appropriate instructions to move SRC into DEST. Assume
2029 that SRC is operand 1 and DEST is operand 0. */
2030
2031 const char *
riscv_output_move(rtx dest,rtx src)2032 riscv_output_move (rtx dest, rtx src)
2033 {
2034 enum rtx_code dest_code, src_code;
2035 machine_mode mode;
2036 bool dbl_p;
2037
2038 dest_code = GET_CODE (dest);
2039 src_code = GET_CODE (src);
2040 mode = GET_MODE (dest);
2041 dbl_p = (GET_MODE_SIZE (mode) == 8);
2042
2043 if (dbl_p && riscv_split_64bit_move_p (dest, src))
2044 return "#";
2045
2046 if (dest_code == REG && GP_REG_P (REGNO (dest)))
2047 {
2048 if (src_code == REG && FP_REG_P (REGNO (src)))
2049 return dbl_p ? "fmv.x.d\t%0,%1" : "fmv.x.w\t%0,%1";
2050
2051 if (src_code == MEM)
2052 switch (GET_MODE_SIZE (mode))
2053 {
2054 case 1: return "lbu\t%0,%1";
2055 case 2: return "lhu\t%0,%1";
2056 case 4: return "lw\t%0,%1";
2057 case 8: return "ld\t%0,%1";
2058 }
2059
2060 if (src_code == CONST_INT)
2061 return "li\t%0,%1";
2062
2063 if (src_code == HIGH)
2064 return "lui\t%0,%h1";
2065
2066 if (symbolic_operand (src, VOIDmode))
2067 switch (riscv_classify_symbolic_expression (src))
2068 {
2069 case SYMBOL_GOT_DISP: return "la\t%0,%1";
2070 case SYMBOL_ABSOLUTE: return "lla\t%0,%1";
2071 case SYMBOL_PCREL: return "lla\t%0,%1";
2072 default: gcc_unreachable ();
2073 }
2074 }
2075 if ((src_code == REG && GP_REG_P (REGNO (src)))
2076 || (src == CONST0_RTX (mode)))
2077 {
2078 if (dest_code == REG)
2079 {
2080 if (GP_REG_P (REGNO (dest)))
2081 return "mv\t%0,%z1";
2082
2083 if (FP_REG_P (REGNO (dest)))
2084 {
2085 if (!dbl_p)
2086 return "fmv.w.x\t%0,%z1";
2087 if (TARGET_64BIT)
2088 return "fmv.d.x\t%0,%z1";
2089 /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */
2090 gcc_assert (src == CONST0_RTX (mode));
2091 return "fcvt.d.w\t%0,x0";
2092 }
2093 }
2094 if (dest_code == MEM)
2095 switch (GET_MODE_SIZE (mode))
2096 {
2097 case 1: return "sb\t%z1,%0";
2098 case 2: return "sh\t%z1,%0";
2099 case 4: return "sw\t%z1,%0";
2100 case 8: return "sd\t%z1,%0";
2101 }
2102 }
2103 if (src_code == REG && FP_REG_P (REGNO (src)))
2104 {
2105 if (dest_code == REG && FP_REG_P (REGNO (dest)))
2106 return dbl_p ? "fmv.d\t%0,%1" : "fmv.s\t%0,%1";
2107
2108 if (dest_code == MEM)
2109 return dbl_p ? "fsd\t%1,%0" : "fsw\t%1,%0";
2110 }
2111 if (dest_code == REG && FP_REG_P (REGNO (dest)))
2112 {
2113 if (src_code == MEM)
2114 return dbl_p ? "fld\t%0,%1" : "flw\t%0,%1";
2115 }
2116 gcc_unreachable ();
2117 }
2118
2119 const char *
riscv_output_return()2120 riscv_output_return ()
2121 {
2122 if (cfun->machine->naked_p)
2123 return "";
2124
2125 return "ret";
2126 }
2127
2128
2129 /* Return true if CMP1 is a suitable second operand for integer ordering
2130 test CODE. See also the *sCC patterns in riscv.md. */
2131
2132 static bool
riscv_int_order_operand_ok_p(enum rtx_code code,rtx cmp1)2133 riscv_int_order_operand_ok_p (enum rtx_code code, rtx cmp1)
2134 {
2135 switch (code)
2136 {
2137 case GT:
2138 case GTU:
2139 return reg_or_0_operand (cmp1, VOIDmode);
2140
2141 case GE:
2142 case GEU:
2143 return cmp1 == const1_rtx;
2144
2145 case LT:
2146 case LTU:
2147 return arith_operand (cmp1, VOIDmode);
2148
2149 case LE:
2150 return sle_operand (cmp1, VOIDmode);
2151
2152 case LEU:
2153 return sleu_operand (cmp1, VOIDmode);
2154
2155 default:
2156 gcc_unreachable ();
2157 }
2158 }
2159
2160 /* Return true if *CMP1 (of mode MODE) is a valid second operand for
2161 integer ordering test *CODE, or if an equivalent combination can
2162 be formed by adjusting *CODE and *CMP1. When returning true, update
2163 *CODE and *CMP1 with the chosen code and operand, otherwise leave
2164 them alone. */
2165
2166 static bool
riscv_canonicalize_int_order_test(enum rtx_code * code,rtx * cmp1,machine_mode mode)2167 riscv_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1,
2168 machine_mode mode)
2169 {
2170 HOST_WIDE_INT plus_one;
2171
2172 if (riscv_int_order_operand_ok_p (*code, *cmp1))
2173 return true;
2174
2175 if (CONST_INT_P (*cmp1))
2176 switch (*code)
2177 {
2178 case LE:
2179 plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
2180 if (INTVAL (*cmp1) < plus_one)
2181 {
2182 *code = LT;
2183 *cmp1 = force_reg (mode, GEN_INT (plus_one));
2184 return true;
2185 }
2186 break;
2187
2188 case LEU:
2189 plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
2190 if (plus_one != 0)
2191 {
2192 *code = LTU;
2193 *cmp1 = force_reg (mode, GEN_INT (plus_one));
2194 return true;
2195 }
2196 break;
2197
2198 default:
2199 break;
2200 }
2201 return false;
2202 }
2203
2204 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
2205 in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
2206 is nonnull, it's OK to set TARGET to the inverse of the result and
2207 flip *INVERT_PTR instead. */
2208
2209 static void
riscv_emit_int_order_test(enum rtx_code code,bool * invert_ptr,rtx target,rtx cmp0,rtx cmp1)2210 riscv_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
2211 rtx target, rtx cmp0, rtx cmp1)
2212 {
2213 machine_mode mode;
2214
2215 /* First see if there is a RISCV instruction that can do this operation.
2216 If not, try doing the same for the inverse operation. If that also
2217 fails, force CMP1 into a register and try again. */
2218 mode = GET_MODE (cmp0);
2219 if (riscv_canonicalize_int_order_test (&code, &cmp1, mode))
2220 riscv_emit_binary (code, target, cmp0, cmp1);
2221 else
2222 {
2223 enum rtx_code inv_code = reverse_condition (code);
2224 if (!riscv_canonicalize_int_order_test (&inv_code, &cmp1, mode))
2225 {
2226 cmp1 = force_reg (mode, cmp1);
2227 riscv_emit_int_order_test (code, invert_ptr, target, cmp0, cmp1);
2228 }
2229 else if (invert_ptr == 0)
2230 {
2231 rtx inv_target = riscv_force_binary (GET_MODE (target),
2232 inv_code, cmp0, cmp1);
2233 riscv_emit_binary (XOR, target, inv_target, const1_rtx);
2234 }
2235 else
2236 {
2237 *invert_ptr = !*invert_ptr;
2238 riscv_emit_binary (inv_code, target, cmp0, cmp1);
2239 }
2240 }
2241 }
2242
2243 /* Return a register that is zero iff CMP0 and CMP1 are equal.
2244 The register will have the same mode as CMP0. */
2245
2246 static rtx
riscv_zero_if_equal(rtx cmp0,rtx cmp1)2247 riscv_zero_if_equal (rtx cmp0, rtx cmp1)
2248 {
2249 if (cmp1 == const0_rtx)
2250 return cmp0;
2251
2252 return expand_binop (GET_MODE (cmp0), sub_optab,
2253 cmp0, cmp1, 0, 0, OPTAB_DIRECT);
2254 }
2255
2256 /* Sign- or zero-extend OP0 and OP1 for integer comparisons. */
2257
2258 static void
riscv_extend_comparands(rtx_code code,rtx * op0,rtx * op1)2259 riscv_extend_comparands (rtx_code code, rtx *op0, rtx *op1)
2260 {
2261 /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */
2262 if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0)))
2263 {
2264 /* It is more profitable to zero-extend QImode values. But not if the
2265 first operand has already been sign-extended, and the second one is
2266 is a constant or has already been sign-extended also. */
2267 if (unsigned_condition (code) == code
2268 && (GET_MODE (*op0) == QImode
2269 && ! (GET_CODE (*op0) == SUBREG
2270 && SUBREG_PROMOTED_VAR_P (*op0)
2271 && SUBREG_PROMOTED_SIGNED_P (*op0)
2272 && (CONST_INT_P (*op1)
2273 || (GET_CODE (*op1) == SUBREG
2274 && SUBREG_PROMOTED_VAR_P (*op1)
2275 && SUBREG_PROMOTED_SIGNED_P (*op1))))))
2276 {
2277 *op0 = gen_rtx_ZERO_EXTEND (word_mode, *op0);
2278 if (CONST_INT_P (*op1))
2279 *op1 = GEN_INT ((uint8_t) INTVAL (*op1));
2280 else
2281 *op1 = gen_rtx_ZERO_EXTEND (word_mode, *op1);
2282 }
2283 else
2284 {
2285 *op0 = gen_rtx_SIGN_EXTEND (word_mode, *op0);
2286 if (*op1 != const0_rtx)
2287 *op1 = gen_rtx_SIGN_EXTEND (word_mode, *op1);
2288 }
2289 }
2290 }
2291
2292 /* Convert a comparison into something that can be used in a branch. On
2293 entry, *OP0 and *OP1 are the values being compared and *CODE is the code
2294 used to compare them. Update them to describe the final comparison. */
2295
2296 static void
riscv_emit_int_compare(enum rtx_code * code,rtx * op0,rtx * op1)2297 riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1)
2298 {
2299 if (splittable_const_int_operand (*op1, VOIDmode))
2300 {
2301 HOST_WIDE_INT rhs = INTVAL (*op1);
2302
2303 if (*code == EQ || *code == NE)
2304 {
2305 /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0. */
2306 if (SMALL_OPERAND (-rhs))
2307 {
2308 *op0 = riscv_force_binary (GET_MODE (*op0), PLUS, *op0,
2309 GEN_INT (-rhs));
2310 *op1 = const0_rtx;
2311 }
2312 }
2313 else
2314 {
2315 static const enum rtx_code mag_comparisons[][2] = {
2316 {LEU, LTU}, {GTU, GEU}, {LE, LT}, {GT, GE}
2317 };
2318
2319 /* Convert e.g. (OP0 <= 0xFFF) into (OP0 < 0x1000). */
2320 for (size_t i = 0; i < ARRAY_SIZE (mag_comparisons); i++)
2321 {
2322 HOST_WIDE_INT new_rhs;
2323 bool increment = *code == mag_comparisons[i][0];
2324 bool decrement = *code == mag_comparisons[i][1];
2325 if (!increment && !decrement)
2326 continue;
2327
2328 new_rhs = rhs + (increment ? 1 : -1);
2329 if (riscv_integer_cost (new_rhs) < riscv_integer_cost (rhs)
2330 && (rhs < 0) == (new_rhs < 0))
2331 {
2332 *op1 = GEN_INT (new_rhs);
2333 *code = mag_comparisons[i][increment];
2334 }
2335 break;
2336 }
2337 }
2338 }
2339
2340 riscv_extend_comparands (*code, op0, op1);
2341
2342 *op0 = force_reg (word_mode, *op0);
2343 if (*op1 != const0_rtx)
2344 *op1 = force_reg (word_mode, *op1);
2345 }
2346
2347 /* Like riscv_emit_int_compare, but for floating-point comparisons. */
2348
2349 static void
riscv_emit_float_compare(enum rtx_code * code,rtx * op0,rtx * op1)2350 riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
2351 {
2352 rtx tmp0, tmp1, cmp_op0 = *op0, cmp_op1 = *op1;
2353 enum rtx_code fp_code = *code;
2354 *code = NE;
2355
2356 switch (fp_code)
2357 {
2358 case UNORDERED:
2359 *code = EQ;
2360 /* Fall through. */
2361
2362 case ORDERED:
2363 /* a == a && b == b */
2364 tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0);
2365 tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1);
2366 *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1);
2367 *op1 = const0_rtx;
2368 break;
2369
2370 case UNEQ:
2371 /* ordered(a, b) > (a == b) */
2372 *code = EQ;
2373 tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0);
2374 tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1);
2375 *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1);
2376 *op1 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op1);
2377 break;
2378
2379 #define UNORDERED_COMPARISON(CODE, CMP) \
2380 case CODE: \
2381 *code = EQ; \
2382 *op0 = gen_reg_rtx (word_mode); \
2383 if (GET_MODE (cmp_op0) == SFmode && TARGET_64BIT) \
2384 emit_insn (gen_f##CMP##_quietsfdi4 (*op0, cmp_op0, cmp_op1)); \
2385 else if (GET_MODE (cmp_op0) == SFmode) \
2386 emit_insn (gen_f##CMP##_quietsfsi4 (*op0, cmp_op0, cmp_op1)); \
2387 else if (GET_MODE (cmp_op0) == DFmode && TARGET_64BIT) \
2388 emit_insn (gen_f##CMP##_quietdfdi4 (*op0, cmp_op0, cmp_op1)); \
2389 else if (GET_MODE (cmp_op0) == DFmode) \
2390 emit_insn (gen_f##CMP##_quietdfsi4 (*op0, cmp_op0, cmp_op1)); \
2391 else \
2392 gcc_unreachable (); \
2393 *op1 = const0_rtx; \
2394 break;
2395
2396 case UNLT:
2397 std::swap (cmp_op0, cmp_op1);
2398 gcc_fallthrough ();
2399
2400 UNORDERED_COMPARISON(UNGT, le)
2401
2402 case UNLE:
2403 std::swap (cmp_op0, cmp_op1);
2404 gcc_fallthrough ();
2405
2406 UNORDERED_COMPARISON(UNGE, lt)
2407 #undef UNORDERED_COMPARISON
2408
2409 case NE:
2410 fp_code = EQ;
2411 *code = EQ;
2412 /* Fall through. */
2413
2414 case EQ:
2415 case LE:
2416 case LT:
2417 case GE:
2418 case GT:
2419 /* We have instructions for these cases. */
2420 *op0 = riscv_force_binary (word_mode, fp_code, cmp_op0, cmp_op1);
2421 *op1 = const0_rtx;
2422 break;
2423
2424 case LTGT:
2425 /* (a < b) | (a > b) */
2426 tmp0 = riscv_force_binary (word_mode, LT, cmp_op0, cmp_op1);
2427 tmp1 = riscv_force_binary (word_mode, GT, cmp_op0, cmp_op1);
2428 *op0 = riscv_force_binary (word_mode, IOR, tmp0, tmp1);
2429 *op1 = const0_rtx;
2430 break;
2431
2432 default:
2433 gcc_unreachable ();
2434 }
2435 }
2436
2437 /* CODE-compare OP0 and OP1. Store the result in TARGET. */
2438
2439 void
riscv_expand_int_scc(rtx target,enum rtx_code code,rtx op0,rtx op1)2440 riscv_expand_int_scc (rtx target, enum rtx_code code, rtx op0, rtx op1)
2441 {
2442 riscv_extend_comparands (code, &op0, &op1);
2443 op0 = force_reg (word_mode, op0);
2444
2445 if (code == EQ || code == NE)
2446 {
2447 rtx zie = riscv_zero_if_equal (op0, op1);
2448 riscv_emit_binary (code, target, zie, const0_rtx);
2449 }
2450 else
2451 riscv_emit_int_order_test (code, 0, target, op0, op1);
2452 }
2453
2454 /* Like riscv_expand_int_scc, but for floating-point comparisons. */
2455
2456 void
riscv_expand_float_scc(rtx target,enum rtx_code code,rtx op0,rtx op1)2457 riscv_expand_float_scc (rtx target, enum rtx_code code, rtx op0, rtx op1)
2458 {
2459 riscv_emit_float_compare (&code, &op0, &op1);
2460
2461 rtx cmp = riscv_force_binary (word_mode, code, op0, op1);
2462 riscv_emit_set (target, lowpart_subreg (SImode, cmp, word_mode));
2463 }
2464
2465 /* Jump to LABEL if (CODE OP0 OP1) holds. */
2466
2467 void
riscv_expand_conditional_branch(rtx label,rtx_code code,rtx op0,rtx op1)2468 riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1)
2469 {
2470 if (FLOAT_MODE_P (GET_MODE (op1)))
2471 riscv_emit_float_compare (&code, &op0, &op1);
2472 else
2473 riscv_emit_int_compare (&code, &op0, &op1);
2474
2475 rtx condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
2476 emit_jump_insn (gen_condjump (condition, label));
2477 }
2478
2479 /* If (CODE OP0 OP1) holds, move CONS to DEST; else move ALT to DEST. */
2480
2481 void
riscv_expand_conditional_move(rtx dest,rtx cons,rtx alt,rtx_code code,rtx op0,rtx op1)2482 riscv_expand_conditional_move (rtx dest, rtx cons, rtx alt, rtx_code code,
2483 rtx op0, rtx op1)
2484 {
2485 riscv_emit_int_compare (&code, &op0, &op1);
2486 rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
2487 emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond,
2488 cons, alt)));
2489 }
2490
2491 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
2492 least PARM_BOUNDARY bits of alignment, but will be given anything up
2493 to PREFERRED_STACK_BOUNDARY bits if the type requires it. */
2494
2495 static unsigned int
riscv_function_arg_boundary(machine_mode mode,const_tree type)2496 riscv_function_arg_boundary (machine_mode mode, const_tree type)
2497 {
2498 unsigned int alignment;
2499
2500 /* Use natural alignment if the type is not aggregate data. */
2501 if (type && !AGGREGATE_TYPE_P (type))
2502 alignment = TYPE_ALIGN (TYPE_MAIN_VARIANT (type));
2503 else
2504 alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
2505
2506 return MIN (PREFERRED_STACK_BOUNDARY, MAX (PARM_BOUNDARY, alignment));
2507 }
2508
2509 /* If MODE represents an argument that can be passed or returned in
2510 floating-point registers, return the number of registers, else 0. */
2511
2512 static unsigned
riscv_pass_mode_in_fpr_p(machine_mode mode)2513 riscv_pass_mode_in_fpr_p (machine_mode mode)
2514 {
2515 if (GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FP_ARG)
2516 {
2517 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2518 return 1;
2519
2520 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
2521 return 2;
2522 }
2523
2524 return 0;
2525 }
2526
2527 typedef struct {
2528 const_tree type;
2529 HOST_WIDE_INT offset;
2530 } riscv_aggregate_field;
2531
2532 /* Identify subfields of aggregates that are candidates for passing in
2533 floating-point registers. */
2534
2535 static int
riscv_flatten_aggregate_field(const_tree type,riscv_aggregate_field fields[2],int n,HOST_WIDE_INT offset,bool ignore_zero_width_bit_field_p)2536 riscv_flatten_aggregate_field (const_tree type,
2537 riscv_aggregate_field fields[2],
2538 int n, HOST_WIDE_INT offset,
2539 bool ignore_zero_width_bit_field_p)
2540 {
2541 switch (TREE_CODE (type))
2542 {
2543 case RECORD_TYPE:
2544 /* Can't handle incomplete types nor sizes that are not fixed. */
2545 if (!COMPLETE_TYPE_P (type)
2546 || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
2547 || !tree_fits_uhwi_p (TYPE_SIZE (type)))
2548 return -1;
2549
2550 for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
2551 if (TREE_CODE (f) == FIELD_DECL)
2552 {
2553 if (!TYPE_P (TREE_TYPE (f)))
2554 return -1;
2555
2556 /* The C++ front end strips zero-length bit-fields from structs.
2557 So we need to ignore them in the C front end to make C code
2558 compatible with C++ code. */
2559 if (ignore_zero_width_bit_field_p
2560 && DECL_BIT_FIELD (f)
2561 && (DECL_SIZE (f) == NULL_TREE
2562 || integer_zerop (DECL_SIZE (f))))
2563 ;
2564 else
2565 {
2566 HOST_WIDE_INT pos = offset + int_byte_position (f);
2567 n = riscv_flatten_aggregate_field (TREE_TYPE (f),
2568 fields, n, pos,
2569 ignore_zero_width_bit_field_p);
2570 }
2571 if (n < 0)
2572 return -1;
2573 }
2574 return n;
2575
2576 case ARRAY_TYPE:
2577 {
2578 HOST_WIDE_INT n_elts;
2579 riscv_aggregate_field subfields[2];
2580 tree index = TYPE_DOMAIN (type);
2581 tree elt_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
2582 int n_subfields = riscv_flatten_aggregate_field (TREE_TYPE (type),
2583 subfields, 0, offset,
2584 ignore_zero_width_bit_field_p);
2585
2586 /* Can't handle incomplete types nor sizes that are not fixed. */
2587 if (n_subfields <= 0
2588 || !COMPLETE_TYPE_P (type)
2589 || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
2590 || !index
2591 || !TYPE_MAX_VALUE (index)
2592 || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index))
2593 || !TYPE_MIN_VALUE (index)
2594 || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index))
2595 || !tree_fits_uhwi_p (elt_size))
2596 return -1;
2597
2598 n_elts = 1 + tree_to_uhwi (TYPE_MAX_VALUE (index))
2599 - tree_to_uhwi (TYPE_MIN_VALUE (index));
2600 gcc_assert (n_elts >= 0);
2601
2602 for (HOST_WIDE_INT i = 0; i < n_elts; i++)
2603 for (int j = 0; j < n_subfields; j++)
2604 {
2605 if (n >= 2)
2606 return -1;
2607
2608 fields[n] = subfields[j];
2609 fields[n++].offset += i * tree_to_uhwi (elt_size);
2610 }
2611
2612 return n;
2613 }
2614
2615 case COMPLEX_TYPE:
2616 {
2617 /* Complex type need consume 2 field, so n must be 0. */
2618 if (n != 0)
2619 return -1;
2620
2621 HOST_WIDE_INT elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)));
2622
2623 if (elt_size <= UNITS_PER_FP_ARG)
2624 {
2625 fields[0].type = TREE_TYPE (type);
2626 fields[0].offset = offset;
2627 fields[1].type = TREE_TYPE (type);
2628 fields[1].offset = offset + elt_size;
2629
2630 return 2;
2631 }
2632
2633 return -1;
2634 }
2635
2636 default:
2637 if (n < 2
2638 && ((SCALAR_FLOAT_TYPE_P (type)
2639 && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FP_ARG)
2640 || (INTEGRAL_TYPE_P (type)
2641 && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD)))
2642 {
2643 fields[n].type = type;
2644 fields[n].offset = offset;
2645 return n + 1;
2646 }
2647 else
2648 return -1;
2649 }
2650 }
2651
2652 /* Identify candidate aggregates for passing in floating-point registers.
2653 Candidates have at most two fields after flattening. */
2654
2655 static int
riscv_flatten_aggregate_argument(const_tree type,riscv_aggregate_field fields[2],bool ignore_zero_width_bit_field_p)2656 riscv_flatten_aggregate_argument (const_tree type,
2657 riscv_aggregate_field fields[2],
2658 bool ignore_zero_width_bit_field_p)
2659 {
2660 if (!type || TREE_CODE (type) != RECORD_TYPE)
2661 return -1;
2662
2663 return riscv_flatten_aggregate_field (type, fields, 0, 0,
2664 ignore_zero_width_bit_field_p);
2665 }
2666
2667 /* See whether TYPE is a record whose fields should be returned in one or
2668 two floating-point registers. If so, populate FIELDS accordingly. */
2669
2670 static unsigned
riscv_pass_aggregate_in_fpr_pair_p(const_tree type,riscv_aggregate_field fields[2])2671 riscv_pass_aggregate_in_fpr_pair_p (const_tree type,
2672 riscv_aggregate_field fields[2])
2673 {
2674 static int warned = 0;
2675
2676 /* This is the old ABI, which differs for C++ and C. */
2677 int n_old = riscv_flatten_aggregate_argument (type, fields, false);
2678 for (int i = 0; i < n_old; i++)
2679 if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
2680 {
2681 n_old = -1;
2682 break;
2683 }
2684
2685 /* This is the new ABI, which is the same for C++ and C. */
2686 int n_new = riscv_flatten_aggregate_argument (type, fields, true);
2687 for (int i = 0; i < n_new; i++)
2688 if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
2689 {
2690 n_new = -1;
2691 break;
2692 }
2693
2694 if ((n_old != n_new) && (warned == 0))
2695 {
2696 warning (0, "ABI for flattened struct with zero-length bit-fields "
2697 "changed in GCC 10");
2698 warned = 1;
2699 }
2700
2701 return n_new > 0 ? n_new : 0;
2702 }
2703
2704 /* See whether TYPE is a record whose fields should be returned in one or
2705 floating-point register and one integer register. If so, populate
2706 FIELDS accordingly. */
2707
2708 static bool
riscv_pass_aggregate_in_fpr_and_gpr_p(const_tree type,riscv_aggregate_field fields[2])2709 riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type,
2710 riscv_aggregate_field fields[2])
2711 {
2712 static int warned = 0;
2713
2714 /* This is the old ABI, which differs for C++ and C. */
2715 unsigned num_int_old = 0, num_float_old = 0;
2716 int n_old = riscv_flatten_aggregate_argument (type, fields, false);
2717 for (int i = 0; i < n_old; i++)
2718 {
2719 num_float_old += SCALAR_FLOAT_TYPE_P (fields[i].type);
2720 num_int_old += INTEGRAL_TYPE_P (fields[i].type);
2721 }
2722
2723 /* This is the new ABI, which is the same for C++ and C. */
2724 unsigned num_int_new = 0, num_float_new = 0;
2725 int n_new = riscv_flatten_aggregate_argument (type, fields, true);
2726 for (int i = 0; i < n_new; i++)
2727 {
2728 num_float_new += SCALAR_FLOAT_TYPE_P (fields[i].type);
2729 num_int_new += INTEGRAL_TYPE_P (fields[i].type);
2730 }
2731
2732 if (((num_int_old == 1 && num_float_old == 1
2733 && (num_int_old != num_int_new || num_float_old != num_float_new))
2734 || (num_int_new == 1 && num_float_new == 1
2735 && (num_int_old != num_int_new || num_float_old != num_float_new)))
2736 && (warned == 0))
2737 {
2738 warning (0, "ABI for flattened struct with zero-length bit-fields "
2739 "changed in GCC 10");
2740 warned = 1;
2741 }
2742
2743 return num_int_new == 1 && num_float_new == 1;
2744 }
2745
2746 /* Return the representation of an argument passed or returned in an FPR
2747 when the value has mode VALUE_MODE and the type has TYPE_MODE. The
2748 two modes may be different for structures like:
2749
2750 struct __attribute__((packed)) foo { float f; }
2751
2752 where the SFmode value "f" is passed in REGNO but the struct itself
2753 has mode BLKmode. */
2754
2755 static rtx
riscv_pass_fpr_single(machine_mode type_mode,unsigned regno,machine_mode value_mode,HOST_WIDE_INT offset)2756 riscv_pass_fpr_single (machine_mode type_mode, unsigned regno,
2757 machine_mode value_mode,
2758 HOST_WIDE_INT offset)
2759 {
2760 rtx x = gen_rtx_REG (value_mode, regno);
2761
2762 if (type_mode != value_mode)
2763 {
2764 x = gen_rtx_EXPR_LIST (VOIDmode, x, GEN_INT (offset));
2765 x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x));
2766 }
2767 return x;
2768 }
2769
2770 /* Pass or return a composite value in the FPR pair REGNO and REGNO + 1.
2771 MODE is the mode of the composite. MODE1 and OFFSET1 are the mode and
2772 byte offset for the first value, likewise MODE2 and OFFSET2 for the
2773 second value. */
2774
2775 static rtx
riscv_pass_fpr_pair(machine_mode mode,unsigned regno1,machine_mode mode1,HOST_WIDE_INT offset1,unsigned regno2,machine_mode mode2,HOST_WIDE_INT offset2)2776 riscv_pass_fpr_pair (machine_mode mode, unsigned regno1,
2777 machine_mode mode1, HOST_WIDE_INT offset1,
2778 unsigned regno2, machine_mode mode2,
2779 HOST_WIDE_INT offset2)
2780 {
2781 return gen_rtx_PARALLEL
2782 (mode,
2783 gen_rtvec (2,
2784 gen_rtx_EXPR_LIST (VOIDmode,
2785 gen_rtx_REG (mode1, regno1),
2786 GEN_INT (offset1)),
2787 gen_rtx_EXPR_LIST (VOIDmode,
2788 gen_rtx_REG (mode2, regno2),
2789 GEN_INT (offset2))));
2790 }
2791
2792 /* Fill INFO with information about a single argument, and return an
2793 RTL pattern to pass or return the argument. CUM is the cumulative
2794 state for earlier arguments. MODE is the mode of this argument and
2795 TYPE is its type (if known). NAMED is true if this is a named
2796 (fixed) argument rather than a variable one. RETURN_P is true if
2797 returning the argument, or false if passing the argument. */
2798
2799 static rtx
riscv_get_arg_info(struct riscv_arg_info * info,const CUMULATIVE_ARGS * cum,machine_mode mode,const_tree type,bool named,bool return_p)2800 riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
2801 machine_mode mode, const_tree type, bool named,
2802 bool return_p)
2803 {
2804 unsigned num_bytes, num_words;
2805 unsigned fpr_base = return_p ? FP_RETURN : FP_ARG_FIRST;
2806 unsigned gpr_base = return_p ? GP_RETURN : GP_ARG_FIRST;
2807 unsigned alignment = riscv_function_arg_boundary (mode, type);
2808
2809 memset (info, 0, sizeof (*info));
2810 info->gpr_offset = cum->num_gprs;
2811 info->fpr_offset = cum->num_fprs;
2812
2813 if (named)
2814 {
2815 riscv_aggregate_field fields[2];
2816 unsigned fregno = fpr_base + info->fpr_offset;
2817 unsigned gregno = gpr_base + info->gpr_offset;
2818
2819 /* Pass one- or two-element floating-point aggregates in FPRs. */
2820 if ((info->num_fprs = riscv_pass_aggregate_in_fpr_pair_p (type, fields))
2821 && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
2822 switch (info->num_fprs)
2823 {
2824 case 1:
2825 return riscv_pass_fpr_single (mode, fregno,
2826 TYPE_MODE (fields[0].type),
2827 fields[0].offset);
2828
2829 case 2:
2830 return riscv_pass_fpr_pair (mode, fregno,
2831 TYPE_MODE (fields[0].type),
2832 fields[0].offset,
2833 fregno + 1,
2834 TYPE_MODE (fields[1].type),
2835 fields[1].offset);
2836
2837 default:
2838 gcc_unreachable ();
2839 }
2840
2841 /* Pass real and complex floating-point numbers in FPRs. */
2842 if ((info->num_fprs = riscv_pass_mode_in_fpr_p (mode))
2843 && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
2844 switch (GET_MODE_CLASS (mode))
2845 {
2846 case MODE_FLOAT:
2847 return gen_rtx_REG (mode, fregno);
2848
2849 case MODE_COMPLEX_FLOAT:
2850 return riscv_pass_fpr_pair (mode, fregno, GET_MODE_INNER (mode), 0,
2851 fregno + 1, GET_MODE_INNER (mode),
2852 GET_MODE_UNIT_SIZE (mode));
2853
2854 default:
2855 gcc_unreachable ();
2856 }
2857
2858 /* Pass structs with one float and one integer in an FPR and a GPR. */
2859 if (riscv_pass_aggregate_in_fpr_and_gpr_p (type, fields)
2860 && info->gpr_offset < MAX_ARGS_IN_REGISTERS
2861 && info->fpr_offset < MAX_ARGS_IN_REGISTERS)
2862 {
2863 info->num_gprs = 1;
2864 info->num_fprs = 1;
2865
2866 if (!SCALAR_FLOAT_TYPE_P (fields[0].type))
2867 std::swap (fregno, gregno);
2868
2869 return riscv_pass_fpr_pair (mode, fregno, TYPE_MODE (fields[0].type),
2870 fields[0].offset,
2871 gregno, TYPE_MODE (fields[1].type),
2872 fields[1].offset);
2873 }
2874 }
2875
2876 /* Work out the size of the argument. */
2877 num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
2878 num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2879
2880 /* Doubleword-aligned varargs start on an even register boundary. */
2881 if (!named && num_bytes != 0 && alignment > BITS_PER_WORD)
2882 info->gpr_offset += info->gpr_offset & 1;
2883
2884 /* Partition the argument between registers and stack. */
2885 info->num_fprs = 0;
2886 info->num_gprs = MIN (num_words, MAX_ARGS_IN_REGISTERS - info->gpr_offset);
2887 info->stack_p = (num_words - info->num_gprs) != 0;
2888
2889 if (info->num_gprs || return_p)
2890 return gen_rtx_REG (mode, gpr_base + info->gpr_offset);
2891
2892 return NULL_RTX;
2893 }
2894
2895 /* Implement TARGET_FUNCTION_ARG. */
2896
2897 static rtx
riscv_function_arg(cumulative_args_t cum_v,const function_arg_info & arg)2898 riscv_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
2899 {
2900 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2901 struct riscv_arg_info info;
2902
2903 if (arg.end_marker_p ())
2904 return NULL;
2905
2906 return riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
2907 }
2908
2909 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
2910
2911 static void
riscv_function_arg_advance(cumulative_args_t cum_v,const function_arg_info & arg)2912 riscv_function_arg_advance (cumulative_args_t cum_v,
2913 const function_arg_info &arg)
2914 {
2915 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2916 struct riscv_arg_info info;
2917
2918 riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
2919
2920 /* Advance the register count. This has the effect of setting
2921 num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
2922 argument required us to skip the final GPR and pass the whole
2923 argument on the stack. */
2924 cum->num_fprs = info.fpr_offset + info.num_fprs;
2925 cum->num_gprs = info.gpr_offset + info.num_gprs;
2926 }
2927
2928 /* Implement TARGET_ARG_PARTIAL_BYTES. */
2929
2930 static int
riscv_arg_partial_bytes(cumulative_args_t cum,const function_arg_info & generic_arg)2931 riscv_arg_partial_bytes (cumulative_args_t cum,
2932 const function_arg_info &generic_arg)
2933 {
2934 struct riscv_arg_info arg;
2935
2936 riscv_get_arg_info (&arg, get_cumulative_args (cum), generic_arg.mode,
2937 generic_arg.type, generic_arg.named, false);
2938 return arg.stack_p ? arg.num_gprs * UNITS_PER_WORD : 0;
2939 }
2940
2941 /* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls,
2942 VALTYPE is the return type and MODE is VOIDmode. For libcalls,
2943 VALTYPE is null and MODE is the mode of the return value. */
2944
2945 rtx
riscv_function_value(const_tree type,const_tree func,machine_mode mode)2946 riscv_function_value (const_tree type, const_tree func, machine_mode mode)
2947 {
2948 struct riscv_arg_info info;
2949 CUMULATIVE_ARGS args;
2950
2951 if (type)
2952 {
2953 int unsigned_p = TYPE_UNSIGNED (type);
2954
2955 mode = TYPE_MODE (type);
2956
2957 /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
2958 return values, promote the mode here too. */
2959 mode = promote_function_mode (type, mode, &unsigned_p, func, 1);
2960 }
2961
2962 memset (&args, 0, sizeof args);
2963 return riscv_get_arg_info (&info, &args, mode, type, true, true);
2964 }
2965
2966 /* Implement TARGET_PASS_BY_REFERENCE. */
2967
2968 static bool
riscv_pass_by_reference(cumulative_args_t cum_v,const function_arg_info & arg)2969 riscv_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
2970 {
2971 HOST_WIDE_INT size = arg.type_size_in_bytes ();
2972 struct riscv_arg_info info;
2973 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2974
2975 /* ??? std_gimplify_va_arg_expr passes NULL for cum. Fortunately, we
2976 never pass variadic arguments in floating-point registers, so we can
2977 avoid the call to riscv_get_arg_info in this case. */
2978 if (cum != NULL)
2979 {
2980 /* Don't pass by reference if we can use a floating-point register. */
2981 riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
2982 if (info.num_fprs)
2983 return false;
2984 }
2985
2986 /* Pass by reference if the data do not fit in two integer registers. */
2987 return !IN_RANGE (size, 0, 2 * UNITS_PER_WORD);
2988 }
2989
2990 /* Implement TARGET_RETURN_IN_MEMORY. */
2991
2992 static bool
riscv_return_in_memory(const_tree type,const_tree fndecl ATTRIBUTE_UNUSED)2993 riscv_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
2994 {
2995 CUMULATIVE_ARGS args;
2996 cumulative_args_t cum = pack_cumulative_args (&args);
2997
2998 /* The rules for returning in memory are the same as for passing the
2999 first named argument by reference. */
3000 memset (&args, 0, sizeof args);
3001 function_arg_info arg (const_cast<tree> (type), /*named=*/true);
3002 return riscv_pass_by_reference (cum, arg);
3003 }
3004
3005 /* Implement TARGET_SETUP_INCOMING_VARARGS. */
3006
3007 static void
riscv_setup_incoming_varargs(cumulative_args_t cum,const function_arg_info & arg,int * pretend_size ATTRIBUTE_UNUSED,int no_rtl)3008 riscv_setup_incoming_varargs (cumulative_args_t cum,
3009 const function_arg_info &arg,
3010 int *pretend_size ATTRIBUTE_UNUSED, int no_rtl)
3011 {
3012 CUMULATIVE_ARGS local_cum;
3013 int gp_saved;
3014
3015 /* The caller has advanced CUM up to, but not beyond, the last named
3016 argument. Advance a local copy of CUM past the last "real" named
3017 argument, to find out how many registers are left over. */
3018 local_cum = *get_cumulative_args (cum);
3019 riscv_function_arg_advance (pack_cumulative_args (&local_cum), arg);
3020
3021 /* Found out how many registers we need to save. */
3022 gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
3023
3024 if (!no_rtl && gp_saved > 0)
3025 {
3026 rtx ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
3027 REG_PARM_STACK_SPACE (cfun->decl)
3028 - gp_saved * UNITS_PER_WORD);
3029 rtx mem = gen_frame_mem (BLKmode, ptr);
3030 set_mem_alias_set (mem, get_varargs_alias_set ());
3031
3032 move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST,
3033 mem, gp_saved);
3034 }
3035 if (REG_PARM_STACK_SPACE (cfun->decl) == 0)
3036 cfun->machine->varargs_size = gp_saved * UNITS_PER_WORD;
3037 }
3038
3039 /* Handle an attribute requiring a FUNCTION_DECL;
3040 arguments as in struct attribute_spec.handler. */
3041 static tree
riscv_handle_fndecl_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)3042 riscv_handle_fndecl_attribute (tree *node, tree name,
3043 tree args ATTRIBUTE_UNUSED,
3044 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
3045 {
3046 if (TREE_CODE (*node) != FUNCTION_DECL)
3047 {
3048 warning (OPT_Wattributes, "%qE attribute only applies to functions",
3049 name);
3050 *no_add_attrs = true;
3051 }
3052
3053 return NULL_TREE;
3054 }
3055
3056 /* Verify type based attributes. NODE is the what the attribute is being
3057 applied to. NAME is the attribute name. ARGS are the attribute args.
3058 FLAGS gives info about the context. NO_ADD_ATTRS should be set to true if
3059 the attribute should be ignored. */
3060
3061 static tree
riscv_handle_type_attribute(tree * node ATTRIBUTE_UNUSED,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)3062 riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
3063 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
3064 {
3065 /* Check for an argument. */
3066 if (is_attribute_p ("interrupt", name))
3067 {
3068 if (args)
3069 {
3070 tree cst = TREE_VALUE (args);
3071 const char *string;
3072
3073 if (TREE_CODE (cst) != STRING_CST)
3074 {
3075 warning (OPT_Wattributes,
3076 "%qE attribute requires a string argument",
3077 name);
3078 *no_add_attrs = true;
3079 return NULL_TREE;
3080 }
3081
3082 string = TREE_STRING_POINTER (cst);
3083 if (strcmp (string, "user") && strcmp (string, "supervisor")
3084 && strcmp (string, "machine"))
3085 {
3086 warning (OPT_Wattributes,
3087 "argument to %qE attribute is not \"user\", \"supervisor\", or \"machine\"",
3088 name);
3089 *no_add_attrs = true;
3090 }
3091 }
3092 }
3093
3094 return NULL_TREE;
3095 }
3096
3097 /* Return true if function TYPE is an interrupt function. */
3098 static bool
riscv_interrupt_type_p(tree type)3099 riscv_interrupt_type_p (tree type)
3100 {
3101 return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type)) != NULL;
3102 }
3103
3104 /* Return true if FUNC is a naked function. */
3105 static bool
riscv_naked_function_p(tree func)3106 riscv_naked_function_p (tree func)
3107 {
3108 tree func_decl = func;
3109 if (func == NULL_TREE)
3110 func_decl = current_function_decl;
3111 return NULL_TREE != lookup_attribute ("naked", DECL_ATTRIBUTES (func_decl));
3112 }
3113
3114 /* Implement TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. */
3115 static bool
riscv_allocate_stack_slots_for_args()3116 riscv_allocate_stack_slots_for_args ()
3117 {
3118 /* Naked functions should not allocate stack slots for arguments. */
3119 return !riscv_naked_function_p (current_function_decl);
3120 }
3121
3122 /* Implement TARGET_WARN_FUNC_RETURN. */
3123 static bool
riscv_warn_func_return(tree decl)3124 riscv_warn_func_return (tree decl)
3125 {
3126 /* Naked functions are implemented entirely in assembly, including the
3127 return sequence, so suppress warnings about this. */
3128 return !riscv_naked_function_p (decl);
3129 }
3130
3131 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */
3132
3133 static void
riscv_va_start(tree valist,rtx nextarg)3134 riscv_va_start (tree valist, rtx nextarg)
3135 {
3136 nextarg = plus_constant (Pmode, nextarg, -cfun->machine->varargs_size);
3137 std_expand_builtin_va_start (valist, nextarg);
3138 }
3139
3140 /* Make ADDR suitable for use as a call or sibcall target. */
3141
3142 rtx
riscv_legitimize_call_address(rtx addr)3143 riscv_legitimize_call_address (rtx addr)
3144 {
3145 if (!call_insn_operand (addr, VOIDmode))
3146 {
3147 rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode);
3148 riscv_emit_move (reg, addr);
3149 return reg;
3150 }
3151 return addr;
3152 }
3153
3154 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
3155 Assume that the areas do not overlap. */
3156
3157 static void
riscv_block_move_straight(rtx dest,rtx src,unsigned HOST_WIDE_INT length)3158 riscv_block_move_straight (rtx dest, rtx src, unsigned HOST_WIDE_INT length)
3159 {
3160 unsigned HOST_WIDE_INT offset, delta;
3161 unsigned HOST_WIDE_INT bits;
3162 int i;
3163 enum machine_mode mode;
3164 rtx *regs;
3165
3166 bits = MAX (BITS_PER_UNIT,
3167 MIN (BITS_PER_WORD, MIN (MEM_ALIGN (src), MEM_ALIGN (dest))));
3168
3169 mode = mode_for_size (bits, MODE_INT, 0).require ();
3170 delta = bits / BITS_PER_UNIT;
3171
3172 /* Allocate a buffer for the temporary registers. */
3173 regs = XALLOCAVEC (rtx, length / delta);
3174
3175 /* Load as many BITS-sized chunks as possible. Use a normal load if
3176 the source has enough alignment, otherwise use left/right pairs. */
3177 for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
3178 {
3179 regs[i] = gen_reg_rtx (mode);
3180 riscv_emit_move (regs[i], adjust_address (src, mode, offset));
3181 }
3182
3183 /* Copy the chunks to the destination. */
3184 for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
3185 riscv_emit_move (adjust_address (dest, mode, offset), regs[i]);
3186
3187 /* Mop up any left-over bytes. */
3188 if (offset < length)
3189 {
3190 src = adjust_address (src, BLKmode, offset);
3191 dest = adjust_address (dest, BLKmode, offset);
3192 move_by_pieces (dest, src, length - offset,
3193 MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), RETURN_BEGIN);
3194 }
3195 }
3196
3197 /* Helper function for doing a loop-based block operation on memory
3198 reference MEM. Each iteration of the loop will operate on LENGTH
3199 bytes of MEM.
3200
3201 Create a new base register for use within the loop and point it to
3202 the start of MEM. Create a new memory reference that uses this
3203 register. Store them in *LOOP_REG and *LOOP_MEM respectively. */
3204
3205 static void
riscv_adjust_block_mem(rtx mem,unsigned HOST_WIDE_INT length,rtx * loop_reg,rtx * loop_mem)3206 riscv_adjust_block_mem (rtx mem, unsigned HOST_WIDE_INT length,
3207 rtx *loop_reg, rtx *loop_mem)
3208 {
3209 *loop_reg = copy_addr_to_reg (XEXP (mem, 0));
3210
3211 /* Although the new mem does not refer to a known location,
3212 it does keep up to LENGTH bytes of alignment. */
3213 *loop_mem = change_address (mem, BLKmode, *loop_reg);
3214 set_mem_align (*loop_mem, MIN (MEM_ALIGN (mem), length * BITS_PER_UNIT));
3215 }
3216
3217 /* Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER
3218 bytes at a time. LENGTH must be at least BYTES_PER_ITER. Assume that
3219 the memory regions do not overlap. */
3220
3221 static void
riscv_block_move_loop(rtx dest,rtx src,unsigned HOST_WIDE_INT length,unsigned HOST_WIDE_INT bytes_per_iter)3222 riscv_block_move_loop (rtx dest, rtx src, unsigned HOST_WIDE_INT length,
3223 unsigned HOST_WIDE_INT bytes_per_iter)
3224 {
3225 rtx label, src_reg, dest_reg, final_src, test;
3226 unsigned HOST_WIDE_INT leftover;
3227
3228 leftover = length % bytes_per_iter;
3229 length -= leftover;
3230
3231 /* Create registers and memory references for use within the loop. */
3232 riscv_adjust_block_mem (src, bytes_per_iter, &src_reg, &src);
3233 riscv_adjust_block_mem (dest, bytes_per_iter, &dest_reg, &dest);
3234
3235 /* Calculate the value that SRC_REG should have after the last iteration
3236 of the loop. */
3237 final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length),
3238 0, 0, OPTAB_WIDEN);
3239
3240 /* Emit the start of the loop. */
3241 label = gen_label_rtx ();
3242 emit_label (label);
3243
3244 /* Emit the loop body. */
3245 riscv_block_move_straight (dest, src, bytes_per_iter);
3246
3247 /* Move on to the next block. */
3248 riscv_emit_move (src_reg, plus_constant (Pmode, src_reg, bytes_per_iter));
3249 riscv_emit_move (dest_reg, plus_constant (Pmode, dest_reg, bytes_per_iter));
3250
3251 /* Emit the loop condition. */
3252 test = gen_rtx_NE (VOIDmode, src_reg, final_src);
3253 if (Pmode == DImode)
3254 emit_jump_insn (gen_cbranchdi4 (test, src_reg, final_src, label));
3255 else
3256 emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label));
3257
3258 /* Mop up any left-over bytes. */
3259 if (leftover)
3260 riscv_block_move_straight (dest, src, leftover);
3261 else
3262 emit_insn(gen_nop ());
3263 }
3264
3265 /* Expand a cpymemsi instruction, which copies LENGTH bytes from
3266 memory reference SRC to memory reference DEST. */
3267
3268 bool
riscv_expand_block_move(rtx dest,rtx src,rtx length)3269 riscv_expand_block_move (rtx dest, rtx src, rtx length)
3270 {
3271 if (CONST_INT_P (length))
3272 {
3273 unsigned HOST_WIDE_INT hwi_length = UINTVAL (length);
3274 unsigned HOST_WIDE_INT factor, align;
3275
3276 align = MIN (MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), BITS_PER_WORD);
3277 factor = BITS_PER_WORD / align;
3278
3279 if (optimize_function_for_size_p (cfun)
3280 && hwi_length * factor * UNITS_PER_WORD > MOVE_RATIO (false))
3281 return false;
3282
3283 if (hwi_length <= (RISCV_MAX_MOVE_BYTES_STRAIGHT / factor))
3284 {
3285 riscv_block_move_straight (dest, src, INTVAL (length));
3286 return true;
3287 }
3288 else if (optimize && align >= BITS_PER_WORD)
3289 {
3290 unsigned min_iter_words
3291 = RISCV_MAX_MOVE_BYTES_PER_LOOP_ITER / UNITS_PER_WORD;
3292 unsigned iter_words = min_iter_words;
3293 unsigned HOST_WIDE_INT bytes = hwi_length;
3294 unsigned HOST_WIDE_INT words = bytes / UNITS_PER_WORD;
3295
3296 /* Lengthen the loop body if it shortens the tail. */
3297 for (unsigned i = min_iter_words; i < min_iter_words * 2 - 1; i++)
3298 {
3299 unsigned cur_cost = iter_words + words % iter_words;
3300 unsigned new_cost = i + words % i;
3301 if (new_cost <= cur_cost)
3302 iter_words = i;
3303 }
3304
3305 riscv_block_move_loop (dest, src, bytes, iter_words * UNITS_PER_WORD);
3306 return true;
3307 }
3308 }
3309 return false;
3310 }
3311
3312 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM
3313 in context CONTEXT. HI_RELOC indicates a high-part reloc. */
3314
3315 static void
riscv_print_operand_reloc(FILE * file,rtx op,bool hi_reloc)3316 riscv_print_operand_reloc (FILE *file, rtx op, bool hi_reloc)
3317 {
3318 const char *reloc;
3319
3320 switch (riscv_classify_symbolic_expression (op))
3321 {
3322 case SYMBOL_ABSOLUTE:
3323 reloc = hi_reloc ? "%hi" : "%lo";
3324 break;
3325
3326 case SYMBOL_PCREL:
3327 reloc = hi_reloc ? "%pcrel_hi" : "%pcrel_lo";
3328 break;
3329
3330 case SYMBOL_TLS_LE:
3331 reloc = hi_reloc ? "%tprel_hi" : "%tprel_lo";
3332 break;
3333
3334 default:
3335 output_operand_lossage ("invalid use of '%%%c'", hi_reloc ? 'h' : 'R');
3336 return;
3337 }
3338
3339 fprintf (file, "%s(", reloc);
3340 output_addr_const (file, riscv_strip_unspec_address (op));
3341 fputc (')', file);
3342 }
3343
3344 /* Return true if the .AQ suffix should be added to an AMO to implement the
3345 acquire portion of memory model MODEL. */
3346
3347 static bool
riscv_memmodel_needs_amo_acquire(enum memmodel model)3348 riscv_memmodel_needs_amo_acquire (enum memmodel model)
3349 {
3350 switch (model)
3351 {
3352 case MEMMODEL_ACQ_REL:
3353 case MEMMODEL_SEQ_CST:
3354 case MEMMODEL_SYNC_SEQ_CST:
3355 case MEMMODEL_ACQUIRE:
3356 case MEMMODEL_CONSUME:
3357 case MEMMODEL_SYNC_ACQUIRE:
3358 return true;
3359
3360 case MEMMODEL_RELEASE:
3361 case MEMMODEL_SYNC_RELEASE:
3362 case MEMMODEL_RELAXED:
3363 return false;
3364
3365 default:
3366 gcc_unreachable ();
3367 }
3368 }
3369
3370 /* Return true if a FENCE should be emitted to before a memory access to
3371 implement the release portion of memory model MODEL. */
3372
3373 static bool
riscv_memmodel_needs_release_fence(enum memmodel model)3374 riscv_memmodel_needs_release_fence (enum memmodel model)
3375 {
3376 switch (model)
3377 {
3378 case MEMMODEL_ACQ_REL:
3379 case MEMMODEL_SEQ_CST:
3380 case MEMMODEL_SYNC_SEQ_CST:
3381 case MEMMODEL_RELEASE:
3382 case MEMMODEL_SYNC_RELEASE:
3383 return true;
3384
3385 case MEMMODEL_ACQUIRE:
3386 case MEMMODEL_CONSUME:
3387 case MEMMODEL_SYNC_ACQUIRE:
3388 case MEMMODEL_RELAXED:
3389 return false;
3390
3391 default:
3392 gcc_unreachable ();
3393 }
3394 }
3395
3396 /* Implement TARGET_PRINT_OPERAND. The RISCV-specific operand codes are:
3397
3398 'h' Print the high-part relocation associated with OP, after stripping
3399 any outermost HIGH.
3400 'R' Print the low-part relocation associated with OP.
3401 'C' Print the integer branch condition for comparison OP.
3402 'A' Print the atomic operation suffix for memory model OP.
3403 'F' Print a FENCE if the memory model requires a release.
3404 'z' Print x0 if OP is zero, otherwise print OP normally.
3405 'i' Print i if the operand is not a register. */
3406
3407 static void
riscv_print_operand(FILE * file,rtx op,int letter)3408 riscv_print_operand (FILE *file, rtx op, int letter)
3409 {
3410 machine_mode mode = GET_MODE (op);
3411 enum rtx_code code = GET_CODE (op);
3412
3413 switch (letter)
3414 {
3415 case 'h':
3416 if (code == HIGH)
3417 op = XEXP (op, 0);
3418 riscv_print_operand_reloc (file, op, true);
3419 break;
3420
3421 case 'R':
3422 riscv_print_operand_reloc (file, op, false);
3423 break;
3424
3425 case 'C':
3426 /* The RTL names match the instruction names. */
3427 fputs (GET_RTX_NAME (code), file);
3428 break;
3429
3430 case 'A':
3431 if (riscv_memmodel_needs_amo_acquire ((enum memmodel) INTVAL (op)))
3432 fputs (".aq", file);
3433 break;
3434
3435 case 'F':
3436 if (riscv_memmodel_needs_release_fence ((enum memmodel) INTVAL (op)))
3437 fputs ("fence iorw,ow; ", file);
3438 break;
3439
3440 case 'i':
3441 if (code != REG)
3442 fputs ("i", file);
3443 break;
3444
3445 default:
3446 switch (code)
3447 {
3448 case REG:
3449 if (letter && letter != 'z')
3450 output_operand_lossage ("invalid use of '%%%c'", letter);
3451 fprintf (file, "%s", reg_names[REGNO (op)]);
3452 break;
3453
3454 case MEM:
3455 if (letter && letter != 'z')
3456 output_operand_lossage ("invalid use of '%%%c'", letter);
3457 else
3458 output_address (mode, XEXP (op, 0));
3459 break;
3460
3461 default:
3462 if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
3463 fputs (reg_names[GP_REG_FIRST], file);
3464 else if (letter && letter != 'z')
3465 output_operand_lossage ("invalid use of '%%%c'", letter);
3466 else
3467 output_addr_const (file, riscv_strip_unspec_address (op));
3468 break;
3469 }
3470 }
3471 }
3472
3473 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
3474
3475 static void
riscv_print_operand_address(FILE * file,machine_mode mode ATTRIBUTE_UNUSED,rtx x)3476 riscv_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED, rtx x)
3477 {
3478 struct riscv_address_info addr;
3479
3480 if (riscv_classify_address (&addr, x, word_mode, true))
3481 switch (addr.type)
3482 {
3483 case ADDRESS_REG:
3484 riscv_print_operand (file, addr.offset, 0);
3485 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
3486 return;
3487
3488 case ADDRESS_LO_SUM:
3489 riscv_print_operand_reloc (file, addr.offset, false);
3490 fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
3491 return;
3492
3493 case ADDRESS_CONST_INT:
3494 output_addr_const (file, x);
3495 fprintf (file, "(%s)", reg_names[GP_REG_FIRST]);
3496 return;
3497
3498 case ADDRESS_SYMBOLIC:
3499 output_addr_const (file, riscv_strip_unspec_address (x));
3500 return;
3501 }
3502 gcc_unreachable ();
3503 }
3504
3505 static bool
riscv_size_ok_for_small_data_p(int size)3506 riscv_size_ok_for_small_data_p (int size)
3507 {
3508 return g_switch_value && IN_RANGE (size, 1, g_switch_value);
3509 }
3510
3511 /* Return true if EXP should be placed in the small data section. */
3512
3513 static bool
riscv_in_small_data_p(const_tree x)3514 riscv_in_small_data_p (const_tree x)
3515 {
3516 if (TREE_CODE (x) == STRING_CST || TREE_CODE (x) == FUNCTION_DECL)
3517 return false;
3518
3519 if (TREE_CODE (x) == VAR_DECL && DECL_SECTION_NAME (x))
3520 {
3521 const char *sec = DECL_SECTION_NAME (x);
3522 return strcmp (sec, ".sdata") == 0 || strcmp (sec, ".sbss") == 0;
3523 }
3524
3525 return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x)));
3526 }
3527
3528 /* Switch to the appropriate section for output of DECL. */
3529
3530 static section *
riscv_select_section(tree decl,int reloc,unsigned HOST_WIDE_INT align)3531 riscv_select_section (tree decl, int reloc,
3532 unsigned HOST_WIDE_INT align)
3533 {
3534 switch (categorize_decl_for_section (decl, reloc))
3535 {
3536 case SECCAT_SRODATA:
3537 return get_named_section (decl, ".srodata", reloc);
3538
3539 default:
3540 return default_elf_select_section (decl, reloc, align);
3541 }
3542 }
3543
3544 /* Switch to the appropriate section for output of DECL. */
3545
3546 static void
riscv_unique_section(tree decl,int reloc)3547 riscv_unique_section (tree decl, int reloc)
3548 {
3549 const char *prefix = NULL;
3550 bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
3551
3552 switch (categorize_decl_for_section (decl, reloc))
3553 {
3554 case SECCAT_SRODATA:
3555 prefix = one_only ? ".sr" : ".srodata";
3556 break;
3557
3558 default:
3559 break;
3560 }
3561 if (prefix)
3562 {
3563 const char *name, *linkonce;
3564 char *string;
3565
3566 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
3567 name = targetm.strip_name_encoding (name);
3568
3569 /* If we're using one_only, then there needs to be a .gnu.linkonce
3570 prefix to the section name. */
3571 linkonce = one_only ? ".gnu.linkonce" : "";
3572
3573 string = ACONCAT ((linkonce, prefix, ".", name, NULL));
3574
3575 set_decl_section_name (decl, string);
3576 return;
3577 }
3578 default_unique_section (decl, reloc);
3579 }
3580
3581 /* Return a section for X, handling small data. */
3582
3583 static section *
riscv_elf_select_rtx_section(machine_mode mode,rtx x,unsigned HOST_WIDE_INT align)3584 riscv_elf_select_rtx_section (machine_mode mode, rtx x,
3585 unsigned HOST_WIDE_INT align)
3586 {
3587 section *s = default_elf_select_rtx_section (mode, x, align);
3588
3589 if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode)))
3590 {
3591 if (strncmp (s->named.name, ".rodata.cst", strlen (".rodata.cst")) == 0)
3592 {
3593 /* Rename .rodata.cst* to .srodata.cst*. */
3594 char *name = (char *) alloca (strlen (s->named.name) + 2);
3595 sprintf (name, ".s%s", s->named.name + 1);
3596 return get_section (name, s->named.common.flags, NULL);
3597 }
3598
3599 if (s == data_section)
3600 return sdata_section;
3601 }
3602
3603 return s;
3604 }
3605
3606 /* Make the last instruction frame-related and note that it performs
3607 the operation described by FRAME_PATTERN. */
3608
3609 static void
riscv_set_frame_expr(rtx frame_pattern)3610 riscv_set_frame_expr (rtx frame_pattern)
3611 {
3612 rtx insn;
3613
3614 insn = get_last_insn ();
3615 RTX_FRAME_RELATED_P (insn) = 1;
3616 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
3617 frame_pattern,
3618 REG_NOTES (insn));
3619 }
3620
3621 /* Return a frame-related rtx that stores REG at MEM.
3622 REG must be a single register. */
3623
3624 static rtx
riscv_frame_set(rtx mem,rtx reg)3625 riscv_frame_set (rtx mem, rtx reg)
3626 {
3627 rtx set = gen_rtx_SET (mem, reg);
3628 RTX_FRAME_RELATED_P (set) = 1;
3629 return set;
3630 }
3631
3632 /* Return true if the current function must save register REGNO. */
3633
3634 static bool
riscv_save_reg_p(unsigned int regno)3635 riscv_save_reg_p (unsigned int regno)
3636 {
3637 bool call_saved = !global_regs[regno] && !call_used_or_fixed_reg_p (regno);
3638 bool might_clobber = crtl->saves_all_registers
3639 || df_regs_ever_live_p (regno);
3640
3641 if (call_saved && might_clobber)
3642 return true;
3643
3644 if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
3645 return true;
3646
3647 if (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return)
3648 return true;
3649
3650 /* If this is an interrupt handler, then must save extra registers. */
3651 if (cfun->machine->interrupt_handler_p)
3652 {
3653 /* zero register is always zero. */
3654 if (regno == GP_REG_FIRST)
3655 return false;
3656
3657 /* The function will return the stack pointer to its original value. */
3658 if (regno == STACK_POINTER_REGNUM)
3659 return false;
3660
3661 /* By convention, we assume that gp and tp are safe. */
3662 if (regno == GP_REGNUM || regno == THREAD_POINTER_REGNUM)
3663 return false;
3664
3665 /* We must save every register used in this function. If this is not a
3666 leaf function, then we must save all temporary registers. */
3667 if (df_regs_ever_live_p (regno)
3668 || (!crtl->is_leaf && call_used_or_fixed_reg_p (regno)))
3669 return true;
3670 }
3671
3672 return false;
3673 }
3674
3675 /* Determine whether to call GPR save/restore routines. */
3676 static bool
riscv_use_save_libcall(const struct riscv_frame_info * frame)3677 riscv_use_save_libcall (const struct riscv_frame_info *frame)
3678 {
3679 if (!TARGET_SAVE_RESTORE || crtl->calls_eh_return || frame_pointer_needed
3680 || cfun->machine->interrupt_handler_p)
3681 return false;
3682
3683 return frame->save_libcall_adjustment != 0;
3684 }
3685
3686 /* Determine which GPR save/restore routine to call. */
3687
3688 static unsigned
riscv_save_libcall_count(unsigned mask)3689 riscv_save_libcall_count (unsigned mask)
3690 {
3691 for (unsigned n = GP_REG_LAST; n > GP_REG_FIRST; n--)
3692 if (BITSET_P (mask, n))
3693 return CALLEE_SAVED_REG_NUMBER (n) + 1;
3694 abort ();
3695 }
3696
3697 /* Populate the current function's riscv_frame_info structure.
3698
3699 RISC-V stack frames grown downward. High addresses are at the top.
3700
3701 +-------------------------------+
3702 | |
3703 | incoming stack arguments |
3704 | |
3705 +-------------------------------+ <-- incoming stack pointer
3706 | |
3707 | callee-allocated save area |
3708 | for arguments that are |
3709 | split between registers and |
3710 | the stack |
3711 | |
3712 +-------------------------------+ <-- arg_pointer_rtx
3713 | |
3714 | callee-allocated save area |
3715 | for register varargs |
3716 | |
3717 +-------------------------------+ <-- hard_frame_pointer_rtx;
3718 | | stack_pointer_rtx + gp_sp_offset
3719 | GPR save area | + UNITS_PER_WORD
3720 | |
3721 +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
3722 | | + UNITS_PER_HWVALUE
3723 | FPR save area |
3724 | |
3725 +-------------------------------+ <-- frame_pointer_rtx (virtual)
3726 | |
3727 | local variables |
3728 | |
3729 P +-------------------------------+
3730 | |
3731 | outgoing stack arguments |
3732 | |
3733 +-------------------------------+ <-- stack_pointer_rtx
3734
3735 Dynamic stack allocations such as alloca insert data at point P.
3736 They decrease stack_pointer_rtx but leave frame_pointer_rtx and
3737 hard_frame_pointer_rtx unchanged. */
3738
3739 static HOST_WIDE_INT riscv_first_stack_step (struct riscv_frame_info *frame);
3740
3741 static void
riscv_compute_frame_info(void)3742 riscv_compute_frame_info (void)
3743 {
3744 struct riscv_frame_info *frame;
3745 HOST_WIDE_INT offset;
3746 bool interrupt_save_prologue_temp = false;
3747 unsigned int regno, i, num_x_saved = 0, num_f_saved = 0;
3748
3749 frame = &cfun->machine->frame;
3750
3751 /* In an interrupt function, if we have a large frame, then we need to
3752 save/restore t0. We check for this before clearing the frame struct. */
3753 if (cfun->machine->interrupt_handler_p)
3754 {
3755 HOST_WIDE_INT step1 = riscv_first_stack_step (frame);
3756 if (! SMALL_OPERAND (frame->total_size - step1))
3757 interrupt_save_prologue_temp = true;
3758 }
3759
3760 memset (frame, 0, sizeof (*frame));
3761
3762 if (!cfun->machine->naked_p)
3763 {
3764 /* Find out which GPRs we need to save. */
3765 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
3766 if (riscv_save_reg_p (regno)
3767 || (interrupt_save_prologue_temp
3768 && (regno == RISCV_PROLOGUE_TEMP_REGNUM)))
3769 frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
3770
3771 /* If this function calls eh_return, we must also save and restore the
3772 EH data registers. */
3773 if (crtl->calls_eh_return)
3774 for (i = 0; (regno = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
3775 frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
3776
3777 /* Find out which FPRs we need to save. This loop must iterate over
3778 the same space as its companion in riscv_for_each_saved_reg. */
3779 if (TARGET_HARD_FLOAT)
3780 for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
3781 if (riscv_save_reg_p (regno))
3782 frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++;
3783 }
3784
3785 /* At the bottom of the frame are any outgoing stack arguments. */
3786 offset = RISCV_STACK_ALIGN (crtl->outgoing_args_size);
3787 /* Next are local stack variables. */
3788 offset += RISCV_STACK_ALIGN (get_frame_size ());
3789 /* The virtual frame pointer points above the local variables. */
3790 frame->frame_pointer_offset = offset;
3791 /* Next are the callee-saved FPRs. */
3792 if (frame->fmask)
3793 offset += RISCV_STACK_ALIGN (num_f_saved * UNITS_PER_FP_REG);
3794 frame->fp_sp_offset = offset - UNITS_PER_FP_REG;
3795 /* Next are the callee-saved GPRs. */
3796 if (frame->mask)
3797 {
3798 unsigned x_save_size = RISCV_STACK_ALIGN (num_x_saved * UNITS_PER_WORD);
3799 unsigned num_save_restore = 1 + riscv_save_libcall_count (frame->mask);
3800
3801 /* Only use save/restore routines if they don't alter the stack size. */
3802 if (RISCV_STACK_ALIGN (num_save_restore * UNITS_PER_WORD) == x_save_size)
3803 {
3804 /* Libcall saves/restores 3 registers at once, so we need to
3805 allocate 12 bytes for callee-saved register. */
3806 if (TARGET_RVE)
3807 x_save_size = 3 * UNITS_PER_WORD;
3808
3809 frame->save_libcall_adjustment = x_save_size;
3810 }
3811
3812 offset += x_save_size;
3813 }
3814 frame->gp_sp_offset = offset - UNITS_PER_WORD;
3815 /* The hard frame pointer points above the callee-saved GPRs. */
3816 frame->hard_frame_pointer_offset = offset;
3817 /* Above the hard frame pointer is the callee-allocated varags save area. */
3818 offset += RISCV_STACK_ALIGN (cfun->machine->varargs_size);
3819 /* Next is the callee-allocated area for pretend stack arguments. */
3820 offset += RISCV_STACK_ALIGN (crtl->args.pretend_args_size);
3821 /* Arg pointer must be below pretend args, but must be above alignment
3822 padding. */
3823 frame->arg_pointer_offset = offset - crtl->args.pretend_args_size;
3824 frame->total_size = offset;
3825 /* Next points the incoming stack pointer and any incoming arguments. */
3826
3827 /* Only use save/restore routines when the GPRs are atop the frame. */
3828 if (frame->hard_frame_pointer_offset != frame->total_size)
3829 frame->save_libcall_adjustment = 0;
3830 }
3831
3832 /* Make sure that we're not trying to eliminate to the wrong hard frame
3833 pointer. */
3834
3835 static bool
riscv_can_eliminate(const int from ATTRIBUTE_UNUSED,const int to)3836 riscv_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
3837 {
3838 return (to == HARD_FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM);
3839 }
3840
3841 /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
3842 or argument pointer. TO is either the stack pointer or hard frame
3843 pointer. */
3844
3845 HOST_WIDE_INT
riscv_initial_elimination_offset(int from,int to)3846 riscv_initial_elimination_offset (int from, int to)
3847 {
3848 HOST_WIDE_INT src, dest;
3849
3850 riscv_compute_frame_info ();
3851
3852 if (to == HARD_FRAME_POINTER_REGNUM)
3853 dest = cfun->machine->frame.hard_frame_pointer_offset;
3854 else if (to == STACK_POINTER_REGNUM)
3855 dest = 0; /* The stack pointer is the base of all offsets, hence 0. */
3856 else
3857 gcc_unreachable ();
3858
3859 if (from == FRAME_POINTER_REGNUM)
3860 src = cfun->machine->frame.frame_pointer_offset;
3861 else if (from == ARG_POINTER_REGNUM)
3862 src = cfun->machine->frame.arg_pointer_offset;
3863 else
3864 gcc_unreachable ();
3865
3866 return src - dest;
3867 }
3868
3869 /* Implement RETURN_ADDR_RTX. We do not support moving back to a
3870 previous frame. */
3871
3872 rtx
riscv_return_addr(int count,rtx frame ATTRIBUTE_UNUSED)3873 riscv_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
3874 {
3875 if (count != 0)
3876 return const0_rtx;
3877
3878 return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
3879 }
3880
3881 /* Emit code to change the current function's return address to
3882 ADDRESS. SCRATCH is available as a scratch register, if needed.
3883 ADDRESS and SCRATCH are both word-mode GPRs. */
3884
3885 void
riscv_set_return_address(rtx address,rtx scratch)3886 riscv_set_return_address (rtx address, rtx scratch)
3887 {
3888 rtx slot_address;
3889
3890 gcc_assert (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM));
3891 slot_address = riscv_add_offset (scratch, stack_pointer_rtx,
3892 cfun->machine->frame.gp_sp_offset);
3893 riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address);
3894 }
3895
3896 /* A function to save or store a register. The first argument is the
3897 register and the second is the stack slot. */
3898 typedef void (*riscv_save_restore_fn) (rtx, rtx);
3899
3900 /* Use FN to save or restore register REGNO. MODE is the register's
3901 mode and OFFSET is the offset of its save slot from the current
3902 stack pointer. */
3903
3904 static void
riscv_save_restore_reg(machine_mode mode,int regno,HOST_WIDE_INT offset,riscv_save_restore_fn fn)3905 riscv_save_restore_reg (machine_mode mode, int regno,
3906 HOST_WIDE_INT offset, riscv_save_restore_fn fn)
3907 {
3908 rtx mem;
3909
3910 mem = gen_frame_mem (mode, plus_constant (Pmode, stack_pointer_rtx, offset));
3911 fn (gen_rtx_REG (mode, regno), mem);
3912 }
3913
3914 /* Call FN for each register that is saved by the current function.
3915 SP_OFFSET is the offset of the current stack pointer from the start
3916 of the frame. */
3917
3918 static void
riscv_for_each_saved_reg(HOST_WIDE_INT sp_offset,riscv_save_restore_fn fn,bool epilogue,bool maybe_eh_return)3919 riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn,
3920 bool epilogue, bool maybe_eh_return)
3921 {
3922 HOST_WIDE_INT offset;
3923
3924 /* Save the link register and s-registers. */
3925 offset = cfun->machine->frame.gp_sp_offset - sp_offset;
3926 for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
3927 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
3928 {
3929 bool handle_reg = TRUE;
3930
3931 /* If this is a normal return in a function that calls the eh_return
3932 builtin, then do not restore the eh return data registers as that
3933 would clobber the return value. But we do still need to save them
3934 in the prologue, and restore them for an exception return, so we
3935 need special handling here. */
3936 if (epilogue && !maybe_eh_return && crtl->calls_eh_return)
3937 {
3938 unsigned int i, regnum;
3939
3940 for (i = 0; (regnum = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM;
3941 i++)
3942 if (regno == regnum)
3943 {
3944 handle_reg = FALSE;
3945 break;
3946 }
3947 }
3948
3949 if (handle_reg)
3950 riscv_save_restore_reg (word_mode, regno, offset, fn);
3951 offset -= UNITS_PER_WORD;
3952 }
3953
3954 /* This loop must iterate over the same space as its companion in
3955 riscv_compute_frame_info. */
3956 offset = cfun->machine->frame.fp_sp_offset - sp_offset;
3957 for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
3958 if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
3959 {
3960 machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
3961
3962 riscv_save_restore_reg (mode, regno, offset, fn);
3963 offset -= GET_MODE_SIZE (mode);
3964 }
3965 }
3966
3967 /* Save register REG to MEM. Make the instruction frame-related. */
3968
3969 static void
riscv_save_reg(rtx reg,rtx mem)3970 riscv_save_reg (rtx reg, rtx mem)
3971 {
3972 riscv_emit_move (mem, reg);
3973 riscv_set_frame_expr (riscv_frame_set (mem, reg));
3974 }
3975
3976 /* Restore register REG from MEM. */
3977
3978 static void
riscv_restore_reg(rtx reg,rtx mem)3979 riscv_restore_reg (rtx reg, rtx mem)
3980 {
3981 rtx insn = riscv_emit_move (reg, mem);
3982 rtx dwarf = NULL_RTX;
3983 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
3984
3985 if (epilogue_cfa_sp_offset && REGNO (reg) == HARD_FRAME_POINTER_REGNUM)
3986 {
3987 rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3988 GEN_INT (epilogue_cfa_sp_offset));
3989 dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
3990 }
3991
3992 REG_NOTES (insn) = dwarf;
3993 RTX_FRAME_RELATED_P (insn) = 1;
3994 }
3995
3996 /* For stack frames that can't be allocated with a single ADDI instruction,
3997 compute the best value to initially allocate. It must at a minimum
3998 allocate enough space to spill the callee-saved registers. If TARGET_RVC,
3999 try to pick a value that will allow compression of the register saves
4000 without adding extra instructions. */
4001
4002 static HOST_WIDE_INT
riscv_first_stack_step(struct riscv_frame_info * frame)4003 riscv_first_stack_step (struct riscv_frame_info *frame)
4004 {
4005 if (SMALL_OPERAND (frame->total_size))
4006 return frame->total_size;
4007
4008 HOST_WIDE_INT min_first_step =
4009 RISCV_STACK_ALIGN (frame->total_size - frame->fp_sp_offset);
4010 HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8;
4011 HOST_WIDE_INT min_second_step = frame->total_size - max_first_step;
4012 gcc_assert (min_first_step <= max_first_step);
4013
4014 /* As an optimization, use the least-significant bits of the total frame
4015 size, so that the second adjustment step is just LUI + ADD. */
4016 if (!SMALL_OPERAND (min_second_step)
4017 && frame->total_size % IMM_REACH < IMM_REACH / 2
4018 && frame->total_size % IMM_REACH >= min_first_step)
4019 return frame->total_size % IMM_REACH;
4020
4021 if (TARGET_RVC)
4022 {
4023 /* If we need two subtracts, and one is small enough to allow compressed
4024 loads and stores, then put that one first. */
4025 if (IN_RANGE (min_second_step, 0,
4026 (TARGET_64BIT ? SDSP_REACH : SWSP_REACH)))
4027 return MAX (min_second_step, min_first_step);
4028
4029 /* If we need LUI + ADDI + ADD for the second adjustment step, then start
4030 with the minimum first step, so that we can get compressed loads and
4031 stores. */
4032 else if (!SMALL_OPERAND (min_second_step))
4033 return min_first_step;
4034 }
4035
4036 return max_first_step;
4037 }
4038
4039 static rtx
riscv_adjust_libcall_cfi_prologue()4040 riscv_adjust_libcall_cfi_prologue ()
4041 {
4042 rtx dwarf = NULL_RTX;
4043 rtx adjust_sp_rtx, reg, mem, insn;
4044 int saved_size = cfun->machine->frame.save_libcall_adjustment;
4045 int offset;
4046
4047 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
4048 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
4049 {
4050 /* The save order is ra, s0, s1, s2 to s11. */
4051 if (regno == RETURN_ADDR_REGNUM)
4052 offset = saved_size - UNITS_PER_WORD;
4053 else if (regno == S0_REGNUM)
4054 offset = saved_size - UNITS_PER_WORD * 2;
4055 else if (regno == S1_REGNUM)
4056 offset = saved_size - UNITS_PER_WORD * 3;
4057 else
4058 offset = saved_size - ((regno - S2_REGNUM + 4) * UNITS_PER_WORD);
4059
4060 reg = gen_rtx_REG (SImode, regno);
4061 mem = gen_frame_mem (SImode, plus_constant (Pmode,
4062 stack_pointer_rtx,
4063 offset));
4064
4065 insn = gen_rtx_SET (mem, reg);
4066 dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf);
4067 }
4068
4069 /* Debug info for adjust sp. */
4070 adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx,
4071 stack_pointer_rtx, GEN_INT (-saved_size));
4072 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx,
4073 dwarf);
4074 return dwarf;
4075 }
4076
4077 static void
riscv_emit_stack_tie(void)4078 riscv_emit_stack_tie (void)
4079 {
4080 if (Pmode == SImode)
4081 emit_insn (gen_stack_tiesi (stack_pointer_rtx, hard_frame_pointer_rtx));
4082 else
4083 emit_insn (gen_stack_tiedi (stack_pointer_rtx, hard_frame_pointer_rtx));
4084 }
4085
4086 /* Expand the "prologue" pattern. */
4087
4088 void
riscv_expand_prologue(void)4089 riscv_expand_prologue (void)
4090 {
4091 struct riscv_frame_info *frame = &cfun->machine->frame;
4092 HOST_WIDE_INT size = frame->total_size;
4093 unsigned mask = frame->mask;
4094 rtx insn;
4095
4096 if (flag_stack_usage_info)
4097 current_function_static_stack_size = size;
4098
4099 if (cfun->machine->naked_p)
4100 return;
4101
4102 /* When optimizing for size, call a subroutine to save the registers. */
4103 if (riscv_use_save_libcall (frame))
4104 {
4105 rtx dwarf = NULL_RTX;
4106 dwarf = riscv_adjust_libcall_cfi_prologue ();
4107
4108 size -= frame->save_libcall_adjustment;
4109 insn = emit_insn (riscv_gen_gpr_save_insn (frame));
4110 frame->mask = 0; /* Temporarily fib that we need not save GPRs. */
4111
4112 RTX_FRAME_RELATED_P (insn) = 1;
4113 REG_NOTES (insn) = dwarf;
4114 }
4115
4116 /* Save the registers. */
4117 if ((frame->mask | frame->fmask) != 0)
4118 {
4119 HOST_WIDE_INT step1 = MIN (size, riscv_first_stack_step (frame));
4120
4121 insn = gen_add3_insn (stack_pointer_rtx,
4122 stack_pointer_rtx,
4123 GEN_INT (-step1));
4124 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
4125 size -= step1;
4126 riscv_for_each_saved_reg (size, riscv_save_reg, false, false);
4127 }
4128
4129 frame->mask = mask; /* Undo the above fib. */
4130
4131 /* Set up the frame pointer, if we're using one. */
4132 if (frame_pointer_needed)
4133 {
4134 insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
4135 GEN_INT (frame->hard_frame_pointer_offset - size));
4136 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
4137
4138 riscv_emit_stack_tie ();
4139 }
4140
4141 /* Allocate the rest of the frame. */
4142 if (size > 0)
4143 {
4144 if (SMALL_OPERAND (-size))
4145 {
4146 insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
4147 GEN_INT (-size));
4148 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
4149 }
4150 else
4151 {
4152 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), GEN_INT (-size));
4153 emit_insn (gen_add3_insn (stack_pointer_rtx,
4154 stack_pointer_rtx,
4155 RISCV_PROLOGUE_TEMP (Pmode)));
4156
4157 /* Describe the effect of the previous instructions. */
4158 insn = plus_constant (Pmode, stack_pointer_rtx, -size);
4159 insn = gen_rtx_SET (stack_pointer_rtx, insn);
4160 riscv_set_frame_expr (insn);
4161 }
4162 }
4163 }
4164
4165 static rtx
riscv_adjust_libcall_cfi_epilogue()4166 riscv_adjust_libcall_cfi_epilogue ()
4167 {
4168 rtx dwarf = NULL_RTX;
4169 rtx adjust_sp_rtx, reg;
4170 int saved_size = cfun->machine->frame.save_libcall_adjustment;
4171
4172 /* Debug info for adjust sp. */
4173 adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx,
4174 stack_pointer_rtx, GEN_INT (saved_size));
4175 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx,
4176 dwarf);
4177
4178 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
4179 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
4180 {
4181 reg = gen_rtx_REG (SImode, regno);
4182 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
4183 }
4184
4185 return dwarf;
4186 }
4187
4188 /* Expand an "epilogue", "sibcall_epilogue", or "eh_return_internal" pattern;
4189 style says which. */
4190
4191 void
riscv_expand_epilogue(int style)4192 riscv_expand_epilogue (int style)
4193 {
4194 /* Split the frame into two. STEP1 is the amount of stack we should
4195 deallocate before restoring the registers. STEP2 is the amount we
4196 should deallocate afterwards.
4197
4198 Start off by assuming that no registers need to be restored. */
4199 struct riscv_frame_info *frame = &cfun->machine->frame;
4200 unsigned mask = frame->mask;
4201 HOST_WIDE_INT step1 = frame->total_size;
4202 HOST_WIDE_INT step2 = 0;
4203 bool use_restore_libcall = ((style == NORMAL_RETURN)
4204 && riscv_use_save_libcall (frame));
4205 rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
4206 rtx insn;
4207
4208 /* We need to add memory barrier to prevent read from deallocated stack. */
4209 bool need_barrier_p = (get_frame_size ()
4210 + cfun->machine->frame.arg_pointer_offset) != 0;
4211
4212 if (cfun->machine->naked_p)
4213 {
4214 gcc_assert (style == NORMAL_RETURN);
4215
4216 emit_jump_insn (gen_return ());
4217
4218 return;
4219 }
4220
4221 if ((style == NORMAL_RETURN) && riscv_can_use_return_insn ())
4222 {
4223 emit_jump_insn (gen_return ());
4224 return;
4225 }
4226
4227 /* Reset the epilogue cfa info before starting to emit the epilogue. */
4228 epilogue_cfa_sp_offset = 0;
4229
4230 /* Move past any dynamic stack allocations. */
4231 if (cfun->calls_alloca)
4232 {
4233 /* Emit a barrier to prevent loads from a deallocated stack. */
4234 riscv_emit_stack_tie ();
4235 need_barrier_p = false;
4236
4237 rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset);
4238 if (!SMALL_OPERAND (INTVAL (adjust)))
4239 {
4240 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
4241 adjust = RISCV_PROLOGUE_TEMP (Pmode);
4242 }
4243
4244 insn = emit_insn (
4245 gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx,
4246 adjust));
4247
4248 rtx dwarf = NULL_RTX;
4249 rtx cfa_adjust_value = gen_rtx_PLUS (
4250 Pmode, hard_frame_pointer_rtx,
4251 GEN_INT (-frame->hard_frame_pointer_offset));
4252 rtx cfa_adjust_rtx = gen_rtx_SET (stack_pointer_rtx, cfa_adjust_value);
4253 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, cfa_adjust_rtx, dwarf);
4254 RTX_FRAME_RELATED_P (insn) = 1;
4255
4256 REG_NOTES (insn) = dwarf;
4257 }
4258
4259 /* If we need to restore registers, deallocate as much stack as
4260 possible in the second step without going out of range. */
4261 if ((frame->mask | frame->fmask) != 0)
4262 {
4263 step2 = riscv_first_stack_step (frame);
4264 step1 -= step2;
4265 }
4266
4267 /* Set TARGET to BASE + STEP1. */
4268 if (step1 > 0)
4269 {
4270 /* Emit a barrier to prevent loads from a deallocated stack. */
4271 riscv_emit_stack_tie ();
4272 need_barrier_p = false;
4273
4274 /* Get an rtx for STEP1 that we can add to BASE. */
4275 rtx adjust = GEN_INT (step1);
4276 if (!SMALL_OPERAND (step1))
4277 {
4278 riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
4279 adjust = RISCV_PROLOGUE_TEMP (Pmode);
4280 }
4281
4282 insn = emit_insn (
4283 gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, adjust));
4284
4285 rtx dwarf = NULL_RTX;
4286 rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
4287 GEN_INT (step2));
4288
4289 dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
4290 RTX_FRAME_RELATED_P (insn) = 1;
4291
4292 REG_NOTES (insn) = dwarf;
4293 }
4294 else if (frame_pointer_needed)
4295 {
4296 /* Tell riscv_restore_reg to emit dwarf to redefine CFA when restoring
4297 old value of FP. */
4298 epilogue_cfa_sp_offset = step2;
4299 }
4300
4301 if (use_restore_libcall)
4302 frame->mask = 0; /* Temporarily fib that we need not save GPRs. */
4303
4304 /* Restore the registers. */
4305 riscv_for_each_saved_reg (frame->total_size - step2, riscv_restore_reg,
4306 true, style == EXCEPTION_RETURN);
4307
4308 if (use_restore_libcall)
4309 {
4310 frame->mask = mask; /* Undo the above fib. */
4311 gcc_assert (step2 >= frame->save_libcall_adjustment);
4312 step2 -= frame->save_libcall_adjustment;
4313 }
4314
4315 if (need_barrier_p)
4316 riscv_emit_stack_tie ();
4317
4318 /* Deallocate the final bit of the frame. */
4319 if (step2 > 0)
4320 {
4321 insn = emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
4322 GEN_INT (step2)));
4323
4324 rtx dwarf = NULL_RTX;
4325 rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
4326 const0_rtx);
4327 dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
4328 RTX_FRAME_RELATED_P (insn) = 1;
4329
4330 REG_NOTES (insn) = dwarf;
4331 }
4332
4333 if (use_restore_libcall)
4334 {
4335 rtx dwarf = riscv_adjust_libcall_cfi_epilogue ();
4336 insn = emit_insn (gen_gpr_restore (GEN_INT (riscv_save_libcall_count (mask))));
4337 RTX_FRAME_RELATED_P (insn) = 1;
4338 REG_NOTES (insn) = dwarf;
4339
4340 emit_jump_insn (gen_gpr_restore_return (ra));
4341 return;
4342 }
4343
4344 /* Add in the __builtin_eh_return stack adjustment. */
4345 if ((style == EXCEPTION_RETURN) && crtl->calls_eh_return)
4346 emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
4347 EH_RETURN_STACKADJ_RTX));
4348
4349 /* Return from interrupt. */
4350 if (cfun->machine->interrupt_handler_p)
4351 {
4352 enum riscv_privilege_levels mode = cfun->machine->interrupt_mode;
4353
4354 gcc_assert (mode != UNKNOWN_MODE);
4355
4356 if (mode == MACHINE_MODE)
4357 emit_jump_insn (gen_riscv_mret ());
4358 else if (mode == SUPERVISOR_MODE)
4359 emit_jump_insn (gen_riscv_sret ());
4360 else
4361 emit_jump_insn (gen_riscv_uret ());
4362 }
4363 else if (style != SIBCALL_RETURN)
4364 emit_jump_insn (gen_simple_return_internal (ra));
4365 }
4366
4367 /* Implement EPILOGUE_USES. */
4368
4369 bool
riscv_epilogue_uses(unsigned int regno)4370 riscv_epilogue_uses (unsigned int regno)
4371 {
4372 if (regno == RETURN_ADDR_REGNUM)
4373 return true;
4374
4375 if (epilogue_completed && cfun->machine->interrupt_handler_p)
4376 {
4377 /* An interrupt function restores temp regs, so we must indicate that
4378 they are live at function end. */
4379 if (df_regs_ever_live_p (regno)
4380 || (!crtl->is_leaf && call_used_or_fixed_reg_p (regno)))
4381 return true;
4382 }
4383
4384 return false;
4385 }
4386
4387 /* Return nonzero if this function is known to have a null epilogue.
4388 This allows the optimizer to omit jumps to jumps if no stack
4389 was created. */
4390
4391 bool
riscv_can_use_return_insn(void)4392 riscv_can_use_return_insn (void)
4393 {
4394 return (reload_completed && cfun->machine->frame.total_size == 0
4395 && ! cfun->machine->interrupt_handler_p);
4396 }
4397
4398 /* Given that there exists at least one variable that is set (produced)
4399 by OUT_INSN and read (consumed) by IN_INSN, return true iff
4400 IN_INSN represents one or more memory store operations and none of
4401 the variables set by OUT_INSN is used by IN_INSN as the address of a
4402 store operation. If either IN_INSN or OUT_INSN does not represent
4403 a "single" RTL SET expression (as loosely defined by the
4404 implementation of the single_set function) or a PARALLEL with only
4405 SETs, CLOBBERs, and USEs inside, this function returns false.
4406
4407 Borrowed from rs6000, riscv_store_data_bypass_p checks for certain
4408 conditions that result in assertion failures in the generic
4409 store_data_bypass_p function and returns FALSE in such cases.
4410
4411 This is required to make -msave-restore work with the sifive-7
4412 pipeline description. */
4413
4414 bool
riscv_store_data_bypass_p(rtx_insn * out_insn,rtx_insn * in_insn)4415 riscv_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
4416 {
4417 rtx out_set, in_set;
4418 rtx out_pat, in_pat;
4419 rtx out_exp, in_exp;
4420 int i, j;
4421
4422 in_set = single_set (in_insn);
4423 if (in_set)
4424 {
4425 if (MEM_P (SET_DEST (in_set)))
4426 {
4427 out_set = single_set (out_insn);
4428 if (!out_set)
4429 {
4430 out_pat = PATTERN (out_insn);
4431 if (GET_CODE (out_pat) == PARALLEL)
4432 {
4433 for (i = 0; i < XVECLEN (out_pat, 0); i++)
4434 {
4435 out_exp = XVECEXP (out_pat, 0, i);
4436 if ((GET_CODE (out_exp) == CLOBBER)
4437 || (GET_CODE (out_exp) == USE))
4438 continue;
4439 else if (GET_CODE (out_exp) != SET)
4440 return false;
4441 }
4442 }
4443 }
4444 }
4445 }
4446 else
4447 {
4448 in_pat = PATTERN (in_insn);
4449 if (GET_CODE (in_pat) != PARALLEL)
4450 return false;
4451
4452 for (i = 0; i < XVECLEN (in_pat, 0); i++)
4453 {
4454 in_exp = XVECEXP (in_pat, 0, i);
4455 if ((GET_CODE (in_exp) == CLOBBER) || (GET_CODE (in_exp) == USE))
4456 continue;
4457 else if (GET_CODE (in_exp) != SET)
4458 return false;
4459
4460 if (MEM_P (SET_DEST (in_exp)))
4461 {
4462 out_set = single_set (out_insn);
4463 if (!out_set)
4464 {
4465 out_pat = PATTERN (out_insn);
4466 if (GET_CODE (out_pat) != PARALLEL)
4467 return false;
4468 for (j = 0; j < XVECLEN (out_pat, 0); j++)
4469 {
4470 out_exp = XVECEXP (out_pat, 0, j);
4471 if ((GET_CODE (out_exp) == CLOBBER)
4472 || (GET_CODE (out_exp) == USE))
4473 continue;
4474 else if (GET_CODE (out_exp) != SET)
4475 return false;
4476 }
4477 }
4478 }
4479 }
4480 }
4481
4482 return store_data_bypass_p (out_insn, in_insn);
4483 }
4484
4485 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
4486
4487 When floating-point registers are wider than integer ones, moves between
4488 them must go through memory. */
4489
4490 static bool
riscv_secondary_memory_needed(machine_mode mode,reg_class_t class1,reg_class_t class2)4491 riscv_secondary_memory_needed (machine_mode mode, reg_class_t class1,
4492 reg_class_t class2)
4493 {
4494 return (GET_MODE_SIZE (mode) > UNITS_PER_WORD
4495 && (class1 == FP_REGS) != (class2 == FP_REGS));
4496 }
4497
4498 /* Implement TARGET_REGISTER_MOVE_COST. */
4499
4500 static int
riscv_register_move_cost(machine_mode mode,reg_class_t from,reg_class_t to)4501 riscv_register_move_cost (machine_mode mode,
4502 reg_class_t from, reg_class_t to)
4503 {
4504 return riscv_secondary_memory_needed (mode, from, to) ? 8 : 2;
4505 }
4506
4507 /* Implement TARGET_HARD_REGNO_NREGS. */
4508
4509 static unsigned int
riscv_hard_regno_nregs(unsigned int regno,machine_mode mode)4510 riscv_hard_regno_nregs (unsigned int regno, machine_mode mode)
4511 {
4512 if (FP_REG_P (regno))
4513 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG;
4514
4515 /* All other registers are word-sized. */
4516 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4517 }
4518
4519 /* Implement TARGET_HARD_REGNO_MODE_OK. */
4520
4521 static bool
riscv_hard_regno_mode_ok(unsigned int regno,machine_mode mode)4522 riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
4523 {
4524 unsigned int nregs = riscv_hard_regno_nregs (regno, mode);
4525
4526 if (GP_REG_P (regno))
4527 {
4528 if (!GP_REG_P (regno + nregs - 1))
4529 return false;
4530 }
4531 else if (FP_REG_P (regno))
4532 {
4533 if (!FP_REG_P (regno + nregs - 1))
4534 return false;
4535
4536 if (GET_MODE_CLASS (mode) != MODE_FLOAT
4537 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
4538 return false;
4539
4540 /* Only use callee-saved registers if a potential callee is guaranteed
4541 to spill the requisite width. */
4542 if (GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_REG
4543 || (!call_used_or_fixed_reg_p (regno)
4544 && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_ARG))
4545 return false;
4546 }
4547 else
4548 return false;
4549
4550 /* Require same callee-savedness for all registers. */
4551 for (unsigned i = 1; i < nregs; i++)
4552 if (call_used_or_fixed_reg_p (regno)
4553 != call_used_or_fixed_reg_p (regno + i))
4554 return false;
4555
4556 return true;
4557 }
4558
4559 /* Implement TARGET_MODES_TIEABLE_P.
4560
4561 Don't allow floating-point modes to be tied, since type punning of
4562 single-precision and double-precision is implementation defined. */
4563
4564 static bool
riscv_modes_tieable_p(machine_mode mode1,machine_mode mode2)4565 riscv_modes_tieable_p (machine_mode mode1, machine_mode mode2)
4566 {
4567 return (mode1 == mode2
4568 || !(GET_MODE_CLASS (mode1) == MODE_FLOAT
4569 && GET_MODE_CLASS (mode2) == MODE_FLOAT));
4570 }
4571
4572 /* Implement CLASS_MAX_NREGS. */
4573
4574 static unsigned char
riscv_class_max_nregs(reg_class_t rclass,machine_mode mode)4575 riscv_class_max_nregs (reg_class_t rclass, machine_mode mode)
4576 {
4577 if (reg_class_subset_p (FP_REGS, rclass))
4578 return riscv_hard_regno_nregs (FP_REG_FIRST, mode);
4579
4580 if (reg_class_subset_p (GR_REGS, rclass))
4581 return riscv_hard_regno_nregs (GP_REG_FIRST, mode);
4582
4583 return 0;
4584 }
4585
4586 /* Implement TARGET_MEMORY_MOVE_COST. */
4587
4588 static int
riscv_memory_move_cost(machine_mode mode,reg_class_t rclass,bool in)4589 riscv_memory_move_cost (machine_mode mode, reg_class_t rclass, bool in)
4590 {
4591 return (tune_param->memory_cost
4592 + memory_move_secondary_cost (mode, rclass, in));
4593 }
4594
4595 /* Return the number of instructions that can be issued per cycle. */
4596
4597 static int
riscv_issue_rate(void)4598 riscv_issue_rate (void)
4599 {
4600 return tune_param->issue_rate;
4601 }
4602
4603 /* Auxiliary function to emit RISC-V ELF attribute. */
4604 static void
riscv_emit_attribute()4605 riscv_emit_attribute ()
4606 {
4607 fprintf (asm_out_file, "\t.attribute arch, \"%s\"\n",
4608 riscv_arch_str ().c_str ());
4609
4610 fprintf (asm_out_file, "\t.attribute unaligned_access, %d\n",
4611 TARGET_STRICT_ALIGN ? 0 : 1);
4612
4613 fprintf (asm_out_file, "\t.attribute stack_align, %d\n",
4614 riscv_stack_boundary / 8);
4615 }
4616
4617 /* Implement TARGET_ASM_FILE_START. */
4618
4619 static void
riscv_file_start(void)4620 riscv_file_start (void)
4621 {
4622 default_file_start ();
4623
4624 /* Instruct GAS to generate position-[in]dependent code. */
4625 fprintf (asm_out_file, "\t.option %spic\n", (flag_pic ? "" : "no"));
4626
4627 /* If the user specifies "-mno-relax" on the command line then disable linker
4628 relaxation in the assembler. */
4629 if (! riscv_mrelax)
4630 fprintf (asm_out_file, "\t.option norelax\n");
4631
4632 if (riscv_emit_attribute_p)
4633 riscv_emit_attribute ();
4634 }
4635
4636 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
4637 in order to avoid duplicating too much logic from elsewhere. */
4638
4639 static void
riscv_output_mi_thunk(FILE * file,tree thunk_fndecl ATTRIBUTE_UNUSED,HOST_WIDE_INT delta,HOST_WIDE_INT vcall_offset,tree function)4640 riscv_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
4641 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
4642 tree function)
4643 {
4644 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
4645 rtx this_rtx, temp1, temp2, fnaddr;
4646 rtx_insn *insn;
4647
4648 /* Pretend to be a post-reload pass while generating rtl. */
4649 reload_completed = 1;
4650
4651 /* Mark the end of the (empty) prologue. */
4652 emit_note (NOTE_INSN_PROLOGUE_END);
4653
4654 /* Determine if we can use a sibcall to call FUNCTION directly. */
4655 fnaddr = gen_rtx_MEM (FUNCTION_MODE, XEXP (DECL_RTL (function), 0));
4656
4657 /* We need two temporary registers in some cases. */
4658 temp1 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP_REGNUM);
4659 temp2 = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
4660
4661 /* Find out which register contains the "this" pointer. */
4662 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
4663 this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1);
4664 else
4665 this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST);
4666
4667 /* Add DELTA to THIS_RTX. */
4668 if (delta != 0)
4669 {
4670 rtx offset = GEN_INT (delta);
4671 if (!SMALL_OPERAND (delta))
4672 {
4673 riscv_emit_move (temp1, offset);
4674 offset = temp1;
4675 }
4676 emit_insn (gen_add3_insn (this_rtx, this_rtx, offset));
4677 }
4678
4679 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
4680 if (vcall_offset != 0)
4681 {
4682 rtx addr;
4683
4684 /* Set TEMP1 to *THIS_RTX. */
4685 riscv_emit_move (temp1, gen_rtx_MEM (Pmode, this_rtx));
4686
4687 /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
4688 addr = riscv_add_offset (temp2, temp1, vcall_offset);
4689
4690 /* Load the offset and add it to THIS_RTX. */
4691 riscv_emit_move (temp1, gen_rtx_MEM (Pmode, addr));
4692 emit_insn (gen_add3_insn (this_rtx, this_rtx, temp1));
4693 }
4694
4695 /* Jump to the target function. */
4696 insn = emit_call_insn (gen_sibcall (fnaddr, const0_rtx, NULL, const0_rtx));
4697 SIBLING_CALL_P (insn) = 1;
4698
4699 /* Run just enough of rest_of_compilation. This sequence was
4700 "borrowed" from alpha.c. */
4701 insn = get_insns ();
4702 split_all_insns_noflow ();
4703 shorten_branches (insn);
4704 assemble_start_function (thunk_fndecl, fnname);
4705 final_start_function (insn, file, 1);
4706 final (insn, file, 1);
4707 final_end_function ();
4708 assemble_end_function (thunk_fndecl, fnname);
4709
4710 /* Clean up the vars set above. Note that final_end_function resets
4711 the global pointer for us. */
4712 reload_completed = 0;
4713 }
4714
4715 /* Allocate a chunk of memory for per-function machine-dependent data. */
4716
4717 static struct machine_function *
riscv_init_machine_status(void)4718 riscv_init_machine_status (void)
4719 {
4720 return ggc_cleared_alloc<machine_function> ();
4721 }
4722
4723 /* Implement TARGET_OPTION_OVERRIDE. */
4724
4725 static void
riscv_option_override(void)4726 riscv_option_override (void)
4727 {
4728 const struct riscv_tune_info *cpu;
4729
4730 #ifdef SUBTARGET_OVERRIDE_OPTIONS
4731 SUBTARGET_OVERRIDE_OPTIONS;
4732 #endif
4733
4734 flag_pcc_struct_return = 0;
4735
4736 if (flag_pic)
4737 g_switch_value = 0;
4738
4739 /* The presence of the M extension implies that division instructions
4740 are present, so include them unless explicitly disabled. */
4741 if (TARGET_MUL && (target_flags_explicit & MASK_DIV) == 0)
4742 target_flags |= MASK_DIV;
4743 else if (!TARGET_MUL && TARGET_DIV)
4744 error ("%<-mdiv%> requires %<-march%> to subsume the %<M%> extension");
4745
4746 /* Likewise floating-point division and square root. */
4747 if (TARGET_HARD_FLOAT && (target_flags_explicit & MASK_FDIV) == 0)
4748 target_flags |= MASK_FDIV;
4749
4750 /* Handle -mtune, use -mcpu if -mtune is not given, and use default -mtune
4751 if -mtune and -mcpu both not not given. */
4752 cpu = riscv_parse_tune (riscv_tune_string ? riscv_tune_string :
4753 (riscv_cpu_string ? riscv_cpu_string :
4754 RISCV_TUNE_STRING_DEFAULT));
4755 riscv_microarchitecture = cpu->microarchitecture;
4756 tune_param = optimize_size ? &optimize_size_tune_info : cpu->tune_param;
4757
4758 /* Use -mtune's setting for slow_unaligned_access, even when optimizing
4759 for size. For architectures that trap and emulate unaligned accesses,
4760 the performance cost is too great, even for -Os. Similarly, if
4761 -m[no-]strict-align is left unspecified, heed -mtune's advice. */
4762 riscv_slow_unaligned_access_p = (cpu->tune_param->slow_unaligned_access
4763 || TARGET_STRICT_ALIGN);
4764 if ((target_flags_explicit & MASK_STRICT_ALIGN) == 0
4765 && cpu->tune_param->slow_unaligned_access)
4766 target_flags |= MASK_STRICT_ALIGN;
4767
4768 /* If the user hasn't specified a branch cost, use the processor's
4769 default. */
4770 if (riscv_branch_cost == 0)
4771 riscv_branch_cost = tune_param->branch_cost;
4772
4773 /* Function to allocate machine-dependent function status. */
4774 init_machine_status = &riscv_init_machine_status;
4775
4776 if (flag_pic)
4777 riscv_cmodel = CM_PIC;
4778
4779 /* We get better code with explicit relocs for CM_MEDLOW, but
4780 worse code for the others (for now). Pick the best default. */
4781 if ((target_flags_explicit & MASK_EXPLICIT_RELOCS) == 0)
4782 if (riscv_cmodel == CM_MEDLOW)
4783 target_flags |= MASK_EXPLICIT_RELOCS;
4784
4785 /* Require that the ISA supports the requested floating-point ABI. */
4786 if (UNITS_PER_FP_ARG > (TARGET_HARD_FLOAT ? UNITS_PER_FP_REG : 0))
4787 error ("requested ABI requires %<-march%> to subsume the %qc extension",
4788 UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));
4789
4790 if (TARGET_RVE && riscv_abi != ABI_ILP32E)
4791 error ("rv32e requires ilp32e ABI");
4792
4793 /* We do not yet support ILP32 on RV64. */
4794 if (BITS_PER_WORD != POINTER_SIZE)
4795 error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);
4796
4797 /* Validate -mpreferred-stack-boundary= value. */
4798 riscv_stack_boundary = ABI_STACK_BOUNDARY;
4799 if (riscv_preferred_stack_boundary_arg)
4800 {
4801 int min = ctz_hwi (STACK_BOUNDARY / 8);
4802 int max = 8;
4803
4804 if (!IN_RANGE (riscv_preferred_stack_boundary_arg, min, max))
4805 error ("%<-mpreferred-stack-boundary=%d%> must be between %d and %d",
4806 riscv_preferred_stack_boundary_arg, min, max);
4807
4808 riscv_stack_boundary = 8 << riscv_preferred_stack_boundary_arg;
4809 }
4810
4811 if (riscv_emit_attribute_p < 0)
4812 #ifdef HAVE_AS_RISCV_ATTRIBUTE
4813 riscv_emit_attribute_p = TARGET_RISCV_ATTRIBUTE;
4814 #else
4815 riscv_emit_attribute_p = 0;
4816
4817 if (riscv_emit_attribute_p)
4818 error ("%<-mriscv-attribute%> RISC-V ELF attribute requires GNU as 2.32"
4819 " [%<-mriscv-attribute%>]");
4820 #endif
4821
4822 if (riscv_stack_protector_guard == SSP_GLOBAL
4823 && global_options_set.x_riscv_stack_protector_guard_offset_str)
4824 {
4825 error ("incompatible options %<-mstack-protector-guard=global%> and "
4826 "%<-mstack-protector-guard-offset=%s%>",
4827 riscv_stack_protector_guard_offset_str);
4828 }
4829
4830 if (riscv_stack_protector_guard == SSP_TLS
4831 && !(global_options_set.x_riscv_stack_protector_guard_offset_str
4832 && global_options_set.x_riscv_stack_protector_guard_reg_str))
4833 {
4834 error ("both %<-mstack-protector-guard-offset%> and "
4835 "%<-mstack-protector-guard-reg%> must be used "
4836 "with %<-mstack-protector-guard=sysreg%>");
4837 }
4838
4839 if (global_options_set.x_riscv_stack_protector_guard_reg_str)
4840 {
4841 const char *str = riscv_stack_protector_guard_reg_str;
4842 int reg = decode_reg_name (str);
4843
4844 if (!IN_RANGE (reg, GP_REG_FIRST + 1, GP_REG_LAST))
4845 error ("%qs is not a valid base register in %qs", str,
4846 "-mstack-protector-guard-reg=");
4847
4848 riscv_stack_protector_guard_reg = reg;
4849 }
4850
4851 if (global_options_set.x_riscv_stack_protector_guard_offset_str)
4852 {
4853 char *end;
4854 const char *str = riscv_stack_protector_guard_offset_str;
4855 errno = 0;
4856 long offs = strtol (riscv_stack_protector_guard_offset_str, &end, 0);
4857
4858 if (!*str || *end || errno)
4859 error ("%qs is not a valid number in %qs", str,
4860 "-mstack-protector-guard-offset=");
4861
4862 if (!SMALL_OPERAND (offs))
4863 error ("%qs is not a valid offset in %qs", str,
4864 "-mstack-protector-guard-offset=");
4865
4866 riscv_stack_protector_guard_offset = offs;
4867 }
4868
4869 }
4870
4871 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
4872
4873 static void
riscv_conditional_register_usage(void)4874 riscv_conditional_register_usage (void)
4875 {
4876 /* We have only x0~x15 on RV32E. */
4877 if (TARGET_RVE)
4878 {
4879 for (int r = 16; r <= 31; r++)
4880 fixed_regs[r] = 1;
4881 }
4882
4883 if (riscv_abi == ABI_ILP32E)
4884 {
4885 for (int r = 16; r <= 31; r++)
4886 call_used_regs[r] = 1;
4887 }
4888
4889 if (!TARGET_HARD_FLOAT)
4890 {
4891 for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
4892 fixed_regs[regno] = call_used_regs[regno] = 1;
4893 }
4894
4895 /* In the soft-float ABI, there are no callee-saved FP registers. */
4896 if (UNITS_PER_FP_ARG == 0)
4897 {
4898 for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
4899 call_used_regs[regno] = 1;
4900 }
4901 }
4902
4903 /* Return a register priority for hard reg REGNO. */
4904
4905 static int
riscv_register_priority(int regno)4906 riscv_register_priority (int regno)
4907 {
4908 /* Favor compressed registers to improve the odds of RVC instruction
4909 selection. */
4910 if (riscv_compressed_reg_p (regno))
4911 return 1;
4912
4913 return 0;
4914 }
4915
4916 /* Implement TARGET_TRAMPOLINE_INIT. */
4917
4918 static void
riscv_trampoline_init(rtx m_tramp,tree fndecl,rtx chain_value)4919 riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
4920 {
4921 rtx addr, end_addr, mem;
4922 uint32_t trampoline[4];
4923 unsigned int i;
4924 HOST_WIDE_INT static_chain_offset, target_function_offset;
4925
4926 /* Work out the offsets of the pointers from the start of the
4927 trampoline code. */
4928 gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE);
4929
4930 /* Get pointers to the beginning and end of the code block. */
4931 addr = force_reg (Pmode, XEXP (m_tramp, 0));
4932 end_addr = riscv_force_binary (Pmode, PLUS, addr,
4933 GEN_INT (TRAMPOLINE_CODE_SIZE));
4934
4935
4936 if (Pmode == SImode)
4937 {
4938 chain_value = force_reg (Pmode, chain_value);
4939
4940 rtx target_function = force_reg (Pmode, XEXP (DECL_RTL (fndecl), 0));
4941 /* lui t2, hi(chain)
4942 lui t0, hi(func)
4943 addi t2, t2, lo(chain)
4944 jr t0, lo(func)
4945 */
4946 unsigned HOST_WIDE_INT lui_hi_chain_code, lui_hi_func_code;
4947 unsigned HOST_WIDE_INT lo_chain_code, lo_func_code;
4948
4949 rtx uimm_mask = force_reg (SImode, gen_int_mode (-IMM_REACH, SImode));
4950
4951 /* 0xfff. */
4952 rtx imm12_mask = gen_reg_rtx (SImode);
4953 emit_insn (gen_one_cmplsi2 (imm12_mask, uimm_mask));
4954
4955 rtx fixup_value = force_reg (SImode, gen_int_mode (IMM_REACH/2, SImode));
4956
4957 /* Gen lui t2, hi(chain). */
4958 rtx hi_chain = riscv_force_binary (SImode, PLUS, chain_value,
4959 fixup_value);
4960 hi_chain = riscv_force_binary (SImode, AND, hi_chain,
4961 uimm_mask);
4962 lui_hi_chain_code = OPCODE_LUI | (STATIC_CHAIN_REGNUM << SHIFT_RD);
4963 rtx lui_hi_chain = riscv_force_binary (SImode, IOR, hi_chain,
4964 gen_int_mode (lui_hi_chain_code, SImode));
4965
4966 mem = adjust_address (m_tramp, SImode, 0);
4967 riscv_emit_move (mem, riscv_swap_instruction (lui_hi_chain));
4968
4969 /* Gen lui t0, hi(func). */
4970 rtx hi_func = riscv_force_binary (SImode, PLUS, target_function,
4971 fixup_value);
4972 hi_func = riscv_force_binary (SImode, AND, hi_func,
4973 uimm_mask);
4974 lui_hi_func_code = OPCODE_LUI | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD);
4975 rtx lui_hi_func = riscv_force_binary (SImode, IOR, hi_func,
4976 gen_int_mode (lui_hi_func_code, SImode));
4977
4978 mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode));
4979 riscv_emit_move (mem, riscv_swap_instruction (lui_hi_func));
4980
4981 /* Gen addi t2, t2, lo(chain). */
4982 rtx lo_chain = riscv_force_binary (SImode, AND, chain_value,
4983 imm12_mask);
4984 lo_chain = riscv_force_binary (SImode, ASHIFT, lo_chain, GEN_INT (20));
4985
4986 lo_chain_code = OPCODE_ADDI
4987 | (STATIC_CHAIN_REGNUM << SHIFT_RD)
4988 | (STATIC_CHAIN_REGNUM << SHIFT_RS1);
4989
4990 rtx addi_lo_chain = riscv_force_binary (SImode, IOR, lo_chain,
4991 force_reg (SImode, GEN_INT (lo_chain_code)));
4992
4993 mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode));
4994 riscv_emit_move (mem, riscv_swap_instruction (addi_lo_chain));
4995
4996 /* Gen jr t0, lo(func). */
4997 rtx lo_func = riscv_force_binary (SImode, AND, target_function,
4998 imm12_mask);
4999 lo_func = riscv_force_binary (SImode, ASHIFT, lo_func, GEN_INT (20));
5000
5001 lo_func_code = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1);
5002
5003 rtx jr_lo_func = riscv_force_binary (SImode, IOR, lo_func,
5004 force_reg (SImode, GEN_INT (lo_func_code)));
5005
5006 mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode));
5007 riscv_emit_move (mem, riscv_swap_instruction (jr_lo_func));
5008 }
5009 else
5010 {
5011 static_chain_offset = TRAMPOLINE_CODE_SIZE;
5012 target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
5013
5014 /* auipc t2, 0
5015 l[wd] t0, target_function_offset(t2)
5016 l[wd] t2, static_chain_offset(t2)
5017 jr t0
5018 */
5019 trampoline[0] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD);
5020 trampoline[1] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
5021 | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD)
5022 | (STATIC_CHAIN_REGNUM << SHIFT_RS1)
5023 | (target_function_offset << SHIFT_IMM);
5024 trampoline[2] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
5025 | (STATIC_CHAIN_REGNUM << SHIFT_RD)
5026 | (STATIC_CHAIN_REGNUM << SHIFT_RS1)
5027 | (static_chain_offset << SHIFT_IMM);
5028 trampoline[3] = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1);
5029
5030 /* Copy the trampoline code. */
5031 for (i = 0; i < ARRAY_SIZE (trampoline); i++)
5032 {
5033 if (BYTES_BIG_ENDIAN)
5034 trampoline[i] = __builtin_bswap32(trampoline[i]);
5035 mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode));
5036 riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode));
5037 }
5038
5039 /* Set up the static chain pointer field. */
5040 mem = adjust_address (m_tramp, ptr_mode, static_chain_offset);
5041 riscv_emit_move (mem, chain_value);
5042
5043 /* Set up the target function field. */
5044 mem = adjust_address (m_tramp, ptr_mode, target_function_offset);
5045 riscv_emit_move (mem, XEXP (DECL_RTL (fndecl), 0));
5046 }
5047
5048 /* Flush the code part of the trampoline. */
5049 emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE)));
5050 emit_insn (gen_clear_cache (addr, end_addr));
5051 }
5052
5053 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
5054
5055 static bool
riscv_function_ok_for_sibcall(tree decl ATTRIBUTE_UNUSED,tree exp ATTRIBUTE_UNUSED)5056 riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
5057 tree exp ATTRIBUTE_UNUSED)
5058 {
5059 /* Don't use sibcalls when use save-restore routine. */
5060 if (TARGET_SAVE_RESTORE)
5061 return false;
5062
5063 /* Don't use sibcall for naked functions. */
5064 if (cfun->machine->naked_p)
5065 return false;
5066
5067 /* Don't use sibcall for interrupt functions. */
5068 if (cfun->machine->interrupt_handler_p)
5069 return false;
5070
5071 return true;
5072 }
5073
5074 /* Get the interrupt type, return UNKNOWN_MODE if it's not
5075 interrupt function. */
5076 static enum riscv_privilege_levels
riscv_get_interrupt_type(tree decl)5077 riscv_get_interrupt_type (tree decl)
5078 {
5079 gcc_assert (decl != NULL_TREE);
5080
5081 if ((TREE_CODE(decl) != FUNCTION_DECL)
5082 || (!riscv_interrupt_type_p (TREE_TYPE (decl))))
5083 return UNKNOWN_MODE;
5084
5085 tree attr_args
5086 = TREE_VALUE (lookup_attribute ("interrupt",
5087 TYPE_ATTRIBUTES (TREE_TYPE (decl))));
5088
5089 if (attr_args && TREE_CODE (TREE_VALUE (attr_args)) != VOID_TYPE)
5090 {
5091 const char *string = TREE_STRING_POINTER (TREE_VALUE (attr_args));
5092
5093 if (!strcmp (string, "user"))
5094 return USER_MODE;
5095 else if (!strcmp (string, "supervisor"))
5096 return SUPERVISOR_MODE;
5097 else /* Must be "machine". */
5098 return MACHINE_MODE;
5099 }
5100 else
5101 /* Interrupt attributes are machine mode by default. */
5102 return MACHINE_MODE;
5103 }
5104
5105 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */
5106 /* Sanity cheching for above function attributes. */
5107 static void
riscv_set_current_function(tree decl)5108 riscv_set_current_function (tree decl)
5109 {
5110 if (decl == NULL_TREE
5111 || current_function_decl == NULL_TREE
5112 || current_function_decl == error_mark_node
5113 || ! cfun->machine
5114 || cfun->machine->attributes_checked_p)
5115 return;
5116
5117 cfun->machine->naked_p = riscv_naked_function_p (decl);
5118 cfun->machine->interrupt_handler_p
5119 = riscv_interrupt_type_p (TREE_TYPE (decl));
5120
5121 if (cfun->machine->naked_p && cfun->machine->interrupt_handler_p)
5122 error ("function attributes %qs and %qs are mutually exclusive",
5123 "interrupt", "naked");
5124
5125 if (cfun->machine->interrupt_handler_p)
5126 {
5127 tree ret = TREE_TYPE (TREE_TYPE (decl));
5128 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
5129
5130 if (TREE_CODE (ret) != VOID_TYPE)
5131 error ("%qs function cannot return a value", "interrupt");
5132
5133 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
5134 error ("%qs function cannot have arguments", "interrupt");
5135
5136 cfun->machine->interrupt_mode = riscv_get_interrupt_type (decl);
5137
5138 gcc_assert (cfun->machine->interrupt_mode != UNKNOWN_MODE);
5139 }
5140
5141 /* Don't print the above diagnostics more than once. */
5142 cfun->machine->attributes_checked_p = 1;
5143 }
5144
5145 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
5146 static tree
riscv_merge_decl_attributes(tree olddecl,tree newdecl)5147 riscv_merge_decl_attributes (tree olddecl, tree newdecl)
5148 {
5149 tree combined_attrs;
5150
5151 enum riscv_privilege_levels old_interrupt_type
5152 = riscv_get_interrupt_type (olddecl);
5153 enum riscv_privilege_levels new_interrupt_type
5154 = riscv_get_interrupt_type (newdecl);
5155
5156 /* Check old and new has same interrupt type. */
5157 if ((old_interrupt_type != UNKNOWN_MODE)
5158 && (new_interrupt_type != UNKNOWN_MODE)
5159 && (old_interrupt_type != new_interrupt_type))
5160 error ("%qs function cannot have different interrupt type", "interrupt");
5161
5162 /* Create combined attributes. */
5163 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
5164 DECL_ATTRIBUTES (newdecl));
5165
5166 return combined_attrs;
5167 }
5168
5169 /* Implement TARGET_CANNOT_COPY_INSN_P. */
5170
5171 static bool
riscv_cannot_copy_insn_p(rtx_insn * insn)5172 riscv_cannot_copy_insn_p (rtx_insn *insn)
5173 {
5174 return recog_memoized (insn) >= 0 && get_attr_cannot_copy (insn);
5175 }
5176
5177 /* Implement TARGET_SLOW_UNALIGNED_ACCESS. */
5178
5179 static bool
riscv_slow_unaligned_access(machine_mode,unsigned int)5180 riscv_slow_unaligned_access (machine_mode, unsigned int)
5181 {
5182 return riscv_slow_unaligned_access_p;
5183 }
5184
5185 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
5186
5187 static bool
riscv_can_change_mode_class(machine_mode,machine_mode,reg_class_t rclass)5188 riscv_can_change_mode_class (machine_mode, machine_mode, reg_class_t rclass)
5189 {
5190 return !reg_classes_intersect_p (FP_REGS, rclass);
5191 }
5192
5193
5194 /* Implement TARGET_CONSTANT_ALIGNMENT. */
5195
5196 static HOST_WIDE_INT
riscv_constant_alignment(const_tree exp,HOST_WIDE_INT align)5197 riscv_constant_alignment (const_tree exp, HOST_WIDE_INT align)
5198 {
5199 if ((TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
5200 && (riscv_align_data_type == riscv_align_data_type_xlen))
5201 return MAX (align, BITS_PER_WORD);
5202 return align;
5203 }
5204
5205 /* Implement TARGET_PROMOTE_FUNCTION_MODE. */
5206
5207 /* This function is equivalent to default_promote_function_mode_always_promote
5208 except that it returns a promoted mode even if type is NULL_TREE. This is
5209 needed by libcalls which have no type (only a mode) such as fixed conversion
5210 routines that take a signed or unsigned char/short/int argument and convert
5211 it to a fixed type. */
5212
5213 static machine_mode
riscv_promote_function_mode(const_tree type ATTRIBUTE_UNUSED,machine_mode mode,int * punsignedp ATTRIBUTE_UNUSED,const_tree fntype ATTRIBUTE_UNUSED,int for_return ATTRIBUTE_UNUSED)5214 riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
5215 machine_mode mode,
5216 int *punsignedp ATTRIBUTE_UNUSED,
5217 const_tree fntype ATTRIBUTE_UNUSED,
5218 int for_return ATTRIBUTE_UNUSED)
5219 {
5220 int unsignedp;
5221
5222 if (type != NULL_TREE)
5223 return promote_mode (type, mode, punsignedp);
5224
5225 unsignedp = *punsignedp;
5226 PROMOTE_MODE (mode, unsignedp, type);
5227 *punsignedp = unsignedp;
5228 return mode;
5229 }
5230
5231 /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
5232
5233 static void
riscv_reorg(void)5234 riscv_reorg (void)
5235 {
5236 /* Do nothing unless we have -msave-restore */
5237 if (TARGET_SAVE_RESTORE)
5238 riscv_remove_unneeded_save_restore_calls ();
5239 }
5240
5241 /* Return nonzero if register FROM_REGNO can be renamed to register
5242 TO_REGNO. */
5243
5244 bool
riscv_hard_regno_rename_ok(unsigned from_regno ATTRIBUTE_UNUSED,unsigned to_regno)5245 riscv_hard_regno_rename_ok (unsigned from_regno ATTRIBUTE_UNUSED,
5246 unsigned to_regno)
5247 {
5248 /* Interrupt functions can only use registers that have already been
5249 saved by the prologue, even if they would normally be
5250 call-clobbered. */
5251 return !cfun->machine->interrupt_handler_p || df_regs_ever_live_p (to_regno);
5252 }
5253
5254 /* Implement TARGET_NEW_ADDRESS_PROFITABLE_P. */
5255
5256 bool
riscv_new_address_profitable_p(rtx memref,rtx_insn * insn,rtx new_addr)5257 riscv_new_address_profitable_p (rtx memref, rtx_insn *insn, rtx new_addr)
5258 {
5259 /* Prefer old address if it is less expensive. */
5260 addr_space_t as = MEM_ADDR_SPACE (memref);
5261 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
5262 int old_cost = address_cost (XEXP (memref, 0), GET_MODE (memref), as, speed);
5263 int new_cost = address_cost (new_addr, GET_MODE (memref), as, speed);
5264 return new_cost <= old_cost;
5265 }
5266
5267 /* Helper function for generating gpr_save pattern. */
5268
5269 rtx
riscv_gen_gpr_save_insn(struct riscv_frame_info * frame)5270 riscv_gen_gpr_save_insn (struct riscv_frame_info *frame)
5271 {
5272 unsigned count = riscv_save_libcall_count (frame->mask);
5273 /* 1 for unspec 2 for clobber t0/t1 and 1 for ra. */
5274 unsigned veclen = 1 + 2 + 1 + count;
5275 rtvec vec = rtvec_alloc (veclen);
5276
5277 gcc_assert (veclen <= ARRAY_SIZE (gpr_save_reg_order));
5278
5279 RTVEC_ELT (vec, 0) =
5280 gen_rtx_UNSPEC_VOLATILE (VOIDmode,
5281 gen_rtvec (1, GEN_INT (count)), UNSPECV_GPR_SAVE);
5282
5283 for (unsigned i = 1; i < veclen; ++i)
5284 {
5285 unsigned regno = gpr_save_reg_order[i];
5286 rtx reg = gen_rtx_REG (Pmode, regno);
5287 rtx elt;
5288
5289 /* t0 and t1 are CLOBBERs, others are USEs. */
5290 if (i < 3)
5291 elt = gen_rtx_CLOBBER (Pmode, reg);
5292 else
5293 elt = gen_rtx_USE (Pmode, reg);
5294
5295 RTVEC_ELT (vec, i) = elt;
5296 }
5297
5298 /* Largest number of caller-save register must set in mask if we are
5299 not using __riscv_save_0. */
5300 gcc_assert ((count == 0) ||
5301 BITSET_P (frame->mask, gpr_save_reg_order[veclen - 1]));
5302
5303 return gen_rtx_PARALLEL (VOIDmode, vec);
5304 }
5305
5306 /* Return true if it's valid gpr_save pattern. */
5307
5308 bool
riscv_gpr_save_operation_p(rtx op)5309 riscv_gpr_save_operation_p (rtx op)
5310 {
5311 unsigned len = XVECLEN (op, 0);
5312
5313 if (len > ARRAY_SIZE (gpr_save_reg_order))
5314 return false;
5315
5316 for (unsigned i = 0; i < len; i++)
5317 {
5318 rtx elt = XVECEXP (op, 0, i);
5319 if (i == 0)
5320 {
5321 /* First element in parallel is unspec. */
5322 if (GET_CODE (elt) != UNSPEC_VOLATILE
5323 || GET_CODE (XVECEXP (elt, 0, 0)) != CONST_INT
5324 || XINT (elt, 1) != UNSPECV_GPR_SAVE)
5325 return false;
5326 }
5327 else
5328 {
5329 /* Two CLOBBER and USEs, must check the order. */
5330 unsigned expect_code = i < 3 ? CLOBBER : USE;
5331 if (GET_CODE (elt) != expect_code
5332 || !REG_P (XEXP (elt, 1))
5333 || (REGNO (XEXP (elt, 1)) != gpr_save_reg_order[i]))
5334 return false;
5335 }
5336 break;
5337 }
5338 return true;
5339 }
5340
5341 /* Implement TARGET_ASAN_SHADOW_OFFSET. */
5342
5343 static unsigned HOST_WIDE_INT
riscv_asan_shadow_offset(void)5344 riscv_asan_shadow_offset (void)
5345 {
5346 /* We only have libsanitizer support for RV64 at present.
5347
5348 This number must match kRiscv*_ShadowOffset* in the file
5349 libsanitizer/asan/asan_mapping.h which is currently 1<<29 for rv64,
5350 even though 1<<36 makes more sense. */
5351 return TARGET_64BIT ? (HOST_WIDE_INT_1 << 29) : 0;
5352 }
5353
5354 /* Initialize the GCC target structure. */
5355 #undef TARGET_ASM_ALIGNED_HI_OP
5356 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
5357 #undef TARGET_ASM_ALIGNED_SI_OP
5358 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
5359 #undef TARGET_ASM_ALIGNED_DI_OP
5360 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
5361
5362 #undef TARGET_OPTION_OVERRIDE
5363 #define TARGET_OPTION_OVERRIDE riscv_option_override
5364
5365 #undef TARGET_LEGITIMIZE_ADDRESS
5366 #define TARGET_LEGITIMIZE_ADDRESS riscv_legitimize_address
5367
5368 #undef TARGET_SCHED_ISSUE_RATE
5369 #define TARGET_SCHED_ISSUE_RATE riscv_issue_rate
5370
5371 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
5372 #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall
5373
5374 #undef TARGET_SET_CURRENT_FUNCTION
5375 #define TARGET_SET_CURRENT_FUNCTION riscv_set_current_function
5376
5377 #undef TARGET_REGISTER_MOVE_COST
5378 #define TARGET_REGISTER_MOVE_COST riscv_register_move_cost
5379 #undef TARGET_MEMORY_MOVE_COST
5380 #define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost
5381 #undef TARGET_RTX_COSTS
5382 #define TARGET_RTX_COSTS riscv_rtx_costs
5383 #undef TARGET_ADDRESS_COST
5384 #define TARGET_ADDRESS_COST riscv_address_cost
5385
5386 #undef TARGET_ASM_FILE_START
5387 #define TARGET_ASM_FILE_START riscv_file_start
5388 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
5389 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
5390
5391 #undef TARGET_EXPAND_BUILTIN_VA_START
5392 #define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start
5393
5394 #undef TARGET_PROMOTE_FUNCTION_MODE
5395 #define TARGET_PROMOTE_FUNCTION_MODE riscv_promote_function_mode
5396
5397 #undef TARGET_RETURN_IN_MEMORY
5398 #define TARGET_RETURN_IN_MEMORY riscv_return_in_memory
5399
5400 #undef TARGET_ASM_OUTPUT_MI_THUNK
5401 #define TARGET_ASM_OUTPUT_MI_THUNK riscv_output_mi_thunk
5402 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5403 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
5404
5405 #undef TARGET_PRINT_OPERAND
5406 #define TARGET_PRINT_OPERAND riscv_print_operand
5407 #undef TARGET_PRINT_OPERAND_ADDRESS
5408 #define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address
5409
5410 #undef TARGET_SETUP_INCOMING_VARARGS
5411 #define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs
5412 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
5413 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS riscv_allocate_stack_slots_for_args
5414 #undef TARGET_STRICT_ARGUMENT_NAMING
5415 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
5416 #undef TARGET_MUST_PASS_IN_STACK
5417 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
5418 #undef TARGET_PASS_BY_REFERENCE
5419 #define TARGET_PASS_BY_REFERENCE riscv_pass_by_reference
5420 #undef TARGET_ARG_PARTIAL_BYTES
5421 #define TARGET_ARG_PARTIAL_BYTES riscv_arg_partial_bytes
5422 #undef TARGET_FUNCTION_ARG
5423 #define TARGET_FUNCTION_ARG riscv_function_arg
5424 #undef TARGET_FUNCTION_ARG_ADVANCE
5425 #define TARGET_FUNCTION_ARG_ADVANCE riscv_function_arg_advance
5426 #undef TARGET_FUNCTION_ARG_BOUNDARY
5427 #define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary
5428
5429 /* The generic ELF target does not always have TLS support. */
5430 #ifdef HAVE_AS_TLS
5431 #undef TARGET_HAVE_TLS
5432 #define TARGET_HAVE_TLS true
5433 #endif
5434
5435 #undef TARGET_CANNOT_FORCE_CONST_MEM
5436 #define TARGET_CANNOT_FORCE_CONST_MEM riscv_cannot_force_const_mem
5437
5438 #undef TARGET_LEGITIMATE_CONSTANT_P
5439 #define TARGET_LEGITIMATE_CONSTANT_P riscv_legitimate_constant_p
5440
5441 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
5442 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
5443
5444 #undef TARGET_LEGITIMATE_ADDRESS_P
5445 #define TARGET_LEGITIMATE_ADDRESS_P riscv_legitimate_address_p
5446
5447 #undef TARGET_CAN_ELIMINATE
5448 #define TARGET_CAN_ELIMINATE riscv_can_eliminate
5449
5450 #undef TARGET_CONDITIONAL_REGISTER_USAGE
5451 #define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage
5452
5453 #undef TARGET_CLASS_MAX_NREGS
5454 #define TARGET_CLASS_MAX_NREGS riscv_class_max_nregs
5455
5456 #undef TARGET_TRAMPOLINE_INIT
5457 #define TARGET_TRAMPOLINE_INIT riscv_trampoline_init
5458
5459 #undef TARGET_IN_SMALL_DATA_P
5460 #define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p
5461
5462 #undef TARGET_HAVE_SRODATA_SECTION
5463 #define TARGET_HAVE_SRODATA_SECTION true
5464
5465 #undef TARGET_ASM_SELECT_SECTION
5466 #define TARGET_ASM_SELECT_SECTION riscv_select_section
5467
5468 #undef TARGET_ASM_UNIQUE_SECTION
5469 #define TARGET_ASM_UNIQUE_SECTION riscv_unique_section
5470
5471 #undef TARGET_ASM_SELECT_RTX_SECTION
5472 #define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section
5473
5474 #undef TARGET_MIN_ANCHOR_OFFSET
5475 #define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2)
5476
5477 #undef TARGET_MAX_ANCHOR_OFFSET
5478 #define TARGET_MAX_ANCHOR_OFFSET (IMM_REACH/2-1)
5479
5480 #undef TARGET_REGISTER_PRIORITY
5481 #define TARGET_REGISTER_PRIORITY riscv_register_priority
5482
5483 #undef TARGET_CANNOT_COPY_INSN_P
5484 #define TARGET_CANNOT_COPY_INSN_P riscv_cannot_copy_insn_p
5485
5486 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
5487 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV riscv_atomic_assign_expand_fenv
5488
5489 #undef TARGET_INIT_BUILTINS
5490 #define TARGET_INIT_BUILTINS riscv_init_builtins
5491
5492 #undef TARGET_BUILTIN_DECL
5493 #define TARGET_BUILTIN_DECL riscv_builtin_decl
5494
5495 #undef TARGET_EXPAND_BUILTIN
5496 #define TARGET_EXPAND_BUILTIN riscv_expand_builtin
5497
5498 #undef TARGET_HARD_REGNO_NREGS
5499 #define TARGET_HARD_REGNO_NREGS riscv_hard_regno_nregs
5500 #undef TARGET_HARD_REGNO_MODE_OK
5501 #define TARGET_HARD_REGNO_MODE_OK riscv_hard_regno_mode_ok
5502
5503 #undef TARGET_MODES_TIEABLE_P
5504 #define TARGET_MODES_TIEABLE_P riscv_modes_tieable_p
5505
5506 #undef TARGET_SLOW_UNALIGNED_ACCESS
5507 #define TARGET_SLOW_UNALIGNED_ACCESS riscv_slow_unaligned_access
5508
5509 #undef TARGET_SECONDARY_MEMORY_NEEDED
5510 #define TARGET_SECONDARY_MEMORY_NEEDED riscv_secondary_memory_needed
5511
5512 #undef TARGET_CAN_CHANGE_MODE_CLASS
5513 #define TARGET_CAN_CHANGE_MODE_CLASS riscv_can_change_mode_class
5514
5515 #undef TARGET_CONSTANT_ALIGNMENT
5516 #define TARGET_CONSTANT_ALIGNMENT riscv_constant_alignment
5517
5518 #undef TARGET_MERGE_DECL_ATTRIBUTES
5519 #define TARGET_MERGE_DECL_ATTRIBUTES riscv_merge_decl_attributes
5520
5521 #undef TARGET_ATTRIBUTE_TABLE
5522 #define TARGET_ATTRIBUTE_TABLE riscv_attribute_table
5523
5524 #undef TARGET_WARN_FUNC_RETURN
5525 #define TARGET_WARN_FUNC_RETURN riscv_warn_func_return
5526
5527 /* The low bit is ignored by jump instructions so is safe to use. */
5528 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
5529 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
5530
5531 #undef TARGET_MACHINE_DEPENDENT_REORG
5532 #define TARGET_MACHINE_DEPENDENT_REORG riscv_reorg
5533
5534 #undef TARGET_NEW_ADDRESS_PROFITABLE_P
5535 #define TARGET_NEW_ADDRESS_PROFITABLE_P riscv_new_address_profitable_p
5536
5537 #undef TARGET_ASAN_SHADOW_OFFSET
5538 #define TARGET_ASAN_SHADOW_OFFSET riscv_asan_shadow_offset
5539
5540 #ifdef TARGET_BIG_ENDIAN_DEFAULT
5541 #undef TARGET_DEFAULT_TARGET_FLAGS
5542 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
5543 #endif
5544
5545 struct gcc_target targetm = TARGET_INITIALIZER;
5546
5547 #include "gt-riscv.h"
5548