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