xref: /netbsd/external/gpl3/gdb/dist/gas/itbl-ops.c (revision 1424dfb3)
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