1 /* Subroutines used for code generation for eBPF.
2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
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
69 /* Handle an attribute requiring a FUNCTION_DECL;
70 arguments as in struct attribute_spec.handler. */
71
72 static tree
bpf_handle_fndecl_attribute(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)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
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,
135 /* Built-ins for non-generic loads and stores. */
136 BPF_BUILTIN_LOAD_BYTE,
137 BPF_BUILTIN_LOAD_HALF,
138 BPF_BUILTIN_LOAD_WORD,
139 BPF_BUILTIN_MAX,
140 };
141
142 static GTY (()) tree bpf_builtins[(int) BPF_BUILTIN_MAX];
143
144 /* Initialize the per-function machine status. */
145
146 static struct machine_function *
bpf_init_machine_status(void)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
bpf_option_override(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
bpf_target_macros(cpp_reader * pfile)172 bpf_target_macros (cpp_reader *pfile)
173 {
174 builtin_define ("__BPF__");
175
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:
213 gcc_unreachable ();
214 }
215
216 kernel_version_code = ACONCAT (("__BPF_KERNEL_VERSION_CODE__=",
217 version_code, NULL));
218 builtin_define (kernel_version_code);
219 }
220 }
221
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
bpf_function_value(const_tree ret_type,const_tree fntype_or_decl,bool outgoing ATTRIBUTE_UNUSED)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
bpf_function_value_regno_p(const unsigned int regno)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
bpf_compute_frame_layout(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
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 }
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
bpf_expand_prologue(void)309 bpf_expand_prologue (void)
310 {
311 rtx insn;
312 HOST_WIDE_INT size;
313
314 size = (cfun->machine->local_vars_size
315 + cfun->machine->callee_saved_reg_size);
316
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)
326 {
327 int regno;
328 int fp_offset = -cfun->machine->local_vars_size;
329
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))
338 {
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 }
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;
368
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
bpf_expand_epilogue(void)384 bpf_expand_epilogue (void)
385 {
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)
389 {
390 rtx insn;
391 int regno;
392 int fp_offset = -cfun->machine->local_vars_size;
393
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))
401 {
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 }
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
bpf_initial_elimination_offset(int from,int to)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
bpf_hard_regno_nregs(unsigned int regno ATTRIBUTE_UNUSED,enum machine_mode mode)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
bpf_hard_regno_mode_ok(unsigned int regno ATTRIBUTE_UNUSED,enum machine_mode mode)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
bpf_frame_pointer_required(void)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
bpf_address_base_p(rtx x,bool strict)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
bpf_legitimate_address_p(machine_mode mode ATTRIBUTE_UNUSED,rtx x,bool strict)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);
537
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
bpf_rtx_costs(rtx x ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED,int outer_code ATTRIBUTE_UNUSED,int opno ATTRIBUTE_UNUSED,int * total ATTRIBUTE_UNUSED,bool speed ATTRIBUTE_UNUSED)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
bpf_pass_by_reference(cumulative_args_t cum ATTRIBUTE_UNUSED,const function_arg_info & arg)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
bpf_function_arg(cumulative_args_t ca,const function_arg_info & arg)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
bpf_function_arg_advance(cumulative_args_t ca,const function_arg_info & arg)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
bpf_output_constructor(rtx symbol,int priority ATTRIBUTE_UNUSED)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
bpf_output_destructor(rtx symbol,int priority ATTRIBUTE_UNUSED)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 *
bpf_output_call(rtx target)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 {
690 tree decl = SYMBOL_REF_DECL (target);
691 tree attr;
692
693 if (decl
694 && (attr = lookup_attribute ("kernel_helper",
695 DECL_ATTRIBUTES (decl))))
696 {
697 tree attr_args = TREE_VALUE (attr);
698
699 xops[0] = GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (attr_args)));
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:
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 }
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
bpf_print_operand(FILE * file,rtx op,int code ATTRIBUTE_UNUSED)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
bpf_print_operand_address(FILE * file,rtx addr)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
def_builtin(const char * name,enum bpf_builtins code,tree type)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
bpf_init_builtins(void)807 bpf_init_builtins (void)
808 {
809 tree ullt = long_long_unsigned_type_node;
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
bpf_expand_builtin(tree exp,rtx target ATTRIBUTE_UNUSED,rtx subtarget ATTRIBUTE_UNUSED,machine_mode mode ATTRIBUTE_UNUSED,int ignore ATTRIBUTE_UNUSED)828 bpf_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
829 rtx subtarget ATTRIBUTE_UNUSED,
830 machine_mode mode ATTRIBUTE_UNUSED,
831 int ignore ATTRIBUTE_UNUSED)
832 {
833 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
834 int code = DECL_MD_FUNCTION_CODE (fndecl);
835
836 if (code == BPF_BUILTIN_LOAD_BYTE
837 || code == BPF_BUILTIN_LOAD_HALF
838 || code == BPF_BUILTIN_LOAD_WORD)
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
bpf_init_libfuncs(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
bpf_debug_unwind_info()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"
933