1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
|
/* Definition of the eBPF target for GCC.
Copyright (C) 2019-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_BPF_H
#define GCC_BPF_H
/**** Controlling the Compilation Driver. */
#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL} %{mxbpf:-mxbpf} " \
"%{masm=normal:-mdialect=normal} " \
"%{masm=pseudoc:-mdialect=pseudoc} " \
"%{!masm=normal:%{!masm=pseudoc:-mdialect=pseudoc}}"
#define LINK_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL}"
#define LIB_SPEC ""
#define STARTFILE_SPEC ""
/**** Run-time Target Specification. */
#define TARGET_CPU_CPP_BUILTINS() bpf_target_macros (pfile)
/**** Storage Layout. */
/* Endianness and word size. */
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN)
#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN)
#define BITS_PER_WORD 64
#define UNITS_PER_WORD 8
/* When storing an integer whose size is less than 64-bit in a
register, promote it to a DImode. */
#define PROMOTE_MODE(M, UNSIGNEDP, TYPE) \
do \
{ \
if (GET_MODE_CLASS (M) == MODE_INT \
&& GET_MODE_SIZE (M) < 8) \
M = DImode; \
} while (0)
/* Align argument parameters on the stack to 64-bit, at a minimum. */
#define PARM_BOUNDARY 64
/* The hardware enforces that the stack pointer should be aligned to
64-bit at any time. */
#define STACK_BOUNDARY 64
/* Function entry points are aligned to 64 bits. */
#define FUNCTION_BOUNDARY 64
/* Maximum alignment required by data of any type. */
#define BIGGEST_ALIGNMENT 64
/* The best alignment to use in cases where we have a choice. */
#define FASTEST_ALIGNMENT 64
/* Use a fast alignment when storing arrays of chars in a local. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
(TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
/* The load and store instructions won't work if the data is not in
it's expected alignment. */
#define STRICT_ALIGNMENT 1
/* We use Pmode as the mode of the size increment operand in an
`allocate_stack' pattern. */
#define STACK_SIZE_MODE Pmode
/**** Layout of Source Language Data Types. */
#define INT_TYPE_SIZE 32
#define SHORT_TYPE_SIZE 16
#define LONG_TYPE_SIZE 64
#define LONG_LONG_TYPE_SIZE 64
#define CHAR_TYPE_SIZE 8
#define INTPTR_TYPE "long int"
#define UINTPTR_TYPE "long unsigned int"
#define SIZE_TYPE "long unsigned int"
#define PTRDIFF_TYPE "long int"
#define SIG_ATOMIC_TYPE "char"
#define INT8_TYPE "signed char"
#define INT16_TYPE "short int"
#define INT32_TYPE "int"
#define INT64_TYPE "long int"
#define UINT8_TYPE "unsigned char"
#define UINT16_TYPE "short unsigned int"
#define UINT32_TYPE "unsigned int"
#define UINT64_TYPE "long unsigned int"
#define INT_LEAST8_TYPE INT8_TYPE
#define INT_LEAST16_TYPE INT16_TYPE
#define INT_LEAST32_TYPE INT32_TYPE
#define INT_LEAST64_TYPE INT64_TYPE
#define UINT_LEAST8_TYPE UINT8_TYPE
#define UINT_LEAST16_TYPE UINT16_TYPE
#define UINT_LEAST32_TYPE UINT32_TYPE
#define UINT_LEAST64_TYPE UINT64_TYPE
#define INT_FAST8_TYPE INT8_TYPE
#define INT_FAST16_TYPE INT16_TYPE
#define INT_FAST32_TYPE INT32_TYPE
#define INT_FAST64_TYPE INT64_TYPE
#define UINT_FAST8_TYPE UINT8_TYPE
#define UINT_FAST16_TYPE UINT16_TYPE
#define UINT_FAST32_TYPE UINT32_TYPE
#define UINT_FAST64_TYPE UINT64_TYPE
/* `char' is signed by default, like in x86. */
#define DEFAULT_SIGNED_CHAR 1
/* `wchar_t' is a signed 32-bit type. The second constant is used by
cpp, which can't use WCHAR_TYPE. */
#define WCHAR_TYPE "int"
#define WCHAR_TYPE_SIZE 32
/* `wint_t' is a signed 32-bit type. */
#define WINT_TYPE "int"
#define WINT_TYPE_SIZE 32
/**** Register Usage. */
/*** Basic Characteristics of Registers. */
#define BPF_R0 0
#define BPF_R1 1
#define BPF_R2 2
#define BPF_R3 3
#define BPF_R4 4
#define BPF_R5 5
#define BPF_R6 6
#define BPF_CTX BPF_R6
#define BPF_R7 7
#define BPF_R8 8
#define BPF_R9 9
#define BPF_R10 10
#define BPF_FP BPF_R10
#define BPF_R11 11
#define BPF_R12 12
#define BPF_SP BPF_R12
/* 11 is not a real eBPF hard register and is eliminated or not used
in the final assembler. See below. */
#define FIRST_PSEUDO_REGISTER 13
/* The registers %r0..%r8 are available for general allocation.
%r10 is the stack frame, which is read-only.
%r11 (__arg__) is a fake register that always gets eliminated.
%r12 is the pseudo-stack pointer that always gets eliminated. */
#define FIXED_REGISTERS \
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1}
/* %r0..%r5 are clobbered by function calls. */
#define CALL_USED_REGISTERS \
{1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
/**** Register Classes. */
enum reg_class
{
NO_REGS, /* no registers in set. */
R0, /* register r0. */
ALL_REGS, /* all registers. */
LIM_REG_CLASSES /* max value + 1. */
};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
#define GENERAL_REGS ALL_REGS
/* An initializer containing the names of the register classes as C
string constants. These names are used in writing some of the
debugging dumps. */
#define REG_CLASS_NAMES \
{ \
"NO_REGS", \
"R0", \
"ALL_REGS" \
}
/* An initializer containing the contents of the register classes, as
integers which are bit masks. The Nth integer specifies the
contents of class N. The way the integer MASK is interpreted is
that register R is in the class if `MASK & (1 << R)' is 1.
In eBPF all the hard registers are considered general-purpose
integer registers. */
#define REG_CLASS_CONTENTS \
{ \
0x00000000, /* NO_REGS */ \
0x00000001, /* R0 */ \
0x00001fff, /* ALL_REGS */ \
}
/* A C expression whose value is a register class containing hard
register REGNO. In general there is more that one such class;
choose a class which is "minimal", meaning that no smaller class
also contains the register. */
#define REGNO_REG_CLASS(REGNO) \
((REGNO) == 0 ? R0 : GENERAL_REGS)
/* A macro whose definition is the name of the class to which a
valid base register must belong. A base register is one used in
an address which is the register value plus a displacement. */
#define BASE_REG_CLASS GENERAL_REGS
/* A macro whose definition is the name of the class to which a
valid index register must belong. An index register is one used
in an address where its value is either multiplied by a scale
factor or added to another register (as well as added to a
displacement). */
#define INDEX_REG_CLASS NO_REGS
/* C expression which is nonzero if register number REGNO is suitable
for use as a base register in operand addresses. In eBPF every
hard register can be used for this purpose. */
#define REGNO_OK_FOR_BASE_P(REGNO) \
((REGNO) < FIRST_PSEUDO_REGISTER)
/* C expression which is nonzero if register number REGNO is suitable
for use as an index register in operand addresses. */
#define REGNO_OK_FOR_INDEX_P(REGNO) false
/**** Debugging Info ****/
/* Use BTF debug info by default. */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE BTF_DEBUG
/* In eBPF it is not possible to unwind frames. Disable CFA. */
#define DWARF2_FRAME_INFO 0
/**** Stack Layout and Calling Conventions. */
/*** Basic Stack Layout. */
#define STACK_GROWS_DOWNWARD 1
#define FRAME_GROWS_DOWNWARD 1
/* The argument pointer always points to the first argument. */
#define FIRST_PARM_OFFSET(FNDECL) 0
/* Unsupported. */
#define RETURN_ADDR_RTX(count, frame) const0_rtx
/*** Registers That Address the Stack Frame. */
#define FRAME_POINTER_REGNUM 10
#define ARG_POINTER_REGNUM 11
#define STACK_POINTER_REGNUM 12
#define STATIC_CHAIN_REGNUM 8
/*** Registers elimination. */
#define ELIMINABLE_REGS \
{{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \
{ STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM }}
/* Define the offset between two registers, one to be eliminated, and
the other its replacement, at the start of a routine. */
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
do \
{ \
(OFFSET) = bpf_initial_elimination_offset ((FROM), (TO)); \
} while (0)
/*** Passing Function Arguments on the Stack. */
/* The eBPF ABI doesn't support passing arguments on the stack. Only
in the first five registers. Code in bpf.cc assures the stack is
never used when passing arguments. However, we still have to
define the constants below. */
/* If nonzero, function arguments will be evaluated from last to
first, rather than from first to last. */
#define PUSH_ARGS_REVERSED 1
/* Allocate stack space for arguments at the beginning of each
function. */
#define ACCUMULATE_OUTGOING_ARGS 1
/*** Passing Arguments in Registers. */
/* Use an integer in order to keep track of the number of arguments
passed to a function in integer registers, up to
MAX_ARGS_IN_REGISTERS. */
#define CUMULATIVE_ARGS int
/* INIT_CUMULATIVE_ARGS initializes a variable CUM of type
CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \
memset (&(CUM), 0, sizeof (CUM))
/* Nonzero if N is the number of a hard register in which function
arguments are sometimes passed. */
#define FUNCTION_ARG_REGNO_P(N) ((N) >= 1 && (N) <= 5)
/*** How Scalar Function Values are Returned. */
/* Define how to find the value returned by a library function
assuming the value has mode MODE. This is always %r0 for eBPF. */
#define LIBCALL_VALUE(MODE) \
gen_rtx_REG ((MODE), 0)
/*** Generating Code for Profiling. */
/* We do not support profiling yet, so do not call `mcount'. */
#define FUNCTION_PROFILER(FILE, LABELNO) do { } while (0)
/*** Function Entry and Exit. */
/* We do not require an accurate stack pointer at function return.
This is because the stack pointer's original value is initialized
from the frame pointer, rather than decreased, to satisfy the
kernel's verifier. Thus, we have to save the stack pointer in
function prologue and restore it in function epilogue. If
EXIT_IGNORE_STACK is not set, then superfluous instructions are
generated to save and restore the stack pointer after and before
the function epilogue, respectively. */
#define EXIT_IGNORE_STACK 1
/**** Support for Nested Functions. */
/* We have to define TRAMPOLINE_SIZE even if we don't ever generate
them. Set to 64 arbitrarily. */
#define TRAMPOLINE_SIZE 64
/**** Addressing Modes. */
/* Maximum number of registers that can appear in a valid memory
address. */
#define MAX_REGS_PER_ADDRESS 1
/* 1 if X is an rtx for a constant that is a valid address. */
#define CONSTANT_ADDRESS_P(X) 0
/**** Describing Relative Costs of Operations. */
/* Cost of a branch instruction. A value of 1 is the default. */
#define BRANCH_COST(SPEED_P,PREDICTABLE_P) 1
/* The SPARC port says: Nonzero if access to memory by bytes is slow
and undesirable. For RISC chips, it means that access to memory by
bytes is no better than access by words when possible, so grab a
whole word and maybe make use of that. */
#define SLOW_BYTE_ACCESS 1
/* Threshold of number of scalar memory-to-memory move instructions,
_below_ which a sequence of insns should be generated instead of a
string move insn or a library call. */
#define MOVE_RATIO(speed) 128
/* Threshold of number of scalar move instructions, _below_ which a
sequence of insns should be generated to clear memory instead of a
string clear insn or a library call. */
#define CLEAR_RATIO(speed) 128
/* Threshold of number of scalar move instructions, _below_ which a
sequence of insns should be generated to set memory to a constant
value, instead of a block set insn or a library call. */
#define SET_RATIO(speed) 128
/* True if it is as good or better to call a constant function address
than to call an address kept in a register. */
#define NO_FUNCTION_CSE 1
/**** Dividing the Output into Sections. */
#define TEXT_SECTION_ASM_OP "\t.text"
#define DATA_SECTION_ASM_OP "\t.data"
#define BSS_SECTION_ASM_OP "\t.bss"
/**** Defining the Output Assembler Language. */
/*** The Overall Framework of an Assembler File. */
#define ASM_COMMENT_START "#"
/* Output to assembler file text saying following lines
may contain character constants, extra white space, comments, etc. */
#ifndef ASM_APP_ON
#define ASM_APP_ON " #APP\n"
#endif
/* Output to assembler file text saying following lines
no longer contain unusual constructs. */
#ifndef ASM_APP_OFF
#define ASM_APP_OFF " #NO_APP\n"
#endif
/*** Output of Data. */
/*** Output of Uninitialized Variables. */
/* A C statement (sans semicolon) to output to the stdio stream
FILE the assembler definition of uninitialized global DECL named
NAME whose size is SIZE bytes and alignment is ALIGN bytes.
Try to use asm_output_aligned_bss to implement this macro. */
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do \
{ \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
fprintf ((FILE), "%s", "\t.lcomm\t"); \
assemble_name ((FILE), (NAME)); \
fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", \
(SIZE), (ALIGN) / BITS_PER_UNIT); \
} \
while (0)
/*** Output and Generation of Labels. */
/* Globalizing directive for a label. */
#define GLOBAL_ASM_OP "\t.global\t"
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
This is suitable for output with `assemble_name'. */
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM))
/*** Output of Assembler Instructions. */
#define REGISTER_NAMES \
{ "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \
"%r8", "%r9", "%fp", "__arg__", "__sp__" }
#define ADDITIONAL_REGISTER_NAMES \
{ { "%a", 0 }, { "%ctx", 6 }, { "%r10" , 10 } }
#define LOCAL_LABEL_PREFIX "."
#define USER_LABEL_PREFIX ""
#define PRINT_OPERAND(STREAM,X,CODE) \
bpf_print_operand ((STREAM),(X),(CODE))
#define PRINT_OPERAND_ADDRESS(STREAM,X) \
bpf_print_operand_address ((STREAM), (X))
/*** Assembler Commands for Alignment. */
/* This is how to output an assembler line that says to advance the
location counter to a multiple of 2**LOG bytes. */
#define ASM_OUTPUT_ALIGN(STREAM,LOG) \
fprintf (STREAM, "\t.align\t%d\n", (LOG))
/**** Miscellaneous Parameters. */
/* Specify the machine mode that this machine uses for the index in
the tablejump instruction. */
#define CASE_VECTOR_MODE DImode
/* Define if operations between registers with integral mode smaller
than a word are always performed on the entire register. */
#define WORD_REGISTER_OPERATIONS 1
/* C expression indicating when insns that read memory in MEM_MODE, an
integral mode narrower than a word, set the bits outsize of
MEM_MODE to be either the sign-extension or the zero-extension of
the data read. */
#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
/* The maximum number of bytes that a single instruction can move
quickly between memory and registers or between two memory
locations. */
#define MOVE_MAX 8
/* Allow upto 1024 bytes moves to occur using by_pieces
infrastructure. This mimics clang behaviour when using
__builtin_memcmp. */
#define COMPARE_MAX_PIECES 1024
/* An alias for the machine mode for pointers. */
#define Pmode DImode
/* An alias for the machine mode used for memory references to
functions being called, in 'call' RTL expressions. */
#define FUNCTION_MODE Pmode
/* No libm on eBPF (for now.) */
#define MATH_LIBRARY ""
/**** libgcc settings. */
/* Iterating over the global constructors and destructors and
executing them requires the ability of doing indirect calls.
eBPF doesn't support indirect calls, so no chance of supporting
constructors and destructors. */
#define DO_GLOBAL_CTORS_BODY \
do { } while (0)
#define DO_GLOBAL_DTORS_BODY \
do { } while (0)
#define ASSEMBLER_DIALECT ((int) asm_dialect)
#endif /* ! GCC_BPF_H */
|