itbl-parse.y revision 33965
1/* itbl-parse.y
2   Copyright (C) 1997  Free Software Foundation, Inc.
3
4   This file is part of GAS, the GNU Assembler.
5
6   GAS is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   GAS is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with GAS; see the file COPYING.  If not, write to the Free
18   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.  */
20
21%{
22
23/*
24
25Yacc grammar for instruction table entries.
26
27=======================================================================
28Original Instruction table specification document:
29
30	    MIPS Coprocessor Table Specification
31	    ====================================
32
33This document describes the format of the MIPS coprocessor table.  The
34table specifies a list of valid functions, data registers and control
35registers that can be used in coprocessor instructions.  This list,
36together with the coprocessor instruction classes listed below,
37specifies the complete list of coprocessor instructions that will
38be recognized and assembled by the GNU assembler.  In effect,
39this makes the GNU assembler table-driven, where the table is
40specified by the programmer.
41
42The table is an ordinary text file that the GNU assembler reads when
43it starts.  Using the information in the table, the assembler
44generates an internal list of valid coprocessor registers and
45functions.  The assembler uses this internal list in addition to the
46standard MIPS registers and instructions which are built-in to the
47assembler during code generation.
48
49To specify the coprocessor table when invoking the GNU assembler, use
50the command line option "--itbl file", where file is the
51complete name of the table, including path and extension.
52
53Examples:
54
55	    gas -t cop.tbl test.s -o test.o
56	    gas -t /usr/local/lib/cop.tbl test.s -o test.o
57	    gas --itbl d:\gnu\data\cop.tbl test.s -o test.o
58
59Only one table may be supplied during a single invocation of
60the assembler.
61
62
63Instruction classes
64===================
65
66Below is a list of the valid coprocessor instruction classes for
67any given coprocessor "z".  These instructions are already recognized
68by the assembler, and are listed here only for reference.
69
70Class   format	    	    	      instructions
71-------------------------------------------------
72Class1:
73	op base rt offset
74	    	    	    	    	    	    	    LWCz rt,offset (base)
75	    	    	    	    	    	    	    SWCz rt,offset (base)
76Class2:
77	COPz sub rt rd 0
78	    	    	    	    	    	    	    MTCz rt,rd
79	    	    	    	    	    	    	    MFCz rt,rd
80	    	    	    	    	    	    	    CTCz rt,rd
81	    	    	    	    	    	    	    CFCz rt,rd
82Class3:
83	COPz CO cofun
84	    	    	    	    	    	    	    COPz cofun
85Class4:
86	COPz BC br offset
87	    	    	    	    	    	    	    BCzT offset
88	    	    	    	    	    	    	    BCzF offset
89Class5:
90	COPz sub rt rd 0
91	    	    	    	    	    	    	    DMFCz rt,rd
92	    	    	    	    	    	    	    DMTCz rt,rd
93Class6:
94	op base rt offset
95	    	    	    	    	    	    	    LDCz rt,offset (base)
96	    	    	    	    	    	    	    SDCz rt,offset (base)
97Class7:
98	COPz BC br offset
99	    	    	    	    	    	    	    BCzTL offset
100	    	    	    	    	    	    	    BCzFL offset
101
102The coprocessor table defines coprocessor-specific registers that can
103be used with all of the above classes of instructions, where
104appropriate.  It also defines additional coprocessor-specific
105functions for Class3 (COPz cofun) instructions, Thus, the table allows
106the programmer to use convenient mnemonics and operands for these
107functions, instead of the COPz mmenmonic and cofun operand.
108
109The names of the MIPS general registers and their aliases are defined
110by the assembler and will be recognized as valid register names by the
111assembler when used (where allowed) in coprocessor instructions.
112However, the names and values of all coprocessor data and control
113register mnemonics must be specified in the coprocessor table.
114
115
116Table Grammar
117=============
118
119Here is the grammar for the coprocessor table:
120
121	    table -> entry*
122
123	    entry -> [z entrydef] [comment] '\n'
124
125	    entrydef -> type name val
126	    entrydef -> 'insn' name val funcdef ; type of entry (instruction)
127
128	    z -> 'p'['0'..'3']	    	     ; processor number
129	    type -> ['dreg' | 'creg' | 'greg' ]	     ; type of entry (register)
130	; 'dreg', 'creg' or 'greg' specifies a data, control, or general
131	;	    register mnemonic, respectively
132	    name -> [ltr|dec]*	    	     ; mnemonic of register/function
133	    val -> [dec|hex]	    	     ; register/function number (integer constant)
134
135	    funcdef -> frange flags fields
136	    	    	    	; bitfield range for opcode
137	    	    	    	; list of fields' formats
138	    fields -> field*
139	    field -> [','] ftype frange flags
140	    flags -> ['*' flagexpr]
141	    flagexpr -> '[' flagexpr ']'
142	    flagexpr -> val '|' flagexpr
143	    ftype -> [ type | 'immed' | 'addr' ]
144	; 'immed' specifies an immediate value; see grammar for "val" above
145	    	; 'addr' specifies a C identifier; name of symbol to be resolved at
146	;	    link time
147	    frange -> ':' val '-' val	; starting to ending bit positions, where
148	    	    	    	; where 0 is least significant bit
149	    frange -> (null)	    	; default range of 31-0 will be assumed
150
151	    comment -> [';'|'#'] [char]*
152	    char -> any printable character
153	    ltr -> ['a'..'z'|'A'..'Z']
154	    dec -> ['0'..'9']*	    	    	    	    	     ; value in decimal
155	    hex -> '0x'['0'..'9' | 'a'..'f' | 'A'..'F']*	; value in hexidecimal
156
157
158Examples
159========
160
161Example 1:
162
163The table:
164
165	    p1 dreg d1 1	     ; data register "d1" for COP1 has value 1
166	    p1 creg c3 3	     ; ctrl register "c3" for COP1 has value 3
167	    p3 func fill 0x1f:24-20	      ; function "fill" for COP3 has value 31 and
168	    	    	; no fields
169
170will allow the assembler to accept the following coprocessor instructions:
171
172	    LWC1 d1,0x100 ($2)
173	    fill
174
175Here, the general purpose register "$2", and instruction "LWC1", are standard
176mnemonics built-in to the MIPS assembler.
177
178
179Example 2:
180
181The table:
182
183	    p3 dreg d3 3	     ; data register "d3" for COP3 has value 3
184	    p3 creg c2 22	     ; control register "c2" for COP3 has value 22
185	    p3 func fee 0x1f:24-20 dreg:17-13 creg:12-8 immed:7-0
186	    	; function "fee" for COP3 has value 31, and 3 fields
187	    	; consisting of a data register, a control register,
188	    	; and an immediate value.
189
190will allow the assembler to accept the following coprocessor instruction:
191
192	    fee d3,c2,0x1
193
194and will emit the object code:
195
196	    31-26  25 24-20 19-18  17-13 12-8  7-0
197	    COPz   CO fun	    	      dreg  creg  immed
198	    010011 1  11111 00	     00011 10110 00000001
199
200	    0x4ff07601
201
202
203Example 3:
204
205The table:
206
207	    p3 dreg d3 3	     ; data register "d3" for COP3 has value 3
208	    p3 creg c2 22	     ; control register "c2" for COP3 has value 22
209	    p3 func fuu 0x01f00001 dreg:17-13 creg:12-8
210
211will allow the assembler to accept the following coprocessor
212instruction:
213
214	    fuu d3,c2
215
216and will emit the object code:
217
218	    31-26  25 24-20 19-18  17-13 12-8  7-0
219	    COPz   CO fun	    	      dreg  creg
220	    010011 1  11111 00	     00011 10110 00000001
221
222	    0x4ff07601
223
224In this way, the programmer can force arbitrary bits of an instruction
225to have predefined values.
226
227=======================================================================
228Additional notes:
229
230Encoding of ranges:
231To handle more than one bit position range within an instruction,
232use 0s to mask out the ranges which don't apply.
233May decide to modify the syntax to allow commas separate multiple
234ranges within an instruction (range','range).
235
236Changes in grammar:
237	The number of parms argument to the function entry
238was deleted from the original format such that we now count the fields.
239
240----
241FIXME! should really change lexical analyzer
242to recognize 'dreg' etc. in context sensative way.
243Currently function names or mnemonics may be incorrectly parsed as keywords
244
245FIXME! hex is ambiguous with any digit
246
247*/
248
249#include <stdio.h>
250#include "itbl-ops.h"
251
252/* #define DEBUG */
253
254#ifdef DEBUG
255#ifndef DBG_LVL
256#define DBG_LVL 1
257#endif
258#else
259#define DBG_LVL 0
260#endif
261
262#if DBG_LVL >= 1
263#define DBG(x) printf x
264#else
265#define DBG(x)
266#endif
267
268#if DBG_LVL >= 2
269#define DBGL2(x) printf x
270#else
271#define DBGL2(x)
272#endif
273
274static int sbit, ebit;
275static struct itbl_entry *insn=0;
276extern int insntbl_line;
277int yyparse PARAMS ((void));
278int yylex PARAMS ((void));
279static int yyerror PARAMS ((const char *));
280
281%}
282
283%union
284  {
285    char *str;
286    int num;
287    int processor;
288    unsigned long val;
289  }
290
291%token	    DREG CREG GREG IMMED ADDR INSN NUM ID NL PNUM
292%type	    <val> value flags flagexpr
293%type	    <num> number NUM ftype regtype pnum PNUM
294%type	    <str> ID name
295
296%start insntbl
297
298%%
299
300insntbl:
301	entrys
302	;
303
304entrys:
305	entry entrys
306	|
307	;
308
309entry:
310	pnum regtype name value NL
311	  {
312	    DBG (("line %d: entry pnum=%d type=%d name=%s value=x%x\n",
313	    	    insntbl_line, $1, $2, $3, $4));
314	    itbl_add_reg ($1, $2, $3, $4);
315	  }
316	| pnum INSN name value range flags
317	  {
318	    DBG (("line %d: entry pnum=%d type=INSN name=%s value=x%x",
319	    	    insntbl_line, $1, $3, $4));
320	    DBG ((" sbit=%d ebit=%d flags=0x%x\n", sbit, ebit, $6));
321	    insn=itbl_add_insn ($1, $3, $4, sbit, ebit, $6);
322	  }
323	fieldspecs NL
324	| NL
325	| error NL
326	;
327
328fieldspecs:
329	',' fieldspec fieldspecs
330	| fieldspec fieldspecs
331	|
332	;
333
334ftype:
335	regtype
336	  {
337	    DBGL2 (("ftype\n"));
338	    $$ = $1;
339	  }
340	| ADDR
341	  {
342	    DBGL2 (("addr\n"));
343	    $$ = ADDR;
344	  }
345	| IMMED
346	  {
347	    DBGL2 (("immed\n"));
348	    $$ = IMMED;
349	  }
350	;
351
352fieldspec:
353	ftype range flags
354	  {
355	    DBG (("line %d: field type=%d sbit=%d ebit=%d, flags=0x%x\n",
356	    	    insntbl_line, $1, sbit, ebit, $3));
357	    itbl_add_operand (insn, $1, sbit, ebit, $3);
358	  }
359	;
360
361flagexpr:
362	NUM '|' flagexpr
363	  {
364	    $$ = $1 | $3;
365	  }
366	| '[' flagexpr ']'
367	  {
368	    $$ = $2;
369	  }
370	| NUM
371	  {
372	    $$ = $1;
373	  }
374	;
375
376flags:
377	'*' flagexpr
378	  {
379	    DBGL2 (("flags=%d\n", $2));
380	    $$ = $2;
381	  }
382	|
383	  {
384	    $$ = 0;
385	  }
386	;
387
388range:
389	':' NUM '-' NUM
390	  {
391	    DBGL2 (("range %d %d\n", $2, $4));
392	    sbit = $2;
393	    ebit = $4;
394	  }
395	|
396	  {
397	    sbit = 31;
398	    ebit = 0;
399	  }
400	;
401
402pnum:
403	PNUM
404	  {
405	    DBGL2 (("pnum=%d\n",$1));
406	    $$ = $1;
407	  }
408	;
409
410regtype:
411	     DREG
412	  {
413	    DBGL2 (("dreg\n"));
414	    $$ = DREG;
415	  }
416	| CREG
417	  {
418	    DBGL2 (("creg\n"));
419	    $$ = CREG;
420	  }
421	| GREG
422	  {
423	    DBGL2 (("greg\n"));
424	    $$ = GREG;
425	  }
426	;
427
428name:
429	ID
430	  {
431	    DBGL2 (("name=%s\n",$1));
432	    $$ = $1;
433	  }
434	;
435
436number:
437	NUM
438	  {
439	    DBGL2 (("num=%d\n",$1));
440	    $$ = $1;
441	  }
442	;
443
444value:
445	NUM
446	  {
447	    DBGL2 (("val=x%x\n",$1));
448	    $$ = $1;
449	  }
450	;
451%%
452
453static int
454yyerror (msg)
455     const char *msg;
456{
457  printf ("line %d: %s\n", insntbl_line, msg);
458  return 0;
459}
460