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