1 /* Subroutines used for code generation for eBPF.
2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
4 This file is part of GCC.
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)
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.
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/>. */
20 #define IN_TARGET_CODE 1
24 #include "coretypes.h"
28 #include "insn-config.h"
29 #include "insn-attr.h"
34 #include "stringpool.h"
37 #include "stor-layout.h"
46 #include "target-def.h"
47 #include "basic-block.h"
52 #include "c-family/c-common.h"
53 #include "diagnostic.h"
56 #include "langhooks.h"
58 /* Per-function machine data. */
59 struct GTY(()) machine_function
61 /* Number of bytes saved on the stack for local variables. */
64 /* Number of bytes saved on the stack for callee-saved
66 int callee_saved_reg_size
;
69 /* Handle an attribute requiring a FUNCTION_DECL;
70 arguments as in struct attribute_spec.handler. */
73 bpf_handle_fndecl_attribute (tree
*node
, tree name
,
75 int flags ATTRIBUTE_UNUSED
,
78 if (TREE_CODE (*node
) != FUNCTION_DECL
)
80 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
85 if (is_attribute_p ("kernel_helper", name
))
89 tree cst
= TREE_VALUE (args
);
90 if (TREE_CODE (cst
) != INTEGER_CST
)
92 warning (OPT_Wattributes
, "%qE attribute requires an integer argument",
99 warning (OPT_Wattributes
, "%qE requires an argument", name
);
100 *no_add_attrs
= true;
107 /* Target-specific attributes. */
109 static const struct attribute_spec bpf_attribute_table
[] =
111 /* Syntax: { name, min_len, max_len, decl_required, type_required,
112 function_type_required, affects_type_identity, handler,
115 /* Attribute to mark function prototypes as kernel helpers. */
116 { "kernel_helper", 1, 1, true, false, false, false,
117 bpf_handle_fndecl_attribute
, NULL
},
119 /* The last attribute spec is set to be NULL. */
120 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
123 #undef TARGET_ATTRIBUTE_TABLE
124 #define TARGET_ATTRIBUTE_TABLE bpf_attribute_table
126 /* Data structures for the eBPF specific built-ins. */
128 /* Maximum number of arguments taken by a builtin function, plus
130 #define BPF_BUILTIN_MAX_ARGS 5
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
,
142 static GTY (()) tree bpf_builtins
[(int) BPF_BUILTIN_MAX
];
144 /* Initialize the per-function machine status. */
146 static struct machine_function
*
147 bpf_init_machine_status (void)
149 /* Note this initializes all fields to 0, which is just OK for
151 return ggc_cleared_alloc
<machine_function
> ();
154 /* Override options and do some other initialization. */
157 bpf_option_override (void)
159 /* Set the initializer for the per-function status structure. */
160 init_machine_status
= bpf_init_machine_status
;
163 #undef TARGET_OPTION_OVERRIDE
164 #define TARGET_OPTION_OVERRIDE bpf_option_override
166 /* Define target-specific CPP macros. This function in used in the
167 definition of TARGET_CPU_CPP_BUILTINS in bpf.h */
169 #define builtin_define(TXT) cpp_define (pfile, TXT)
172 bpf_target_macros (cpp_reader
*pfile
)
174 builtin_define ("__BPF__");
176 if (TARGET_BIG_ENDIAN
)
177 builtin_define ("__BPF_BIG_ENDIAN__");
179 builtin_define ("__BPF_LITTLE_ENDIAN__");
181 /* Define BPF_KERNEL_VERSION_CODE */
183 const char *version_code
;
184 char *kernel_version_code
;
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;
216 kernel_version_code
= ACONCAT (("__BPF_KERNEL_VERSION_CODE__=",
217 version_code
, NULL
));
218 builtin_define (kernel_version_code
);
222 /* Output assembly directives to switch to section NAME. The section
223 should have attributes as specified by FLAGS, which is a bit mask
224 of the 'SECTION_*' flags defined in 'output.h'. If DECL is
225 non-NULL, it is the 'VAR_DECL' or 'FUNCTION_DECL' with which this
226 section is associated. */
229 bpf_asm_named_section (const char *name
,
230 unsigned int flags ATTRIBUTE_UNUSED
,
231 tree decl ATTRIBUTE_UNUSED
)
233 fprintf (asm_out_file
, "\t.section\t%s\n", name
);
236 #undef TARGET_ASM_NAMED_SECTION
237 #define TARGET_ASM_NAMED_SECTION bpf_asm_named_section
239 /* Return an RTX representing the place where a function returns or
240 receives a value of data type RET_TYPE, a tree node representing a
244 bpf_function_value (const_tree ret_type
,
245 const_tree fntype_or_decl
,
246 bool outgoing ATTRIBUTE_UNUSED
)
248 enum machine_mode mode
;
251 mode
= TYPE_MODE (ret_type
);
252 if (INTEGRAL_TYPE_P (ret_type
))
253 mode
= promote_function_mode (ret_type
, mode
, &unsignedp
,
256 return gen_rtx_REG (mode
, BPF_R0
);
259 #undef TARGET_FUNCTION_VALUE
260 #define TARGET_FUNCTION_VALUE bpf_function_value
262 /* Return true if REGNO is the number of a hard register in which the
263 values of called function may come back. */
266 bpf_function_value_regno_p (const unsigned int regno
)
268 return (regno
== BPF_R0
);
271 #undef TARGET_FUNCTION_VALUE_REGNO_P
272 #define TARGET_FUNCTION_VALUE_REGNO_P bpf_function_value_regno_p
274 /* Compute the size of the function's stack frame, including the local
275 area and the register-save area. */
278 bpf_compute_frame_layout (void)
280 int stack_alignment
= STACK_BOUNDARY
/ BITS_PER_UNIT
;
281 int padding_locals
, regno
;
283 /* Set the space used in the stack by local variables. This is
284 rounded up to respect the minimum stack alignment. */
285 cfun
->machine
->local_vars_size
= get_frame_size ();
287 padding_locals
= cfun
->machine
->local_vars_size
% stack_alignment
;
289 padding_locals
= stack_alignment
- padding_locals
;
291 cfun
->machine
->local_vars_size
+= padding_locals
;
295 /* Set the space used in the stack by callee-saved used
296 registers in the current function. There is no need to round
297 up, since the registers are all 8 bytes wide. */
298 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
299 if ((df_regs_ever_live_p (regno
)
300 && !call_used_or_fixed_reg_p (regno
))
301 || (cfun
->calls_alloca
302 && regno
== STACK_POINTER_REGNUM
))
303 cfun
->machine
->callee_saved_reg_size
+= 8;
306 /* Check that the total size of the frame doesn't exceed the limit
308 if ((cfun
->machine
->local_vars_size
309 + cfun
->machine
->callee_saved_reg_size
) > bpf_frame_limit
)
311 static int stack_limit_exceeded
= 0;
313 if (!stack_limit_exceeded
)
314 error ("eBPF stack limit exceeded");
315 stack_limit_exceeded
= 1;
319 #undef TARGET_COMPUTE_FRAME_LAYOUT
320 #define TARGET_COMPUTE_FRAME_LAYOUT bpf_compute_frame_layout
322 /* Expand to the instructions in a function prologue. This function
323 is called when expanding the 'prologue' pattern in bpf.md. */
326 bpf_expand_prologue (void)
331 size
= (cfun
->machine
->local_vars_size
332 + cfun
->machine
->callee_saved_reg_size
);
334 /* The BPF "hardware" provides a fresh new set of registers for each
335 called function, some of which are initialized to the values of
336 the arguments passed in the first five registers. In doing so,
337 it saves the values of the registers of the caller, and restored
338 them upon returning. Therefore, there is no need to save the
339 callee-saved registers here. What is worse, the kernel
340 implementation refuses to run programs in which registers are
341 referred before being initialized. */
345 int fp_offset
= -cfun
->machine
->local_vars_size
;
347 /* Save callee-saved hard registes. The register-save-area
348 starts right after the local variables. */
349 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
351 if ((df_regs_ever_live_p (regno
)
352 && !call_used_or_fixed_reg_p (regno
))
353 || (cfun
->calls_alloca
354 && regno
== STACK_POINTER_REGNUM
))
358 if (!IN_RANGE (fp_offset
, -1 - 0x7fff, 0x7fff))
359 /* This has been already reported as an error in
360 bpf_compute_frame_layout. */
364 mem
= gen_frame_mem (DImode
,
365 plus_constant (DImode
,
366 hard_frame_pointer_rtx
,
368 insn
= emit_move_insn (mem
, gen_rtx_REG (DImode
, regno
));
369 RTX_FRAME_RELATED_P (insn
) = 1;
376 /* Set the stack pointer, if the function allocates space
377 dynamically. Note that the value of %sp should be directly
378 derived from %fp, for the kernel verifier to track it as a stack
380 if (cfun
->calls_alloca
)
382 insn
= emit_move_insn (stack_pointer_rtx
,
383 hard_frame_pointer_rtx
);
384 RTX_FRAME_RELATED_P (insn
) = 1;
388 insn
= emit_insn (gen_rtx_SET (stack_pointer_rtx
,
392 RTX_FRAME_RELATED_P (insn
) = 1;
397 /* Expand to the instructions in a function epilogue. This function
398 is called when expanding the 'epilogue' pattern in bpf.md. */
401 bpf_expand_epilogue (void)
403 /* See note in bpf_expand_prologue for an explanation on why we are
404 not restoring callee-saved registers in BPF. */
409 int fp_offset
= -cfun
->machine
->local_vars_size
;
411 /* Restore callee-saved hard registes from the stack. */
412 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
414 if ((df_regs_ever_live_p (regno
)
415 && !call_used_or_fixed_reg_p (regno
))
416 || (cfun
->calls_alloca
417 && regno
== STACK_POINTER_REGNUM
))
421 if (!IN_RANGE (fp_offset
, -1 - 0x7fff, 0x7fff))
422 /* This has been already reported as an error in
423 bpf_compute_frame_layout. */
427 mem
= gen_frame_mem (DImode
,
428 plus_constant (DImode
,
429 hard_frame_pointer_rtx
,
431 insn
= emit_move_insn (gen_rtx_REG (DImode
, regno
), mem
);
432 RTX_FRAME_RELATED_P (insn
) = 1;
439 emit_jump_insn (gen_exit ());
442 /* Return the initial difference between the specified pair of
443 registers. The registers that can figure in FROM, and TO, are
444 specified by ELIMINABLE_REGS in bpf.h.
446 This function is used in the definition of
447 INITIAL_ELIMINATION_OFFSET in bpf.h */
450 bpf_initial_elimination_offset (int from
, int to
)
454 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
455 ret
= (cfun
->machine
->local_vars_size
456 + cfun
->machine
->callee_saved_reg_size
);
457 else if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
465 /* Return the number of consecutive hard registers, starting at
466 register number REGNO, required to hold a value of mode MODE. */
469 bpf_hard_regno_nregs (unsigned int regno ATTRIBUTE_UNUSED
,
470 enum machine_mode mode
)
472 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
475 #undef TARGET_HARD_REGNO_NREGS
476 #define TARGET_HARD_REGNO_NREGS bpf_hard_regno_nregs
478 /* Return true if it is permissible to store a value of mode MODE in
479 hard register number REGNO, or in several registers starting with
483 bpf_hard_regno_mode_ok (unsigned int regno ATTRIBUTE_UNUSED
,
484 enum machine_mode mode
)
501 #undef TARGET_HARD_REGNO_MODE_OK
502 #define TARGET_HARD_REGNO_MODE_OK bpf_hard_regno_mode_ok
504 /* Return true if a function must have and use a frame pointer. */
507 bpf_frame_pointer_required (void)
509 /* We do not have a stack pointer, so we absolutely depend on the
510 frame-pointer in order to access the stack... and fishes walk and
515 #undef TARGET_FRAME_POINTER_REQUIRED
516 #define TARGET_FRAME_POINTER_REQUIRED bpf_frame_pointer_required
518 /* Return `true' if the given RTX X is a valid base for an indirect
519 memory access. STRICT has the same meaning than in
520 bpf_legitimate_address_p. */
523 bpf_address_base_p (rtx x
, bool strict
)
525 return (GET_CODE (x
) == REG
527 || (!strict
&& REGNO (x
) >= FIRST_PSEUDO_REGISTER
)));
530 /* Return true if X (a RTX) is a legitimate memory address on the
531 target machine for a memory operand of mode MODE. */
534 bpf_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED
,
538 switch (GET_CODE (x
))
541 return bpf_address_base_p (x
, strict
);
545 /* Accept (PLUS ADDR_BASE CONST_INT), provided CONST_INT fits
548 Note that LABEL_REF and SYMBOL_REF are not allowed in
549 REG+IMM addresses, because it is almost certain they will
550 overload the offset field. */
552 rtx x0
= XEXP (x
, 0);
553 rtx x1
= XEXP (x
, 1);
555 if (bpf_address_base_p (x0
, strict
) && GET_CODE (x1
) == CONST_INT
)
556 return IN_RANGE (INTVAL (x1
), -1 - 0x7fff, 0x7fff);
567 #undef TARGET_LEGITIMATE_ADDRESS_P
568 #define TARGET_LEGITIMATE_ADDRESS_P bpf_legitimate_address_p
570 /* Describe the relative costs of RTL expressions. Return true when
571 all subexpressions of X have been processed, and false when
572 `rtx_cost' should recurse. */
575 bpf_rtx_costs (rtx x ATTRIBUTE_UNUSED
,
576 enum machine_mode mode ATTRIBUTE_UNUSED
,
577 int outer_code ATTRIBUTE_UNUSED
,
578 int opno ATTRIBUTE_UNUSED
,
579 int *total ATTRIBUTE_UNUSED
,
580 bool speed ATTRIBUTE_UNUSED
)
586 #undef TARGET_RTX_COSTS
587 #define TARGET_RTX_COSTS bpf_rtx_costs
589 /* Return true if an argument at the position indicated by CUM should
590 be passed by reference. If the hook returns true, a copy of that
591 argument is made in memory and a pointer to the argument is passed
592 instead of the argument itself. */
595 bpf_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED
,
596 const function_arg_info
&arg
)
598 unsigned num_bytes
= arg
.type_size_in_bytes ();
600 /* Pass aggregates and values bigger than 5 words by reference.
601 Everything else is passed by copy. */
602 return (arg
.aggregate_type_p () || (num_bytes
> 8*5));
605 #undef TARGET_PASS_BY_REFERENCE
606 #define TARGET_PASS_BY_REFERENCE bpf_pass_by_reference
608 /* Return a RTX indicating whether a function argument is passed in a
609 register and if so, which register. */
612 bpf_function_arg (cumulative_args_t ca
, const function_arg_info
&arg
)
614 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
617 return gen_rtx_REG (arg
.mode
, *cum
+ 1);
619 /* An error will be emitted for this in
620 bpf_function_arg_advance. */
624 #undef TARGET_FUNCTION_ARG
625 #define TARGET_FUNCTION_ARG bpf_function_arg
627 /* Update the summarizer variable pointed by CA to advance past an
628 argument in the argument list. */
631 bpf_function_arg_advance (cumulative_args_t ca
,
632 const function_arg_info
&arg
)
634 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
635 unsigned num_bytes
= arg
.type_size_in_bytes ();
636 unsigned num_words
= CEIL (num_bytes
, UNITS_PER_WORD
);
638 if (*cum
<= 5 && *cum
+ num_words
> 5)
639 error ("too many function arguments for eBPF");
644 #undef TARGET_FUNCTION_ARG_ADVANCE
645 #define TARGET_FUNCTION_ARG_ADVANCE bpf_function_arg_advance
647 /* Output the assembly code for a constructor. Since eBPF doesn't
648 support indirect calls, constructors are not supported. */
651 bpf_output_constructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
653 tree decl
= SYMBOL_REF_DECL (symbol
);
656 sorry_at (DECL_SOURCE_LOCATION (decl
),
659 sorry ("no constructors");
662 #undef TARGET_ASM_CONSTRUCTOR
663 #define TARGET_ASM_CONSTRUCTOR bpf_output_constructor
665 /* Output the assembly code for a destructor. Since eBPF doesn't
666 support indirect calls, destructors are not supported. */
669 bpf_output_destructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
671 tree decl
= SYMBOL_REF_DECL (symbol
);
674 sorry_at (DECL_SOURCE_LOCATION (decl
),
677 sorry ("no destructors");
680 #undef TARGET_ASM_DESTRUCTOR
681 #define TARGET_ASM_DESTRUCTOR bpf_output_destructor
683 /* Return the appropriate instruction to CALL to a function. TARGET
684 is an RTX denoting the address of the called function.
686 The main purposes of this function are:
687 - To reject indirect CALL instructions, which are not supported by
689 - To recognize calls to kernel helper functions and emit the
690 corresponding CALL N instruction.
692 This function is called from the expansion of the 'call' pattern in
696 bpf_output_call (rtx target
)
700 switch (GET_CODE (target
))
703 output_asm_insn ("call\t%0", &target
);
707 tree decl
= SYMBOL_REF_DECL (target
);
711 && (attr
= lookup_attribute ("kernel_helper",
712 DECL_ATTRIBUTES (decl
))))
714 tree attr_args
= TREE_VALUE (attr
);
716 xops
[0] = GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (attr_args
)));
717 output_asm_insn ("call\t%0", xops
);
720 output_asm_insn ("call\t%0", &target
);
725 error ("indirect call in function, which are not supported by eBPF");
726 output_asm_insn ("call 0", NULL
);
733 /* Print an instruction operand. This function is called in the macro
734 PRINT_OPERAND defined in bpf.h */
737 bpf_print_operand (FILE *file
, rtx op
, int code ATTRIBUTE_UNUSED
)
739 switch (GET_CODE (op
))
742 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
745 output_address (GET_MODE (op
), XEXP (op
, 0));
748 if (CONST_DOUBLE_HIGH (op
))
749 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
750 CONST_DOUBLE_HIGH (op
), CONST_DOUBLE_LOW (op
));
751 else if (CONST_DOUBLE_LOW (op
) < 0)
752 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (op
));
754 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (op
));
757 output_addr_const (file
, op
);
761 /* Print an operand which is an address. This function should handle
762 any legit address, as accepted by bpf_legitimate_address_p, and
763 also addresses that are valid in CALL instructions.
765 This function is called in the PRINT_OPERAND_ADDRESS macro defined
769 bpf_print_operand_address (FILE *file
, rtx addr
)
771 switch (GET_CODE (addr
))
774 fprintf (file
, "[%s+0]", reg_names
[REGNO (addr
)]);
778 rtx op0
= XEXP (addr
, 0);
779 rtx op1
= XEXP (addr
, 1);
781 if (GET_CODE (op0
) == REG
&& GET_CODE (op1
) == CONST_INT
)
783 fprintf (file
, "[%s+", reg_names
[REGNO (op0
)]);
784 output_addr_const (file
, op1
);
788 fatal_insn ("invalid address in operand", addr
);
795 fatal_insn ("unsupported operand", addr
);
798 output_addr_const (file
, addr
);
803 /* Add a BPF builtin function with NAME, CODE and TYPE. Return
804 the function decl or NULL_TREE if the builtin was not added. */
807 def_builtin (const char *name
, enum bpf_builtins code
, tree type
)
810 = add_builtin_function (name
, type
, code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
812 bpf_builtins
[code
] = t
;
816 /* Define machine-specific built-in functions. */
819 bpf_init_builtins (void)
821 tree ullt
= long_long_unsigned_type_node
;
823 /* Built-ins for BPF_LD_ABS and BPF_LD_IND instructions. */
825 def_builtin ("__builtin_bpf_load_byte", BPF_BUILTIN_LOAD_BYTE
,
826 build_function_type_list (ullt
, ullt
, 0));
827 def_builtin ("__builtin_bpf_load_half", BPF_BUILTIN_LOAD_HALF
,
828 build_function_type_list (ullt
, ullt
, 0));
829 def_builtin ("__builtin_bpf_load_word", BPF_BUILTIN_LOAD_WORD
,
830 build_function_type_list (ullt
, ullt
, 0));
833 #undef TARGET_INIT_BUILTINS
834 #define TARGET_INIT_BUILTINS bpf_init_builtins
836 /* Expand a call to a BPF-specific built-in function that was set up
837 with bpf_init_builtins. */
840 bpf_expand_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
841 rtx subtarget ATTRIBUTE_UNUSED
,
842 machine_mode mode ATTRIBUTE_UNUSED
,
843 int ignore ATTRIBUTE_UNUSED
)
845 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
846 int code
= DECL_MD_FUNCTION_CODE (fndecl
);
848 if (code
== BPF_BUILTIN_LOAD_BYTE
849 || code
== BPF_BUILTIN_LOAD_HALF
850 || code
== BPF_BUILTIN_LOAD_WORD
)
852 /* Expand an indirect load from the sk_buff in the context.
853 There is just one argument to the builtin, which is the
856 We try first to expand a ldabs* instruction. In case this
857 fails, we try a ldind* instruction. */
859 enum insn_code abs_icode
860 = (code
== BPF_BUILTIN_LOAD_BYTE
? CODE_FOR_ldabsb
861 : code
== BPF_BUILTIN_LOAD_HALF
? CODE_FOR_ldabsh
864 enum insn_code ind_icode
865 = (code
== BPF_BUILTIN_LOAD_BYTE
? CODE_FOR_ldindb
866 : code
== BPF_BUILTIN_LOAD_HALF
? CODE_FOR_ldindh
869 tree offset_arg
= CALL_EXPR_ARG (exp
, 0);
870 struct expand_operand ops
[2];
872 create_input_operand (&ops
[0], expand_normal (offset_arg
),
873 TYPE_MODE (TREE_TYPE (offset_arg
)));
874 create_input_operand (&ops
[1], const0_rtx
, SImode
);
876 if (!maybe_expand_insn (abs_icode
, 2, ops
)
877 && !maybe_expand_insn (ind_icode
, 2, ops
))
879 error ("invalid argument to built-in function");
880 return gen_rtx_REG (ops
[0].mode
, BPF_R0
);
883 /* The result of the load is in R0. */
884 return gen_rtx_REG (ops
[0].mode
, BPF_R0
);
890 #undef TARGET_EXPAND_BUILTIN
891 #define TARGET_EXPAND_BUILTIN bpf_expand_builtin
893 /* Initialize target-specific function library calls. This is mainly
894 used to call library-provided soft-fp operations, since eBPF
895 doesn't support floating-point in "hardware". */
898 bpf_init_libfuncs (void)
900 set_conv_libfunc (sext_optab
, DFmode
, SFmode
,
901 "__bpf_extendsfdf2");
902 set_conv_libfunc (trunc_optab
, SFmode
, DFmode
,
904 set_conv_libfunc (sfix_optab
, SImode
, DFmode
,
905 "__bpf_fix_truncdfsi");
906 set_conv_libfunc (sfloat_optab
, DFmode
, SImode
,
908 set_conv_libfunc (ufloat_optab
, DFmode
, SImode
,
909 "__bpf_floatunsidf");
912 #undef TARGET_INIT_LIBFUNCS
913 #define TARGET_INIT_LIBFUNCS bpf_init_libfuncs
915 /* Define the mechanism that will be used for describing frame unwind
916 information to the debugger. In eBPF it is not possible to unwind
919 static enum unwind_info_type
920 bpf_debug_unwind_info ()
925 #undef TARGET_DEBUG_UNWIND_INFO
926 #define TARGET_DEBUG_UNWIND_INFO bpf_debug_unwind_info
928 /* Output assembly directives to assemble data of various sized and
931 #undef TARGET_ASM_BYTE_OP
932 #define TARGET_ASM_BYTE_OP "\t.byte\t"
933 #undef TARGET_ASM_ALIGNED_HI_OP
934 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
935 #undef TARGET_ASM_ALIGNED_SI_OP
936 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
937 #undef TARGET_ASM_ALIGNED_DI_OP
938 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
940 /* Finally, build the GCC target. */
942 struct gcc_target targetm
= TARGET_INITIALIZER
;