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 hexadecimal 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 sensitive 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 {} 325 | NL 326 | error NL 327 ; 328 329 fieldspecs: 330 ',' fieldspec fieldspecs 331 | fieldspec fieldspecs 332 | 333 ; 334 335 ftype: 336 regtype 337 { 338 DBGL2 (("ftype\n")); 339 $$ = $1; 340 } 341 | ADDR 342 { 343 DBGL2 (("addr\n")); 344 $$ = ADDR; 345 } 346 | IMMED 347 { 348 DBGL2 (("immed\n")); 349 $$ = IMMED; 350 } 351 ; 352 353 fieldspec: 354 ftype range flags 355 { 356 DBG (("line %d: field type=%d sbit=%d ebit=%d, flags=0x%x\n", 357 insntbl_line, $1, sbit, ebit, $3)); 358 itbl_add_operand (insn, $1, sbit, ebit, $3); 359 } 360 ; 361 362 flagexpr: 363 NUM '|' flagexpr 364 { 365 $$ = $1 | $3; 366 } 367 | '[' flagexpr ']' 368 { 369 $$ = $2; 370 } 371 | NUM 372 { 373 $$ = $1; 374 } 375 ; 376 377 flags: 378 '*' flagexpr 379 { 380 DBGL2 (("flags=%d\n", $2)); 381 $$ = $2; 382 } 383 | 384 { 385 $$ = 0; 386 } 387 ; 388 389 range: 390 ':' NUM '-' NUM 391 { 392 DBGL2 (("range %d %d\n", $2, $4)); 393 sbit = $2; 394 ebit = $4; 395 } 396 | 397 { 398 sbit = 31; 399 ebit = 0; 400 } 401 ; 402 403 pnum: 404 PNUM 405 { 406 DBGL2 (("pnum=%d\n",$1)); 407 $$ = $1; 408 } 409 ; 410 411 regtype: 412 DREG 413 { 414 DBGL2 (("dreg\n")); 415 $$ = DREG; 416 } 417 | CREG 418 { 419 DBGL2 (("creg\n")); 420 $$ = CREG; 421 } 422 | GREG 423 { 424 DBGL2 (("greg\n")); 425 $$ = GREG; 426 } 427 ; 428 429 name: 430 ID 431 { 432 DBGL2 (("name=%s\n",$1)); 433 $$ = $1; 434 } 435 ; 436 437 number: 438 NUM 439 { 440 DBGL2 (("num=%d\n",$1)); 441 $$ = $1; 442 } 443 ; 444 445 value: 446 NUM 447 { 448 DBGL2 (("val=x%x\n",$1)); 449 $$ = $1; 450 } 451 ; 452 %% 453 454 static int 455 yyerror (msg) 456 const char *msg; 457 { 458 printf ("line %d: %s\n", insntbl_line, msg); 459 return 0; 460 } 461