]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - cpu/bpf.opc
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / cpu / bpf.opc
1 /* EBPF opcode support. -*- c -*-
2
3 Copyright (C) 2019 Free Software Foundation, Inc.
4
5 Contributed by Oracle, Inc.
6
7 This file is part of the GNU Binutils and of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
23
24 /*
25 Each section is delimited with start and end markers.
26
27 <arch>-opc.h additions use: "-- opc.h"
28 <arch>-opc.c additions use: "-- opc.c"
29 <arch>-asm.c additions use: "-- asm.c"
30 <arch>-dis.c additions use: "-- dis.c"
31 <arch>-ibd.h additions use: "-- ibd.h". */
32 \f
33 /* -- opc.h */
34
35 #undef CGEN_DIS_HASH_SIZE
36 #define CGEN_DIS_HASH_SIZE 1
37
38 #undef CGEN_DIS_HASH
39 #define CGEN_DIS_HASH(buffer, value) 0
40
41 /* Allows reason codes to be output when assembler errors occur. */
42 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
43
44 #define CGEN_VALIDATE_INSN_SUPPORTED
45 extern int bpf_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
46
47 \f
48 /* -- opc.c */
49 \f
50 /* -- asm.c */
51
52 /* Parse a signed 64-bit immediate. */
53
54 static const char *
55 parse_imm64 (CGEN_CPU_DESC cd,
56 const char **strp,
57 int opindex,
58 int64_t *valuep)
59 {
60 bfd_vma value;
61 enum cgen_parse_operand_result result;
62 const char *errmsg;
63
64 errmsg = (* cd->parse_operand_fn)
65 (cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
66 &result, &value);
67 if (!errmsg)
68 *valuep = value;
69
70 return errmsg;
71 }
72
73 /* Endianness size operands are integer immediates whose values can be
74 16, 32 or 64. */
75
76 static const char *
77 parse_endsize (CGEN_CPU_DESC cd,
78 const char **strp,
79 int opindex,
80 unsigned long *valuep)
81 {
82 const char *errmsg;
83
84 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
85 if (errmsg)
86 return errmsg;
87
88 switch (*valuep)
89 {
90 case 16:
91 case 32:
92 case 64:
93 break;
94 default:
95 return _("expected 16, 32 or 64 in");
96 }
97
98 return NULL;
99 }
100
101 /* Special check to ensure that the right instruction variant is used
102 for the given endianness induced by the ISA selected in the CPU.
103 See bpf.cpu for a discussion on how eBPF is really two instruction
104 sets. */
105
106 int
107 bpf_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
108 {
109 CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
110
111 return cgen_bitset_intersect_p (&isas, cd->isas);
112 }
113
114 \f
115 /* -- dis.c */
116
117 /* We need to customize the disassembler a bit:
118 - Use 8 bytes per line by default.
119 */
120
121 #define CGEN_PRINT_INSN bpf_print_insn
122
123 static int
124 bpf_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
125 {
126 bfd_byte buf[CGEN_MAX_INSN_SIZE];
127 int buflen;
128 int status;
129
130 info->bytes_per_chunk = 1;
131 info->bytes_per_line = 8;
132 info->endian_code = BFD_ENDIAN_BIG;
133
134 /* Attempt to read the base part of the insn. */
135 buflen = cd->base_insn_bitsize / 8;
136 status = (*info->read_memory_func) (pc, buf, buflen, info);
137
138 /* Try again with the minimum part, if min < base. */
139 if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
140 {
141 buflen = cd->min_insn_bitsize / 8;
142 status = (*info->read_memory_func) (pc, buf, buflen, info);
143 }
144
145 if (status != 0)
146 {
147 (*info->memory_error_func) (status, pc, info);
148 return -1;
149 }
150
151 return print_insn (cd, pc, info, buf, buflen);
152 }
153
154 /* Signed immediates should be printed in hexadecimal. */
155
156 static void
157 print_immediate (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
158 void *dis_info,
159 int64_t value,
160 unsigned int attrs ATTRIBUTE_UNUSED,
161 bfd_vma pc ATTRIBUTE_UNUSED,
162 int length ATTRIBUTE_UNUSED)
163 {
164 disassemble_info *info = (disassemble_info *) dis_info;
165
166 if (value <= 9)
167 (*info->fprintf_func) (info->stream, "%" PRId64, value);
168 else
169 (*info->fprintf_func) (info->stream, "%#" PRIx64, value);
170
171 /* This is to avoid -Wunused-function for print_normal. */
172 if (0)
173 print_normal (cd, dis_info, value, attrs, pc, length);
174 }
175
176 /* Endianness bit sizes should be printed in decimal. */
177
178 static void
179 print_endsize (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
180 void *dis_info,
181 unsigned long value,
182 unsigned int attrs ATTRIBUTE_UNUSED,
183 bfd_vma pc ATTRIBUTE_UNUSED,
184 int length ATTRIBUTE_UNUSED)
185 {
186 disassemble_info *info = (disassemble_info *) dis_info;
187 (*info->fprintf_func) (info->stream, "%lu", value);
188 }
189
190 \f
191 /* -- */
192