Automatic date update in version.in
[binutils-gdb.git] / cpu / bpf.opc
blobe70ee04841df05bb8267961968c6b8d64e49f40c
1 /* EBPF opcode support.  -*- c -*-
3    Copyright (C) 2019 Free Software Foundation, Inc.
5    Contributed by Oracle, Inc.
7    This file is part of the GNU Binutils and of GDB.
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.
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.
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.  */
25    Each section is delimited with start and end markers.
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".  */
33 /* -- opc.h */
35 #undef CGEN_DIS_HASH_SIZE
36 #define CGEN_DIS_HASH_SIZE 1
38 #undef CGEN_DIS_HASH
39 #define CGEN_DIS_HASH(buffer, value) 0
41 /* Allows reason codes to be output when assembler errors occur.  */
42 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
44 #define CGEN_VALIDATE_INSN_SUPPORTED
45 extern int bpf_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
48 /* -- opc.c */
50 /* -- asm.c */
52 /* Parse a signed 64-bit immediate.  */
54 static const char *
55 parse_imm64 (CGEN_CPU_DESC cd,
56              const char **strp,
57              int opindex,
58              int64_t *valuep)
60   bfd_vma value;
61   enum cgen_parse_operand_result result;
62   const char *errmsg;
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;
70   return errmsg;
73 /* Endianness size operands are integer immediates whose values can be
74    16, 32 or 64.  */
76 static const char *
77 parse_endsize (CGEN_CPU_DESC cd,
78                const char **strp,
79                int opindex,
80                unsigned long *valuep)
82   const char *errmsg;
84   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
85   if (errmsg)
86     return errmsg;
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     }
98   return NULL;
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.  */
107 bpf_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
109   CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
111   return cgen_bitset_intersect_p (&isas, cd->isas);
115 /* -- dis.c */
117 /* We need to customize the disassembler a bit:
118    - Use 8 bytes per line by default.
121 #define CGEN_PRINT_INSN bpf_print_insn
123 static int
124 bpf_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
126   bfd_byte buf[CGEN_MAX_INSN_SIZE];
127   int buflen;
128   int status;
130   info->bytes_per_chunk = 1;
131   info->bytes_per_line = 8;
133   /* Attempt to read the base part of the insn.  */
134   buflen = cd->base_insn_bitsize / 8;
135   status = (*info->read_memory_func) (pc, buf, buflen, info);
137   /* Try again with the minimum part, if min < base.  */
138   if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
139     {
140       buflen = cd->min_insn_bitsize / 8;
141       status = (*info->read_memory_func) (pc, buf, buflen, info);
142     }
144   if (status != 0)
145     {
146       (*info->memory_error_func) (status, pc, info);
147       return -1;
148     }
150   return print_insn (cd, pc, info, buf, buflen);
153 /* Signed immediates should be printed in hexadecimal.  */
155 static void
156 print_immediate (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
157                  void *dis_info,
158                  int64_t value,
159                  unsigned int attrs ATTRIBUTE_UNUSED,
160                  bfd_vma pc ATTRIBUTE_UNUSED,
161                  int length ATTRIBUTE_UNUSED)
163   disassemble_info *info = (disassemble_info *) dis_info;
165   if (value <= 9)
166     (*info->fprintf_func) (info->stream, "%" PRId64, value);
167   else
168     (*info->fprintf_func) (info->stream, "%#" PRIx64, value);
170   /* This is to avoid -Wunused-function for print_normal.  */
171   if (0)
172     print_normal (cd, dis_info, value, attrs, pc, length);
175 /* Endianness bit sizes should be printed in decimal.  */
177 static void
178 print_endsize (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
179                void *dis_info,
180                unsigned long value,
181                unsigned int attrs ATTRIBUTE_UNUSED,
182                bfd_vma pc ATTRIBUTE_UNUSED,
183                int length ATTRIBUTE_UNUSED)
185   disassemble_info *info = (disassemble_info *) dis_info;
186   (*info->fprintf_func) (info->stream, "%lu", value);
190 /* -- */