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