]>
Commit | Line | Data |
---|---|---|
91dfef96 | 1 | /* Subroutines used for code generation for eBPF. |
99dee823 | 2 | Copyright (C) 2019-2021 Free Software Foundation, Inc. |
91dfef96 JM |
3 | |
4 | This file is part of GCC. | |
5 | ||
6 | GCC is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 3, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GCC is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GCC; see the file COPYING3. If not see | |
18 | <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #define IN_TARGET_CODE 1 | |
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 "c-family/c-common.h" | |
53 | #include "diagnostic.h" | |
54 | #include "builtins.h" | |
55 | #include "predict.h" | |
56 | #include "langhooks.h" | |
57 | ||
58 | /* Per-function machine data. */ | |
59 | struct GTY(()) machine_function | |
60 | { | |
61 | /* Number of bytes saved on the stack for local variables. */ | |
62 | int local_vars_size; | |
63 | ||
64 | /* Number of bytes saved on the stack for callee-saved | |
65 | registers. */ | |
66 | int callee_saved_reg_size; | |
67 | }; | |
68 | ||
af30b83b JM |
69 | /* Handle an attribute requiring a FUNCTION_DECL; |
70 | arguments as in struct attribute_spec.handler. */ | |
71 | ||
72 | static tree | |
73 | bpf_handle_fndecl_attribute (tree *node, tree name, | |
74 | tree args, | |
75 | int flags ATTRIBUTE_UNUSED, | |
76 | bool *no_add_attrs) | |
77 | { | |
78 | if (TREE_CODE (*node) != FUNCTION_DECL) | |
79 | { | |
80 | warning (OPT_Wattributes, "%qE attribute only applies to functions", | |
81 | name); | |
82 | *no_add_attrs = true; | |
83 | } | |
84 | ||
85 | if (is_attribute_p ("kernel_helper", name)) | |
86 | { | |
87 | if (args) | |
88 | { | |
89 | tree cst = TREE_VALUE (args); | |
90 | if (TREE_CODE (cst) != INTEGER_CST) | |
91 | { | |
92 | warning (OPT_Wattributes, "%qE attribute requires an integer argument", | |
93 | name); | |
94 | *no_add_attrs = true; | |
95 | } | |
96 | } | |
97 | else | |
98 | { | |
99 | warning (OPT_Wattributes, "%qE requires an argument", name); | |
100 | *no_add_attrs = true; | |
101 | } | |
102 | } | |
103 | ||
104 | return NULL_TREE; | |
105 | } | |
106 | ||
107 | /* Target-specific attributes. */ | |
108 | ||
109 | static const struct attribute_spec bpf_attribute_table[] = | |
110 | { | |
111 | /* Syntax: { name, min_len, max_len, decl_required, type_required, | |
112 | function_type_required, affects_type_identity, handler, | |
113 | exclude } */ | |
114 | ||
115 | /* Attribute to mark function prototypes as kernel helpers. */ | |
116 | { "kernel_helper", 1, 1, true, false, false, false, | |
117 | bpf_handle_fndecl_attribute, NULL }, | |
118 | ||
119 | /* The last attribute spec is set to be NULL. */ | |
120 | { NULL, 0, 0, false, false, false, false, NULL, NULL } | |
121 | }; | |
122 | ||
123 | #undef TARGET_ATTRIBUTE_TABLE | |
124 | #define TARGET_ATTRIBUTE_TABLE bpf_attribute_table | |
125 | ||
91dfef96 JM |
126 | /* Data structures for the eBPF specific built-ins. */ |
127 | ||
128 | /* Maximum number of arguments taken by a builtin function, plus | |
129 | one. */ | |
130 | #define BPF_BUILTIN_MAX_ARGS 5 | |
131 | ||
132 | enum bpf_builtins | |
133 | { | |
134 | BPF_BUILTIN_UNUSED = 0, | |
91dfef96 | 135 | /* Built-ins for non-generic loads and stores. */ |
af30b83b | 136 | BPF_BUILTIN_LOAD_BYTE, |
91dfef96 JM |
137 | BPF_BUILTIN_LOAD_HALF, |
138 | BPF_BUILTIN_LOAD_WORD, | |
139 | BPF_BUILTIN_MAX, | |
140 | }; | |
141 | ||
91dfef96 JM |
142 | static GTY (()) tree bpf_builtins[(int) BPF_BUILTIN_MAX]; |
143 | ||
144 | /* Initialize the per-function machine status. */ | |
145 | ||
146 | static struct machine_function * | |
147 | bpf_init_machine_status (void) | |
148 | { | |
149 | /* Note this initializes all fields to 0, which is just OK for | |
150 | us. */ | |
151 | return ggc_cleared_alloc<machine_function> (); | |
152 | } | |
153 | ||
154 | /* Override options and do some other initialization. */ | |
155 | ||
156 | static void | |
157 | bpf_option_override (void) | |
158 | { | |
159 | /* Set the initializer for the per-function status structure. */ | |
160 | init_machine_status = bpf_init_machine_status; | |
161 | } | |
162 | ||
163 | #undef TARGET_OPTION_OVERRIDE | |
164 | #define TARGET_OPTION_OVERRIDE bpf_option_override | |
165 | ||
166 | /* Define target-specific CPP macros. This function in used in the | |
167 | definition of TARGET_CPU_CPP_BUILTINS in bpf.h */ | |
168 | ||
169 | #define builtin_define(TXT) cpp_define (pfile, TXT) | |
170 | ||
171 | void | |
172 | bpf_target_macros (cpp_reader *pfile) | |
173 | { | |
174 | builtin_define ("__BPF__"); | |
af30b83b | 175 | |
91dfef96 JM |
176 | if (TARGET_BIG_ENDIAN) |
177 | builtin_define ("__BPF_BIG_ENDIAN__"); | |
178 | else | |
179 | builtin_define ("__BPF_LITTLE_ENDIAN__"); | |
180 | ||
181 | /* Define BPF_KERNEL_VERSION_CODE */ | |
182 | { | |
183 | const char *version_code; | |
184 | char *kernel_version_code; | |
185 | ||
186 | switch (bpf_kernel) | |
187 | { | |
188 | case LINUX_V4_0: version_code = "0x40000"; break; | |
189 | case LINUX_V4_1: version_code = "0x40100"; break; | |
190 | case LINUX_V4_2: version_code = "0x40200"; break; | |
191 | case LINUX_V4_3: version_code = "0x40300"; break; | |
192 | case LINUX_V4_4: version_code = "0x40400"; break; | |
193 | case LINUX_V4_5: version_code = "0x40500"; break; | |
194 | case LINUX_V4_6: version_code = "0x40600"; break; | |
195 | case LINUX_V4_7: version_code = "0x40700"; break; | |
196 | case LINUX_V4_8: version_code = "0x40800"; break; | |
197 | case LINUX_V4_9: version_code = "0x40900"; break; | |
198 | case LINUX_V4_10: version_code = "0x40a00"; break; | |
199 | case LINUX_V4_11: version_code = "0x40b00"; break; | |
200 | case LINUX_V4_12: version_code = "0x40c00"; break; | |
201 | case LINUX_V4_13: version_code = "0x40d00"; break; | |
202 | case LINUX_V4_14: version_code = "0x40e00"; break; | |
203 | case LINUX_V4_15: version_code = "0x40f00"; break; | |
204 | case LINUX_V4_16: version_code = "0x41000"; break; | |
205 | case LINUX_V4_17: version_code = "0x42000"; break; | |
206 | case LINUX_V4_18: version_code = "0x43000"; break; | |
207 | case LINUX_V4_19: version_code = "0x44000"; break; | |
208 | case LINUX_V4_20: version_code = "0x45000"; break; | |
209 | case LINUX_V5_0: version_code = "0x50000"; break; | |
210 | case LINUX_V5_1: version_code = "0x50100"; break; | |
211 | case LINUX_V5_2: version_code = "0x50200"; break; | |
212 | default: | |
af30b83b | 213 | gcc_unreachable (); |
91dfef96 JM |
214 | } |
215 | ||
216 | kernel_version_code = ACONCAT (("__BPF_KERNEL_VERSION_CODE__=", | |
217 | version_code, NULL)); | |
218 | builtin_define (kernel_version_code); | |
219 | } | |
220 | } | |
221 | ||
91dfef96 JM |
222 | /* Return an RTX representing the place where a function returns or |
223 | receives a value of data type RET_TYPE, a tree node representing a | |
224 | data type. */ | |
225 | ||
226 | static rtx | |
227 | bpf_function_value (const_tree ret_type, | |
228 | const_tree fntype_or_decl, | |
229 | bool outgoing ATTRIBUTE_UNUSED) | |
230 | { | |
231 | enum machine_mode mode; | |
232 | int unsignedp; | |
233 | ||
234 | mode = TYPE_MODE (ret_type); | |
235 | if (INTEGRAL_TYPE_P (ret_type)) | |
236 | mode = promote_function_mode (ret_type, mode, &unsignedp, | |
237 | fntype_or_decl, 1); | |
238 | ||
239 | return gen_rtx_REG (mode, BPF_R0); | |
240 | } | |
241 | ||
242 | #undef TARGET_FUNCTION_VALUE | |
243 | #define TARGET_FUNCTION_VALUE bpf_function_value | |
244 | ||
245 | /* Return true if REGNO is the number of a hard register in which the | |
246 | values of called function may come back. */ | |
247 | ||
248 | static bool | |
249 | bpf_function_value_regno_p (const unsigned int regno) | |
250 | { | |
251 | return (regno == BPF_R0); | |
252 | } | |
253 | ||
254 | #undef TARGET_FUNCTION_VALUE_REGNO_P | |
255 | #define TARGET_FUNCTION_VALUE_REGNO_P bpf_function_value_regno_p | |
256 | ||
257 | /* Compute the size of the function's stack frame, including the local | |
258 | area and the register-save area. */ | |
259 | ||
260 | static void | |
261 | bpf_compute_frame_layout (void) | |
262 | { | |
263 | int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT; | |
264 | int padding_locals, regno; | |
265 | ||
266 | /* Set the space used in the stack by local variables. This is | |
267 | rounded up to respect the minimum stack alignment. */ | |
268 | cfun->machine->local_vars_size = get_frame_size (); | |
269 | ||
270 | padding_locals = cfun->machine->local_vars_size % stack_alignment; | |
271 | if (padding_locals) | |
272 | padding_locals = stack_alignment - padding_locals; | |
273 | ||
274 | cfun->machine->local_vars_size += padding_locals; | |
275 | ||
98456a64 JM |
276 | if (TARGET_XBPF) |
277 | { | |
278 | /* Set the space used in the stack by callee-saved used | |
279 | registers in the current function. There is no need to round | |
280 | up, since the registers are all 8 bytes wide. */ | |
281 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | |
282 | if ((df_regs_ever_live_p (regno) | |
283 | && !call_used_or_fixed_reg_p (regno)) | |
284 | || (cfun->calls_alloca | |
285 | && regno == STACK_POINTER_REGNUM)) | |
286 | cfun->machine->callee_saved_reg_size += 8; | |
287 | } | |
91dfef96 JM |
288 | |
289 | /* Check that the total size of the frame doesn't exceed the limit | |
290 | imposed by eBPF. */ | |
291 | if ((cfun->machine->local_vars_size | |
292 | + cfun->machine->callee_saved_reg_size) > bpf_frame_limit) | |
293 | { | |
294 | static int stack_limit_exceeded = 0; | |
295 | ||
296 | if (!stack_limit_exceeded) | |
297 | error ("eBPF stack limit exceeded"); | |
298 | stack_limit_exceeded = 1; | |
299 | } | |
300 | } | |
301 | ||
302 | #undef TARGET_COMPUTE_FRAME_LAYOUT | |
303 | #define TARGET_COMPUTE_FRAME_LAYOUT bpf_compute_frame_layout | |
304 | ||
305 | /* Expand to the instructions in a function prologue. This function | |
306 | is called when expanding the 'prologue' pattern in bpf.md. */ | |
307 | ||
308 | void | |
309 | bpf_expand_prologue (void) | |
310 | { | |
91dfef96 JM |
311 | rtx insn; |
312 | HOST_WIDE_INT size; | |
313 | ||
314 | size = (cfun->machine->local_vars_size | |
315 | + cfun->machine->callee_saved_reg_size); | |
91dfef96 | 316 | |
98456a64 JM |
317 | /* The BPF "hardware" provides a fresh new set of registers for each |
318 | called function, some of which are initialized to the values of | |
319 | the arguments passed in the first five registers. In doing so, | |
320 | it saves the values of the registers of the caller, and restored | |
321 | them upon returning. Therefore, there is no need to save the | |
322 | callee-saved registers here. What is worse, the kernel | |
323 | implementation refuses to run programs in which registers are | |
324 | referred before being initialized. */ | |
325 | if (TARGET_XBPF) | |
91dfef96 | 326 | { |
98456a64 JM |
327 | int regno; |
328 | int fp_offset = -cfun->machine->local_vars_size; | |
91dfef96 | 329 | |
98456a64 JM |
330 | /* Save callee-saved hard registes. The register-save-area |
331 | starts right after the local variables. */ | |
332 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | |
333 | { | |
334 | if ((df_regs_ever_live_p (regno) | |
335 | && !call_used_or_fixed_reg_p (regno)) | |
336 | || (cfun->calls_alloca | |
337 | && regno == STACK_POINTER_REGNUM)) | |
91dfef96 | 338 | { |
98456a64 JM |
339 | rtx mem; |
340 | ||
341 | if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff)) | |
342 | /* This has been already reported as an error in | |
343 | bpf_compute_frame_layout. */ | |
344 | break; | |
345 | else | |
346 | { | |
347 | mem = gen_frame_mem (DImode, | |
348 | plus_constant (DImode, | |
349 | hard_frame_pointer_rtx, | |
350 | fp_offset - 8)); | |
351 | insn = emit_move_insn (mem, gen_rtx_REG (DImode, regno)); | |
352 | RTX_FRAME_RELATED_P (insn) = 1; | |
353 | fp_offset -= 8; | |
354 | } | |
91dfef96 JM |
355 | } |
356 | } | |
357 | } | |
358 | ||
359 | /* Set the stack pointer, if the function allocates space | |
360 | dynamically. Note that the value of %sp should be directly | |
361 | derived from %fp, for the kernel verifier to track it as a stack | |
362 | accessor. */ | |
363 | if (cfun->calls_alloca) | |
364 | { | |
365 | insn = emit_move_insn (stack_pointer_rtx, | |
366 | hard_frame_pointer_rtx); | |
367 | RTX_FRAME_RELATED_P (insn) = 1; | |
af30b83b | 368 | |
91dfef96 JM |
369 | if (size > 0) |
370 | { | |
371 | insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, | |
372 | gen_rtx_PLUS (Pmode, | |
373 | stack_pointer_rtx, | |
374 | GEN_INT (-size)))); | |
375 | RTX_FRAME_RELATED_P (insn) = 1; | |
376 | } | |
377 | } | |
378 | } | |
379 | ||
380 | /* Expand to the instructions in a function epilogue. This function | |
381 | is called when expanding the 'epilogue' pattern in bpf.md. */ | |
382 | ||
383 | void | |
384 | bpf_expand_epilogue (void) | |
385 | { | |
98456a64 JM |
386 | /* See note in bpf_expand_prologue for an explanation on why we are |
387 | not restoring callee-saved registers in BPF. */ | |
388 | if (TARGET_XBPF) | |
91dfef96 | 389 | { |
98456a64 JM |
390 | rtx insn; |
391 | int regno; | |
392 | int fp_offset = -cfun->machine->local_vars_size; | |
91dfef96 | 393 | |
98456a64 JM |
394 | /* Restore callee-saved hard registes from the stack. */ |
395 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | |
396 | { | |
397 | if ((df_regs_ever_live_p (regno) | |
398 | && !call_used_or_fixed_reg_p (regno)) | |
399 | || (cfun->calls_alloca | |
400 | && regno == STACK_POINTER_REGNUM)) | |
91dfef96 | 401 | { |
98456a64 JM |
402 | rtx mem; |
403 | ||
404 | if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff)) | |
405 | /* This has been already reported as an error in | |
406 | bpf_compute_frame_layout. */ | |
407 | break; | |
408 | else | |
409 | { | |
410 | mem = gen_frame_mem (DImode, | |
411 | plus_constant (DImode, | |
412 | hard_frame_pointer_rtx, | |
413 | fp_offset - 8)); | |
414 | insn = emit_move_insn (gen_rtx_REG (DImode, regno), mem); | |
415 | RTX_FRAME_RELATED_P (insn) = 1; | |
416 | fp_offset -= 8; | |
417 | } | |
91dfef96 JM |
418 | } |
419 | } | |
420 | } | |
421 | ||
422 | emit_jump_insn (gen_exit ()); | |
423 | } | |
424 | ||
425 | /* Return the initial difference between the specified pair of | |
426 | registers. The registers that can figure in FROM, and TO, are | |
427 | specified by ELIMINABLE_REGS in bpf.h. | |
428 | ||
429 | This function is used in the definition of | |
430 | INITIAL_ELIMINATION_OFFSET in bpf.h */ | |
431 | ||
432 | HOST_WIDE_INT | |
433 | bpf_initial_elimination_offset (int from, int to) | |
434 | { | |
435 | HOST_WIDE_INT ret; | |
436 | ||
437 | if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) | |
438 | ret = (cfun->machine->local_vars_size | |
439 | + cfun->machine->callee_saved_reg_size); | |
440 | else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) | |
441 | ret = 0; | |
442 | else | |
443 | gcc_unreachable (); | |
444 | ||
445 | return ret; | |
446 | } | |
447 | ||
448 | /* Return the number of consecutive hard registers, starting at | |
449 | register number REGNO, required to hold a value of mode MODE. */ | |
450 | ||
451 | static unsigned int | |
452 | bpf_hard_regno_nregs (unsigned int regno ATTRIBUTE_UNUSED, | |
453 | enum machine_mode mode) | |
454 | { | |
455 | return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); | |
456 | } | |
457 | ||
458 | #undef TARGET_HARD_REGNO_NREGS | |
459 | #define TARGET_HARD_REGNO_NREGS bpf_hard_regno_nregs | |
460 | ||
461 | /* Return true if it is permissible to store a value of mode MODE in | |
462 | hard register number REGNO, or in several registers starting with | |
463 | that one. */ | |
464 | ||
465 | static bool | |
466 | bpf_hard_regno_mode_ok (unsigned int regno ATTRIBUTE_UNUSED, | |
467 | enum machine_mode mode) | |
468 | { | |
469 | switch (mode) | |
470 | { | |
471 | case E_SImode: | |
472 | case E_DImode: | |
473 | case E_HImode: | |
474 | case E_QImode: | |
475 | case E_TImode: | |
476 | case E_SFmode: | |
477 | case E_DFmode: | |
478 | return true; | |
479 | default: | |
480 | return false; | |
481 | } | |
482 | } | |
483 | ||
484 | #undef TARGET_HARD_REGNO_MODE_OK | |
485 | #define TARGET_HARD_REGNO_MODE_OK bpf_hard_regno_mode_ok | |
486 | ||
487 | /* Return true if a function must have and use a frame pointer. */ | |
488 | ||
489 | static bool | |
490 | bpf_frame_pointer_required (void) | |
491 | { | |
492 | /* We do not have a stack pointer, so we absolutely depend on the | |
493 | frame-pointer in order to access the stack... and fishes walk and | |
494 | pigs fly glglgl */ | |
495 | return true; | |
496 | } | |
497 | ||
498 | #undef TARGET_FRAME_POINTER_REQUIRED | |
499 | #define TARGET_FRAME_POINTER_REQUIRED bpf_frame_pointer_required | |
500 | ||
501 | /* Return `true' if the given RTX X is a valid base for an indirect | |
502 | memory access. STRICT has the same meaning than in | |
503 | bpf_legitimate_address_p. */ | |
504 | ||
505 | static inline bool | |
506 | bpf_address_base_p (rtx x, bool strict) | |
507 | { | |
508 | return (GET_CODE (x) == REG | |
509 | && (REGNO (x) < 11 | |
510 | || (!strict && REGNO (x) >= FIRST_PSEUDO_REGISTER))); | |
511 | } | |
512 | ||
513 | /* Return true if X (a RTX) is a legitimate memory address on the | |
514 | target machine for a memory operand of mode MODE. */ | |
515 | ||
516 | static bool | |
517 | bpf_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, | |
518 | rtx x, | |
519 | bool strict) | |
520 | { | |
521 | switch (GET_CODE (x)) | |
522 | { | |
523 | case REG: | |
524 | return bpf_address_base_p (x, strict); | |
525 | ||
526 | case PLUS: | |
527 | { | |
528 | /* Accept (PLUS ADDR_BASE CONST_INT), provided CONST_INT fits | |
529 | in a signed 16-bit. | |
530 | ||
531 | Note that LABEL_REF and SYMBOL_REF are not allowed in | |
532 | REG+IMM addresses, because it is almost certain they will | |
533 | overload the offset field. */ | |
534 | ||
535 | rtx x0 = XEXP (x, 0); | |
536 | rtx x1 = XEXP (x, 1); | |
af30b83b | 537 | |
91dfef96 JM |
538 | if (bpf_address_base_p (x0, strict) && GET_CODE (x1) == CONST_INT) |
539 | return IN_RANGE (INTVAL (x1), -1 - 0x7fff, 0x7fff); | |
540 | ||
541 | break; | |
542 | } | |
543 | default: | |
544 | break; | |
545 | } | |
546 | ||
547 | return false; | |
548 | } | |
549 | ||
550 | #undef TARGET_LEGITIMATE_ADDRESS_P | |
551 | #define TARGET_LEGITIMATE_ADDRESS_P bpf_legitimate_address_p | |
552 | ||
553 | /* Describe the relative costs of RTL expressions. Return true when | |
554 | all subexpressions of X have been processed, and false when | |
555 | `rtx_cost' should recurse. */ | |
556 | ||
557 | static bool | |
558 | bpf_rtx_costs (rtx x ATTRIBUTE_UNUSED, | |
559 | enum machine_mode mode ATTRIBUTE_UNUSED, | |
560 | int outer_code ATTRIBUTE_UNUSED, | |
561 | int opno ATTRIBUTE_UNUSED, | |
562 | int *total ATTRIBUTE_UNUSED, | |
563 | bool speed ATTRIBUTE_UNUSED) | |
564 | { | |
565 | /* To be written. */ | |
566 | return false; | |
567 | } | |
568 | ||
569 | #undef TARGET_RTX_COSTS | |
570 | #define TARGET_RTX_COSTS bpf_rtx_costs | |
571 | ||
572 | /* Return true if an argument at the position indicated by CUM should | |
573 | be passed by reference. If the hook returns true, a copy of that | |
574 | argument is made in memory and a pointer to the argument is passed | |
575 | instead of the argument itself. */ | |
576 | ||
577 | static bool | |
578 | bpf_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, | |
579 | const function_arg_info &arg) | |
580 | { | |
581 | unsigned num_bytes = arg.type_size_in_bytes (); | |
582 | ||
583 | /* Pass aggregates and values bigger than 5 words by reference. | |
584 | Everything else is passed by copy. */ | |
585 | return (arg.aggregate_type_p () || (num_bytes > 8*5)); | |
586 | } | |
587 | ||
588 | #undef TARGET_PASS_BY_REFERENCE | |
589 | #define TARGET_PASS_BY_REFERENCE bpf_pass_by_reference | |
590 | ||
591 | /* Return a RTX indicating whether a function argument is passed in a | |
592 | register and if so, which register. */ | |
593 | ||
594 | static rtx | |
595 | bpf_function_arg (cumulative_args_t ca, const function_arg_info &arg) | |
596 | { | |
597 | CUMULATIVE_ARGS *cum = get_cumulative_args (ca); | |
598 | ||
599 | if (*cum < 5) | |
600 | return gen_rtx_REG (arg.mode, *cum + 1); | |
601 | else | |
602 | /* An error will be emitted for this in | |
603 | bpf_function_arg_advance. */ | |
604 | return NULL_RTX; | |
605 | } | |
606 | ||
607 | #undef TARGET_FUNCTION_ARG | |
608 | #define TARGET_FUNCTION_ARG bpf_function_arg | |
609 | ||
610 | /* Update the summarizer variable pointed by CA to advance past an | |
611 | argument in the argument list. */ | |
612 | ||
613 | static void | |
614 | bpf_function_arg_advance (cumulative_args_t ca, | |
615 | const function_arg_info &arg) | |
616 | { | |
617 | CUMULATIVE_ARGS *cum = get_cumulative_args (ca); | |
618 | unsigned num_bytes = arg.type_size_in_bytes (); | |
619 | unsigned num_words = CEIL (num_bytes, UNITS_PER_WORD); | |
620 | ||
621 | if (*cum <= 5 && *cum + num_words > 5) | |
622 | error ("too many function arguments for eBPF"); | |
623 | ||
624 | *cum += num_words; | |
625 | } | |
626 | ||
627 | #undef TARGET_FUNCTION_ARG_ADVANCE | |
628 | #define TARGET_FUNCTION_ARG_ADVANCE bpf_function_arg_advance | |
629 | ||
630 | /* Output the assembly code for a constructor. Since eBPF doesn't | |
631 | support indirect calls, constructors are not supported. */ | |
632 | ||
633 | static void | |
634 | bpf_output_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED) | |
635 | { | |
636 | tree decl = SYMBOL_REF_DECL (symbol); | |
637 | ||
638 | if (decl) | |
639 | sorry_at (DECL_SOURCE_LOCATION (decl), | |
640 | "no constructors"); | |
641 | else | |
642 | sorry ("no constructors"); | |
643 | } | |
644 | ||
645 | #undef TARGET_ASM_CONSTRUCTOR | |
646 | #define TARGET_ASM_CONSTRUCTOR bpf_output_constructor | |
647 | ||
648 | /* Output the assembly code for a destructor. Since eBPF doesn't | |
649 | support indirect calls, destructors are not supported. */ | |
650 | ||
651 | static void | |
652 | bpf_output_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED) | |
653 | { | |
654 | tree decl = SYMBOL_REF_DECL (symbol); | |
655 | ||
656 | if (decl) | |
657 | sorry_at (DECL_SOURCE_LOCATION (decl), | |
658 | "no destructors"); | |
659 | else | |
660 | sorry ("no destructors"); | |
661 | } | |
662 | ||
663 | #undef TARGET_ASM_DESTRUCTOR | |
664 | #define TARGET_ASM_DESTRUCTOR bpf_output_destructor | |
665 | ||
666 | /* Return the appropriate instruction to CALL to a function. TARGET | |
667 | is an RTX denoting the address of the called function. | |
668 | ||
669 | The main purposes of this function are: | |
670 | - To reject indirect CALL instructions, which are not supported by | |
671 | eBPF. | |
672 | - To recognize calls to kernel helper functions and emit the | |
673 | corresponding CALL N instruction. | |
674 | ||
675 | This function is called from the expansion of the 'call' pattern in | |
676 | bpf.md. */ | |
677 | ||
678 | const char * | |
679 | bpf_output_call (rtx target) | |
680 | { | |
681 | rtx xops[1]; | |
682 | ||
683 | switch (GET_CODE (target)) | |
684 | { | |
685 | case CONST_INT: | |
686 | output_asm_insn ("call\t%0", &target); | |
687 | break; | |
688 | case SYMBOL_REF: | |
689 | { | |
af30b83b JM |
690 | tree decl = SYMBOL_REF_DECL (target); |
691 | tree attr; | |
692 | ||
693 | if (decl | |
694 | && (attr = lookup_attribute ("kernel_helper", | |
695 | DECL_ATTRIBUTES (decl)))) | |
91dfef96 | 696 | { |
af30b83b JM |
697 | tree attr_args = TREE_VALUE (attr); |
698 | ||
699 | xops[0] = GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (attr_args))); | |
91dfef96 JM |
700 | output_asm_insn ("call\t%0", xops); |
701 | } | |
702 | else | |
703 | output_asm_insn ("call\t%0", &target); | |
704 | ||
705 | break; | |
706 | } | |
707 | default: | |
c3a0f537 DF |
708 | if (TARGET_XBPF) |
709 | output_asm_insn ("call\t%0", &target); | |
710 | else | |
711 | { | |
712 | error ("indirect call in function, which are not supported by eBPF"); | |
713 | output_asm_insn ("call 0", NULL); | |
714 | } | |
91dfef96 JM |
715 | break; |
716 | } | |
717 | ||
718 | return ""; | |
719 | } | |
720 | ||
721 | /* Print an instruction operand. This function is called in the macro | |
722 | PRINT_OPERAND defined in bpf.h */ | |
723 | ||
724 | void | |
725 | bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED) | |
726 | { | |
727 | switch (GET_CODE (op)) | |
728 | { | |
729 | case REG: | |
730 | fprintf (file, "%s", reg_names[REGNO (op)]); | |
731 | break; | |
732 | case MEM: | |
733 | output_address (GET_MODE (op), XEXP (op, 0)); | |
734 | break; | |
735 | case CONST_DOUBLE: | |
736 | if (CONST_DOUBLE_HIGH (op)) | |
737 | fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, | |
738 | CONST_DOUBLE_HIGH (op), CONST_DOUBLE_LOW (op)); | |
739 | else if (CONST_DOUBLE_LOW (op) < 0) | |
740 | fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (op)); | |
741 | else | |
742 | fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (op)); | |
743 | break; | |
744 | default: | |
745 | output_addr_const (file, op); | |
746 | } | |
747 | } | |
748 | ||
749 | /* Print an operand which is an address. This function should handle | |
750 | any legit address, as accepted by bpf_legitimate_address_p, and | |
751 | also addresses that are valid in CALL instructions. | |
752 | ||
753 | This function is called in the PRINT_OPERAND_ADDRESS macro defined | |
754 | in bpf.h */ | |
755 | ||
756 | void | |
757 | bpf_print_operand_address (FILE *file, rtx addr) | |
758 | { | |
759 | switch (GET_CODE (addr)) | |
760 | { | |
761 | case REG: | |
762 | fprintf (file, "[%s+0]", reg_names[REGNO (addr)]); | |
763 | break; | |
764 | case PLUS: | |
765 | { | |
766 | rtx op0 = XEXP (addr, 0); | |
767 | rtx op1 = XEXP (addr, 1); | |
768 | ||
769 | if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT) | |
770 | { | |
771 | fprintf (file, "[%s+", reg_names[REGNO (op0)]); | |
772 | output_addr_const (file, op1); | |
773 | fputs ("]", file); | |
774 | } | |
775 | else | |
776 | fatal_insn ("invalid address in operand", addr); | |
777 | break; | |
778 | } | |
779 | case MEM: | |
780 | /* Fallthrough. */ | |
781 | case LABEL_REF: | |
782 | /* Fallthrough. */ | |
783 | fatal_insn ("unsupported operand", addr); | |
784 | break; | |
785 | default: | |
786 | output_addr_const (file, addr); | |
787 | break; | |
788 | } | |
789 | } | |
790 | ||
791 | /* Add a BPF builtin function with NAME, CODE and TYPE. Return | |
792 | the function decl or NULL_TREE if the builtin was not added. */ | |
793 | ||
794 | static tree | |
795 | def_builtin (const char *name, enum bpf_builtins code, tree type) | |
796 | { | |
797 | tree t | |
798 | = add_builtin_function (name, type, code, BUILT_IN_MD, NULL, NULL_TREE); | |
799 | ||
800 | bpf_builtins[code] = t; | |
801 | return t; | |
802 | } | |
803 | ||
804 | /* Define machine-specific built-in functions. */ | |
805 | ||
806 | static void | |
807 | bpf_init_builtins (void) | |
808 | { | |
91dfef96 | 809 | tree ullt = long_long_unsigned_type_node; |
91dfef96 JM |
810 | |
811 | /* Built-ins for BPF_LD_ABS and BPF_LD_IND instructions. */ | |
812 | ||
813 | def_builtin ("__builtin_bpf_load_byte", BPF_BUILTIN_LOAD_BYTE, | |
814 | build_function_type_list (ullt, ullt, 0)); | |
815 | def_builtin ("__builtin_bpf_load_half", BPF_BUILTIN_LOAD_HALF, | |
816 | build_function_type_list (ullt, ullt, 0)); | |
817 | def_builtin ("__builtin_bpf_load_word", BPF_BUILTIN_LOAD_WORD, | |
818 | build_function_type_list (ullt, ullt, 0)); | |
819 | } | |
820 | ||
821 | #undef TARGET_INIT_BUILTINS | |
822 | #define TARGET_INIT_BUILTINS bpf_init_builtins | |
823 | ||
824 | /* Expand a call to a BPF-specific built-in function that was set up | |
825 | with bpf_init_builtins. */ | |
826 | ||
827 | static rtx | |
af30b83b | 828 | bpf_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, |
91dfef96 JM |
829 | rtx subtarget ATTRIBUTE_UNUSED, |
830 | machine_mode mode ATTRIBUTE_UNUSED, | |
af30b83b | 831 | int ignore ATTRIBUTE_UNUSED) |
91dfef96 JM |
832 | { |
833 | tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); | |
834 | int code = DECL_MD_FUNCTION_CODE (fndecl); | |
835 | ||
af30b83b JM |
836 | if (code == BPF_BUILTIN_LOAD_BYTE |
837 | || code == BPF_BUILTIN_LOAD_HALF | |
838 | || code == BPF_BUILTIN_LOAD_WORD) | |
91dfef96 JM |
839 | { |
840 | /* Expand an indirect load from the sk_buff in the context. | |
841 | There is just one argument to the builtin, which is the | |
842 | offset. | |
843 | ||
844 | We try first to expand a ldabs* instruction. In case this | |
845 | fails, we try a ldind* instruction. */ | |
846 | ||
847 | enum insn_code abs_icode | |
848 | = (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldabsb | |
849 | : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldabsh | |
850 | : CODE_FOR_ldabsw); | |
851 | ||
852 | enum insn_code ind_icode | |
853 | = (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldindb | |
854 | : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldindh | |
855 | : CODE_FOR_ldindw); | |
856 | ||
857 | tree offset_arg = CALL_EXPR_ARG (exp, 0); | |
858 | struct expand_operand ops[2]; | |
859 | ||
860 | create_input_operand (&ops[0], expand_normal (offset_arg), | |
861 | TYPE_MODE (TREE_TYPE (offset_arg))); | |
862 | create_input_operand (&ops[1], const0_rtx, SImode); | |
863 | ||
864 | if (!maybe_expand_insn (abs_icode, 2, ops) | |
865 | && !maybe_expand_insn (ind_icode, 2, ops)) | |
866 | { | |
867 | error ("invalid argument to built-in function"); | |
868 | return gen_rtx_REG (ops[0].mode, BPF_R0); | |
869 | } | |
870 | ||
871 | /* The result of the load is in R0. */ | |
872 | return gen_rtx_REG (ops[0].mode, BPF_R0); | |
873 | } | |
874 | ||
875 | gcc_unreachable (); | |
876 | } | |
877 | ||
878 | #undef TARGET_EXPAND_BUILTIN | |
879 | #define TARGET_EXPAND_BUILTIN bpf_expand_builtin | |
880 | ||
881 | /* Initialize target-specific function library calls. This is mainly | |
882 | used to call library-provided soft-fp operations, since eBPF | |
883 | doesn't support floating-point in "hardware". */ | |
884 | ||
885 | static void | |
886 | bpf_init_libfuncs (void) | |
887 | { | |
888 | set_conv_libfunc (sext_optab, DFmode, SFmode, | |
889 | "__bpf_extendsfdf2"); | |
890 | set_conv_libfunc (trunc_optab, SFmode, DFmode, | |
891 | "__bpf_truncdfsf2"); | |
892 | set_conv_libfunc (sfix_optab, SImode, DFmode, | |
893 | "__bpf_fix_truncdfsi"); | |
894 | set_conv_libfunc (sfloat_optab, DFmode, SImode, | |
895 | "__bpf_floatsidf"); | |
896 | set_conv_libfunc (ufloat_optab, DFmode, SImode, | |
897 | "__bpf_floatunsidf"); | |
898 | } | |
899 | ||
900 | #undef TARGET_INIT_LIBFUNCS | |
901 | #define TARGET_INIT_LIBFUNCS bpf_init_libfuncs | |
902 | ||
903 | /* Define the mechanism that will be used for describing frame unwind | |
904 | information to the debugger. In eBPF it is not possible to unwind | |
905 | frames. */ | |
906 | ||
907 | static enum unwind_info_type | |
908 | bpf_debug_unwind_info () | |
909 | { | |
910 | return UI_NONE; | |
911 | } | |
912 | ||
913 | #undef TARGET_DEBUG_UNWIND_INFO | |
914 | #define TARGET_DEBUG_UNWIND_INFO bpf_debug_unwind_info | |
915 | ||
916 | /* Output assembly directives to assemble data of various sized and | |
917 | alignments. */ | |
918 | ||
919 | #undef TARGET_ASM_BYTE_OP | |
920 | #define TARGET_ASM_BYTE_OP "\t.byte\t" | |
921 | #undef TARGET_ASM_ALIGNED_HI_OP | |
922 | #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" | |
923 | #undef TARGET_ASM_ALIGNED_SI_OP | |
924 | #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" | |
925 | #undef TARGET_ASM_ALIGNED_DI_OP | |
926 | #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t" | |
927 | ||
928 | /* Finally, build the GCC target. */ | |
929 | ||
930 | struct gcc_target targetm = TARGET_INITIALIZER; | |
931 | ||
932 | #include "gt-bpf.h" |