2 /*======================================================================*/
4 * Herein lies the support for dynamic specification of processor
5 * instructions and registers. Mnemonics, values, and formats for each
6 * instruction and register are specified in an ascii file consisting of
7 * table entries. The grammar for the table is defined in the document
8 * "Processor instruction table specification".
10 * Instructions use the gnu assembler syntax, with the addition of
11 * allowing mnemonics for register.
12 * Eg. "func $2,reg3,0x100,symbol ; comment"
15 * reg3 - mnemonic for processor's register defined in table
16 * 0xddd..d - immediate value
17 * symbol - address of label or external symbol
19 * First, itbl_parse reads in the table of register and instruction
20 * names and formats, and builds a list of entries for each
21 * processor/type combination. lex and yacc are used to parse
22 * the entries in the table and call functions defined here to
23 * add each entry to our list.
25 * Then, when assembling or disassembling, these functions are called to
26 * 1) get information on a processor's registers and
27 * 2) assemble/disassemble an instruction.
28 * To assemble(disassemble) an instruction, the function
29 * itbl_assemble(itbl_disassemble) is called to search the list of
30 * instruction entries, and if a match is found, uses the format
31 * described in the instruction entry structure to complete the action.
33 * Eg. Suppose we have a Mips coprocessor "cop3" with data register "d2"
34 * and we want to define function "pig" which takes two operands.
36 * Given the table entries:
37 * "p3 insn pig 0x1:24-21 dreg:20-16 immed:15-0"
39 * and that the instruction encoding for coprocessor pz has encoding:
40 * #define MIPS_ENCODE_COP_NUM(z) ((0x21|(z<<1))<<25)
41 * #define ITBL_ENCODE_PNUM(pnum) MIPS_ENCODE_COP_NUM(pnum)
43 * a structure to describe the instruction might look something like:
44 * struct itbl_entry = {
45 * e_processor processor = e_p3
46 * e_type type = e_insn
50 * struct itbl_range range = 24-21
51 * struct itbl_field *field = {
52 * e_type type = e_dreg
53 * struct itbl_range range = 20-16
54 * struct itbl_field *next = {
55 * e_type type = e_immed
56 * struct itbl_range range = 15-0
57 * struct itbl_field *next = 0
60 * struct itbl_entry *next = 0
63 * And the assembler instructions:
67 * would both assemble to the hex value:
76 #include "itbl-parse.h"
82 #define ASSERT(x) assert(x)
83 #define DBG(x) printf x
90 #define min(a,b) (a<b?a:b)
93 /*======================================================================*/
94 /* structures for keeping itbl format entries */
97 int sbit; /* mask starting bit position */
98 int ebit; /* mask ending bit position */
102 e_type type; /* dreg/creg/greg/immed/symb */
103 struct itbl_range range; /* field's bitfield range within instruction */
104 unsigned long flags; /* field flags */
105 struct itbl_field *next; /* next field in list */
109 /* These structures define the instructions and registers for a processor.
110 * If the type is an instruction, the structure defines the format of an
111 * instruction where the fields are the list of operands.
112 * The flags field below uses the same values as those defined in the
113 * gnu assembler and are machine specific. */
115 e_processor processor; /* processor number */
116 e_type type; /* dreg/creg/greg/insn */
117 char *name; /* mnemionic name for insn/register */
118 unsigned long value; /* opcode/instruction mask/register number */
119 unsigned long flags; /* effects of the instruction */
120 struct itbl_range range;/* bit range within instruction for value */
121 struct itbl_field *fields; /* list of operand definitions (if any) */
122 struct itbl_entry *next; /* next entry */
126 /* local data and structures */
128 static int itbl_num_opcodes = 0;
129 /* Array of entries for each processor and entry type */
130 static struct itbl_entry *entries[e_nprocs][e_ntypes] =
132 { 0, 0, 0, 0, 0, 0 },
133 { 0, 0, 0, 0, 0, 0 },
134 { 0, 0, 0, 0, 0, 0 },
138 /* local prototypes */
139 static unsigned long build_opcode(struct itbl_entry *e);
140 static e_type get_type(int yytype);
141 static e_processor get_processor(int yyproc);
142 static struct itbl_entry **get_entries(e_processor processor, e_type type);
143 static struct itbl_entry *find_entry_byname(e_processor processor, e_type type,
145 static struct itbl_entry *find_entry_byval(e_processor processor, e_type type,
146 unsigned long val, struct itbl_range *r);
147 static struct itbl_entry *alloc_entry(e_processor processor, e_type type, char *name,
148 unsigned long value);
149 static unsigned long apply_range(unsigned long value, struct itbl_range r);
150 static unsigned long extract_range(unsigned long value, struct itbl_range r);
151 static struct itbl_field *alloc_field(e_type type, int sbit, int ebit, unsigned long flags);
154 /*======================================================================*/
155 /* Interfaces to the parser */
158 /* Open the table and use lex and yacc to parse the entries.
159 * Return 1 for failure; 0 for success. */
161 int itbl_parse(char* insntbl)
164 extern int yyparse(void);
165 yyin = fopen(insntbl, "r");
168 printf("Can't open processor instruction specification file \"%s\"\n",
180 /* Add a register entry */
182 struct itbl_entry *itbl_add_reg(int yyprocessor, int yytype, char *regname,
185 #if 0 /* ndef STAND_ALONE */
188 /* Since register names don't have a prefix, we put them in the symbol table so
189 they can't be used as symbols. This also simplifies argument parsing as
190 we can let gas parse registers for us. The recorded register number is
192 /* Use symbol_create here instead of symbol_new so we don't try to
193 output registers into the object file's symbol table. */
194 symbol_table_insert (symbol_create (regname, reg_section,
195 regnum, &zero_address_frag));
197 return alloc_entry(get_processor(yyprocessor),get_type(yytype),regname,
198 (unsigned long)regnum);
201 /* Add an instruction entry */
203 struct itbl_entry *itbl_add_insn(int yyprocessor, char *name, unsigned long value,
204 int sbit, int ebit, unsigned long flags)
206 struct itbl_entry *e;
207 e = alloc_entry(get_processor(yyprocessor),e_insn,name,value);
218 /* Add an operand to an instruction entry */
220 struct itbl_field *itbl_add_operand(struct itbl_entry *e, int yytype, int sbit,
221 int ebit, unsigned long flags)
223 struct itbl_field *f, **last_f;
226 /* Add to end of fields' list. */
227 f = alloc_field(get_type(yytype),sbit,ebit,flags);
232 last_f = &(*last_f)->next;
240 /*======================================================================*/
241 /* Interfaces for assembler and disassembler */
246 static void append_insns_as_macros(void);
248 /* initialize for gas */
251 struct itbl_entry *e, **es;
255 /* Since register names don't have a prefix, put them in the symbol table so
256 they can't be used as symbols. This simplifies argument parsing as
257 we can let gas parse registers for us. */
258 /* Use symbol_create instead of symbol_new so we don't try to
259 output registers into the object file's symbol table. */
261 for (type=e_regtype0; type<e_nregtypes; type++)
262 for (procn=e_p0; procn<e_nprocs; procn++)
264 es = get_entries(procn, type);
265 for (e=*es; e; e=e->next)
267 symbol_table_insert (symbol_create (e->name, reg_section,
268 e->value, &zero_address_frag));
271 append_insns_as_macros();
275 /* Append insns to opcodes table and increase number of opcodes */
276 /* Structure of opcodes table: */
277 /* struct itbl_opcode
280 /* const char *args; /* string describing the arguments . */
281 /* unsigned long match; /* opcode, or ISA level if pinfo=INSN_MACRO */
282 /* unsigned long mask; /* opcode mask, or macro id if pinfo=INSN_MACRO */
283 /* unsigned long pinfo; /* insn flags, or INSN_MACRO */
286 * {"li", "t,i", 0x34000000, 0xffe00000, WR_t },
287 * {"li", "t,I", 0, (int) M_LI, INSN_MACRO },
289 static char *form_args(struct itbl_entry *e);
290 static void append_insns_as_macros(void)
292 struct ITBL_OPCODE_STRUCT *new_opcodes, *o;
293 struct itbl_entry *e, **es;
294 int n, id, size, new_size, new_num_opcodes;
296 ASSERT(itbl_num_opcodes > 0);
297 if (!itbl_num_opcodes) /* no new instructions to add! */
301 DBG(("previous num_opcodes=%d\n",ITBL_NUM_OPCODES));
303 new_num_opcodes = ITBL_NUM_OPCODES + itbl_num_opcodes;
304 ASSERT(new_num_opcodes >= itbl_num_opcodes);
306 size = sizeof(struct ITBL_OPCODE_STRUCT) * ITBL_NUM_OPCODES;
308 DBG(("I get=%d\n", size / sizeof(ITBL_OPCODES[0])));
310 new_size = sizeof(struct ITBL_OPCODE_STRUCT) * new_num_opcodes;
311 ASSERT(new_size > size);
313 /* FIXME since ITBL_OPCODES culd be a static table,
314 we can't realloc or delete the old memory. */
315 new_opcodes = (struct ITBL_OPCODE_STRUCT*)malloc(new_size);
318 printf("Unable to allocate memory for new instructions\n");
321 if (size) /* copy prexisting opcodes table */
322 memcpy(new_opcodes, ITBL_OPCODES, size);
324 /* FIXME! some NUMOPCODES are calculated expressions.
325 These need to be changed before itbls can be supported. */
327 id = ITBL_NUM_MACROS; /* begin the next macro id after the last */
328 o = &new_opcodes[ITBL_NUM_OPCODES]; /* append macro to opcodes list */
329 for (n=e_p0; n<e_nprocs; n++)
331 es = get_entries(n,e_insn);
332 for (e=*es; e; e=e->next)
334 /* name, args, mask, match, pinfo
335 * {"li", "t,i", 0x34000000, 0xffe00000, WR_t },
336 * {"li", "t,I", 0, (int) M_LI, INSN_MACRO },
337 * Construct args from itbl_fields.
340 o->args = strdup(form_args(e));
341 o->mask = apply_range(e->value,e->range);
342 /* FIXME how to catch durring assembly? */
343 /* mask to identify this insn */
344 o->match = apply_range(e->value,e->range);
348 o->mask = id++; /* FIXME how to catch durring assembly? */
349 o->match = 0; /* for macros, the insn_isa number */
350 o->pinfo = INSN_MACRO;
353 /* Don't add instructions which caused an error */
360 ITBL_OPCODES = new_opcodes;
361 ITBL_NUM_OPCODES = new_num_opcodes;
364 At this point, we can free the entries, as they should have
365 been added to the assembler's tables.
366 Don't free name though, since name is being used by the new
369 Eventually, we should also free the new opcodes table itself on exit.
373 static char *form_args(struct itbl_entry *e)
377 struct itbl_field *f;
380 for (f=e->fields; f; f=f->next)
384 case e_dreg: c='d'; break;
385 case e_creg: c='t'; break;
386 case e_greg: c='s'; break;
387 case e_immed: c='i'; break;
388 case e_addr: c='a'; break;
389 default: c=0; /* ignore; unknown field type */
401 #endif /* !STAND_ALONE */
404 /* Get processor's register name from val */
406 unsigned long itbl_get_reg_val(char *name)
411 for (p=e_p0; p<e_nprocs; p++)
412 for (t=e_regtype0; t<e_nregtypes; t++)
414 if (r = itbl_get_val(p, t, name), r)
420 char *itbl_get_name(e_processor processor, e_type type, unsigned long val)
422 struct itbl_entry *r;
423 /* type depends on instruction passed */
424 r = find_entry_byval(processor,type,val,0);
428 return 0; /* error; invalid operand */
431 /* Get processor's register value from name */
433 unsigned long itbl_get_val(e_processor processor, e_type type, char *name)
435 struct itbl_entry *r;
436 /* type depends on instruction passed */
437 r = find_entry_byname(processor,type,name);
441 return 0; /* error; invalid operand */
445 /* Assemble instruction "name" with operands "s".
446 * name - name of instruction
448 * returns - long word for assembled instruction */
450 unsigned long itbl_assemble(char *name, char *s)
452 unsigned long opcode;
453 struct itbl_entry *e;
454 struct itbl_field *f;
459 return 0; /* error! must have a opcode name/expr */
461 /* find entry in list of instructions for all processors */
462 for (processor=0; processor<e_nprocs; processor++)
464 e = find_entry_byname(processor, e_insn, name);
468 return 0; /* opcode not in table; invalid instrustion */
469 opcode = build_opcode(e);
471 /* parse opcode's args (if any) */
472 for (f=e->fields; f; f=f->next) /* for each arg, ... */
474 struct itbl_entry *r;
477 return 0; /* error - not enough operands */
478 n = itbl_get_field(&s);
479 /* n should be in form $n or 0xhhh (are symbol names valid?? */
485 /* Accept either a string name
486 * or '$' followed by the register number */
490 value = strtol(n,0,10);
491 /* FIXME! could have "0l"... then what?? */
492 if (value == 0 && *n!='0')
493 return 0; /* error; invalid operand */
497 r = find_entry_byname(e->processor,f->type,n);
501 return 0; /* error; invalid operand */
505 /* use assembler's symbol table to find symbol */
506 /* FIXME!! Do we need this?
507 if so, what about relocs??
508 my_getExpression (&imm_expr, s);
509 return 0; /-* error; invalid operand *-/
512 /* If not a symbol, fall thru to IMMED */
514 if (*n=='0' && *(n+1)=='x') /* hex begins 0x... */
517 value = strtol(n,0,16);
518 /* FIXME! could have "0xl"... then what?? */
522 value = strtol(n,0,10);
523 /* FIXME! could have "0l"... then what?? */
524 if (value == 0 && *n!='0')
525 return 0; /* error; invalid operand */
529 return 0; /* error; invalid field spec */
531 opcode |= apply_range(value,f->range);
534 return 0; /* error - too many operands */
535 return opcode; /* done! */
538 /* Disassemble instruction "insn".
540 * s - buffer to hold disassembled instruction
541 * returns - 1 if succeeded; 0 if failed
544 int itbl_disassemble(char *s, unsigned long insn)
546 e_processor processor;
547 struct itbl_entry *e;
548 struct itbl_field *f;
550 if (!ITBL_IS_INSN(insn))
552 processor = get_processor(ITBL_DECODE_PNUM(insn));
554 /* find entry in list */
555 e = find_entry_byval(processor, e_insn, insn, 0);
557 return 0; /* opcode not in table; invalid instrustion */
560 /* parse insn's args (if any) */
561 for (f=e->fields; f; f=f->next) /* for each arg, ... */
563 struct itbl_entry *r;
566 if (f==e->fields) /* first operand is preceeded by tab */
568 else /* ','s separate following operands */
570 value = extract_range(insn, f->range);
571 /* n should be in form $n or 0xhhh (are symbol names valid?? */
577 /* Accept either a string name
578 * or '$' followed by the register number */
579 r = find_entry_byval(e->processor,f->type,value,&f->range);
583 sprintf(s,"%s$%d",s,value);
586 /* use assembler's symbol table to find symbol */
587 /* FIXME!! Do we need this?
588 * if so, what about relocs??
590 /* If not a symbol, fall thru to IMMED */
592 sprintf(s,"%s0x%x",s,value);
595 return 0; /* error; invalid field spec */
598 return 1; /* done! */
601 /*======================================================================*/
603 * Local functions for manipulating private structures containing
604 * the names and format for the new instructions and registers
605 * for each processor.
608 /* Calculate instruction's opcode and function values from entry */
610 static unsigned long build_opcode(struct itbl_entry *e)
612 unsigned long opcode;
614 opcode = apply_range(e->value,e->range);
615 opcode |= ITBL_ENCODE_PNUM(e->processor);
619 /* Calculate absolute value given the relative value and bit position range
620 * within the instruction.
621 * The range is inclusive where 0 is least significant bit.
622 * A range of { 24, 20 } will have a mask of
624 * pos: 1098 7654 3210 9876 5432 1098 7654 3210
625 * bin: 0000 0001 1111 0000 0000 0000 0000 0000
626 * hex: 0 1 f 0 0 0 0 0
630 static unsigned long apply_range(unsigned long rval, struct itbl_range r)
634 int len = MAX_BITPOS - r.sbit;
636 ASSERT(r.sbit >= r.ebit);
637 ASSERT(MAX_BITPOS >= r.sbit);
640 /* create mask by truncating 1s by shifting */
641 mask = 0xffffffff << len;
643 mask = mask >> r.ebit;
644 mask = mask << r.ebit;
646 aval = (rval << r.ebit) & mask;
650 /* Calculate relative value given the absolute value and bit position range
651 * within the instruction. */
653 static unsigned long extract_range(unsigned long aval, struct itbl_range r)
657 int len = MAX_BITPOS - r.sbit;
659 /* create mask by truncating 1s by shifting */
660 mask = 0xffffffff << len;
662 mask = mask >> r.ebit;
663 mask = mask << r.ebit;
665 rval = (aval & mask) >> r.ebit;
669 /* Extract processor's assembly instruction field name from s;
670 * forms are "n args" "n,args" or "n" */
671 /* Return next argument from string pointer "s" and advance s.
672 * delimiters are " ,\0" */
674 char *itbl_get_field(char **S)
684 if (ps=strchr(s,','),ps) p = ps;
685 if (ps=strchr(s,' '),ps) p = min(p,ps);
686 if (ps=strchr(s,'\0'),ps) p = min(p,ps);
688 return 0; /* error! */
693 if (s[len]=='\0') s=0; /* no more args */
694 else s+=len+1; /* advance to next arg */
700 /* Search entries for a given processor and type
701 * to find one matching the name "n".
702 * Return a pointer to the entry */
704 static struct itbl_entry *find_entry_byname(e_processor processor,
705 e_type type, char *n)
707 struct itbl_entry *e, **es;
709 es = get_entries(processor, type);
710 for (e=*es; e; e=e->next) /* for each entry, ... */
712 if (!strcmp(e->name,n))
718 /* Search entries for a given processor and type
719 * to find one matching the value "val" for the range "r".
720 * Return a pointer to the entry.
721 * This function is used for disassembling fields of an instruction.
724 static struct itbl_entry *find_entry_byval(e_processor processor, e_type type,
725 unsigned long val, struct itbl_range *r)
727 struct itbl_entry *e, **es;
730 es = get_entries(processor, type);
731 for (e=*es; e; e=e->next) /* for each entry, ... */
733 if (processor != e->processor)
735 /* For insns, we might not know the range of the opcode,
736 * so a range of 0 will allow this routine to match against
737 * the range of the entry to be compared with.
738 * This could cause ambiguities.
739 * For operands, we get an extracted value and a range.
741 /* if range is 0, mask val against the range of the compared entry. */
742 if (r==0) /* if no range passed, must be whole 32-bits
743 * so create 32-bit value from entry's range */
745 eval = apply_range(e->value,e->range);
746 val &= apply_range(0xffffffff,e->range);
748 else if (r->sbit == e->range.sbit && r->ebit == e->range.ebit
749 || e->range.sbit == 0 && e->range.ebit == 0)
751 eval = apply_range(e->value,*r);
752 val = apply_range(val, *r);
762 /* Return a pointer to the list of entries for a given processor and type. */
764 static struct itbl_entry **get_entries(e_processor processor, e_type type)
766 return &entries[processor][type];
769 /* Return an integral value for the processor passed from yyparse. */
771 static e_processor get_processor(int yyproc)
773 /* translate from yacc's processor to enum */
774 if (yyproc >= e_p0 && yyproc < e_nprocs)
775 return (e_processor) yyproc;
776 return e_invproc; /* error; invalid processor */
779 /* Return an integral value for the entry type passed from yyparse. */
781 static e_type get_type(int yytype)
785 /* translate from yacc's type to enum */
786 case INSN: return e_insn;
787 case DREG: return e_dreg;
788 case CREG: return e_creg;
789 case GREG: return e_greg;
790 case ADDR: return e_addr;
791 case IMMED: return e_immed;
793 return e_invtype; /* error; invalid type */
798 /* Allocate and initialize an entry */
800 static struct itbl_entry *alloc_entry(e_processor processor, e_type type,
801 char *name, unsigned long value)
803 struct itbl_entry *e, **es;
805 e = (struct itbl_entry*) malloc(sizeof(struct itbl_entry));
808 memset(e,0,sizeof(struct itbl_entry));
809 e->name = (char *) malloc(sizeof(strlen(name))+1);
810 if (e->name) strcpy(e->name,name);
811 e->processor = processor;
814 es = get_entries(e->processor,e->type);
821 /* Allocate and initialize an entry's field */
823 static struct itbl_field *alloc_field(e_type type, int sbit, int ebit,
826 struct itbl_field *f;
827 f = (struct itbl_field*) malloc(sizeof(struct itbl_field));
830 memset(f,0,sizeof(struct itbl_field));
832 f->range.sbit = sbit;
833 f->range.ebit = ebit;