]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-bpf.c
bpf: gas: support relaxation of V4 jump instructions
[thirdparty/binutils-gdb.git] / gas / config / tc-bpf.c
CommitLineData
f8861f5d 1/* tc-bpf.c -- Assembler for the Linux eBPF.
d87bef3a 2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
f8861f5d
JM
3 Contributed by Oracle, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21
22#include "as.h"
23#include "subsegs.h"
24#include "symcat.h"
d218e7fe 25#include "opcode/bpf.h"
f8861f5d
JM
26#include "elf/common.h"
27#include "elf/bpf.h"
28#include "dwarf2dbg.h"
d218e7fe 29#include "libiberty.h"
ff5a51b3 30#include <ctype.h>
f8861f5d 31
d218e7fe
JM
32/* Data structure representing a parsed BPF instruction. */
33
34struct bpf_insn
35{
c2ca88d7 36 enum bpf_insn_id id;
d218e7fe
JM
37 int size; /* Instruction size in bytes. */
38 bpf_insn_word opcode;
39 uint8_t dst;
40 uint8_t src;
41 expressionS offset16;
42 expressionS imm32;
43 expressionS imm64;
44 expressionS disp16;
45 expressionS disp32;
46
47 unsigned int has_dst : 1;
48 unsigned int has_src : 1;
49 unsigned int has_offset16 : 1;
50 unsigned int has_disp16 : 1;
51 unsigned int has_disp32 : 1;
52 unsigned int has_imm32 : 1;
53 unsigned int has_imm64 : 1;
249d4715
JM
54
55 unsigned int is_relaxable : 1;
56 expressionS *relaxed_exp;
d218e7fe
JM
57};
58
9d1e07bd 59const char comment_chars[] = ";#";
ff5a51b3 60const char line_comment_chars[] = "#";
f8861f5d
JM
61const char line_separator_chars[] = "`";
62const char EXP_CHARS[] = "eE";
63const char FLT_CHARS[] = "fFdD";
64
1802aae8
JM
65/* Like s_lcomm_internal in gas/read.c but the alignment string
66 is allowed to be optional. */
67
68static symbolS *
69pe_lcomm_internal (int needs_align, symbolS *symbolP, addressT size)
70{
71 addressT align = 0;
72
73 SKIP_WHITESPACE ();
74
75 if (needs_align
76 && *input_line_pointer == ',')
77 {
78 align = parse_align (needs_align - 1);
79
80 if (align == (addressT) -1)
81 return NULL;
82 }
83 else
84 {
85 if (size >= 8)
86 align = 3;
87 else if (size >= 4)
88 align = 2;
89 else if (size >= 2)
90 align = 1;
91 else
92 align = 0;
93 }
94
95 bss_alloc (symbolP, size, align);
96 return symbolP;
97}
98
99static void
100pe_lcomm (int needs_align)
101{
102 s_comm_internal (needs_align * 2, pe_lcomm_internal);
103}
104
f8861f5d
JM
105/* The target specific pseudo-ops which we support. */
106const pseudo_typeS md_pseudo_table[] =
107{
e0b989a6
JM
108 { "half", cons, 2 },
109 { "word", cons, 4 },
110 { "dword", cons, 8 },
1802aae8 111 { "lcomm", pe_lcomm, 1 },
d0044bac 112 { NULL, NULL, 0 }
f8861f5d
JM
113};
114
1802aae8
JM
115\f
116
f8861f5d
JM
117/* Command-line options processing. */
118
119enum options
120{
121 OPTION_LITTLE_ENDIAN = OPTION_MD_BASE,
4449c81a 122 OPTION_BIG_ENDIAN,
d218e7fe
JM
123 OPTION_XBPF,
124 OPTION_DIALECT,
125 OPTION_ISA_SPEC,
249d4715 126 OPTION_NO_RELAX,
f8861f5d
JM
127};
128
129struct option md_longopts[] =
130{
131 { "EL", no_argument, NULL, OPTION_LITTLE_ENDIAN },
132 { "EB", no_argument, NULL, OPTION_BIG_ENDIAN },
4449c81a 133 { "mxbpf", no_argument, NULL, OPTION_XBPF },
d218e7fe
JM
134 { "mdialect", required_argument, NULL, OPTION_DIALECT},
135 { "misa-spec", required_argument, NULL, OPTION_ISA_SPEC},
249d4715 136 { "mno-relax", no_argument, NULL, OPTION_NO_RELAX},
f8861f5d
JM
137 { NULL, no_argument, NULL, 0 },
138};
139
140size_t md_longopts_size = sizeof (md_longopts);
141
142const char * md_shortopts = "";
143
d218e7fe
JM
144/* BPF supports little-endian and big-endian variants. The following
145 global records what endianness to use. It can be configured using
146 command-line options. It defaults to the host endianness
147 initialized in md_begin. */
f8861f5d 148
f8861f5d 149static int set_target_endian = 0;
d218e7fe
JM
150extern int target_big_endian;
151
249d4715
JM
152/* Whether to relax branch instructions. Default is yes. Can be
153 changed using the -mno-relax command line option. */
154
155static int do_relax = 1;
156
d218e7fe
JM
157/* The ISA specification can be one of BPF_V1, BPF_V2, BPF_V3, BPF_V4
158 or BPF_XPBF. The ISA spec to use can be configured using
159 command-line options. It defaults to the latest BPF spec. */
160
161static int isa_spec = BPF_V4;
f8861f5d 162
d218e7fe
JM
163/* The assembler supports two different dialects: "normal" syntax and
164 "pseudoc" syntax. The dialect to use can be configured using
165 command-line options. */
4449c81a 166
d218e7fe
JM
167enum target_asm_dialect
168{
169 DIALECT_NORMAL,
170 DIALECT_PSEUDOC
171};
172
173static int asm_dialect = DIALECT_NORMAL;
4449c81a 174
f8861f5d 175int
d218e7fe 176md_parse_option (int c, const char * arg)
f8861f5d
JM
177{
178 switch (c)
179 {
180 case OPTION_BIG_ENDIAN:
181 set_target_endian = 1;
182 target_big_endian = 1;
183 break;
184 case OPTION_LITTLE_ENDIAN:
d218e7fe 185 set_target_endian = 0;
f8861f5d
JM
186 target_big_endian = 0;
187 break;
d218e7fe
JM
188 case OPTION_DIALECT:
189 if (strcmp (arg, "normal") == 0)
190 asm_dialect = DIALECT_NORMAL;
191 else if (strcmp (arg, "pseudoc") == 0)
192 asm_dialect = DIALECT_PSEUDOC;
193 else
194 as_fatal (_("-mdialect=%s is not valid. Expected normal or pseudoc"),
195 arg);
196 break;
197 case OPTION_ISA_SPEC:
198 if (strcmp (arg, "v1") == 0)
199 isa_spec = BPF_V1;
200 else if (strcmp (arg, "v2") == 0)
201 isa_spec = BPF_V2;
202 else if (strcmp (arg, "v3") == 0)
203 isa_spec = BPF_V3;
204 else if (strcmp (arg, "v4") == 0)
205 isa_spec = BPF_V4;
206 else if (strcmp (arg, "xbpf") == 0)
207 isa_spec = BPF_XBPF;
208 else
209 as_fatal (_("-misa-spec=%s is not valid. Expected v1, v2, v3, v4 o xbpf"),
210 arg);
211 break;
4449c81a 212 case OPTION_XBPF:
d218e7fe
JM
213 /* This is an alias for -misa-spec=xbpf. */
214 isa_spec = BPF_XBPF;
4449c81a 215 break;
249d4715
JM
216 case OPTION_NO_RELAX:
217 do_relax = 0;
218 break;
f8861f5d
JM
219 default:
220 return 0;
221 }
222
223 return 1;
224}
225
226void
227md_show_usage (FILE * stream)
228{
229 fprintf (stream, _("\nBPF options:\n"));
230 fprintf (stream, _("\
d218e7fe
JM
231BPF options:\n\
232 -EL generate code for a little endian machine\n\
233 -EB generate code for a big endian machine\n\
234 -mdialect=DIALECT set the assembly dialect (normal, pseudoc)\n\
235 -misa-spec set the BPF ISA spec (v1, v2, v3, v4, xbpf)\n\
236 -mxbpf alias for -misa-spec=xbpf\n"));
f8861f5d
JM
237}
238
239\f
d218e7fe
JM
240/* This function is called once, at assembler startup time. This
241 should set up all the tables, etc that the MD part of the assembler
242 needs. */
ff5a51b3 243
f8861f5d
JM
244void
245md_begin (void)
246{
f8861f5d
JM
247 /* If not specified in the command line, use the host
248 endianness. */
249 if (!set_target_endian)
250 {
251#ifdef WORDS_BIGENDIAN
252 target_big_endian = 1;
253#else
254 target_big_endian = 0;
255#endif
256 }
257
ff5a51b3
GM
258 /* Ensure that lines can begin with '*' in BPF store pseudoc instruction. */
259 lex_type['*'] |= LEX_BEGIN_NAME;
260
f8861f5d
JM
261 /* Set the machine type. */
262 bfd_default_set_arch_mach (stdoutput, bfd_arch_bpf, bfd_mach_bpf);
263}
264
d218e7fe
JM
265/* Round up a section size to the appropriate boundary. */
266
f8861f5d
JM
267valueT
268md_section_align (segT segment, valueT size)
269{
fd361982 270 int align = bfd_section_alignment (segment);
f8861f5d
JM
271
272 return ((size + (1 << align) - 1) & -(1 << align));
273}
274
275\f
276/* Functions concerning relocs. */
277
278/* The location from which a PC relative jump should be calculated,
279 given a PC relative reloc. */
280
281long
282md_pcrel_from_section (fixS *fixP, segT sec)
283{
284 if (fixP->fx_addsy != (symbolS *) NULL
285 && (! S_IS_DEFINED (fixP->fx_addsy)
286 || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
287 || S_IS_EXTERNAL (fixP->fx_addsy)
288 || S_IS_WEAK (fixP->fx_addsy)))
289 {
290 /* The symbol is undefined (or is defined but not in this section).
291 Let the linker figure it out. */
292 return 0;
293 }
294
295 return fixP->fx_where + fixP->fx_frag->fr_address;
296}
297
298/* Write a value out to the object file, using the appropriate endianness. */
299
300void
301md_number_to_chars (char * buf, valueT val, int n)
302{
303 if (target_big_endian)
304 number_to_chars_bigendian (buf, val, n);
305 else
306 number_to_chars_littleendian (buf, val, n);
307}
308
309arelent *
d218e7fe 310tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixP)
f8861f5d 311{
d218e7fe
JM
312 bfd_reloc_code_real_type r_type = fixP->fx_r_type;
313 arelent *reloc;
f8861f5d 314
d218e7fe 315 reloc = XNEW (arelent);
f8861f5d 316
d218e7fe
JM
317 if (fixP->fx_pcrel)
318 {
319 r_type = (r_type == BFD_RELOC_8 ? BFD_RELOC_8_PCREL
320 : r_type == BFD_RELOC_16 ? BFD_RELOC_16_PCREL
321 : r_type == BFD_RELOC_24 ? BFD_RELOC_24_PCREL
322 : r_type == BFD_RELOC_32 ? BFD_RELOC_32_PCREL
323 : r_type == BFD_RELOC_64 ? BFD_RELOC_64_PCREL
324 : r_type);
325 }
326
327 reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
328
329 if (reloc->howto == (reloc_howto_type *) NULL)
f8861f5d 330 {
d218e7fe
JM
331 as_bad_where (fixP->fx_file, fixP->fx_line,
332 _("relocation is not supported"));
333 return NULL;
f8861f5d 334 }
d218e7fe
JM
335
336 //XXX gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
337
338 reloc->sym_ptr_ptr = XNEW (asymbol *);
339 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
340
341 /* Use fx_offset for these cases. */
342 if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
343 || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
344 reloc->addend = fixP->fx_offset;
345 else
346 reloc->addend = fixP->fx_addnumber;
347
348 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
349 return reloc;
f8861f5d 350}
d218e7fe 351
f8861f5d 352\f
249d4715
JM
353/* Relaxations supported by this assembler. */
354
355#define RELAX_BRANCH_ENCODE(uncond, constant, length) \
356 ((relax_substateT) \
357 (0xc0000000 \
358 | ((uncond) ? 1 : 0) \
359 | ((constant) ? 2 : 0) \
360 | ((length) << 2)))
361
362#define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000)
363#define RELAX_BRANCH_LENGTH(i) (((i) >> 2) & 0xff)
364#define RELAX_BRANCH_CONST(i) (((i) & 2) != 0)
365#define RELAX_BRANCH_UNCOND(i) (((i) & 1) != 0)
366
367
368/* Compute the length of a branch seuqence, and adjust the stored
369 length accordingly. If FRAG is NULL, the worst-case length is
370 returned. */
371
372static unsigned
373relaxed_branch_length (fragS *fragp, asection *sec, int update)
374{
375 int length, uncond;
376
377 if (!fragp)
378 return 8 * 3;
379
380 uncond = RELAX_BRANCH_UNCOND (fragp->fr_subtype);
381 length = RELAX_BRANCH_LENGTH (fragp->fr_subtype);
382
383 if (uncond)
384 /* Length is the same for both JA and JAL. */
385 length = 8;
386 else
387 {
388 if (RELAX_BRANCH_CONST (fragp->fr_subtype))
389 {
390 int64_t val = fragp->fr_offset;
391
392 if (val < -32768 || val > 32767)
393 length = 8 * 3;
394 else
395 length = 8;
396 }
397 else if (fragp->fr_symbol != NULL
398 && S_IS_DEFINED (fragp->fr_symbol)
399 && !S_IS_WEAK (fragp->fr_symbol)
400 && sec == S_GET_SEGMENT (fragp->fr_symbol))
401 {
402 offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
403
404 /* Convert to 64-bit words, minus one. */
405 val = (val - 8) / 8;
406
407 /* See if it fits in the signed 16-bits field. */
408 if (val < -32768 || val > 32767)
409 length = 8 * 3;
410 else
411 length = 8;
412 }
413 else
414 /* Use short version, and let the linker relax instead, if
415 appropriate and if supported. */
416 length = 8;
417 }
418
419 if (update)
420 fragp->fr_subtype = RELAX_BRANCH_ENCODE (uncond,
421 RELAX_BRANCH_CONST (fragp->fr_subtype),
422 length);
423
424 return length;
425}
426
427/* Estimate the size of a variant frag before relaxing. */
428
429int
430md_estimate_size_before_relax (fragS *fragp, asection *sec)
431{
432 return (fragp->fr_var = relaxed_branch_length (fragp, sec, true));
433}
434
435/* Read a BPF instruction word from BUF. */
436
437static uint64_t
438read_insn_word (bfd_byte *buf)
439{
440 return bfd_getb64 (buf);
441}
442
443/* Write the given signed 16-bit value in the given BUFFER using the
444 target endianness. */
445
446static void
447encode_int16 (int16_t value, char *buffer)
448{
449 uint16_t val = value;
450
451 if (target_big_endian)
452 {
453 buffer[0] = (val >> 8) & 0xff;
454 buffer[1] = val & 0xff;
455 }
456 else
457 {
458 buffer[1] = (val >> 8) & 0xff;
459 buffer[0] = val & 0xff;
460 }
461}
462
463/* Write the given signed 32-bit value in the given BUFFER using the
464 target endianness. */
465
466static void
467encode_int32 (int32_t value, char *buffer)
468{
469 uint32_t val = value;
470
471 if (target_big_endian)
472 {
473 buffer[0] = (val >> 24) & 0xff;
474 buffer[1] = (val >> 16) & 0xff;
475 buffer[2] = (val >> 8) & 0xff;
476 buffer[3] = val & 0xff;
477 }
478 else
479 {
480 buffer[3] = (val >> 24) & 0xff;
481 buffer[2] = (val >> 16) & 0xff;
482 buffer[1] = (val >> 8) & 0xff;
483 buffer[0] = value & 0xff;
484 }
485}
486
487/* Write a BPF instruction to BUF. */
488
489static void
490write_insn_bytes (bfd_byte *buf, char *bytes)
491{
492 int i;
493
494 for (i = 0; i < 8; ++i)
495 md_number_to_chars ((char *) buf + i, (valueT) bytes[i], 1);
496}
497
f8861f5d
JM
498/* *FRAGP has been relaxed to its final size, and now needs to have
499 the bytes inside it modified to conform to the new size.
500
501 Called after relaxation is finished.
502 fragP->fr_type == rs_machine_dependent.
503 fragP->fr_subtype is the subtype of what the address relaxed to. */
504
505void
506md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
507 segT sec ATTRIBUTE_UNUSED,
249d4715 508 fragS *fragp ATTRIBUTE_UNUSED)
f8861f5d 509{
249d4715
JM
510 bfd_byte *buf = (bfd_byte *) fragp->fr_literal + fragp->fr_fix;
511 expressionS exp;
512 fixS *fixp;
513 bpf_insn_word word;
514 int disp_is_known = 0;
515 int64_t disp_to_target = 0;
f8861f5d 516
249d4715
JM
517 uint64_t code;
518
519 gas_assert (RELAX_BRANCH_P (fragp->fr_subtype));
520
521 /* Expression to be used in any resulting relocation in the relaxed
522 instructions. */
523 exp.X_op = O_symbol;
524 exp.X_add_symbol = fragp->fr_symbol;
525 exp.X_add_number = fragp->fr_offset;
526
527 gas_assert (fragp->fr_var == RELAX_BRANCH_LENGTH (fragp->fr_subtype));
528
529 /* Read an instruction word from the instruction to be relaxed, and
530 get the code. */
531 word = read_insn_word (buf);
532 code = (word >> 60) & 0xf;
533
534 /* Determine whether the 16-bit displacement to the target is known
535 at this point. */
536 if (RELAX_BRANCH_CONST (fragp->fr_subtype))
537 {
538 /* XXX this loses the 32-bit value if the constant was
539 overflown! */
540 disp_to_target = fragp->fr_offset;
541 disp_is_known = 1;
542 }
543 else if (fragp->fr_symbol != NULL
544 && S_IS_DEFINED (fragp->fr_symbol)
545 && !S_IS_WEAK (fragp->fr_symbol)
546 && sec == S_GET_SEGMENT (fragp->fr_symbol))
547 {
548 offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
549 /* Convert to 64-bit blocks minus one. */
550 disp_to_target = (val - 8) / 8;
551 disp_is_known = 1;
552 }
553
554 /* Now relax particular jump instructions. */
555 if (code == BPF_CODE_JA)
556 {
557 /* Unconditional jump.
558 JA d16 -> JAL d32 */
559
560 gas_assert (RELAX_BRANCH_UNCOND (fragp->fr_subtype));
561
562 if (disp_is_known)
563 {
564 if (disp_to_target >= -32768 && disp_to_target <= 32767)
565 {
566 /* 16-bit disp is known and in range. Install a fixup
567 for the disp16 if the branch value is not constant.
568 This will be resolved by the assembler and units
569 converted. */
570
571 if (!RELAX_BRANCH_CONST (fragp->fr_subtype))
572 {
573 /* Install fixup for the JA. */
574 reloc_howto_type *reloc_howto
575 = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
576 if (!reloc_howto)
577 abort();
578
579 fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal,
580 bfd_get_reloc_size (reloc_howto),
581 &exp,
582 reloc_howto->pc_relative,
583 BFD_RELOC_BPF_DISP16);
584 fixp->fx_file = fragp->fr_file;
585 fixp->fx_line = fragp->fr_line;
586 }
587 }
588 else
589 {
590 /* 16-bit disp is known and not in range. Turn the JA
591 into a JAL with a 32-bit displacement. */
592 char bytes[8];
593
594 bytes[0] = ((BPF_CLASS_JMP32|BPF_CODE_JA|BPF_SRC_K) >> 56) & 0xff;
595 bytes[1] = (word >> 48) & 0xff;
596 bytes[2] = 0; /* disp16 high */
597 bytes[3] = 0; /* disp16 lo */
598 encode_int32 ((int32_t) disp_to_target, bytes + 4);
599
600 write_insn_bytes (buf, bytes);
601 }
602 }
603 else
604 {
605 /* The displacement to the target is not known. Do not
606 relax. The linker will maybe do it if it chooses to. */
607
608 reloc_howto_type *reloc_howto = NULL;
609
610 gas_assert (!RELAX_BRANCH_CONST (fragp->fr_subtype));
611
612 /* Install fixup for the JA. */
613 reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
614 if (!reloc_howto)
615 abort ();
616
617 fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal,
618 bfd_get_reloc_size (reloc_howto),
619 &exp,
620 reloc_howto->pc_relative,
621 BFD_RELOC_BPF_DISP16);
622 fixp->fx_file = fragp->fr_file;
623 fixp->fx_line = fragp->fr_line;
624 }
625
626 buf += 8;
627 }
628 else
629 {
630 /* Conditional jump.
631 JXX d16 -> JXX +1; JA +1; JAL d32 */
632
633 gas_assert (!RELAX_BRANCH_UNCOND (fragp->fr_subtype));
634
635 if (disp_is_known)
636 {
637 if (disp_to_target >= -32768 && disp_to_target <= 32767)
638 {
639 /* 16-bit disp is known and in range. Install a fixup
640 for the disp16 if the branch value is not constant.
641 This will be resolved by the assembler and units
642 converted. */
643
644 if (!RELAX_BRANCH_CONST (fragp->fr_subtype))
645 {
646 /* Install fixup for the branch. */
647 reloc_howto_type *reloc_howto
648 = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
649 if (!reloc_howto)
650 abort();
651
652 fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal,
653 bfd_get_reloc_size (reloc_howto),
654 &exp,
655 reloc_howto->pc_relative,
656 BFD_RELOC_BPF_DISP16);
657 fixp->fx_file = fragp->fr_file;
658 fixp->fx_line = fragp->fr_line;
659 }
660
661 buf += 8;
662 }
663 else
664 {
665 /* 16-bit disp is known and not in range. Turn the JXX
666 into a sequence JXX +1; JA +1; JAL d32. */
667
668 char bytes[8];
669
670 /* First, set the 16-bit offset in the current
671 instruction to 1. */
672
673 if (target_big_endian)
674 bfd_putb16 (1, buf + 2);
675 else
676 bfd_putl16 (1, buf + 2);
677 buf += 8;
678
679 /* Then, write the JA + 1 */
680
681 bytes[0] = 0x05; /* JA */
682 bytes[1] = 0x0;
683 encode_int16 (1, bytes + 2);
684 bytes[4] = 0x0;
685 bytes[5] = 0x0;
686 bytes[6] = 0x0;
687 bytes[7] = 0x0;
688 write_insn_bytes (buf, bytes);
689 buf += 8;
690
691 /* Finally, write the JAL to the target. */
692
693 bytes[0] = ((BPF_CLASS_JMP32|BPF_CODE_JA|BPF_SRC_K) >> 56) & 0xff;
694 bytes[1] = 0;
695 bytes[2] = 0;
696 bytes[3] = 0;
697 encode_int32 ((int32_t) disp_to_target, bytes + 4);
698 write_insn_bytes (buf, bytes);
699 buf += 8;
700 }
701 }
702 else
703 {
704 /* The displacement to the target is not known. Do not
705 relax. The linker will maybe do it if it chooses to. */
706
707 reloc_howto_type *reloc_howto = NULL;
708
709 gas_assert (!RELAX_BRANCH_CONST (fragp->fr_subtype));
710
711 /* Install fixup for the conditional jump. */
712 reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
713 if (!reloc_howto)
714 abort ();
715
716 fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal,
717 bfd_get_reloc_size (reloc_howto),
718 &exp,
719 reloc_howto->pc_relative,
720 BFD_RELOC_BPF_DISP16);
721 fixp->fx_file = fragp->fr_file;
722 fixp->fx_line = fragp->fr_line;
723 buf += 8;
724 }
725 }
726
727 gas_assert (buf == (bfd_byte *)fragp->fr_literal
728 + fragp->fr_fix + fragp->fr_var);
729
730 fragp->fr_fix += fragp->fr_var;
f8861f5d
JM
731}
732
733\f
d218e7fe
JM
734/* Apply a fixS (fixup of an instruction or data that we didn't have
735 enough info to complete immediately) to the data in a frag. */
736
f8861f5d 737void
d218e7fe 738md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
f8861f5d 739{
d218e7fe
JM
740 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
741
742 switch (fixP->fx_r_type)
f8861f5d 743 {
d218e7fe
JM
744 case BFD_RELOC_BPF_DISP16:
745 /* Convert from bytes to number of 64-bit words to the target,
746 minus one. */
747 *valP = (((long) (*valP)) - 8) / 8;
748 break;
c2ca88d7 749 case BFD_RELOC_BPF_DISPCALL32:
d218e7fe 750 case BFD_RELOC_BPF_DISP32:
d218e7fe
JM
751 /* Convert from bytes to number of 64-bit words to the target,
752 minus one. */
753 *valP = (((long) (*valP)) - 8) / 8;
c2ca88d7
JM
754
755 if (fixP->fx_r_type == BFD_RELOC_BPF_DISPCALL32)
756 {
757 /* eBPF supports two kind of CALL instructions: the so
758 called pseudo calls ("bpf to bpf") and external calls
759 ("bpf to kernel").
760
761 Both kind of calls use the same instruction (CALL).
762 However, external calls are constructed by passing a
763 constant argument to the instruction, whereas pseudo
764 calls result from expressions involving symbols. In
765 practice, instructions requiring a fixup are interpreted
766 as pseudo-calls. If we are executing this code, this is
767 a pseudo call.
768
769 The kernel expects for pseudo-calls to be annotated by
770 having BPF_PSEUDO_CALL in the SRC field of the
771 instruction. But beware the infamous nibble-swapping of
772 eBPF and take endianness into account here.
773
774 Note that the CALL instruction has only one operand, so
775 this code is executed only once per instruction. */
776 md_number_to_chars (where + 1, target_big_endian ? 0x01 : 0x10, 1);
777 }
d218e7fe
JM
778 break;
779 case BFD_RELOC_16_PCREL:
780 /* Convert from bytes to number of 64-bit words to the target,
781 minus one. */
782 *valP = (((long) (*valP)) - 8) / 8;
783 break;
784 default:
785 break;
786 }
f8861f5d 787
d218e7fe
JM
788 if (fixP->fx_addsy == (symbolS *) NULL)
789 fixP->fx_done = 1;
790
791 if (fixP->fx_done)
792 {
793 /* We're finished with this fixup. Install it because
794 bfd_install_relocation won't be called to do it. */
795 switch (fixP->fx_r_type)
796 {
797 case BFD_RELOC_8:
798 md_number_to_chars (where, *valP, 1);
799 break;
800 case BFD_RELOC_16:
801 md_number_to_chars (where, *valP, 2);
802 break;
803 case BFD_RELOC_32:
804 md_number_to_chars (where, *valP, 4);
805 break;
806 case BFD_RELOC_64:
807 md_number_to_chars (where, *valP, 8);
808 break;
809 case BFD_RELOC_BPF_DISP16:
810 md_number_to_chars (where + 2, (uint16_t) *valP, 2);
f8861f5d 811 break;
d218e7fe 812 case BFD_RELOC_BPF_DISP32:
c2ca88d7 813 case BFD_RELOC_BPF_DISPCALL32:
d218e7fe 814 md_number_to_chars (where + 4, (uint32_t) *valP, 4);
f8861f5d 815 break;
d218e7fe
JM
816 case BFD_RELOC_16_PCREL:
817 md_number_to_chars (where + 2, (uint32_t) *valP, 2);
818 break;
819 default:
820 as_bad_where (fixP->fx_file, fixP->fx_line,
821 _("internal error: can't install fix for reloc type %d (`%s')"),
822 fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
823 break;
824 }
f8861f5d
JM
825 }
826
d218e7fe
JM
827 /* Tuck `value' away for use by tc_gen_reloc.
828 See the comment describing fx_addnumber in write.h.
829 This field is misnamed (or misused :-). */
830 fixP->fx_addnumber = *valP;
f8861f5d
JM
831}
832
249d4715
JM
833\f
834/* Instruction writing routines. */
835
836/* Encode a BPF instruction in the given buffer BYTES. Non-constant
837 immediates are encoded as zeroes. */
838
839static void
840encode_insn (struct bpf_insn *insn, char *bytes)
841{
842 uint8_t src, dst;
843
844 /* Zero all the bytes. */
845 memset (bytes, 0, 16);
846
847 /* First encode the opcodes. Note that we have to handle the
848 endianness groups of the BPF instructions: 8 | 4 | 4 | 16 |
849 32. */
850 if (target_big_endian)
851 {
852 /* code */
853 bytes[0] = (insn->opcode >> 56) & 0xff;
854 /* regs */
855 bytes[1] = (insn->opcode >> 48) & 0xff;
856 /* offset16 */
857 bytes[2] = (insn->opcode >> 40) & 0xff;
858 bytes[3] = (insn->opcode >> 32) & 0xff;
859 /* imm32 */
860 bytes[4] = (insn->opcode >> 24) & 0xff;
861 bytes[5] = (insn->opcode >> 16) & 0xff;
862 bytes[6] = (insn->opcode >> 8) & 0xff;
863 bytes[7] = insn->opcode & 0xff;
864 }
865 else
866 {
867 /* code */
868 bytes[0] = (insn->opcode >> 56) & 0xff;
869 /* regs */
870 bytes[1] = (((((insn->opcode >> 48) & 0xff) & 0xf) << 4)
871 | (((insn->opcode >> 48) & 0xff) & 0xf));
872 /* offset16 */
873 bytes[3] = (insn->opcode >> 40) & 0xff;
874 bytes[2] = (insn->opcode >> 32) & 0xff;
875 /* imm32 */
876 bytes[7] = (insn->opcode >> 24) & 0xff;
877 bytes[6] = (insn->opcode >> 16) & 0xff;
878 bytes[5] = (insn->opcode >> 8) & 0xff;
879 bytes[4] = insn->opcode & 0xff;
880 }
881
882 /* Now the registers. */
883 src = insn->has_src ? insn->src : 0;
884 dst = insn->has_dst ? insn->dst : 0;
885
886 if (target_big_endian)
887 bytes[1] = ((dst & 0xf) << 4) | (src & 0xf);
888 else
889 bytes[1] = ((src & 0xf) << 4) | (dst & 0xf);
890
891 /* Now the immediates that are known to be constant. */
892
893 if (insn->has_imm32 && insn->imm32.X_op == O_constant)
894 encode_int32 (insn->imm32.X_add_number, bytes + 4);
895
896 if (insn->has_disp32 && insn->disp32.X_op == O_constant)
897 encode_int32 (insn->disp32.X_add_number, bytes + 4);
898
899 if (insn->has_offset16 && insn->offset16.X_op == O_constant)
900 encode_int16 (insn->offset16.X_add_number, bytes + 2);
901
902 if (insn->has_disp16 && insn->disp16.X_op == O_constant)
903 encode_int16 (insn->disp16.X_add_number, bytes + 2);
904
905 if (insn->has_imm64 && insn->imm64.X_op == O_constant)
906 {
907 uint64_t imm64 = insn->imm64.X_add_number;
908
909 if (target_big_endian)
910 {
911 bytes[12] = (imm64 >> 56) & 0xff;
912 bytes[13] = (imm64 >> 48) & 0xff;
913 bytes[14] = (imm64 >> 40) & 0xff;
914 bytes[15] = (imm64 >> 32) & 0xff;
915 bytes[4] = (imm64 >> 24) & 0xff;
916 bytes[5] = (imm64 >> 16) & 0xff;
917 bytes[6] = (imm64 >> 8) & 0xff;
918 bytes[7] = imm64 & 0xff;
919 }
920 else
921 {
922 bytes[15] = (imm64 >> 56) & 0xff;
923 bytes[14] = (imm64 >> 48) & 0xff;
924 bytes[13] = (imm64 >> 40) & 0xff;
925 bytes[12] = (imm64 >> 32) & 0xff;
926 bytes[7] = (imm64 >> 24) & 0xff;
927 bytes[6] = (imm64 >> 16) & 0xff;
928 bytes[5] = (imm64 >> 8) & 0xff;
929 bytes[4] = imm64 & 0xff;
930 }
931 }
932}
933
934/* Install the fixups in INSN in their proper location in the
935 specified FRAG at the location pointed by WHERE. */
936
937static void
938install_insn_fixups (struct bpf_insn *insn, fragS *frag, long where)
939{
940 if (insn->has_imm64)
941 {
942 switch (insn->imm64.X_op)
943 {
944 case O_symbol:
945 case O_subtract:
946 case O_add:
947 {
948 reloc_howto_type *reloc_howto;
949 int size;
950
951 reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_64);
952 if (!reloc_howto)
953 abort ();
954
955 size = bfd_get_reloc_size (reloc_howto);
956
957 fix_new_exp (frag, where,
958 size, &insn->imm64, reloc_howto->pc_relative,
959 BFD_RELOC_BPF_64);
960 break;
961 }
962 case O_constant:
963 /* Already handled in encode_insn. */
964 break;
965 default:
966 abort ();
967 }
968 }
969
970 if (insn->has_imm32)
971 {
972 switch (insn->imm32.X_op)
973 {
974 case O_symbol:
975 case O_subtract:
976 case O_add:
977 case O_uminus:
978 {
979 reloc_howto_type *reloc_howto;
980 int size;
981
982 reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
983 if (!reloc_howto)
984 abort ();
985
986 size = bfd_get_reloc_size (reloc_howto);
987
988 fix_new_exp (frag, where + 4,
989 size, &insn->imm32, reloc_howto->pc_relative,
990 BFD_RELOC_32);
991 break;
992 }
993 case O_constant:
994 /* Already handled in encode_insn. */
995 break;
996 default:
997 abort ();
998 }
999 }
1000
1001 if (insn->has_disp32)
1002 {
1003 switch (insn->disp32.X_op)
1004 {
1005 case O_symbol:
1006 case O_subtract:
1007 case O_add:
1008 {
1009 reloc_howto_type *reloc_howto;
1010 int size;
1011 unsigned int bfd_reloc
1012 = (insn->id == BPF_INSN_CALL
1013 ? BFD_RELOC_BPF_DISPCALL32
1014 : BFD_RELOC_BPF_DISP32);
1015
1016 reloc_howto = bfd_reloc_type_lookup (stdoutput, bfd_reloc);
1017 if (!reloc_howto)
1018 abort ();
1019
1020 size = bfd_get_reloc_size (reloc_howto);
1021
1022 fix_new_exp (frag, where,
1023 size, &insn->disp32, reloc_howto->pc_relative,
1024 bfd_reloc);
1025 break;
1026 }
1027 case O_constant:
1028 /* Already handled in encode_insn. */
1029 break;
1030 default:
1031 abort ();
1032 }
1033 }
1034
1035 if (insn->has_offset16)
1036 {
1037 switch (insn->offset16.X_op)
1038 {
1039 case O_symbol:
1040 case O_subtract:
1041 case O_add:
1042 {
1043 reloc_howto_type *reloc_howto;
1044 int size;
1045
1046 /* XXX we really need a new pc-rel offset in bytes
1047 relocation for this. */
1048 reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
1049 if (!reloc_howto)
1050 abort ();
1051
1052 size = bfd_get_reloc_size (reloc_howto);
1053
1054 fix_new_exp (frag, where,
1055 size, &insn->offset16, reloc_howto->pc_relative,
1056 BFD_RELOC_BPF_DISP16);
1057 break;
1058 }
1059 case O_constant:
1060 /* Already handled in encode_insn. */
1061 break;
1062 default:
1063 abort ();
1064 }
1065 }
1066
1067 if (insn->has_disp16)
1068 {
1069 switch (insn->disp16.X_op)
1070 {
1071 case O_symbol:
1072 case O_subtract:
1073 case O_add:
1074 {
1075 reloc_howto_type *reloc_howto;
1076 int size;
1077
1078 reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
1079 if (!reloc_howto)
1080 abort ();
1081
1082 size = bfd_get_reloc_size (reloc_howto);
1083
1084 fix_new_exp (frag, where,
1085 size, &insn->disp16, reloc_howto->pc_relative,
1086 BFD_RELOC_BPF_DISP16);
1087 break;
1088 }
1089 case O_constant:
1090 /* Already handled in encode_insn. */
1091 break;
1092 default:
1093 abort ();
1094 }
1095 }
1096
1097}
1098
1099/* Add a new insn to the list of instructions. */
1100
1101static void
1102add_fixed_insn (struct bpf_insn *insn)
1103{
1104 char *this_frag = frag_more (insn->size);
1105 char bytes[16];
1106 int i;
1107
1108 /* First encode the known parts of the instruction, including
1109 opcodes and constant immediates, and write them to the frag. */
1110 encode_insn (insn, bytes);
1111 for (i = 0; i < insn->size; ++i)
1112 md_number_to_chars (this_frag + i, (valueT) bytes[i], 1);
1113
1114 /* Now install the instruction fixups. */
1115 install_insn_fixups (insn, frag_now,
1116 this_frag - frag_now->fr_literal);
1117}
1118
1119/* Add a new relaxable to the list of instructions. */
1120
1121static void
1122add_relaxed_insn (struct bpf_insn *insn, expressionS *exp)
1123{
1124 char bytes[16];
1125 int i;
1126 char *this_frag;
1127 unsigned worst_case = relaxed_branch_length (NULL, NULL, 0);
1128 unsigned best_case = insn->size;
1129
1130 /* We only support relaxing branches, for the moment. */
1131 relax_substateT subtype
1132 = RELAX_BRANCH_ENCODE (insn->id == BPF_INSN_JAR,
1133 exp->X_op == O_constant,
1134 worst_case);
1135
1136 frag_grow (worst_case);
1137 this_frag = frag_more (0);
1138
1139 /* First encode the known parts of the instruction, including
1140 opcodes and constant immediates, and write them to the frag. */
1141 encode_insn (insn, bytes);
1142 for (i = 0; i < insn->size; ++i)
1143 md_number_to_chars (this_frag + i, (valueT) bytes[i], 1);
1144
1145 /* Note that instruction fixups will be applied once the frag is
1146 relaxed, in md_convert_frag. */
1147 frag_var (rs_machine_dependent,
1148 worst_case, best_case,
1149 subtype, exp->X_add_symbol, exp->X_add_number /* offset */,
1150 NULL);
1151}
1152
1153\f
d218e7fe
JM
1154/* Parse an operand expression. Returns the first character that is
1155 not part of the expression, or NULL in case of parse error.
ff5a51b3 1156
d218e7fe 1157 See md_operand below to see how exp_parse_failed is used. */
ff5a51b3 1158
d218e7fe 1159static int exp_parse_failed = 0;
ff5a51b3
GM
1160
1161static char *
d218e7fe 1162parse_expression (char *s, expressionS *exp)
ff5a51b3 1163{
d218e7fe
JM
1164 char *saved_input_line_pointer = input_line_pointer;
1165 char *saved_s = s;
ff5a51b3 1166
d218e7fe
JM
1167 exp_parse_failed = 0;
1168 input_line_pointer = s;
1169 expression (exp);
1170 s = input_line_pointer;
1171 input_line_pointer = saved_input_line_pointer;
ff5a51b3 1172
d218e7fe
JM
1173 switch (exp->X_op == O_absent || exp_parse_failed)
1174 return NULL;
ff5a51b3 1175
d218e7fe
JM
1176 /* The expression parser may consume trailing whitespaces. We have
1177 to undo that since the instruction templates may be expecting
1178 these whitespaces. */
1179 {
1180 char *p;
1181 for (p = s - 1; p >= saved_s && *p == ' '; --p)
1182 --s;
1183 }
ff5a51b3 1184
d218e7fe 1185 return s;
ff5a51b3
GM
1186}
1187
d218e7fe
JM
1188/* Parse a BPF register name and return the corresponding register
1189 number. Return NULL in case of parse error, or a pointer to the
1190 first character in S that is not part of the register name. */
ff5a51b3 1191
d218e7fe
JM
1192static char *
1193parse_bpf_register (char *s, char rw, uint8_t *regno)
ff5a51b3 1194{
d218e7fe 1195 if (asm_dialect == DIALECT_NORMAL)
ff5a51b3 1196 {
d218e7fe
JM
1197 rw = 'r';
1198 if (*s != '%')
1199 return NULL;
1200 s += 1;
ff5a51b3 1201
d218e7fe
JM
1202 if (*s == 'f' && *(s + 1) == 'p')
1203 {
1204 *regno = 10;
1205 s += 2;
1206 return s;
1207 }
1208 }
ff5a51b3 1209
d218e7fe
JM
1210 if (*s != rw)
1211 return NULL;
1212 s += 1;
ff5a51b3 1213
d218e7fe
JM
1214 if (*s == '1')
1215 {
1216 if (*(s + 1) == '0')
1217 {
1218 *regno = 10;
1219 s += 2;
1220 }
1221 else
1222 {
1223 *regno = 1;
1224 s += 1;
1225 }
1226 }
1227 else if (*s >= '0' && *s <= '9')
1228 {
1229 *regno = *s - '0';
1230 s += 1;
1231 }
ff5a51b3 1232
d218e7fe 1233 return s;
ff5a51b3
GM
1234}
1235
d218e7fe 1236/* Collect a parse error message. */
ff5a51b3 1237
d218e7fe
JM
1238static int partial_match_length = 0;
1239static char *errmsg = NULL;
ff5a51b3 1240
d218e7fe
JM
1241static void
1242parse_error (int length, const char *fmt, ...)
ff5a51b3 1243{
d218e7fe 1244 if (length > partial_match_length)
ff5a51b3 1245 {
d218e7fe 1246 va_list args;
ff5a51b3 1247
d218e7fe
JM
1248 free (errmsg);
1249 va_start (args, fmt);
1250 errmsg = xvasprintf (fmt, args);
1251 va_end (args);
1252 partial_match_length = length;
ff5a51b3 1253 }
ff5a51b3
GM
1254}
1255
d218e7fe
JM
1256/* Assemble a machine instruction in STR and emit the frags/bytes it
1257 assembles to. */
ff5a51b3 1258
d218e7fe
JM
1259void
1260md_assemble (char *str ATTRIBUTE_UNUSED)
ff5a51b3 1261{
d218e7fe
JM
1262 /* There are two different syntaxes that can be used to write BPF
1263 instructions. One is very conventional and like any other
1264 assembly language where each instruction is conformed by an
1265 instruction mnemonic followed by its operands. This is what we
1266 call the "normal" syntax. The other syntax tries to look like C
1267 statements. We have to support both syntaxes in this assembler.
1268
1269 One of the many nuisances introduced by this eccentricity is that
1270 in the pseudo-c syntax it is not possible to hash the opcodes
1271 table by instruction mnemonic, because there is none. So we have
1272 no other choice than to try to parse all instruction opcodes
1273 until one matches. This is slow.
1274
1275 Another problem is that emitting detailed diagnostics becomes
1276 tricky, since the lack of mnemonic means it is not clear what
1277 instruction was intended by the user, and we cannot emit
1278 diagnostics for every attempted template. So if an instruction
1279 is not parsed, we report the diagnostic corresponding to the
1280 partially parsed instruction that was matched further. */
1281
1282 unsigned int idx = 0;
1283 struct bpf_insn insn;
1284 const struct bpf_opcode *opcode;
1285
1286 /* Initialize the global diagnostic variables. See the parse_error
1287 function above. */
1288 partial_match_length = 0;
1289 errmsg = NULL;
1290
1291#define PARSE_ERROR(...) parse_error (s - str, __VA_ARGS__)
1292
1293 while ((opcode = bpf_get_opcode (idx++)) != NULL)
ff5a51b3 1294 {
d218e7fe
JM
1295 const char *p;
1296 char *s;
1297 const char *template
1298 = (asm_dialect == DIALECT_PSEUDOC ? opcode->pseudoc : opcode->normal);
1299
1300 /* Do not try to match opcodes with a higher version than the
1301 selected ISA spec. */
1302 if (opcode->version > isa_spec)
1303 continue;
1304
1305 memset (&insn, 0, sizeof (struct bpf_insn));
1306 insn.size = 8;
1307 for (s = str, p = template; *p != '\0';)
1308 {
1309 if (*p == ' ')
1310 {
1311 /* Expect zero or more spaces. */
1312 while (*s != '\0' && (*s == ' ' || *s == '\t'))
1313 s += 1;
1314 p += 1;
1315 }
1316 else if (*p == '%')
1317 {
1318 if (*(p + 1) == '%')
1319 {
1320 if (*s != '%')
1321 {
1322 PARSE_ERROR ("expected '%%'");
1323 break;
1324 }
1325 p += 2;
1326 s += 1;
1327 }
1328 else if (*(p + 1) == 'w')
1329 {
1330 /* Expect zero or more spaces. */
1331 while (*s != '\0' && (*s == ' ' || *s == '\t'))
1332 s += 1;
1333 p += 2;
1334 }
1335 else if (*(p + 1) == 'W')
1336 {
1337 /* Expect one or more spaces. */
1338 if (*s != ' ' && *s != '\t')
1339 {
1340 PARSE_ERROR ("expected white space, got '%s'",
1341 s);
1342 break;
1343 }
1344 while (*s != '\0' && (*s == ' ' || *s == '\t'))
1345 s += 1;
1346 p += 2;
1347 }
1348 else if (strncmp (p, "%dr", 3) == 0)
1349 {
1350 uint8_t regno;
1351 char *news = parse_bpf_register (s, 'r', &regno);
1352
1353 if (news == NULL || (insn.has_dst && regno != insn.dst))
1354 {
1355 if (news != NULL)
1356 PARSE_ERROR ("expected register r%d, got r%d",
1357 insn.dst, regno);
1358 else
1359 PARSE_ERROR ("expected register name, got '%s'", s);
1360 break;
1361 }
1362 s = news;
1363 insn.dst = regno;
1364 insn.has_dst = 1;
1365 p += 3;
1366 }
1367 else if (strncmp (p, "%sr", 3) == 0)
1368 {
1369 uint8_t regno;
1370 char *news = parse_bpf_register (s, 'r', &regno);
1371
1372 if (news == NULL || (insn.has_src && regno != insn.src))
1373 {
1374 if (news != NULL)
1375 PARSE_ERROR ("expected register r%d, got r%d",
1376 insn.dst, regno);
1377 else
1378 PARSE_ERROR ("expected register name, got '%s'", s);
1379 break;
1380 }
1381 s = news;
1382 insn.src = regno;
1383 insn.has_src = 1;
1384 p += 3;
1385 }
1386 else if (strncmp (p, "%dw", 3) == 0)
1387 {
1388 uint8_t regno;
1389 char *news = parse_bpf_register (s, 'w', &regno);
1390
1391 if (news == NULL || (insn.has_dst && regno != insn.dst))
1392 {
1393 if (news != NULL)
1394 PARSE_ERROR ("expected register r%d, got r%d",
1395 insn.dst, regno);
1396 else
1397 PARSE_ERROR ("expected register name, got '%s'", s);
1398 break;
1399 }
1400 s = news;
1401 insn.dst = regno;
1402 insn.has_dst = 1;
1403 p += 3;
1404 }
1405 else if (strncmp (p, "%sw", 3) == 0)
1406 {
1407 uint8_t regno;
1408 char *news = parse_bpf_register (s, 'w', &regno);
1409
1410 if (news == NULL || (insn.has_src && regno != insn.src))
1411 {
1412 if (news != NULL)
1413 PARSE_ERROR ("expected register r%d, got r%d",
1414 insn.dst, regno);
1415 else
1416 PARSE_ERROR ("expected register name, got '%s'", s);
1417 break;
1418 }
1419 s = news;
1420 insn.src = regno;
1421 insn.has_src = 1;
1422 p += 3;
1423 }
1424 else if (strncmp (p, "%i32", 4) == 0
1425 || strncmp (p, "%I32", 4) == 0)
1426 {
1427 if (p[1] == 'I')
1428 {
1429 while (*s == ' ' || *s == '\t')
1430 s += 1;
1431 if (*s != '+' && *s != '-')
1432 {
1433 PARSE_ERROR ("expected `+' or `-', got `%c'", *s);
1434 break;
1435 }
1436 }
1437
1438 s = parse_expression (s, &insn.imm32);
1439 if (s == NULL)
1440 {
1441 PARSE_ERROR ("expected signed 32-bit immediate");
1442 break;
1443 }
1444 insn.has_imm32 = 1;
1445 p += 4;
1446 }
1447 else if (strncmp (p, "%o16", 4) == 0)
1448 {
1449 while (*s == ' ' || *s == '\t')
1450 s += 1;
1451 if (*s != '+' && *s != '-')
1452 {
1453 PARSE_ERROR ("expected `+' or `-', got `%c'", *s);
1454 break;
1455 }
1456
1457 s = parse_expression (s, &insn.offset16);
1458 if (s == NULL)
1459 {
1460 PARSE_ERROR ("expected signed 16-bit offset");
1461 break;
1462 }
1463 insn.has_offset16 = 1;
1464 p += 4;
1465 }
1466 else if (strncmp (p, "%d16", 4) == 0)
1467 {
1468 s = parse_expression (s, &insn.disp16);
1469 if (s == NULL)
1470 {
1471 PARSE_ERROR ("expected signed 16-bit displacement");
1472 break;
1473 }
1474 insn.has_disp16 = 1;
249d4715 1475 insn.is_relaxable = 1;
d218e7fe
JM
1476 p += 4;
1477 }
1478 else if (strncmp (p, "%d32", 4) == 0)
1479 {
1480 s = parse_expression (s, &insn.disp32);
1481 if (s == NULL)
1482 {
1483 PARSE_ERROR ("expected signed 32-bit displacement");
1484 break;
1485 }
1486 insn.has_disp32 = 1;
1487 p += 4;
1488 }
1489 else if (strncmp (p, "%i64", 4) == 0)
1490 {
1491 s = parse_expression (s, &insn.imm64);
1492 if (s == NULL)
1493 {
1494 PARSE_ERROR ("expected signed 64-bit immediate");
1495 break;
1496 }
1497 insn.has_imm64 = 1;
1498 insn.size = 16;
1499 p += 4;
1500 }
1501 else
1502 as_fatal (_("invalid %%-tag in BPF opcode '%s'\n"), template);
1503 }
1504 else
1505 {
1506 /* Match a literal character. */
1507 if (*s != *p)
1508 {
1509 if (*s == '\0')
1510 PARSE_ERROR ("expected '%c'", *p);
1511 else if (*s == '%')
1512 {
1513 /* This is to workaround a bug in as_bad. */
1514 char tmp[3];
1515
1516 tmp[0] = '%';
1517 tmp[1] = '%';
1518 tmp[2] = '\0';
1519
1520 PARSE_ERROR ("expected '%c', got '%s'", *p, tmp);
1521 }
1522 else
1523 PARSE_ERROR ("expected '%c', got '%c'", *p, *s);
1524 break;
1525 }
1526 p += 1;
1527 s += 1;
1528 }
1529 }
ff5a51b3 1530
d218e7fe
JM
1531 if (*p == '\0')
1532 {
1533 /* Allow white spaces at the end of the line. */
1534 while (*s != '\0' && (*s == ' ' || *s == '\t'))
1535 s += 1;
1536 if (*s == '\0')
1537 /* We parsed an instruction successfully. */
1538 break;
1539 PARSE_ERROR ("extra junk at end of line");
1540 }
1541 }
ff5a51b3 1542
d218e7fe
JM
1543 if (opcode == NULL)
1544 {
1545 as_bad (_("unrecognized instruction `%s'"), str);
1546 if (errmsg != NULL)
1547 {
fafcbd14 1548 as_bad ("%s", errmsg);
d218e7fe
JM
1549 free (errmsg);
1550 }
ff5a51b3 1551
d218e7fe
JM
1552 return;
1553 }
c2ca88d7 1554 insn.id = opcode->id;
d218e7fe 1555 insn.opcode = opcode->opcode;
ff5a51b3 1556
d218e7fe 1557#undef PARSE_ERROR
ff5a51b3 1558
d218e7fe 1559 /* Generate the frags and fixups for the parsed instruction. */
249d4715
JM
1560 if (do_relax && insn.is_relaxable)
1561 {
1562 expressionS *relaxable_exp = NULL;
d218e7fe 1563
249d4715
JM
1564 if (insn.has_disp16)
1565 relaxable_exp = &insn.disp16;
1566 else
1567 abort ();
d218e7fe 1568
249d4715
JM
1569 add_relaxed_insn (&insn, relaxable_exp);
1570 }
1571 else
1572 add_fixed_insn (&insn);
ff5a51b3 1573
d218e7fe
JM
1574 /* Emit DWARF2 debugging information. */
1575 dwarf2_emit_insn (insn.size);
ff5a51b3
GM
1576}
1577
d218e7fe 1578/* Parse an operand that is machine-specific. */
f8861f5d
JM
1579
1580void
1581md_operand (expressionS *expressionP)
1582{
d218e7fe
JM
1583 /* If this hook is invoked it means GAS failed to parse a generic
1584 expression. We should inhibit the as_bad in expr.c, so we can fail
1585 while parsing instruction alternatives. To do that, we change the
1586 expression to not have an O_absent. But then we also need to set
1587 exp_parse_failed to parse_expression above does the right thing. */
1588 ++input_line_pointer;
1589 expressionP->X_op = O_constant;
1590 expressionP->X_add_number = 0;
1591 exp_parse_failed = 1;
f8861f5d
JM
1592}
1593
f8861f5d
JM
1594symbolS *
1595md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1596{
1597 return NULL;
1598}
1599
1600\f
1601/* Turn a string in input_line_pointer into a floating point constant
1602 of type TYPE, and store the appropriate bytes in *LITP. The number
1603 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1604 returned, or NULL on OK. */
1605
1606const char *
1607md_atof (int type, char *litP, int *sizeP)
1608{
5b7c81bd 1609 return ieee_md_atof (type, litP, sizeP, false);
f8861f5d 1610}
d218e7fe
JM
1611
1612\f
1613/* Determine whether the equal sign in the given string corresponds to
1614 a BPF instruction, i.e. when it is not to be considered a symbol
1615 assignment. */
1616
1617bool
1618bpf_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char *str ATTRIBUTE_UNUSED)
1619{
1620 uint8_t regno;
1621
1622 /* Only pseudo-c instructions can have equal signs, and of these,
1623 all that could be confused with a symbol assignment all start
1624 with a register name. */
1625 if (asm_dialect == DIALECT_PSEUDOC)
1626 {
1627 char *w = parse_bpf_register (str, 'w', &regno);
1628 char *r = parse_bpf_register (str, 'r', &regno);
1629
1630 if ((w != NULL && *w == '\0')
1631 || (r != NULL && *r == '\0'))
1632 return 1;
1633 }
1634
1635 return 0;
1636}