133965Sjdp/* itbl-parse.y 2218822Sdim Copyright 1997, 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. 333965Sjdp 433965Sjdp This file is part of GAS, the GNU Assembler. 533965Sjdp 633965Sjdp GAS is free software; you can redistribute it and/or modify 733965Sjdp it under the terms of the GNU General Public License as published by 833965Sjdp the Free Software Foundation; either version 2, or (at your option) 933965Sjdp any later version. 1033965Sjdp 1133965Sjdp GAS is distributed in the hope that it will be useful, 1233965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1333965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1433965Sjdp GNU General Public License for more details. 1533965Sjdp 1633965Sjdp You should have received a copy of the GNU General Public License 1733965Sjdp along with GAS; see the file COPYING. If not, write to the Free 18218822Sdim Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19218822Sdim 02110-1301, USA. */ 2033965Sjdp 2133965Sjdp%{ 2233965Sjdp 2333965Sjdp/* 2433965Sjdp 2533965SjdpYacc grammar for instruction table entries. 2633965Sjdp 2733965Sjdp======================================================================= 2833965SjdpOriginal Instruction table specification document: 2933965Sjdp 3033965Sjdp MIPS Coprocessor Table Specification 3133965Sjdp ==================================== 3233965Sjdp 3333965SjdpThis document describes the format of the MIPS coprocessor table. The 3433965Sjdptable specifies a list of valid functions, data registers and control 3533965Sjdpregisters that can be used in coprocessor instructions. This list, 3633965Sjdptogether with the coprocessor instruction classes listed below, 3733965Sjdpspecifies the complete list of coprocessor instructions that will 3833965Sjdpbe recognized and assembled by the GNU assembler. In effect, 3933965Sjdpthis makes the GNU assembler table-driven, where the table is 4033965Sjdpspecified by the programmer. 4133965Sjdp 4233965SjdpThe table is an ordinary text file that the GNU assembler reads when 4333965Sjdpit starts. Using the information in the table, the assembler 4433965Sjdpgenerates an internal list of valid coprocessor registers and 4533965Sjdpfunctions. The assembler uses this internal list in addition to the 4633965Sjdpstandard MIPS registers and instructions which are built-in to the 4733965Sjdpassembler during code generation. 4833965Sjdp 4933965SjdpTo specify the coprocessor table when invoking the GNU assembler, use 5033965Sjdpthe command line option "--itbl file", where file is the 5133965Sjdpcomplete name of the table, including path and extension. 5233965Sjdp 5333965SjdpExamples: 5433965Sjdp 5533965Sjdp gas -t cop.tbl test.s -o test.o 5633965Sjdp gas -t /usr/local/lib/cop.tbl test.s -o test.o 5733965Sjdp gas --itbl d:\gnu\data\cop.tbl test.s -o test.o 5833965Sjdp 5933965SjdpOnly one table may be supplied during a single invocation of 6033965Sjdpthe assembler. 6133965Sjdp 6233965Sjdp 6333965SjdpInstruction classes 6433965Sjdp=================== 6533965Sjdp 6633965SjdpBelow is a list of the valid coprocessor instruction classes for 6733965Sjdpany given coprocessor "z". These instructions are already recognized 6833965Sjdpby the assembler, and are listed here only for reference. 6933965Sjdp 7033965SjdpClass format instructions 7133965Sjdp------------------------------------------------- 7233965SjdpClass1: 7333965Sjdp op base rt offset 7433965Sjdp LWCz rt,offset (base) 7533965Sjdp SWCz rt,offset (base) 7633965SjdpClass2: 7733965Sjdp COPz sub rt rd 0 7833965Sjdp MTCz rt,rd 7933965Sjdp MFCz rt,rd 8033965Sjdp CTCz rt,rd 8133965Sjdp CFCz rt,rd 8233965SjdpClass3: 8333965Sjdp COPz CO cofun 8433965Sjdp COPz cofun 8533965SjdpClass4: 8633965Sjdp COPz BC br offset 8733965Sjdp BCzT offset 8833965Sjdp BCzF offset 8933965SjdpClass5: 9033965Sjdp COPz sub rt rd 0 9133965Sjdp DMFCz rt,rd 9233965Sjdp DMTCz rt,rd 9333965SjdpClass6: 9433965Sjdp op base rt offset 9533965Sjdp LDCz rt,offset (base) 9633965Sjdp SDCz rt,offset (base) 9733965SjdpClass7: 9833965Sjdp COPz BC br offset 9933965Sjdp BCzTL offset 10033965Sjdp BCzFL offset 10133965Sjdp 10233965SjdpThe coprocessor table defines coprocessor-specific registers that can 10333965Sjdpbe used with all of the above classes of instructions, where 10433965Sjdpappropriate. It also defines additional coprocessor-specific 10533965Sjdpfunctions for Class3 (COPz cofun) instructions, Thus, the table allows 10633965Sjdpthe programmer to use convenient mnemonics and operands for these 10733965Sjdpfunctions, instead of the COPz mmenmonic and cofun operand. 10833965Sjdp 10933965SjdpThe names of the MIPS general registers and their aliases are defined 11033965Sjdpby the assembler and will be recognized as valid register names by the 11133965Sjdpassembler when used (where allowed) in coprocessor instructions. 11233965SjdpHowever, the names and values of all coprocessor data and control 11333965Sjdpregister mnemonics must be specified in the coprocessor table. 11433965Sjdp 11533965Sjdp 11633965SjdpTable Grammar 11733965Sjdp============= 11833965Sjdp 11933965SjdpHere is the grammar for the coprocessor table: 12033965Sjdp 12133965Sjdp table -> entry* 12233965Sjdp 12333965Sjdp entry -> [z entrydef] [comment] '\n' 12433965Sjdp 12533965Sjdp entrydef -> type name val 12633965Sjdp entrydef -> 'insn' name val funcdef ; type of entry (instruction) 12733965Sjdp 12833965Sjdp z -> 'p'['0'..'3'] ; processor number 12933965Sjdp type -> ['dreg' | 'creg' | 'greg' ] ; type of entry (register) 13033965Sjdp ; 'dreg', 'creg' or 'greg' specifies a data, control, or general 13133965Sjdp ; register mnemonic, respectively 13233965Sjdp name -> [ltr|dec]* ; mnemonic of register/function 13333965Sjdp val -> [dec|hex] ; register/function number (integer constant) 13433965Sjdp 13533965Sjdp funcdef -> frange flags fields 13633965Sjdp ; bitfield range for opcode 13733965Sjdp ; list of fields' formats 13833965Sjdp fields -> field* 13933965Sjdp field -> [','] ftype frange flags 14033965Sjdp flags -> ['*' flagexpr] 14133965Sjdp flagexpr -> '[' flagexpr ']' 14233965Sjdp flagexpr -> val '|' flagexpr 14333965Sjdp ftype -> [ type | 'immed' | 'addr' ] 14433965Sjdp ; 'immed' specifies an immediate value; see grammar for "val" above 14533965Sjdp ; 'addr' specifies a C identifier; name of symbol to be resolved at 14633965Sjdp ; link time 14733965Sjdp frange -> ':' val '-' val ; starting to ending bit positions, where 14833965Sjdp ; where 0 is least significant bit 14933965Sjdp frange -> (null) ; default range of 31-0 will be assumed 15033965Sjdp 15133965Sjdp comment -> [';'|'#'] [char]* 15233965Sjdp char -> any printable character 15333965Sjdp ltr -> ['a'..'z'|'A'..'Z'] 15433965Sjdp dec -> ['0'..'9']* ; value in decimal 155218822Sdim hex -> '0x'['0'..'9' | 'a'..'f' | 'A'..'F']* ; value in hexadecimal 15633965Sjdp 15733965Sjdp 15833965SjdpExamples 15933965Sjdp======== 16033965Sjdp 16133965SjdpExample 1: 16233965Sjdp 16333965SjdpThe table: 16433965Sjdp 16533965Sjdp p1 dreg d1 1 ; data register "d1" for COP1 has value 1 16633965Sjdp p1 creg c3 3 ; ctrl register "c3" for COP1 has value 3 16733965Sjdp p3 func fill 0x1f:24-20 ; function "fill" for COP3 has value 31 and 16833965Sjdp ; no fields 16933965Sjdp 17033965Sjdpwill allow the assembler to accept the following coprocessor instructions: 17133965Sjdp 17233965Sjdp LWC1 d1,0x100 ($2) 17333965Sjdp fill 17433965Sjdp 17533965SjdpHere, the general purpose register "$2", and instruction "LWC1", are standard 17633965Sjdpmnemonics built-in to the MIPS assembler. 17733965Sjdp 17833965Sjdp 17933965SjdpExample 2: 18033965Sjdp 18133965SjdpThe table: 18233965Sjdp 18333965Sjdp p3 dreg d3 3 ; data register "d3" for COP3 has value 3 18433965Sjdp p3 creg c2 22 ; control register "c2" for COP3 has value 22 18533965Sjdp p3 func fee 0x1f:24-20 dreg:17-13 creg:12-8 immed:7-0 18633965Sjdp ; function "fee" for COP3 has value 31, and 3 fields 18733965Sjdp ; consisting of a data register, a control register, 18833965Sjdp ; and an immediate value. 18933965Sjdp 19033965Sjdpwill allow the assembler to accept the following coprocessor instruction: 19133965Sjdp 19233965Sjdp fee d3,c2,0x1 19333965Sjdp 19433965Sjdpand will emit the object code: 19533965Sjdp 19633965Sjdp 31-26 25 24-20 19-18 17-13 12-8 7-0 19733965Sjdp COPz CO fun dreg creg immed 19833965Sjdp 010011 1 11111 00 00011 10110 00000001 19933965Sjdp 20033965Sjdp 0x4ff07601 20133965Sjdp 20233965Sjdp 20333965SjdpExample 3: 20433965Sjdp 20533965SjdpThe table: 20633965Sjdp 20733965Sjdp p3 dreg d3 3 ; data register "d3" for COP3 has value 3 20833965Sjdp p3 creg c2 22 ; control register "c2" for COP3 has value 22 20933965Sjdp p3 func fuu 0x01f00001 dreg:17-13 creg:12-8 21033965Sjdp 21133965Sjdpwill allow the assembler to accept the following coprocessor 21233965Sjdpinstruction: 21333965Sjdp 21433965Sjdp fuu d3,c2 21533965Sjdp 21633965Sjdpand will emit the object code: 21733965Sjdp 21833965Sjdp 31-26 25 24-20 19-18 17-13 12-8 7-0 21933965Sjdp COPz CO fun dreg creg 22033965Sjdp 010011 1 11111 00 00011 10110 00000001 22133965Sjdp 22233965Sjdp 0x4ff07601 22333965Sjdp 22433965SjdpIn this way, the programmer can force arbitrary bits of an instruction 22533965Sjdpto have predefined values. 22633965Sjdp 22733965Sjdp======================================================================= 22833965SjdpAdditional notes: 22933965Sjdp 23033965SjdpEncoding of ranges: 23133965SjdpTo handle more than one bit position range within an instruction, 23233965Sjdpuse 0s to mask out the ranges which don't apply. 23333965SjdpMay decide to modify the syntax to allow commas separate multiple 23433965Sjdpranges within an instruction (range','range). 23533965Sjdp 23633965SjdpChanges in grammar: 23733965Sjdp The number of parms argument to the function entry 23833965Sjdpwas deleted from the original format such that we now count the fields. 23933965Sjdp 24033965Sjdp---- 24133965SjdpFIXME! should really change lexical analyzer 242218822Sdimto recognize 'dreg' etc. in context sensitive way. 24333965SjdpCurrently function names or mnemonics may be incorrectly parsed as keywords 24433965Sjdp 24533965SjdpFIXME! hex is ambiguous with any digit 24633965Sjdp 24733965Sjdp*/ 24833965Sjdp 249218822Sdim#include "as.h" 250218822Sdim#include "itbl-lex.h" 25133965Sjdp#include "itbl-ops.h" 25233965Sjdp 25333965Sjdp/* #define DEBUG */ 25433965Sjdp 25533965Sjdp#ifdef DEBUG 25633965Sjdp#ifndef DBG_LVL 25733965Sjdp#define DBG_LVL 1 25833965Sjdp#endif 25933965Sjdp#else 26033965Sjdp#define DBG_LVL 0 26133965Sjdp#endif 26233965Sjdp 26333965Sjdp#if DBG_LVL >= 1 26433965Sjdp#define DBG(x) printf x 26533965Sjdp#else 26633965Sjdp#define DBG(x) 26733965Sjdp#endif 26833965Sjdp 26933965Sjdp#if DBG_LVL >= 2 27033965Sjdp#define DBGL2(x) printf x 27133965Sjdp#else 27233965Sjdp#define DBGL2(x) 27333965Sjdp#endif 27433965Sjdp 27533965Sjdpstatic int sbit, ebit; 27633965Sjdpstatic struct itbl_entry *insn=0; 277218822Sdimstatic int yyerror (const char *); 27833965Sjdp 27933965Sjdp%} 28033965Sjdp 28133965Sjdp%union 28233965Sjdp { 28333965Sjdp char *str; 28433965Sjdp int num; 28533965Sjdp int processor; 28633965Sjdp unsigned long val; 28733965Sjdp } 28833965Sjdp 28933965Sjdp%token DREG CREG GREG IMMED ADDR INSN NUM ID NL PNUM 29033965Sjdp%type <val> value flags flagexpr 29133965Sjdp%type <num> number NUM ftype regtype pnum PNUM 29233965Sjdp%type <str> ID name 29333965Sjdp 29433965Sjdp%start insntbl 29533965Sjdp 29633965Sjdp%% 29733965Sjdp 29833965Sjdpinsntbl: 29933965Sjdp entrys 30033965Sjdp ; 30133965Sjdp 30233965Sjdpentrys: 30333965Sjdp entry entrys 30433965Sjdp | 30533965Sjdp ; 30633965Sjdp 30733965Sjdpentry: 30833965Sjdp pnum regtype name value NL 30933965Sjdp { 31033965Sjdp DBG (("line %d: entry pnum=%d type=%d name=%s value=x%x\n", 31133965Sjdp insntbl_line, $1, $2, $3, $4)); 31233965Sjdp itbl_add_reg ($1, $2, $3, $4); 31333965Sjdp } 31433965Sjdp | pnum INSN name value range flags 31533965Sjdp { 31633965Sjdp DBG (("line %d: entry pnum=%d type=INSN name=%s value=x%x", 31733965Sjdp insntbl_line, $1, $3, $4)); 31833965Sjdp DBG ((" sbit=%d ebit=%d flags=0x%x\n", sbit, ebit, $6)); 31933965Sjdp insn=itbl_add_insn ($1, $3, $4, sbit, ebit, $6); 32033965Sjdp } 32133965Sjdp fieldspecs NL 322107492Sobrien {} 32333965Sjdp | NL 32433965Sjdp | error NL 32533965Sjdp ; 32633965Sjdp 32733965Sjdpfieldspecs: 32833965Sjdp ',' fieldspec fieldspecs 32933965Sjdp | fieldspec fieldspecs 33033965Sjdp | 33133965Sjdp ; 33233965Sjdp 33333965Sjdpftype: 33433965Sjdp regtype 33533965Sjdp { 33633965Sjdp DBGL2 (("ftype\n")); 33733965Sjdp $$ = $1; 33833965Sjdp } 33933965Sjdp | ADDR 34033965Sjdp { 34133965Sjdp DBGL2 (("addr\n")); 34233965Sjdp $$ = ADDR; 34333965Sjdp } 34433965Sjdp | IMMED 34533965Sjdp { 34633965Sjdp DBGL2 (("immed\n")); 34733965Sjdp $$ = IMMED; 34833965Sjdp } 34933965Sjdp ; 35033965Sjdp 35133965Sjdpfieldspec: 35233965Sjdp ftype range flags 35333965Sjdp { 35433965Sjdp DBG (("line %d: field type=%d sbit=%d ebit=%d, flags=0x%x\n", 35533965Sjdp insntbl_line, $1, sbit, ebit, $3)); 35633965Sjdp itbl_add_operand (insn, $1, sbit, ebit, $3); 35733965Sjdp } 35833965Sjdp ; 35933965Sjdp 36033965Sjdpflagexpr: 36133965Sjdp NUM '|' flagexpr 36233965Sjdp { 36333965Sjdp $$ = $1 | $3; 36433965Sjdp } 36533965Sjdp | '[' flagexpr ']' 36633965Sjdp { 36733965Sjdp $$ = $2; 36833965Sjdp } 36933965Sjdp | NUM 37033965Sjdp { 37133965Sjdp $$ = $1; 37233965Sjdp } 37333965Sjdp ; 37433965Sjdp 37533965Sjdpflags: 37633965Sjdp '*' flagexpr 37733965Sjdp { 37833965Sjdp DBGL2 (("flags=%d\n", $2)); 37933965Sjdp $$ = $2; 38033965Sjdp } 38133965Sjdp | 38233965Sjdp { 38333965Sjdp $$ = 0; 38433965Sjdp } 38533965Sjdp ; 38633965Sjdp 38733965Sjdprange: 38833965Sjdp ':' NUM '-' NUM 38933965Sjdp { 39033965Sjdp DBGL2 (("range %d %d\n", $2, $4)); 39133965Sjdp sbit = $2; 39233965Sjdp ebit = $4; 39333965Sjdp } 39433965Sjdp | 39533965Sjdp { 39633965Sjdp sbit = 31; 39733965Sjdp ebit = 0; 39833965Sjdp } 39933965Sjdp ; 40033965Sjdp 40133965Sjdppnum: 40233965Sjdp PNUM 40333965Sjdp { 40433965Sjdp DBGL2 (("pnum=%d\n",$1)); 40533965Sjdp $$ = $1; 40633965Sjdp } 40733965Sjdp ; 40833965Sjdp 40933965Sjdpregtype: 41033965Sjdp DREG 41133965Sjdp { 41233965Sjdp DBGL2 (("dreg\n")); 41333965Sjdp $$ = DREG; 41433965Sjdp } 41533965Sjdp | CREG 41633965Sjdp { 41733965Sjdp DBGL2 (("creg\n")); 41833965Sjdp $$ = CREG; 41933965Sjdp } 42033965Sjdp | GREG 42133965Sjdp { 42233965Sjdp DBGL2 (("greg\n")); 42333965Sjdp $$ = GREG; 42433965Sjdp } 42533965Sjdp ; 42633965Sjdp 42733965Sjdpname: 42833965Sjdp ID 42933965Sjdp { 43033965Sjdp DBGL2 (("name=%s\n",$1)); 43133965Sjdp $$ = $1; 43233965Sjdp } 43333965Sjdp ; 43433965Sjdp 43533965Sjdpnumber: 43633965Sjdp NUM 43733965Sjdp { 43833965Sjdp DBGL2 (("num=%d\n",$1)); 43933965Sjdp $$ = $1; 44033965Sjdp } 44133965Sjdp ; 44233965Sjdp 44333965Sjdpvalue: 44433965Sjdp NUM 44533965Sjdp { 44633965Sjdp DBGL2 (("val=x%x\n",$1)); 44733965Sjdp $$ = $1; 44833965Sjdp } 44933965Sjdp ; 45033965Sjdp%% 45133965Sjdp 45233965Sjdpstatic int 45333965Sjdpyyerror (msg) 45433965Sjdp const char *msg; 45533965Sjdp{ 45633965Sjdp printf ("line %d: %s\n", insntbl_line, msg); 45733965Sjdp return 0; 45833965Sjdp} 459