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