1*1424dfb3Schristos /* itbl-ops.c
2*1424dfb3Schristos Copyright (C) 1997-2020 Free Software Foundation, Inc.
3*1424dfb3Schristos
4*1424dfb3Schristos This file is part of GAS, the GNU Assembler.
5*1424dfb3Schristos
6*1424dfb3Schristos GAS is free software; you can redistribute it and/or modify
7*1424dfb3Schristos it under the terms of the GNU General Public License as published by
8*1424dfb3Schristos the Free Software Foundation; either version 3, or (at your option)
9*1424dfb3Schristos any later version.
10*1424dfb3Schristos
11*1424dfb3Schristos GAS is distributed in the hope that it will be useful,
12*1424dfb3Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
13*1424dfb3Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*1424dfb3Schristos GNU General Public License for more details.
15*1424dfb3Schristos
16*1424dfb3Schristos You should have received a copy of the GNU General Public License
17*1424dfb3Schristos along with GAS; see the file COPYING. If not, write to the Free
18*1424dfb3Schristos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19*1424dfb3Schristos 02110-1301, USA. */
20*1424dfb3Schristos
21*1424dfb3Schristos /*======================================================================*/
22*1424dfb3Schristos /*
23*1424dfb3Schristos * Herein lies the support for dynamic specification of processor
24*1424dfb3Schristos * instructions and registers. Mnemonics, values, and formats for each
25*1424dfb3Schristos * instruction and register are specified in an ascii file consisting of
26*1424dfb3Schristos * table entries. The grammar for the table is defined in the document
27*1424dfb3Schristos * "Processor instruction table specification".
28*1424dfb3Schristos *
29*1424dfb3Schristos * Instructions use the gnu assembler syntax, with the addition of
30*1424dfb3Schristos * allowing mnemonics for register.
31*1424dfb3Schristos * Eg. "func $2,reg3,0x100,symbol ; comment"
32*1424dfb3Schristos * func - opcode name
33*1424dfb3Schristos * $n - register n
34*1424dfb3Schristos * reg3 - mnemonic for processor's register defined in table
35*1424dfb3Schristos * 0xddd..d - immediate value
36*1424dfb3Schristos * symbol - address of label or external symbol
37*1424dfb3Schristos *
38*1424dfb3Schristos * First, itbl_parse reads in the table of register and instruction
39*1424dfb3Schristos * names and formats, and builds a list of entries for each
40*1424dfb3Schristos * processor/type combination. lex and yacc are used to parse
41*1424dfb3Schristos * the entries in the table and call functions defined here to
42*1424dfb3Schristos * add each entry to our list.
43*1424dfb3Schristos *
44*1424dfb3Schristos * Then, when assembling or disassembling, these functions are called to
45*1424dfb3Schristos * 1) get information on a processor's registers and
46*1424dfb3Schristos * 2) assemble/disassemble an instruction.
47*1424dfb3Schristos * To assemble(disassemble) an instruction, the function
48*1424dfb3Schristos * itbl_assemble(itbl_disassemble) is called to search the list of
49*1424dfb3Schristos * instruction entries, and if a match is found, uses the format
50*1424dfb3Schristos * described in the instruction entry structure to complete the action.
51*1424dfb3Schristos *
52*1424dfb3Schristos * Eg. Suppose we have a Mips coprocessor "cop3" with data register "d2"
53*1424dfb3Schristos * and we want to define function "pig" which takes two operands.
54*1424dfb3Schristos *
55*1424dfb3Schristos * Given the table entries:
56*1424dfb3Schristos * "p3 insn pig 0x1:24-21 dreg:20-16 immed:15-0"
57*1424dfb3Schristos * "p3 dreg d2 0x2"
58*1424dfb3Schristos * and that the instruction encoding for coprocessor pz has encoding:
59*1424dfb3Schristos * #define MIPS_ENCODE_COP_NUM(z) ((0x21|(z<<1))<<25)
60*1424dfb3Schristos * #define ITBL_ENCODE_PNUM(pnum) MIPS_ENCODE_COP_NUM(pnum)
61*1424dfb3Schristos *
62*1424dfb3Schristos * a structure to describe the instruction might look something like:
63*1424dfb3Schristos * struct itbl_entry = {
64*1424dfb3Schristos * e_processor processor = e_p3
65*1424dfb3Schristos * e_type type = e_insn
66*1424dfb3Schristos * char *name = "pig"
67*1424dfb3Schristos * uint value = 0x1
68*1424dfb3Schristos * uint flags = 0
69*1424dfb3Schristos * struct itbl_range range = 24-21
70*1424dfb3Schristos * struct itbl_field *field = {
71*1424dfb3Schristos * e_type type = e_dreg
72*1424dfb3Schristos * struct itbl_range range = 20-16
73*1424dfb3Schristos * struct itbl_field *next = {
74*1424dfb3Schristos * e_type type = e_immed
75*1424dfb3Schristos * struct itbl_range range = 15-0
76*1424dfb3Schristos * struct itbl_field *next = 0
77*1424dfb3Schristos * };
78*1424dfb3Schristos * };
79*1424dfb3Schristos * struct itbl_entry *next = 0
80*1424dfb3Schristos * };
81*1424dfb3Schristos *
82*1424dfb3Schristos * And the assembler instructions:
83*1424dfb3Schristos * "pig d2,0x100"
84*1424dfb3Schristos * "pig $2,0x100"
85*1424dfb3Schristos *
86*1424dfb3Schristos * would both assemble to the hex value:
87*1424dfb3Schristos * "0x4e220100"
88*1424dfb3Schristos *
89*1424dfb3Schristos */
90*1424dfb3Schristos
91*1424dfb3Schristos #include "as.h"
92*1424dfb3Schristos #include "itbl-ops.h"
93*1424dfb3Schristos #include <itbl-parse.h>
94*1424dfb3Schristos
95*1424dfb3Schristos /* #define DEBUG */
96*1424dfb3Schristos
97*1424dfb3Schristos #ifdef DEBUG
98*1424dfb3Schristos #include <assert.h>
99*1424dfb3Schristos #define ASSERT(x) gas_assert (x)
100*1424dfb3Schristos #define DBG(x) printf x
101*1424dfb3Schristos #else
102*1424dfb3Schristos #define ASSERT(x)
103*1424dfb3Schristos #define DBG(x)
104*1424dfb3Schristos #endif
105*1424dfb3Schristos
106*1424dfb3Schristos #ifndef min
107*1424dfb3Schristos #define min(a,b) (a<b?a:b)
108*1424dfb3Schristos #endif
109*1424dfb3Schristos
110*1424dfb3Schristos int itbl_have_entries = 0;
111*1424dfb3Schristos
112*1424dfb3Schristos /*======================================================================*/
113*1424dfb3Schristos /* structures for keeping itbl format entries */
114*1424dfb3Schristos
115*1424dfb3Schristos struct itbl_range {
116*1424dfb3Schristos int sbit; /* mask starting bit position */
117*1424dfb3Schristos int ebit; /* mask ending bit position */
118*1424dfb3Schristos };
119*1424dfb3Schristos
120*1424dfb3Schristos struct itbl_field {
121*1424dfb3Schristos e_type type; /* dreg/creg/greg/immed/symb */
122*1424dfb3Schristos struct itbl_range range; /* field's bitfield range within instruction */
123*1424dfb3Schristos unsigned long flags; /* field flags */
124*1424dfb3Schristos struct itbl_field *next; /* next field in list */
125*1424dfb3Schristos };
126*1424dfb3Schristos
127*1424dfb3Schristos /* These structures define the instructions and registers for a processor.
128*1424dfb3Schristos * If the type is an instruction, the structure defines the format of an
129*1424dfb3Schristos * instruction where the fields are the list of operands.
130*1424dfb3Schristos * The flags field below uses the same values as those defined in the
131*1424dfb3Schristos * gnu assembler and are machine specific. */
132*1424dfb3Schristos struct itbl_entry {
133*1424dfb3Schristos e_processor processor; /* processor number */
134*1424dfb3Schristos e_type type; /* dreg/creg/greg/insn */
135*1424dfb3Schristos char *name; /* mnemonic name for insn/register */
136*1424dfb3Schristos unsigned long value; /* opcode/instruction mask/register number */
137*1424dfb3Schristos unsigned long flags; /* effects of the instruction */
138*1424dfb3Schristos struct itbl_range range; /* bit range within instruction for value */
139*1424dfb3Schristos struct itbl_field *fields; /* list of operand definitions (if any) */
140*1424dfb3Schristos struct itbl_entry *next; /* next entry */
141*1424dfb3Schristos };
142*1424dfb3Schristos
143*1424dfb3Schristos /* local data and structures */
144*1424dfb3Schristos
145*1424dfb3Schristos static int itbl_num_opcodes = 0;
146*1424dfb3Schristos /* Array of entries for each processor and entry type */
147*1424dfb3Schristos static struct itbl_entry *entries[e_nprocs][e_ntypes];
148*1424dfb3Schristos
149*1424dfb3Schristos /* local prototypes */
150*1424dfb3Schristos static unsigned long build_opcode (struct itbl_entry *e);
151*1424dfb3Schristos static e_type get_type (int yytype);
152*1424dfb3Schristos static e_processor get_processor (int yyproc);
153*1424dfb3Schristos static struct itbl_entry **get_entries (e_processor processor,
154*1424dfb3Schristos e_type type);
155*1424dfb3Schristos static struct itbl_entry *find_entry_byname (e_processor processor,
156*1424dfb3Schristos e_type type, char *name);
157*1424dfb3Schristos static struct itbl_entry *find_entry_byval (e_processor processor,
158*1424dfb3Schristos e_type type, unsigned long val, struct itbl_range *r);
159*1424dfb3Schristos static struct itbl_entry *alloc_entry (e_processor processor,
160*1424dfb3Schristos e_type type, char *name, unsigned long value);
161*1424dfb3Schristos static unsigned long apply_range (unsigned long value, struct itbl_range r);
162*1424dfb3Schristos static unsigned long extract_range (unsigned long value, struct itbl_range r);
163*1424dfb3Schristos static struct itbl_field *alloc_field (e_type type, int sbit,
164*1424dfb3Schristos int ebit, unsigned long flags);
165*1424dfb3Schristos
166*1424dfb3Schristos /*======================================================================*/
167*1424dfb3Schristos /* Interfaces to the parser */
168*1424dfb3Schristos
169*1424dfb3Schristos /* Open the table and use lex and yacc to parse the entries.
170*1424dfb3Schristos * Return 1 for failure; 0 for success. */
171*1424dfb3Schristos
172*1424dfb3Schristos int
itbl_parse(char * insntbl)173*1424dfb3Schristos itbl_parse (char *insntbl)
174*1424dfb3Schristos {
175*1424dfb3Schristos extern FILE *yyin;
176*1424dfb3Schristos extern int yyparse (void);
177*1424dfb3Schristos
178*1424dfb3Schristos yyin = fopen (insntbl, FOPEN_RT);
179*1424dfb3Schristos if (yyin == 0)
180*1424dfb3Schristos {
181*1424dfb3Schristos printf ("Can't open processor instruction specification file \"%s\"\n",
182*1424dfb3Schristos insntbl);
183*1424dfb3Schristos return 1;
184*1424dfb3Schristos }
185*1424dfb3Schristos
186*1424dfb3Schristos while (yyparse ())
187*1424dfb3Schristos ;
188*1424dfb3Schristos
189*1424dfb3Schristos fclose (yyin);
190*1424dfb3Schristos itbl_have_entries = 1;
191*1424dfb3Schristos return 0;
192*1424dfb3Schristos }
193*1424dfb3Schristos
194*1424dfb3Schristos /* Add a register entry */
195*1424dfb3Schristos
196*1424dfb3Schristos struct itbl_entry *
itbl_add_reg(int yyprocessor,int yytype,char * regname,int regnum)197*1424dfb3Schristos itbl_add_reg (int yyprocessor, int yytype, char *regname,
198*1424dfb3Schristos int regnum)
199*1424dfb3Schristos {
200*1424dfb3Schristos return alloc_entry (get_processor (yyprocessor), get_type (yytype), regname,
201*1424dfb3Schristos (unsigned long) regnum);
202*1424dfb3Schristos }
203*1424dfb3Schristos
204*1424dfb3Schristos /* Add an instruction entry */
205*1424dfb3Schristos
206*1424dfb3Schristos struct itbl_entry *
itbl_add_insn(int yyprocessor,char * name,unsigned long value,int sbit,int ebit,unsigned long flags)207*1424dfb3Schristos itbl_add_insn (int yyprocessor, char *name, unsigned long value,
208*1424dfb3Schristos int sbit, int ebit, unsigned long flags)
209*1424dfb3Schristos {
210*1424dfb3Schristos struct itbl_entry *e;
211*1424dfb3Schristos e = alloc_entry (get_processor (yyprocessor), e_insn, name, value);
212*1424dfb3Schristos if (e)
213*1424dfb3Schristos {
214*1424dfb3Schristos e->range.sbit = sbit;
215*1424dfb3Schristos e->range.ebit = ebit;
216*1424dfb3Schristos e->flags = flags;
217*1424dfb3Schristos itbl_num_opcodes++;
218*1424dfb3Schristos }
219*1424dfb3Schristos return e;
220*1424dfb3Schristos }
221*1424dfb3Schristos
222*1424dfb3Schristos /* Add an operand to an instruction entry */
223*1424dfb3Schristos
224*1424dfb3Schristos struct itbl_field *
itbl_add_operand(struct itbl_entry * e,int yytype,int sbit,int ebit,unsigned long flags)225*1424dfb3Schristos itbl_add_operand (struct itbl_entry *e, int yytype, int sbit,
226*1424dfb3Schristos int ebit, unsigned long flags)
227*1424dfb3Schristos {
228*1424dfb3Schristos struct itbl_field *f, **last_f;
229*1424dfb3Schristos if (!e)
230*1424dfb3Schristos return 0;
231*1424dfb3Schristos /* Add to end of fields' list. */
232*1424dfb3Schristos f = alloc_field (get_type (yytype), sbit, ebit, flags);
233*1424dfb3Schristos if (f)
234*1424dfb3Schristos {
235*1424dfb3Schristos last_f = &e->fields;
236*1424dfb3Schristos while (*last_f)
237*1424dfb3Schristos last_f = &(*last_f)->next;
238*1424dfb3Schristos *last_f = f;
239*1424dfb3Schristos f->next = 0;
240*1424dfb3Schristos }
241*1424dfb3Schristos return f;
242*1424dfb3Schristos }
243*1424dfb3Schristos
244*1424dfb3Schristos /*======================================================================*/
245*1424dfb3Schristos /* Interfaces for assembler and disassembler */
246*1424dfb3Schristos
247*1424dfb3Schristos #ifndef STAND_ALONE
248*1424dfb3Schristos static void append_insns_as_macros (void);
249*1424dfb3Schristos
250*1424dfb3Schristos /* Initialize for gas. */
251*1424dfb3Schristos
252*1424dfb3Schristos void
itbl_init(void)253*1424dfb3Schristos itbl_init (void)
254*1424dfb3Schristos {
255*1424dfb3Schristos struct itbl_entry *e, **es;
256*1424dfb3Schristos e_processor procn;
257*1424dfb3Schristos e_type type;
258*1424dfb3Schristos
259*1424dfb3Schristos if (!itbl_have_entries)
260*1424dfb3Schristos return;
261*1424dfb3Schristos
262*1424dfb3Schristos /* Since register names don't have a prefix, put them in the symbol table so
263*1424dfb3Schristos they can't be used as symbols. This simplifies argument parsing as
264*1424dfb3Schristos we can let gas parse registers for us. */
265*1424dfb3Schristos /* Use symbol_create instead of symbol_new so we don't try to
266*1424dfb3Schristos output registers into the object file's symbol table. */
267*1424dfb3Schristos
268*1424dfb3Schristos for (type = e_regtype0; type < e_nregtypes; type++)
269*1424dfb3Schristos for (procn = e_p0; procn < e_nprocs; procn++)
270*1424dfb3Schristos {
271*1424dfb3Schristos es = get_entries (procn, type);
272*1424dfb3Schristos for (e = *es; e; e = e->next)
273*1424dfb3Schristos {
274*1424dfb3Schristos symbol_table_insert (symbol_create (e->name, reg_section,
275*1424dfb3Schristos &zero_address_frag, e->value));
276*1424dfb3Schristos }
277*1424dfb3Schristos }
278*1424dfb3Schristos append_insns_as_macros ();
279*1424dfb3Schristos }
280*1424dfb3Schristos
281*1424dfb3Schristos /* Append insns to opcodes table and increase number of opcodes
282*1424dfb3Schristos * Structure of opcodes table:
283*1424dfb3Schristos * struct itbl_opcode
284*1424dfb3Schristos * {
285*1424dfb3Schristos * const char *name;
286*1424dfb3Schristos * const char *args; - string describing the arguments.
287*1424dfb3Schristos * unsigned long match; - opcode, or ISA level if pinfo=INSN_MACRO
288*1424dfb3Schristos * unsigned long mask; - opcode mask, or macro id if pinfo=INSN_MACRO
289*1424dfb3Schristos * unsigned long pinfo; - insn flags, or INSN_MACRO
290*1424dfb3Schristos * };
291*1424dfb3Schristos * examples:
292*1424dfb3Schristos * {"li", "t,i", 0x34000000, 0xffe00000, WR_t },
293*1424dfb3Schristos * {"li", "t,I", 0, (int) M_LI, INSN_MACRO },
294*1424dfb3Schristos */
295*1424dfb3Schristos
296*1424dfb3Schristos static char *form_args (struct itbl_entry *e);
297*1424dfb3Schristos static void
append_insns_as_macros(void)298*1424dfb3Schristos append_insns_as_macros (void)
299*1424dfb3Schristos {
300*1424dfb3Schristos struct ITBL_OPCODE_STRUCT *new_opcodes, *o;
301*1424dfb3Schristos struct itbl_entry *e, **es;
302*1424dfb3Schristos int n, size, new_num_opcodes;
303*1424dfb3Schristos #ifdef USE_MACROS
304*1424dfb3Schristos int id;
305*1424dfb3Schristos #endif
306*1424dfb3Schristos
307*1424dfb3Schristos if (!itbl_have_entries)
308*1424dfb3Schristos return;
309*1424dfb3Schristos
310*1424dfb3Schristos if (!itbl_num_opcodes) /* no new instructions to add! */
311*1424dfb3Schristos {
312*1424dfb3Schristos return;
313*1424dfb3Schristos }
314*1424dfb3Schristos DBG (("previous num_opcodes=%d\n", ITBL_NUM_OPCODES));
315*1424dfb3Schristos
316*1424dfb3Schristos new_num_opcodes = ITBL_NUM_OPCODES + itbl_num_opcodes;
317*1424dfb3Schristos ASSERT (new_num_opcodes >= itbl_num_opcodes);
318*1424dfb3Schristos
319*1424dfb3Schristos size = sizeof (struct ITBL_OPCODE_STRUCT) * ITBL_NUM_OPCODES;
320*1424dfb3Schristos ASSERT (size >= 0);
321*1424dfb3Schristos DBG (("I get=%d\n", size / sizeof (ITBL_OPCODES[0])));
322*1424dfb3Schristos
323*1424dfb3Schristos /* FIXME since ITBL_OPCODES could be a static table,
324*1424dfb3Schristos we can't realloc or delete the old memory. */
325*1424dfb3Schristos new_opcodes = XNEWVEC (struct ITBL_OPCODE_STRUCT, new_num_opcodes);
326*1424dfb3Schristos if (!new_opcodes)
327*1424dfb3Schristos {
328*1424dfb3Schristos printf (_("Unable to allocate memory for new instructions\n"));
329*1424dfb3Schristos return;
330*1424dfb3Schristos }
331*1424dfb3Schristos if (size) /* copy preexisting opcodes table */
332*1424dfb3Schristos memcpy (new_opcodes, ITBL_OPCODES, size);
333*1424dfb3Schristos
334*1424dfb3Schristos /* FIXME! some NUMOPCODES are calculated expressions.
335*1424dfb3Schristos These need to be changed before itbls can be supported. */
336*1424dfb3Schristos
337*1424dfb3Schristos #ifdef USE_MACROS
338*1424dfb3Schristos id = ITBL_NUM_MACROS; /* begin the next macro id after the last */
339*1424dfb3Schristos #endif
340*1424dfb3Schristos o = &new_opcodes[ITBL_NUM_OPCODES]; /* append macro to opcodes list */
341*1424dfb3Schristos for (n = e_p0; n < e_nprocs; n++)
342*1424dfb3Schristos {
343*1424dfb3Schristos es = get_entries (n, e_insn);
344*1424dfb3Schristos for (e = *es; e; e = e->next)
345*1424dfb3Schristos {
346*1424dfb3Schristos /* name, args, mask, match, pinfo
347*1424dfb3Schristos * {"li", "t,i", 0x34000000, 0xffe00000, WR_t },
348*1424dfb3Schristos * {"li", "t,I", 0, (int) M_LI, INSN_MACRO },
349*1424dfb3Schristos * Construct args from itbl_fields.
350*1424dfb3Schristos */
351*1424dfb3Schristos o->name = e->name;
352*1424dfb3Schristos o->args = strdup (form_args (e));
353*1424dfb3Schristos o->mask = apply_range (e->value, e->range);
354*1424dfb3Schristos /* FIXME how to catch during assembly? */
355*1424dfb3Schristos /* mask to identify this insn */
356*1424dfb3Schristos o->match = apply_range (e->value, e->range);
357*1424dfb3Schristos o->pinfo = 0;
358*1424dfb3Schristos
359*1424dfb3Schristos #ifdef USE_MACROS
360*1424dfb3Schristos o->mask = id++; /* FIXME how to catch during assembly? */
361*1424dfb3Schristos o->match = 0; /* for macros, the insn_isa number */
362*1424dfb3Schristos o->pinfo = INSN_MACRO;
363*1424dfb3Schristos #endif
364*1424dfb3Schristos
365*1424dfb3Schristos /* Don't add instructions which caused an error */
366*1424dfb3Schristos if (o->args)
367*1424dfb3Schristos o++;
368*1424dfb3Schristos else
369*1424dfb3Schristos new_num_opcodes--;
370*1424dfb3Schristos }
371*1424dfb3Schristos }
372*1424dfb3Schristos ITBL_OPCODES = new_opcodes;
373*1424dfb3Schristos ITBL_NUM_OPCODES = new_num_opcodes;
374*1424dfb3Schristos
375*1424dfb3Schristos /* FIXME
376*1424dfb3Schristos At this point, we can free the entries, as they should have
377*1424dfb3Schristos been added to the assembler's tables.
378*1424dfb3Schristos Don't free name though, since name is being used by the new
379*1424dfb3Schristos opcodes table.
380*1424dfb3Schristos
381*1424dfb3Schristos Eventually, we should also free the new opcodes table itself
382*1424dfb3Schristos on exit.
383*1424dfb3Schristos */
384*1424dfb3Schristos }
385*1424dfb3Schristos
386*1424dfb3Schristos static char *
form_args(struct itbl_entry * e)387*1424dfb3Schristos form_args (struct itbl_entry *e)
388*1424dfb3Schristos {
389*1424dfb3Schristos static char s[31];
390*1424dfb3Schristos char c = 0, *p = s;
391*1424dfb3Schristos struct itbl_field *f;
392*1424dfb3Schristos
393*1424dfb3Schristos ASSERT (e);
394*1424dfb3Schristos for (f = e->fields; f; f = f->next)
395*1424dfb3Schristos {
396*1424dfb3Schristos switch (f->type)
397*1424dfb3Schristos {
398*1424dfb3Schristos case e_dreg:
399*1424dfb3Schristos c = 'd';
400*1424dfb3Schristos break;
401*1424dfb3Schristos case e_creg:
402*1424dfb3Schristos c = 't';
403*1424dfb3Schristos break;
404*1424dfb3Schristos case e_greg:
405*1424dfb3Schristos c = 's';
406*1424dfb3Schristos break;
407*1424dfb3Schristos case e_immed:
408*1424dfb3Schristos c = 'i';
409*1424dfb3Schristos break;
410*1424dfb3Schristos case e_addr:
411*1424dfb3Schristos c = 'a';
412*1424dfb3Schristos break;
413*1424dfb3Schristos default:
414*1424dfb3Schristos c = 0; /* ignore; unknown field type */
415*1424dfb3Schristos }
416*1424dfb3Schristos if (c)
417*1424dfb3Schristos {
418*1424dfb3Schristos if (p != s)
419*1424dfb3Schristos *p++ = ',';
420*1424dfb3Schristos *p++ = c;
421*1424dfb3Schristos }
422*1424dfb3Schristos }
423*1424dfb3Schristos *p = 0;
424*1424dfb3Schristos return s;
425*1424dfb3Schristos }
426*1424dfb3Schristos #endif /* !STAND_ALONE */
427*1424dfb3Schristos
428*1424dfb3Schristos /* Get processor's register name from val */
429*1424dfb3Schristos
430*1424dfb3Schristos int
itbl_get_reg_val(char * name,unsigned long * pval)431*1424dfb3Schristos itbl_get_reg_val (char *name, unsigned long *pval)
432*1424dfb3Schristos {
433*1424dfb3Schristos e_type t;
434*1424dfb3Schristos e_processor p;
435*1424dfb3Schristos
436*1424dfb3Schristos for (p = e_p0; p < e_nprocs; p++)
437*1424dfb3Schristos {
438*1424dfb3Schristos for (t = e_regtype0; t < e_nregtypes; t++)
439*1424dfb3Schristos {
440*1424dfb3Schristos if (itbl_get_val (p, t, name, pval))
441*1424dfb3Schristos return 1;
442*1424dfb3Schristos }
443*1424dfb3Schristos }
444*1424dfb3Schristos return 0;
445*1424dfb3Schristos }
446*1424dfb3Schristos
447*1424dfb3Schristos char *
itbl_get_name(e_processor processor,e_type type,unsigned long val)448*1424dfb3Schristos itbl_get_name (e_processor processor, e_type type, unsigned long val)
449*1424dfb3Schristos {
450*1424dfb3Schristos struct itbl_entry *r;
451*1424dfb3Schristos /* type depends on instruction passed */
452*1424dfb3Schristos r = find_entry_byval (processor, type, val, 0);
453*1424dfb3Schristos if (r)
454*1424dfb3Schristos return r->name;
455*1424dfb3Schristos else
456*1424dfb3Schristos return 0; /* error; invalid operand */
457*1424dfb3Schristos }
458*1424dfb3Schristos
459*1424dfb3Schristos /* Get processor's register value from name */
460*1424dfb3Schristos
461*1424dfb3Schristos int
itbl_get_val(e_processor processor,e_type type,char * name,unsigned long * pval)462*1424dfb3Schristos itbl_get_val (e_processor processor, e_type type, char *name,
463*1424dfb3Schristos unsigned long *pval)
464*1424dfb3Schristos {
465*1424dfb3Schristos struct itbl_entry *r;
466*1424dfb3Schristos /* type depends on instruction passed */
467*1424dfb3Schristos r = find_entry_byname (processor, type, name);
468*1424dfb3Schristos if (r == NULL)
469*1424dfb3Schristos return 0;
470*1424dfb3Schristos *pval = r->value;
471*1424dfb3Schristos return 1;
472*1424dfb3Schristos }
473*1424dfb3Schristos
474*1424dfb3Schristos /* Assemble instruction "name" with operands "s".
475*1424dfb3Schristos * name - name of instruction
476*1424dfb3Schristos * s - operands
477*1424dfb3Schristos * returns - long word for assembled instruction */
478*1424dfb3Schristos
479*1424dfb3Schristos unsigned long
itbl_assemble(char * name,char * s)480*1424dfb3Schristos itbl_assemble (char *name, char *s)
481*1424dfb3Schristos {
482*1424dfb3Schristos unsigned long opcode;
483*1424dfb3Schristos struct itbl_entry *e = NULL;
484*1424dfb3Schristos struct itbl_field *f;
485*1424dfb3Schristos char *n;
486*1424dfb3Schristos int processor;
487*1424dfb3Schristos
488*1424dfb3Schristos if (!name || !*name)
489*1424dfb3Schristos return 0; /* error! must have an opcode name/expr */
490*1424dfb3Schristos
491*1424dfb3Schristos /* find entry in list of instructions for all processors */
492*1424dfb3Schristos for (processor = 0; processor < e_nprocs; processor++)
493*1424dfb3Schristos {
494*1424dfb3Schristos e = find_entry_byname (processor, e_insn, name);
495*1424dfb3Schristos if (e)
496*1424dfb3Schristos break;
497*1424dfb3Schristos }
498*1424dfb3Schristos if (!e)
499*1424dfb3Schristos return 0; /* opcode not in table; invalid instruction */
500*1424dfb3Schristos opcode = build_opcode (e);
501*1424dfb3Schristos
502*1424dfb3Schristos /* parse opcode's args (if any) */
503*1424dfb3Schristos for (f = e->fields; f; f = f->next) /* for each arg, ... */
504*1424dfb3Schristos {
505*1424dfb3Schristos struct itbl_entry *r;
506*1424dfb3Schristos unsigned long value;
507*1424dfb3Schristos if (!s || !*s)
508*1424dfb3Schristos return 0; /* error - not enough operands */
509*1424dfb3Schristos n = itbl_get_field (&s);
510*1424dfb3Schristos /* n should be in form $n or 0xhhh (are symbol names valid?? */
511*1424dfb3Schristos switch (f->type)
512*1424dfb3Schristos {
513*1424dfb3Schristos case e_dreg:
514*1424dfb3Schristos case e_creg:
515*1424dfb3Schristos case e_greg:
516*1424dfb3Schristos /* Accept either a string name
517*1424dfb3Schristos * or '$' followed by the register number */
518*1424dfb3Schristos if (*n == '$')
519*1424dfb3Schristos {
520*1424dfb3Schristos n++;
521*1424dfb3Schristos value = strtol (n, 0, 10);
522*1424dfb3Schristos /* FIXME! could have "0l"... then what?? */
523*1424dfb3Schristos if (value == 0 && *n != '0')
524*1424dfb3Schristos return 0; /* error; invalid operand */
525*1424dfb3Schristos }
526*1424dfb3Schristos else
527*1424dfb3Schristos {
528*1424dfb3Schristos r = find_entry_byname (e->processor, f->type, n);
529*1424dfb3Schristos if (r)
530*1424dfb3Schristos value = r->value;
531*1424dfb3Schristos else
532*1424dfb3Schristos return 0; /* error; invalid operand */
533*1424dfb3Schristos }
534*1424dfb3Schristos break;
535*1424dfb3Schristos case e_addr:
536*1424dfb3Schristos /* use assembler's symbol table to find symbol */
537*1424dfb3Schristos /* FIXME!! Do we need this?
538*1424dfb3Schristos if so, what about relocs??
539*1424dfb3Schristos my_getExpression (&imm_expr, s);
540*1424dfb3Schristos return 0; /-* error; invalid operand *-/
541*1424dfb3Schristos break;
542*1424dfb3Schristos */
543*1424dfb3Schristos /* If not a symbol, fallthru to IMMED */
544*1424dfb3Schristos case e_immed:
545*1424dfb3Schristos if (*n == '0' && *(n + 1) == 'x') /* hex begins 0x... */
546*1424dfb3Schristos {
547*1424dfb3Schristos n += 2;
548*1424dfb3Schristos value = strtol (n, 0, 16);
549*1424dfb3Schristos /* FIXME! could have "0xl"... then what?? */
550*1424dfb3Schristos }
551*1424dfb3Schristos else
552*1424dfb3Schristos {
553*1424dfb3Schristos value = strtol (n, 0, 10);
554*1424dfb3Schristos /* FIXME! could have "0l"... then what?? */
555*1424dfb3Schristos if (value == 0 && *n != '0')
556*1424dfb3Schristos return 0; /* error; invalid operand */
557*1424dfb3Schristos }
558*1424dfb3Schristos break;
559*1424dfb3Schristos default:
560*1424dfb3Schristos return 0; /* error; invalid field spec */
561*1424dfb3Schristos }
562*1424dfb3Schristos opcode |= apply_range (value, f->range);
563*1424dfb3Schristos }
564*1424dfb3Schristos if (s && *s)
565*1424dfb3Schristos return 0; /* error - too many operands */
566*1424dfb3Schristos return opcode; /* done! */
567*1424dfb3Schristos }
568*1424dfb3Schristos
569*1424dfb3Schristos /* Disassemble instruction "insn".
570*1424dfb3Schristos * insn - instruction
571*1424dfb3Schristos * s - buffer to hold disassembled instruction
572*1424dfb3Schristos * returns - 1 if succeeded; 0 if failed
573*1424dfb3Schristos */
574*1424dfb3Schristos
575*1424dfb3Schristos int
itbl_disassemble(char * s,unsigned long insn)576*1424dfb3Schristos itbl_disassemble (char *s, unsigned long insn)
577*1424dfb3Schristos {
578*1424dfb3Schristos e_processor processor;
579*1424dfb3Schristos struct itbl_entry *e;
580*1424dfb3Schristos struct itbl_field *f;
581*1424dfb3Schristos
582*1424dfb3Schristos if (!ITBL_IS_INSN (insn))
583*1424dfb3Schristos return 0; /* error */
584*1424dfb3Schristos processor = get_processor (ITBL_DECODE_PNUM (insn));
585*1424dfb3Schristos
586*1424dfb3Schristos /* find entry in list */
587*1424dfb3Schristos e = find_entry_byval (processor, e_insn, insn, 0);
588*1424dfb3Schristos if (!e)
589*1424dfb3Schristos return 0; /* opcode not in table; invalid instruction */
590*1424dfb3Schristos strcpy (s, e->name);
591*1424dfb3Schristos
592*1424dfb3Schristos /* Parse insn's args (if any). */
593*1424dfb3Schristos for (f = e->fields; f; f = f->next) /* for each arg, ... */
594*1424dfb3Schristos {
595*1424dfb3Schristos struct itbl_entry *r;
596*1424dfb3Schristos unsigned long value;
597*1424dfb3Schristos char s_value[20];
598*1424dfb3Schristos
599*1424dfb3Schristos if (f == e->fields) /* First operand is preceded by tab. */
600*1424dfb3Schristos strcat (s, "\t");
601*1424dfb3Schristos else /* ','s separate following operands. */
602*1424dfb3Schristos strcat (s, ",");
603*1424dfb3Schristos value = extract_range (insn, f->range);
604*1424dfb3Schristos /* n should be in form $n or 0xhhh (are symbol names valid?? */
605*1424dfb3Schristos switch (f->type)
606*1424dfb3Schristos {
607*1424dfb3Schristos case e_dreg:
608*1424dfb3Schristos case e_creg:
609*1424dfb3Schristos case e_greg:
610*1424dfb3Schristos /* Accept either a string name
611*1424dfb3Schristos or '$' followed by the register number. */
612*1424dfb3Schristos r = find_entry_byval (e->processor, f->type, value, &f->range);
613*1424dfb3Schristos if (r)
614*1424dfb3Schristos strcat (s, r->name);
615*1424dfb3Schristos else
616*1424dfb3Schristos {
617*1424dfb3Schristos sprintf (s_value, "$%lu", value);
618*1424dfb3Schristos strcat (s, s_value);
619*1424dfb3Schristos }
620*1424dfb3Schristos break;
621*1424dfb3Schristos case e_addr:
622*1424dfb3Schristos /* Use assembler's symbol table to find symbol. */
623*1424dfb3Schristos /* FIXME!! Do we need this? If so, what about relocs?? */
624*1424dfb3Schristos /* If not a symbol, fall through to IMMED. */
625*1424dfb3Schristos case e_immed:
626*1424dfb3Schristos sprintf (s_value, "0x%lx", value);
627*1424dfb3Schristos strcat (s, s_value);
628*1424dfb3Schristos break;
629*1424dfb3Schristos default:
630*1424dfb3Schristos return 0; /* error; invalid field spec */
631*1424dfb3Schristos }
632*1424dfb3Schristos }
633*1424dfb3Schristos return 1; /* Done! */
634*1424dfb3Schristos }
635*1424dfb3Schristos
636*1424dfb3Schristos /*======================================================================*/
637*1424dfb3Schristos /*
638*1424dfb3Schristos * Local functions for manipulating private structures containing
639*1424dfb3Schristos * the names and format for the new instructions and registers
640*1424dfb3Schristos * for each processor.
641*1424dfb3Schristos */
642*1424dfb3Schristos
643*1424dfb3Schristos /* Calculate instruction's opcode and function values from entry */
644*1424dfb3Schristos
645*1424dfb3Schristos static unsigned long
build_opcode(struct itbl_entry * e)646*1424dfb3Schristos build_opcode (struct itbl_entry *e)
647*1424dfb3Schristos {
648*1424dfb3Schristos unsigned long opcode;
649*1424dfb3Schristos
650*1424dfb3Schristos opcode = apply_range (e->value, e->range);
651*1424dfb3Schristos opcode |= ITBL_ENCODE_PNUM (e->processor);
652*1424dfb3Schristos return opcode;
653*1424dfb3Schristos }
654*1424dfb3Schristos
655*1424dfb3Schristos /* Calculate absolute value given the relative value and bit position range
656*1424dfb3Schristos * within the instruction.
657*1424dfb3Schristos * The range is inclusive where 0 is least significant bit.
658*1424dfb3Schristos * A range of { 24, 20 } will have a mask of
659*1424dfb3Schristos * bit 3 2 1
660*1424dfb3Schristos * pos: 1098 7654 3210 9876 5432 1098 7654 3210
661*1424dfb3Schristos * bin: 0000 0001 1111 0000 0000 0000 0000 0000
662*1424dfb3Schristos * hex: 0 1 f 0 0 0 0 0
663*1424dfb3Schristos * mask: 0x01f00000.
664*1424dfb3Schristos */
665*1424dfb3Schristos
666*1424dfb3Schristos static unsigned long
apply_range(unsigned long rval,struct itbl_range r)667*1424dfb3Schristos apply_range (unsigned long rval, struct itbl_range r)
668*1424dfb3Schristos {
669*1424dfb3Schristos unsigned long mask;
670*1424dfb3Schristos unsigned long aval;
671*1424dfb3Schristos int len = MAX_BITPOS - r.sbit;
672*1424dfb3Schristos
673*1424dfb3Schristos ASSERT (r.sbit >= r.ebit);
674*1424dfb3Schristos ASSERT (MAX_BITPOS >= r.sbit);
675*1424dfb3Schristos ASSERT (r.ebit >= 0);
676*1424dfb3Schristos
677*1424dfb3Schristos /* create mask by truncating 1s by shifting */
678*1424dfb3Schristos mask = 0xffffffff << len;
679*1424dfb3Schristos mask = mask >> len;
680*1424dfb3Schristos mask = mask >> r.ebit;
681*1424dfb3Schristos mask = mask << r.ebit;
682*1424dfb3Schristos
683*1424dfb3Schristos aval = (rval << r.ebit) & mask;
684*1424dfb3Schristos return aval;
685*1424dfb3Schristos }
686*1424dfb3Schristos
687*1424dfb3Schristos /* Calculate relative value given the absolute value and bit position range
688*1424dfb3Schristos * within the instruction. */
689*1424dfb3Schristos
690*1424dfb3Schristos static unsigned long
extract_range(unsigned long aval,struct itbl_range r)691*1424dfb3Schristos extract_range (unsigned long aval, struct itbl_range r)
692*1424dfb3Schristos {
693*1424dfb3Schristos unsigned long mask;
694*1424dfb3Schristos unsigned long rval;
695*1424dfb3Schristos int len = MAX_BITPOS - r.sbit;
696*1424dfb3Schristos
697*1424dfb3Schristos /* create mask by truncating 1s by shifting */
698*1424dfb3Schristos mask = 0xffffffff << len;
699*1424dfb3Schristos mask = mask >> len;
700*1424dfb3Schristos mask = mask >> r.ebit;
701*1424dfb3Schristos mask = mask << r.ebit;
702*1424dfb3Schristos
703*1424dfb3Schristos rval = (aval & mask) >> r.ebit;
704*1424dfb3Schristos return rval;
705*1424dfb3Schristos }
706*1424dfb3Schristos
707*1424dfb3Schristos /* Extract processor's assembly instruction field name from s;
708*1424dfb3Schristos * forms are "n args" "n,args" or "n" */
709*1424dfb3Schristos /* Return next argument from string pointer "s" and advance s.
710*1424dfb3Schristos * delimiters are " ,()" */
711*1424dfb3Schristos
712*1424dfb3Schristos char *
itbl_get_field(char ** S)713*1424dfb3Schristos itbl_get_field (char **S)
714*1424dfb3Schristos {
715*1424dfb3Schristos static char n[128];
716*1424dfb3Schristos char *s;
717*1424dfb3Schristos int len;
718*1424dfb3Schristos
719*1424dfb3Schristos s = *S;
720*1424dfb3Schristos if (!s || !*s)
721*1424dfb3Schristos return 0;
722*1424dfb3Schristos /* FIXME: This is a weird set of delimiters. */
723*1424dfb3Schristos len = strcspn (s, " \t,()");
724*1424dfb3Schristos ASSERT (128 > len + 1);
725*1424dfb3Schristos strncpy (n, s, len);
726*1424dfb3Schristos n[len] = 0;
727*1424dfb3Schristos if (s[len] == '\0')
728*1424dfb3Schristos s = 0; /* no more args */
729*1424dfb3Schristos else
730*1424dfb3Schristos s += len + 1; /* advance to next arg */
731*1424dfb3Schristos
732*1424dfb3Schristos *S = s;
733*1424dfb3Schristos return n;
734*1424dfb3Schristos }
735*1424dfb3Schristos
736*1424dfb3Schristos /* Search entries for a given processor and type
737*1424dfb3Schristos * to find one matching the name "n".
738*1424dfb3Schristos * Return a pointer to the entry */
739*1424dfb3Schristos
740*1424dfb3Schristos static struct itbl_entry *
find_entry_byname(e_processor processor,e_type type,char * n)741*1424dfb3Schristos find_entry_byname (e_processor processor,
742*1424dfb3Schristos e_type type, char *n)
743*1424dfb3Schristos {
744*1424dfb3Schristos struct itbl_entry *e, **es;
745*1424dfb3Schristos
746*1424dfb3Schristos es = get_entries (processor, type);
747*1424dfb3Schristos for (e = *es; e; e = e->next) /* for each entry, ... */
748*1424dfb3Schristos {
749*1424dfb3Schristos if (!strcmp (e->name, n))
750*1424dfb3Schristos return e;
751*1424dfb3Schristos }
752*1424dfb3Schristos return 0;
753*1424dfb3Schristos }
754*1424dfb3Schristos
755*1424dfb3Schristos /* Search entries for a given processor and type
756*1424dfb3Schristos * to find one matching the value "val" for the range "r".
757*1424dfb3Schristos * Return a pointer to the entry.
758*1424dfb3Schristos * This function is used for disassembling fields of an instruction.
759*1424dfb3Schristos */
760*1424dfb3Schristos
761*1424dfb3Schristos static struct itbl_entry *
find_entry_byval(e_processor processor,e_type type,unsigned long val,struct itbl_range * r)762*1424dfb3Schristos find_entry_byval (e_processor processor, e_type type,
763*1424dfb3Schristos unsigned long val, struct itbl_range *r)
764*1424dfb3Schristos {
765*1424dfb3Schristos struct itbl_entry *e, **es;
766*1424dfb3Schristos unsigned long eval;
767*1424dfb3Schristos
768*1424dfb3Schristos es = get_entries (processor, type);
769*1424dfb3Schristos for (e = *es; e; e = e->next) /* for each entry, ... */
770*1424dfb3Schristos {
771*1424dfb3Schristos if (processor != e->processor)
772*1424dfb3Schristos continue;
773*1424dfb3Schristos /* For insns, we might not know the range of the opcode,
774*1424dfb3Schristos * so a range of 0 will allow this routine to match against
775*1424dfb3Schristos * the range of the entry to be compared with.
776*1424dfb3Schristos * This could cause ambiguities.
777*1424dfb3Schristos * For operands, we get an extracted value and a range.
778*1424dfb3Schristos */
779*1424dfb3Schristos /* if range is 0, mask val against the range of the compared entry. */
780*1424dfb3Schristos if (r == 0) /* if no range passed, must be whole 32-bits
781*1424dfb3Schristos * so create 32-bit value from entry's range */
782*1424dfb3Schristos {
783*1424dfb3Schristos eval = apply_range (e->value, e->range);
784*1424dfb3Schristos val &= apply_range (0xffffffff, e->range);
785*1424dfb3Schristos }
786*1424dfb3Schristos else if ((r->sbit == e->range.sbit && r->ebit == e->range.ebit)
787*1424dfb3Schristos || (e->range.sbit == 0 && e->range.ebit == 0))
788*1424dfb3Schristos {
789*1424dfb3Schristos eval = apply_range (e->value, *r);
790*1424dfb3Schristos val = apply_range (val, *r);
791*1424dfb3Schristos }
792*1424dfb3Schristos else
793*1424dfb3Schristos continue;
794*1424dfb3Schristos if (val == eval)
795*1424dfb3Schristos return e;
796*1424dfb3Schristos }
797*1424dfb3Schristos return 0;
798*1424dfb3Schristos }
799*1424dfb3Schristos
800*1424dfb3Schristos /* Return a pointer to the list of entries for a given processor and type. */
801*1424dfb3Schristos
802*1424dfb3Schristos static struct itbl_entry **
get_entries(e_processor processor,e_type type)803*1424dfb3Schristos get_entries (e_processor processor, e_type type)
804*1424dfb3Schristos {
805*1424dfb3Schristos return &entries[processor][type];
806*1424dfb3Schristos }
807*1424dfb3Schristos
808*1424dfb3Schristos /* Return an integral value for the processor passed from yyparse. */
809*1424dfb3Schristos
810*1424dfb3Schristos static e_processor
get_processor(int yyproc)811*1424dfb3Schristos get_processor (int yyproc)
812*1424dfb3Schristos {
813*1424dfb3Schristos /* translate from yacc's processor to enum */
814*1424dfb3Schristos if (yyproc >= e_p0 && yyproc < e_nprocs)
815*1424dfb3Schristos return (e_processor) yyproc;
816*1424dfb3Schristos return e_invproc; /* error; invalid processor */
817*1424dfb3Schristos }
818*1424dfb3Schristos
819*1424dfb3Schristos /* Return an integral value for the entry type passed from yyparse. */
820*1424dfb3Schristos
821*1424dfb3Schristos static e_type
get_type(int yytype)822*1424dfb3Schristos get_type (int yytype)
823*1424dfb3Schristos {
824*1424dfb3Schristos switch (yytype)
825*1424dfb3Schristos {
826*1424dfb3Schristos /* translate from yacc's type to enum */
827*1424dfb3Schristos case INSN:
828*1424dfb3Schristos return e_insn;
829*1424dfb3Schristos case DREG:
830*1424dfb3Schristos return e_dreg;
831*1424dfb3Schristos case CREG:
832*1424dfb3Schristos return e_creg;
833*1424dfb3Schristos case GREG:
834*1424dfb3Schristos return e_greg;
835*1424dfb3Schristos case ADDR:
836*1424dfb3Schristos return e_addr;
837*1424dfb3Schristos case IMMED:
838*1424dfb3Schristos return e_immed;
839*1424dfb3Schristos default:
840*1424dfb3Schristos return e_invtype; /* error; invalid type */
841*1424dfb3Schristos }
842*1424dfb3Schristos }
843*1424dfb3Schristos
844*1424dfb3Schristos /* Allocate and initialize an entry */
845*1424dfb3Schristos
846*1424dfb3Schristos static struct itbl_entry *
alloc_entry(e_processor processor,e_type type,char * name,unsigned long value)847*1424dfb3Schristos alloc_entry (e_processor processor, e_type type,
848*1424dfb3Schristos char *name, unsigned long value)
849*1424dfb3Schristos {
850*1424dfb3Schristos struct itbl_entry *e, **es;
851*1424dfb3Schristos if (!name)
852*1424dfb3Schristos return 0;
853*1424dfb3Schristos e = XNEW (struct itbl_entry);
854*1424dfb3Schristos if (e)
855*1424dfb3Schristos {
856*1424dfb3Schristos memset (e, 0, sizeof (struct itbl_entry));
857*1424dfb3Schristos e->name = xstrdup (name);
858*1424dfb3Schristos e->processor = processor;
859*1424dfb3Schristos e->type = type;
860*1424dfb3Schristos e->value = value;
861*1424dfb3Schristos es = get_entries (e->processor, e->type);
862*1424dfb3Schristos e->next = *es;
863*1424dfb3Schristos *es = e;
864*1424dfb3Schristos }
865*1424dfb3Schristos return e;
866*1424dfb3Schristos }
867*1424dfb3Schristos
868*1424dfb3Schristos /* Allocate and initialize an entry's field */
869*1424dfb3Schristos
870*1424dfb3Schristos static struct itbl_field *
alloc_field(e_type type,int sbit,int ebit,unsigned long flags)871*1424dfb3Schristos alloc_field (e_type type, int sbit, int ebit,
872*1424dfb3Schristos unsigned long flags)
873*1424dfb3Schristos {
874*1424dfb3Schristos struct itbl_field *f;
875*1424dfb3Schristos f = XNEW (struct itbl_field);
876*1424dfb3Schristos if (f)
877*1424dfb3Schristos {
878*1424dfb3Schristos memset (f, 0, sizeof (struct itbl_field));
879*1424dfb3Schristos f->type = type;
880*1424dfb3Schristos f->range.sbit = sbit;
881*1424dfb3Schristos f->range.ebit = ebit;
882*1424dfb3Schristos f->flags = flags;
883*1424dfb3Schristos }
884*1424dfb3Schristos return f;
885*1424dfb3Schristos }
886