Merge from vendor branch GCC:
[dragonfly.git] / contrib / binutils / gas / itbl-parse.y
1 /* itbl-parse.y
2    Copyright 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
25 Yacc grammar for instruction table entries.
26
27 =======================================================================
28 Original Instruction table specification document:
29
30             MIPS Coprocessor Table Specification
31             ====================================
32
33 This document describes the format of the MIPS coprocessor table.  The
34 table specifies a list of valid functions, data registers and control
35 registers that can be used in coprocessor instructions.  This list,
36 together with the coprocessor instruction classes listed below,
37 specifies the complete list of coprocessor instructions that will
38 be recognized and assembled by the GNU assembler.  In effect,
39 this makes the GNU assembler table-driven, where the table is
40 specified by the programmer.
41
42 The table is an ordinary text file that the GNU assembler reads when
43 it starts.  Using the information in the table, the assembler
44 generates an internal list of valid coprocessor registers and
45 functions.  The assembler uses this internal list in addition to the
46 standard MIPS registers and instructions which are built-in to the 
47 assembler during code generation.
48
49 To specify the coprocessor table when invoking the GNU assembler, use
50 the command line option "--itbl file", where file is the
51 complete name of the table, including path and extension.
52
53 Examples:
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
59 Only one table may be supplied during a single invocation of
60 the assembler.
61
62
63 Instruction classes
64 ===================
65
66 Below is a list of the valid coprocessor instruction classes for
67 any given coprocessor "z".  These instructions are already recognized
68 by the assembler, and are listed here only for reference.
69
70 Class   format                        instructions
71 -------------------------------------------------
72 Class1:
73         op base rt offset
74                                                             LWCz rt,offset (base)
75                                                             SWCz rt,offset (base)
76 Class2:
77         COPz sub rt rd 0
78                                                             MTCz rt,rd
79                                                             MFCz rt,rd
80                                                             CTCz rt,rd
81                                                             CFCz rt,rd
82 Class3:
83         COPz CO cofun
84                                                             COPz cofun
85 Class4:
86         COPz BC br offset
87                                                             BCzT offset
88                                                             BCzF offset
89 Class5:
90         COPz sub rt rd 0
91                                                             DMFCz rt,rd
92                                                             DMTCz rt,rd
93 Class6:
94         op base rt offset
95                                                             LDCz rt,offset (base)
96                                                             SDCz rt,offset (base)
97 Class7:
98         COPz BC br offset
99                                                             BCzTL offset
100                                                             BCzFL offset
101
102 The coprocessor table defines coprocessor-specific registers that can
103 be used with all of the above classes of instructions, where
104 appropriate.  It also defines additional coprocessor-specific
105 functions for Class3 (COPz cofun) instructions, Thus, the table allows
106 the programmer to use convenient mnemonics and operands for these
107 functions, instead of the COPz mmenmonic and cofun operand.
108
109 The names of the MIPS general registers and their aliases are defined
110 by the assembler and will be recognized as valid register names by the
111 assembler when used (where allowed) in coprocessor instructions.
112 However, the names and values of all coprocessor data and control
113 register mnemonics must be specified in the coprocessor table.
114
115
116 Table Grammar
117 =============
118
119 Here 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
158 Examples
159 ========
160
161 Example 1:
162
163 The 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
170 will allow the assembler to accept the following coprocessor instructions:
171
172             LWC1 d1,0x100 ($2)
173             fill
174
175 Here, the general purpose register "$2", and instruction "LWC1", are standard 
176 mnemonics built-in to the MIPS assembler.  
177
178
179 Example 2:
180
181 The 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
190 will allow the assembler to accept the following coprocessor instruction:
191
192             fee d3,c2,0x1
193
194 and 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
203 Example 3:
204
205 The 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
211 will allow the assembler to accept the following coprocessor
212 instruction:
213
214             fuu d3,c2
215
216 and 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
224 In this way, the programmer can force arbitrary bits of an instruction
225 to have predefined values.
226
227 =======================================================================
228 Additional notes:
229
230 Encoding of ranges:
231 To handle more than one bit position range within an instruction,
232 use 0s to mask out the ranges which don't apply.
233 May decide to modify the syntax to allow commas separate multiple 
234 ranges within an instruction (range','range).
235
236 Changes in grammar:
237         The number of parms argument to the function entry
238 was deleted from the original format such that we now count the fields.
239
240 ----
241 FIXME! should really change lexical analyzer 
242 to recognize 'dreg' etc. in context sensative way.
243 Currently function names or mnemonics may be incorrectly parsed as keywords
244
245 FIXME! 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
274 static int sbit, ebit;
275 static struct itbl_entry *insn=0;
276 extern int insntbl_line;
277 int yyparse PARAMS ((void));
278 int yylex PARAMS ((void));
279 static 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
300 insntbl:
301         entrys
302         ;
303
304 entrys:
305         entry entrys
306         |
307         ;
308
309 entry:
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
328 fieldspecs:
329         ',' fieldspec fieldspecs
330         | fieldspec fieldspecs
331         |
332         ;
333
334 ftype:
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
352 fieldspec:
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
361 flagexpr:
362         NUM '|' flagexpr
363           {
364             $$ = $1 | $3;
365           }
366         | '[' flagexpr ']'
367           {
368             $$ = $2;
369           }
370         | NUM
371           {
372             $$ = $1;
373           }
374         ;
375
376 flags:
377         '*' flagexpr
378           {
379             DBGL2 (("flags=%d\n", $2));
380             $$ = $2;
381           }
382         | 
383           {
384             $$ = 0;
385           }
386         ;
387
388 range:
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             
402 pnum:
403         PNUM
404           {
405             DBGL2 (("pnum=%d\n",$1));
406             $$ = $1;
407           }
408         ;
409
410 regtype:
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
428 name:
429         ID
430           {
431             DBGL2 (("name=%s\n",$1));
432             $$ = $1; 
433           }
434         ;
435
436 number:
437         NUM
438           {
439             DBGL2 (("num=%d\n",$1));
440             $$ = $1;
441           }
442         ;
443
444 value:
445         NUM
446           {
447             DBGL2 (("val=x%x\n",$1));
448             $$ = $1;
449           }
450         ;
451 %%
452
453 static int
454 yyerror (msg)
455      const char *msg;
456 {
457   printf ("line %d: %s\n", insntbl_line, msg);
458   return 0;
459 }