]> git.gag.com Git - fw/sdcc/blob - as/xa51/xa_asm.y
add ucsim z80 test case
[fw/sdcc] / as / xa51 / xa_asm.y
1 %{
2 /* This file is part of Paul's XA51 Assembler, Copyright 1997,2002 Paul Stoffregen
3  *
4  * Paul's XA51 Assembler is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2.
7  *
8  * Paul's XA51 Assembler is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with Foobar; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17
18 /* Author contact: paul@pjrc.com */
19
20 /* parser for the 51-XA assembler, Paul Stoffregen, July 1997 */
21 #include <stdio.h>
22
23 #include "xa_main.h"
24
25 int op[MAX_DB];
26 int size;
27 int inst_size;
28 int arith_opcode, short_opcode, num_op, opcode0, opcode1;
29 int shift_imm_opcode, shift_reg_opcode, rotate_opcode;
30 int stack_addr_opcode, stack_reg_opcode, branch_opcode;
31 int rlist_reg_bank, rlist_bitmask, rlist_size;
32 int db_count, dw_count, i;
33 char symbol_name[MAX_SYMBOL], base_symbol_name[MAX_SYMBOL]={'\0'};
34 char expr_var[MAX_SYMBOL]={0,0,0,'\0'};
35
36 extern char lex_sym_name[];
37 extern int yylex();
38
39 extern void yyrestart(FILE *new_file);
40 extern char * disasm(int byte, int memory_location);
41 extern void hexout(int byte, int memory_location, int end);
42 void error(char *s);
43
44 static int bitmask[]={1, 2, 4, 8, 16, 32, 64, 128};
45
46 %}
47
48 %token ADD ADDC ADDS AND ANL ASL ASR BCC BCS BEQ BG BGE BGT
49 %token BKPT BL BLE BLT BMI BNE BNV BOV BPL BR CALL CJNE CLR
50 %token CMP CPL DA DIV DIVU DJNZ FCALL FJMP JB JBC JMP JNB JNZ
51 %token JZ LEA LSR MOV MOVC MOVS MOVX MUL MULU NEG NOP NORM
52 %token OR ORL POP POPU PUSH PUSHU RESET RET RETI RL RLC RR RRC
53 %token SETB SEXT SUB SUBB TRAP XCH XOR
54 %token REG DPTR PC A C USP
55 %token WORD BIT NUMBER CHAR STRING EOL LOCAL_LABEL
56 %token ORG EQU SFR DB DW BITDEF REGDEF LOW HIGH
57 %token RSHIFT LSHIFT
58 %token AREA AREA_NAME AREA_DESC DS
59 %token MODULE GLOBL 
60
61 %left '&' '|' '^'
62 %left RSHIFT LSHIFT
63 %left '+' '-'
64 %left '*' '/'
65 %nonassoc UNARY
66
67 %%
68
69 all:           line
70              | line all;
71
72 line:          linesymbol ':' linenosym {
73                         if (p1) {
74                                 build_sym_list(symbol_name);
75                                 if (current_area == AREA_BSEG) {
76                                         mk_bit(symbol_name);
77                                 }
78                         }
79                         if (p1 || p2) assign_value(symbol_name, MEM_POS);
80                         MEM_POS += $3;
81                 }
82              | linenosym {
83                         MEM_POS += $1;
84                 }
85
86 linenosym:     directive EOL {
87                         if (p3) out(op, $1);
88                         $$ = $1;
89                 }
90              | instruction EOL {
91                         if (p3) out(op, $1);
92                         $$ = $1;
93                 }
94              | EOL {
95                         if (p3) out(NULL, 0);
96                         $$ = 0;
97                 }
98              | error EOL        /* try to recover from any parse error */
99
100
101 directive:     '.' ORG expr {
102                         MEM_POS = $3;
103                         $$ = 0;
104                 }
105              | ORG expr {
106                         MEM_POS = $2;
107                         $$ = 0;
108                 }
109              | '.' EQU symbol ',' expr { 
110                         if (p1) build_sym_list(symbol_name);
111                         if (p1 || p2) assign_value(symbol_name, $5);
112                         $$ = 0;
113                 }
114              | normal_or_bit_symbol '=' expr {
115                         if (p1) build_sym_list(symbol_name);
116                         if (p1 || p2) assign_value(symbol_name, $3);
117                 }
118              | symbol SFR expr {
119                         if (p1) build_sym_list(symbol_name);
120                         if (p1 || p2) assign_value(symbol_name, $3);
121                         if (p1 || p2) mk_sfr(symbol_name);
122                         $$ = 0;
123                 }
124              | '.' BITDEF bitsymbol ',' bit {
125                         if (p1) {
126                                 build_sym_list(symbol_name);
127                                 mk_bit(symbol_name);
128                         }
129                         if (p1 || p2) assign_value(symbol_name, $5);
130                         $$ = 0;
131                 }
132              | bitsymbol BITDEF bit {
133                         if (p1) {
134                                 build_sym_list(symbol_name);
135                                 mk_bit(symbol_name);
136                         }
137                         if (p1 || p2) assign_value(symbol_name, $3);
138                         $$ = 0;
139                 }
140              | bitsymbol BITDEF expr {
141                         if (p1) {
142                                 build_sym_list(symbol_name);
143                                 mk_bit(symbol_name);
144                         }
145                         if (p1 || p2) assign_value(symbol_name, $3);
146                         $$ = 0;
147                 }
148              | '.' REGDEF regsymbol ',' REG {
149                         if (p1) {
150                                 build_sym_list(symbol_name);
151                                 mk_reg(symbol_name);
152                         }
153                         if (p1 || p2) assign_value(symbol_name, $5);
154                         $$ = 0;
155                 }
156              | regsymbol REGDEF REG {
157                         if (p1) {
158                                 build_sym_list(symbol_name);
159                                 mk_reg(symbol_name);
160                         }
161                         if (p1 || p2) assign_value(symbol_name, $3);
162                         $$ = 0;
163                 }
164
165              | '.' db_directive bytes {
166                         $$ = db_count;
167                 }
168              | '.' dw_directive words {
169                         $$ = dw_count;
170                 }
171              | '.' AREA AREA_NAME AREA_DESC {
172                         if ($3 < 0 || $3 >= NUM_AREAS) {
173                                 error("Illegal Area Directive");
174                         }
175                         symbol_name[0] = '\0';
176                         current_area = $3;
177                         $$ = 0;
178                 }
179              | '.' MODULE WORD {
180                         /* ignore module definition */
181                         $$ = 0;
182                 }
183              | '.' GLOBL WORD {
184                         /* ignore global symbol declaration */
185                         $$ = 0;
186                 }
187              | '.' GLOBL bit {
188                         /* ignore bit symbol declaration */
189                         $$ = 0;
190                 }
191              | '.' DS expr {
192                         /* todo: if CSEG, emit some filler bytes */
193                         $$ = $3;
194                 }
195
196 db_directive:   DB {db_count = 0;}
197
198
199 linesymbol:    normal_or_bit_symbol  { 
200                         strcpy(symbol_name, lex_sym_name);
201                         if (!strchr(lex_sym_name, ':')) {
202                                 /* non-local label, remember base name */
203                                 strcpy(base_symbol_name, lex_sym_name);
204                         }
205                         if (is_target(symbol_name)) pad_with_nop();
206                 }
207
208 normal_or_bit_symbol: WORD {$$ = $1;}
209                 | BIT {$$ = $1;}
210
211 bytes:            byte_element
212                 | bytes ',' byte_element
213
214 byte_element:   expr {
215                         op[db_count] = $1 & 255;
216                         if (++db_count >= MAX_DB) {
217                                 error("too many bytes, use two DB");
218                                 db_count--;
219                         }
220                 }
221                 | STRING {
222                         for(i=1; i < strlen(yytext)-1; i++) {
223                                 op[db_count++] = yytext[i];
224                                 if (db_count >= MAX_DB) {
225                                         error("too many bytes, use two DB");
226                                         db_count--;
227                                 }
228                         }
229                 }
230
231 dw_directive:   DW {dw_count = 0;}
232
233 words:            words ',' word_element
234                 | word_element
235
236 word_element:   expr {
237                         op[dw_count] = $1 & 255;
238                         op[dw_count+1] = ($1 >> 8) & 255;
239                         dw_count += 2;
240                         if (dw_count >= MAX_DB) {
241                                 error("too many bytes, use two DW");
242                                 db_count -= 2;
243                         }
244                 }
245
246
247
248 symbol:     WORD  {
249                 strcpy(symbol_name, lex_sym_name);
250                 }
251
252 bitsymbol:    WORD { strcpy(symbol_name, lex_sym_name); }
253             | BIT  { strcpy(symbol_name, lex_sym_name); }
254
255
256 regsymbol:    WORD { strcpy(symbol_name, lex_sym_name); }
257             | REG  { strcpy(symbol_name, lex_sym_name); }
258
259 bit:    expr '.' expr {
260                 if ($3 < 0 || $3 > 7) {
261                         /* only 8 bits in a byte */
262                         error("Only eight bits in a byte");
263                 }
264                 $$ = 100000;    /* should really check $1 is valid */
265                 if ($1 >= 0x20 && $1 <= 0x3F) {
266                         $$ = $1 * 8 + $3;
267                 }
268                 if ($1 >= 0x400 && $1 <= 0x43F) {
269                         $$ = ($1 - 0x400) * 8 + $3 + 0x200;
270                 }
271         }
272         | REG '.' expr {
273                 $$ = 100000;
274                 if (find_size_reg($1) == SIZE8) {
275                         if ($3 < 0 || $3 > 7)
276                                 error("byte reg has only 8 bits");
277                         $$ = reg($1) * 8 + $3;
278                 }
279                 if (find_size_reg($1) == SIZE16) {
280                         if ($3 < 0 || $3 > 15)
281                                 error("word reg has only 16 bits");
282                         $$ = reg($1) * 16 + $3;
283                 }
284         }
285         | BIT {$$ = $1;}
286
287 jmpaddr:        WORD {
288                         $$ = $1;
289                         if (p1) build_target_list(lex_sym_name);
290                 }
291               | NUMBER {
292                         if ($1 & 1) error("Jump target must be aligned");
293                         $$ = $1;
294                 }
295
296
297 expr:   value   {$$ = $1;}
298         | expr '+' expr {$$ = $1 + $3;}
299         | expr '-' expr {$$ = $1 - $3;}
300         | expr '*' expr {$$ = $1 * $3;}
301         | expr '/' expr {$$ = $1 / $3;}
302         | expr '&' expr {$$ = $1 & $3;}
303         | expr '|' expr {$$ = $1 | $3;}
304         | expr '^' expr {$$ = $1 ^ $3;}
305         | expr RSHIFT expr {$$ = $1 >> $3;}
306         | expr LSHIFT expr {$$ = $1 << $3;}
307         | '-' expr %prec UNARY {$$ = $2 * -1;}
308         | '+' expr %prec UNARY {$$ = $2;}
309         | '(' expr ')' {$$ = $2;}
310         | LOW expr %prec UNARY {$$ = $2 & 255;}
311         | HIGH expr %prec UNARY {$$ = ($2 >> 8) & 255;}
312
313
314 value:    NUMBER {$$ = $1;}
315         | CHAR {$$ = $1;}
316         | WORD {$$ = $1; strcpy(expr_var, yytext);}
317
318
319 rlist:  REG {
320                 rlist_bitmask = bitmask[reg($1) % 8];
321                 rlist_reg_bank = (reg($1) / 8) ? 1 : 0;
322                 rlist_size = find_size_reg($1);
323         }
324         | REG ',' rlist {
325                 rlist_bitmask |= bitmask[reg($1) % 8];
326                 if (rlist_reg_bank != ((reg($1) / 8) ? 1 : 0))
327                         error("register list may not mix 0-7/8-15 regs");
328                 if (rlist_size != find_size_reg($1))
329                         error("register list may not mix 8/16 bit registers");
330         }
331
332
333
334
335
336 instruction:
337
338   arith_inst REG ',' REG {
339         $$ = 2;
340         size = find_size2(inst_size, $2, $4);
341         op[0] = arith_opcode * 16 + size * 8 + 1;
342         op[1] = reg($2) * 16 + reg($4);
343   }
344 | arith_inst REG ',' '[' REG ']' {
345         $$ = 2;
346         size = find_size1(inst_size, $2);
347         op[0] = arith_opcode * 16 + size * 8 + 2;
348         op[1] = reg($2) * 16 + reg_indirect($5);
349   }
350 | arith_inst '[' REG ']' ',' REG {
351         $$ = 2;
352         size = find_size1(inst_size, $6);
353         op[0] = arith_opcode * 16 + size * 8 + 2;
354         op[1] = reg($6) * 16 + 8 + reg_indirect($3);
355   }
356 | arith_inst REG ',' '[' REG '+' expr ']' {
357         size = find_size1(inst_size, $2);
358         if ($7 >= -128 && $7 <= 127) {
359                 $$ = 3;
360                 op[0] = arith_opcode * 16 + size * 8 + 4;
361                 op[1] = reg($2) * 16 + reg_indirect($5);
362                 op[2] = ($7 >= 0) ? $7 : 256 + $7;
363         } else {
364                 $$ = 4;
365                 op[0] = arith_opcode * 16 + size * 8 + 5;
366                 op[1] = reg($2) * 16 + reg_indirect($5);
367                 op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
368                 op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
369         }
370   }
371 | arith_inst '[' REG '+' expr ']' ',' REG {
372         size = find_size1(inst_size, $8);
373         if ($5 >= -128 && $5 <= 127) {
374                 $$ = 3;
375                 op[0] = arith_opcode * 16 + size * 8 + 4;
376                 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
377                 op[2] = ($5 >= 0) ? $5 : 256 + $5;
378         } else {
379                 $$ = 4;
380                 op[0] = arith_opcode * 16 + size * 8 + 5;
381                 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
382                 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
383                 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
384         }
385   }
386 | arith_inst REG ',' '[' REG '+' ']' {
387         $$ = 2;
388         size = find_size1(inst_size, $2);
389         op[0] = arith_opcode * 16 + size * 8 + 3;
390         op[1] = reg($2) * 16 + reg_indirect($5);
391   }
392 | arith_inst '[' REG '+' ']' ',' REG {
393         $$ = 2;
394         size = find_size1(inst_size, $7);
395         op[0] = arith_opcode * 16 + size * 8 + 3;
396         op[1] = reg($7) * 16 + 8 + reg_indirect($3);
397   }
398 | arith_inst expr ',' REG {
399         $$ = 3;
400         size = find_size1(inst_size, $4);
401         op[0] = arith_opcode * 16 + size * 8 + 6;
402         op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
403         op[2] = lsb(direct_addr($2));
404   }
405 | arith_inst REG ',' expr {
406         $$ = 3;
407         size = find_size1(inst_size, $2);
408         op[0] = arith_opcode * 16 + size * 8 + 6;
409         op[1] = reg($2) * 16 + msb(direct_addr($4));
410         op[2] = lsb(direct_addr($4));
411   }
412 | arith_inst REG ',' '#' expr {
413         size = find_size1(inst_size, $2);
414         if (size == SIZE8) {
415                 $$ = 3;
416                 op[0] = 0x91;
417                 op[1] = reg($2) * 16 + arith_opcode;
418                 op[2] = imm_data8($5);
419         } else {
420                 $$ = 4;
421                 op[0] = 0x99;
422                 op[1] = reg($2) * 16 + arith_opcode;
423                 op[2] = msb(imm_data16($5));
424                 op[3] = lsb(imm_data16($5));
425         }
426   }
427 | arith_inst '[' REG ']' ',' '#' expr {
428         size = find_size0(inst_size);
429         if (size == SIZE8) {
430                 $$ = 3;
431                 op[0] = 0x92;
432                 op[1] = reg_indirect($3) * 16 + arith_opcode;
433                 op[2] = imm_data8($7);
434         } else {
435                 $$ = 4;
436                 op[0] = 0x9A;
437                 op[1] = reg_indirect($3) * 16 + arith_opcode;
438                 op[2] = msb(imm_data16($7));
439                 op[3] = lsb(imm_data16($7));
440         }
441   }
442 | arith_inst '[' REG '+' ']' ',' '#' expr {
443         size = find_size0(inst_size);
444         if (size == SIZE8) {
445                 $$ = 3;
446                 op[0] = 0x93;
447                 op[1] = reg_indirect($3) * 16 + arith_opcode;
448                 op[2] = imm_data8($8);
449         } else {
450                 $$ = 4;
451                 op[0] = 0x9B;
452                 op[1] = reg_indirect($3) * 16 + arith_opcode;
453                 op[2] = msb(imm_data16($8));
454                 op[3] = lsb(imm_data16($8));
455         }
456   }
457 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
458         size = find_size0(inst_size);
459         if ($5 >= -128 && $5 <= 127) {
460                 if (size == SIZE8) {
461                         $$ = 4;
462                         op[0] = 0x94;
463                         op[1] = reg_indirect($3) * 16 + arith_opcode;
464                         op[2] = ($5 >= 0) ? $5 : 256 + $5;
465                         op[3] = imm_data8($9);
466                 } else {
467                         $$ = 5;
468                         op[0] = 0x9C;
469                         op[1] = reg_indirect($3) * 16 + arith_opcode;
470                         op[2] = ($5 >= 0) ? $5 : 256 + $5;
471                         op[3] = msb(imm_data16($9));
472                         op[4] = lsb(imm_data16($9));
473                 }
474         } else {
475                 if (size == SIZE8) {
476                         $$ = 5;
477                         op[0] = 0x95;
478                         op[1] = reg_indirect($3) * 16 + arith_opcode;
479                         op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
480                         op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
481                         op[4] = imm_data8($9);
482                 } else {
483                         $$ = 6;
484                         op[0] = 0x9D;
485                         op[1] = reg_indirect($3) * 16 + arith_opcode;
486                         op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
487                         op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
488                         op[4] = msb(imm_data16($9));
489                         op[5] = lsb(imm_data16($9));
490                 }
491         }
492   }
493 | arith_inst expr ',' '#' expr {
494         size = find_size0(inst_size);
495         if (size == SIZE8) {
496                 $$ = 4;
497                 op[0] = 0x96;
498                 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
499                 op[2] = lsb(direct_addr($2));
500                 op[3] = imm_data8($5);
501         } else {
502                 $$ = 5;
503                 op[0] = 0x9E;
504                 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
505                 op[2] = lsb(direct_addr($2));
506                 op[3] = msb(imm_data16($5));
507                 op[4] = lsb(imm_data16($5));
508         }
509   }
510
511 /* the next 8 instructions are MOV, but because MOV was used in the */
512 /* arith_inst group, it will cause a shift/reduce conflict if used */
513 /* directly below... so we're forced to use arith_inst and then */
514 /* add a bit of code to make sure it was MOV and not the other ones */
515
516 | arith_inst '[' REG '+' ']' ',' '[' REG '+' ']' {
517         /* this addr mode is only valid for MOV */
518         if (arith_opcode != 8) error("Addr mode only valid for MOV (1)");
519         size = find_size0(inst_size);
520         $$ = 2;
521         op[0] = 0x90 + size * 8;
522         op[1] = reg_indirect($3) * 16 + reg_indirect($8);
523   }
524 | arith_inst expr ',' '[' REG ']' {
525         /* this addr mode is only valid for MOV */
526         if (arith_opcode != 8) error("Addr mode only valid for MOV (2)");
527         size = find_size0(inst_size);
528         $$ = 3;
529         op[0] = 0xA0 + size * 8;
530         op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
531         op[2] = lsb(direct_addr($2));
532   }
533 | arith_inst '[' REG ']' ',' expr {
534         /* this addr mode is only valid for MOV */
535         if (arith_opcode != 8) error("Addr mode only valid for MOV (3)");
536         size = find_size0(inst_size);
537         $$ = 3;
538         op[0] = 0xA0 + size * 8;
539         op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
540         op[2] = lsb(direct_addr($6));
541   }
542 | arith_inst expr ',' expr {
543         /* this addr mode is only valid for MOV */
544         if (arith_opcode != 8) error("Addr mode only valid for MOV (4)");
545         size = find_size0(inst_size);
546         $$ = 4;
547         op[0] = 0x97 + size * 8;
548         op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
549         op[2] = lsb(direct_addr($2));
550         op[3] = lsb(direct_addr($4));
551   }
552 | arith_inst REG ',' USP {
553         /* this addr mode is only valid for MOV */
554         if (arith_opcode != 8) error("Addr mode only valid for MOV (5)");
555         $$ = 2;
556         op[0] = 0x90;
557         op[1] = reg($2) * 16 + 15;
558   }
559 | arith_inst USP ',' REG {
560         /* this addr mode is only valid for MOV */
561         if (arith_opcode != 8) error("Addr mode only valid for MOV (6)");
562         $$ = 2;
563         op[0] = 0x98;
564         op[1] = reg($4) * 16 + 15;
565   }
566 | arith_inst C ',' bit {
567         /* this addr mode is only valid for MOV */
568         if (arith_opcode != 8) error("Addr mode only valid for MOV (7)");
569         $$ = 3;
570         op[0] = 0x08;
571         op[1] = 0x20 + msb(bit_addr($4));
572         op[2] = lsb(bit_addr($4));
573   }
574 | arith_inst bit ',' C {
575         /* this addr mode is only valid for MOV */
576         if (arith_opcode != 8) error("Addr mode only valid for MOV (8)");
577         $$ = 3;
578         op[0] = 0x08;
579         op[1] = 0x30 + msb(bit_addr($2));
580         op[2] = lsb(bit_addr($2));
581   }
582
583 | MOVC REG ',' '[' REG '+' ']' {
584         size = find_size1(inst_size, $2);
585         $$ = 2;
586         op[0] = 0x80 + size * 8;
587         op[1] = reg($2) * 16 + reg_indirect($5);
588   }
589 | MOVC A ',' '[' A '+' DPTR ']' {
590         $$ = 2;
591         op[0] = 0x90;
592         op[1] = 0x4E;
593   }
594 | MOVC A ',' '[' A '+' PC ']' {
595         $$ = 2;
596         op[0] = 0x90;
597         op[1] = 0x4C;
598   }
599 | MOVX REG ',' '[' REG ']' {
600         $$ = 2;
601         size = find_size1(inst_size, $2);
602         op[0] = 0xA7 + size * 8;
603         op[1] = reg($2) * 16 + reg_indirect($5);
604   }
605 | MOVX '[' REG ']' ',' REG {
606         $$ = 2;
607         size = find_size1(inst_size, $6);
608         op[0] = 0xA7 + size * 8;
609         op[1] = reg($6) * 16 + 8 + reg_indirect($3);
610   }
611 | XCH REG ',' REG {
612         $$ = 2;
613         size = find_size2(inst_size, $2, $4);
614         op[0] = 0x60 + size * 8;
615         op[1] = reg($2) * 16 + reg($4);
616   }
617 | XCH REG ',' '[' REG ']' {
618         $$ = 2;
619         size = find_size1(inst_size, $2);
620         op[0] = 0x50 + size * 8;
621         op[1] = reg($2) * 16 + reg_indirect($5);
622   }
623 | XCH REG ',' expr {
624         $$ = 3;
625         size = find_size1(inst_size, $2);
626         op[0] = 0xA0 + size * 8;
627         op[1] = reg($2) * 16 + msb(direct_addr($4));
628         op[2] = lsb(direct_addr($4));
629   }
630 | short_data_inst REG ',' '#' expr {
631         $$ = 2;
632         size = find_size1(inst_size, $2);
633         op[0] = short_opcode + size * 8 + 1;
634         op[1] = reg($2) * 16 + imm_data4_signed($5);
635   }
636 | short_data_inst '[' REG ']' ',' '#' expr {
637         $$ = 2;
638         size = find_size0(inst_size);
639         op[0] = short_opcode + size * 8 + 2;
640         op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
641   }
642 | short_data_inst '[' REG '+' ']' ',' '#' expr {
643         $$ = 2;
644         size = find_size0(inst_size);
645         op[0] = short_opcode + size * 8 + 3;
646         op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
647   }
648 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
649         size = find_size0(inst_size);
650         if ($5 >= -128 && $5 <= 127) {
651                 $$ = 3;
652                 op[0] = short_opcode + size * 8 + 4;
653                 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
654                 op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
655         } else {
656                 $$ = 4;
657                 op[0] = short_opcode + size * 8 + 5;
658                 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
659                 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
660                 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
661         }
662   }
663 | short_data_inst expr ',' '#' expr {
664         $$ = 3;
665         size = find_size0(inst_size);
666         op[0] = short_opcode + size * 8 + 6;
667         op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
668         op[2] = lsb(direct_addr($2));
669   }
670
671
672
673 | ANL C ',' bit {
674         $$ = 3;
675         op[0] = 0x08;
676         op[1] = 0x40 + msb(bit_addr($4));
677         op[2] = lsb(bit_addr($4));
678   }
679 | ANL C ',' '/' bit {
680         $$ = 3;
681         op[0] = 0x08;
682         op[1] = 0x50 + msb(bit_addr($5));
683         op[2] = lsb(bit_addr($5));
684   }
685
686 | ORL C ',' bit {
687         $$ = 3;
688         op[0] = 0x08;
689         op[1] = 0x60 + msb(bit_addr($4));
690         op[2] = lsb(bit_addr($4));
691   }
692 | ORL C ',' '/' bit {
693         $$ = 3;
694         op[0] = 0x08;
695         op[1] = 0x70 + msb(bit_addr($5));
696         op[2] = lsb(bit_addr($5));
697   }
698 | CLR bit {
699         $$ = 3;
700         op[0] = 0x08;
701         op[1] = msb(bit_addr($2));
702         op[2] = lsb(bit_addr($2));
703   }
704 | SETB bit {
705         $$ = 3;
706         op[0] = 0x08;
707         op[1] = 0x10 + msb(bit_addr($2));
708         op[2] = lsb(bit_addr($2));
709   }
710 | logical_shift_inst REG ',' REG {
711         size = find_size1(inst_size, $2);
712         if (find_size_reg($4) != SIZE8)
713                 error("Second register in logical shift must be byte size");
714         $$ = 2;
715         op[0] = shift_reg_opcode;
716         switch (size) {
717                 case SIZE8:  op[0] += 0; break;
718                 case SIZE16: op[0] += 8; break;
719                 case SIZE32: op[0] += 12; break;
720         }
721         op[1] = reg($2) * 16 + reg($4);
722   }
723 | logical_shift_inst REG ',' '#' expr {
724         size = find_size1(inst_size, $2);
725         $$ = 2;
726         if (shift_imm_opcode == -1)
727                 error("NORM may not use a constant");
728         op[0] = shift_imm_opcode;
729         switch (size) {
730                 case SIZE8:  op[0] += 0; break;
731                 case SIZE16: op[0] += 8; break;
732                 case SIZE32: op[0] += 12; break;
733         }
734         switch (size) {
735                 case SIZE8:
736                 case SIZE16:
737                         op[1] = reg($2) * 16 + imm_data4_unsigned($5);
738                         break;
739                 case SIZE32:
740                         op[1] = (reg($2) / 2) * 32 + imm_data5_unsigned($5);
741                         break;
742         }
743   }
744 | no_opperand_inst {
745         $$ = num_op;
746         op[0] = opcode0;
747         op[1] = opcode1;
748   }
749
750 | TRAP '#' expr {
751         $$ = 2;
752         op[0] = 0xD6;
753         op[1] = 0x30 + imm_data4_unsigned($3);
754   }
755 | CPL REG {
756         $$ = 2;
757         size = find_size1(inst_size, $2);
758         op[0] = 0x90 + size * 8;
759         op[1] = reg($2) * 16 + 10;
760   }
761 | DA REG {
762         $$ = 2;
763         op[0] = 0x90;
764         op[1] = reg($2) * 16 + 8;
765   }
766 | NEG REG {
767         $$ = 2;
768         size = find_size1(inst_size, $2);
769         op[0] = 0x90 + size * 8;
770         op[1] = reg($2) * 16 + 11;
771   }
772 | SEXT REG {
773         $$ = 2;
774         size = find_size1(inst_size, $2);
775         op[0] = 0x90 + size * 8;
776         op[1] = reg($2) * 16 + 9;
777   }
778
779 | rotate_inst REG ',' '#' expr {
780         $$ = 2;
781         size = find_size1(inst_size, $2);
782         op[0] = rotate_opcode + size * 8;
783         op[1] = reg($2) * 16 + imm_data4_unsigned($5);
784   }
785
786
787 | LEA REG ',' REG '+' expr {
788         if ($6 >= -128 && $6 <= 127) {
789                 $$ = 3;
790                 op[0] = 0x40;
791                 op[1] = reg($2) * 16 + reg_indirect($4);
792                 op[2] = ($6 >= 0) ? $6 : 256 + $6;
793         } else {
794                 op[0] = 0x48;
795                 op[1] = reg($2) * 16 + reg_indirect($4);
796                 op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
797                 op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
798         }
799   }
800 | stack_inst expr {
801         $$ = 3;
802         size = find_size0(inst_size);
803         op[0] = msb(stack_addr_opcode) + size * 8;
804         op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
805         op[2] = lsb(direct_addr($2));
806   }
807 | stack_inst rlist {
808         $$ = 2;
809         if (inst_size != UNKNOWN && find_size0(inst_size) != rlist_size)
810                 error("inst specifies different size than registers used");
811         op[0] = stack_reg_opcode + rlist_reg_bank * 64 + rlist_size * 8;
812         op[1] = rlist_bitmask;
813   }
814
815
816 | MUL REG ',' REG {
817         $$ = 2;
818         size = find_size2(inst_size, $2, $4);
819         op[0] = 0xE6;
820         op[1] = reg($2) * 16 + reg($4);
821   }
822 | MULU REG ',' REG {
823         $$ = 2;
824         size = find_size2(inst_size, $2, $4);
825         if (size == SIZE8) {
826                 op[0] = 0xE0;
827                 op[1] = reg($2) * 16 + reg($4);
828         } else {
829                 op[0] = 0xE4;
830                 op[1] = reg($2) * 16 + reg($4);
831         }
832   }
833 | MUL REG ',' '#' expr {
834         $$ = 2;
835         size = find_size1(inst_size, $2);
836         op[0] = 0xE9;
837         op[1] = reg($2) + 8;
838         op[2] = msb(imm_data16($5));
839         op[3] = lsb(imm_data16($5));
840   }
841 | MULU REG ',' '#' expr {
842         size = find_size2(inst_size, $2, $4);
843         if (size == SIZE8) {
844                 $$ = 3;
845                 op[0] = 0xE8;
846                 op[1] = reg($2) * 16;
847                 op[2] = imm_data8($5);
848         } else {
849                 $$ = 4;
850                 op[0] = 0xE9;
851                 op[1] = reg($2) * 16;
852                 op[2] = msb(imm_data16($5));
853                 op[3] = lsb(imm_data16($5));
854         }
855   }
856 | DIV REG ',' REG {
857         $$ = 2;
858         size = find_size2(inst_size, $2, $4);
859         switch (size) {
860         case SIZE8:
861                 error("Singed DIV can't be 8 bit size"); break;
862         case SIZE16:
863                 op[0] = 0xE7;
864                 op[1] = reg($2) * 16 + reg($4);
865                 break;
866         case SIZE32:
867                 op[0] = 0xEF;
868                 op[1] = (reg($2) / 2) * 32 + reg($4);
869                 break;
870         }
871   }
872 | DIVU REG ',' REG {
873         $$ = 2;
874         size = find_size2(inst_size, $2, $4);
875         switch (size) {
876         case SIZE8:
877                 op[0] = 0xE1;
878                 op[1] = reg($2) * 16 + reg($4);
879                 break;
880         case SIZE16:
881                 op[0] = 0xE5;
882                 op[1] = reg($2) * 16 + reg($4);
883                 break;
884         case SIZE32:
885                 op[0] = 0xED;
886                 op[1] = (reg($2) / 2) * 32 + reg($4);
887                 break;
888         }
889   }
890 | DIV REG ',' '#' expr { 
891         size = find_size1(inst_size, $2);
892         switch (size) {
893         case SIZE8:
894                 error("Singed DIV can't be 8 bit size"); break;
895         case SIZE16:
896                 $$ = 3;
897                 op[0] = 0xE8;
898                 op[1] = reg($2) * 16 + 11;
899                 op[2] = imm_data8($5);
900                 break;
901         case SIZE32:
902                 $$ = 4;
903                 op[0] = 0xE9;
904                 op[1] = (reg($2) / 2) * 32 + 9;
905                 op[2] = msb(imm_data16($5));
906                 op[3] = lsb(imm_data16($5));
907                 break;
908         }
909   }
910 | DIVU REG ',' '#' expr { 
911         size = find_size1(inst_size, $2);
912         switch (size) {
913         case SIZE8:
914                 $$ = 3;
915                 op[0] = 0xE8;
916                 op[1] = reg($2) * 16 + 1;
917                 op[2] = imm_data8($5);
918                 break;
919         case SIZE16:
920                 $$ = 3;
921                 op[0] = 0xE8;
922                 op[1] = reg($2) * 16 + 3;
923                 op[2] = imm_data8($5);
924                 break;
925         case SIZE32:
926                 $$ = 4;
927                 op[0] = 0xE9;
928                 op[1] = (reg($2) / 2) * 32 + 1;
929                 op[2] = msb(imm_data16($5));
930                 op[3] = lsb(imm_data16($5));
931                 break;
932         }
933   }
934 | CALL '[' REG ']' {
935         $$ = 2;
936         op[0] = 0xC6;
937         op[1] = reg($3);
938   }
939 | FCALL jmpaddr {
940         $$ = 4;
941         op[0] = 0xC4;
942         op[1] = ($2 >> 8) & 255;
943         op[2] = $2 & 255;
944         op[3] = ($2 >> 16) & 255;
945   }
946 | FJMP jmpaddr {
947         $$ = 4;
948         op[0] = 0xD4;
949         op[1] = ($2 >> 8) & 255;
950         op[2] = $2 & 255;
951         op[3] = ($2 >> 16) & 255;
952   }
953 | JMP '[' REG ']' {
954         $$ = 2;
955         op[0] = 0xD6;
956         op[1] = 0x70 + reg_indirect($3);
957   }
958 | JMP '[' A '+' DPTR ']' {
959         $$ = 2;
960         op[0] = 0xD6;
961         op[1] = 0x46;
962   }
963 | JMP '[' '[' REG '+' ']' ']' {
964         $$ = 2;
965         op[0] = 0xD6;
966         op[1] = 0x60 + reg_indirect($4);
967   }
968
969 | JMP jmpaddr {
970         $$ = 3;
971         op[0] = 0xD5;
972         op[1] = msb(rel16(MEM_POS + $$, $2));
973         op[2] = lsb(rel16(MEM_POS + $$, $2));
974   }
975
976 | CALL jmpaddr {
977         $$ = 3;
978         op[0] = 0xC5;
979         op[1] = msb(rel16(MEM_POS + $$, $2));
980         op[2] = lsb(rel16(MEM_POS + $$, $2));
981   }
982 | branch_inst jmpaddr {
983         $$ = 2;
984         op[0] = branch_opcode;
985         op[1] = rel8(MEM_POS + $$, $2);
986   }
987 | CJNE REG ',' expr ',' jmpaddr {
988         $$ = 4;
989         size = find_size1(inst_size, $2);
990         op[0] = 0xE2 + size * 8;
991         op[1] = reg($2) * 16 + msb(direct_addr($4));
992         op[2] = lsb(direct_addr($4));
993         op[3] = rel8(MEM_POS + $$, $6);
994   }
995 | CJNE REG ',' '#' expr ',' jmpaddr {
996         size  = find_size1(inst_size, $2);
997         if (size == SIZE8) {
998                 $$ = 4;
999                 op[0] = 0xE3;
1000                 op[1] = reg($2) * 16;
1001                 op[2] = rel8(MEM_POS + $$, $7);
1002                 op[3] = imm_data8($5);
1003         } else {
1004                 $$ = 5;
1005                 op[0] = 0xEB;
1006                 op[1] = reg($2) * 16;
1007                 op[2] = rel8(MEM_POS + $$, $7);
1008                 op[3] = msb(imm_data16($5));
1009                 op[4] = lsb(imm_data16($5));
1010         }
1011   }
1012 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
1013         size  = find_size0(inst_size);
1014         if (size == SIZE8) {
1015                 $$ = 4;
1016                 op[0] = 0xE3;
1017                 op[1] = reg_indirect($3) * 16 + 8;
1018                 op[2] = rel8(MEM_POS + $$, $9);
1019                 op[3] = imm_data8($7);
1020         } else {
1021                 $$ = 5;
1022                 op[0] = 0xEB;
1023                 op[1] = reg_indirect($3) * 16 + 8;
1024                 op[2] = rel8(MEM_POS + $$, $9);
1025                 op[3] = msb(imm_data16($7));
1026                 op[4] = lsb(imm_data16($7));
1027         }
1028   }
1029 | DJNZ REG ',' jmpaddr {
1030         $$ = 3;
1031         size  = find_size1(inst_size, $2);
1032         op[0] = 0x87 + size * 8;
1033         op[1] = reg($2) * 16 + 8;
1034         op[2] = rel8(MEM_POS + $$, $4);
1035   }
1036
1037
1038 | DJNZ expr ',' jmpaddr {
1039         $$ = 4;
1040         size  = find_size0(inst_size);
1041         op[0] = 0xE2 + size * 8;
1042         op[1] = msb(direct_addr($2)) + 8;
1043         op[2] = lsb(direct_addr($2));
1044         op[3] = rel8(MEM_POS + $$, $4);
1045   }
1046
1047 | JB bit ',' jmpaddr {
1048         $$ = 4;
1049         op[0] = 0x97;
1050         op[1] = 0x80 + msb(bit_addr($2));
1051         op[2] = lsb(bit_addr($2));
1052         op[3] = rel8(MEM_POS + $$, $4);
1053   }
1054
1055 | JBC bit ',' jmpaddr {
1056         $$ = 4;
1057         op[0] = 0x97;
1058         op[1] = 0xC0 + msb(bit_addr($2));
1059         op[2] = lsb(bit_addr($2));
1060         op[3] = rel8(MEM_POS + $$, $4);
1061   }
1062
1063 | JNB bit ',' jmpaddr {
1064         $$ = 4;
1065         op[0] = 0x97;
1066         op[1] = 0xA0 + msb(bit_addr($2));
1067         op[2] = lsb(bit_addr($2));
1068         op[3] = rel8(MEM_POS + $$, $4);
1069   }
1070
1071
1072 arith_inst:
1073           ADD   {arith_opcode = 0;}
1074         | ADDC  {arith_opcode = 1;}
1075         | AND   {arith_opcode = 5;}
1076         | CMP   {arith_opcode = 4;}
1077         | MOV   {arith_opcode = 8;}
1078         | OR    {arith_opcode = 6;}
1079         | SUB   {arith_opcode = 2;}
1080         | SUBB  {arith_opcode = 3;}
1081         | XOR   {arith_opcode = 7;}
1082
1083 short_data_inst:
1084           ADDS {short_opcode = 0xA0;}
1085         | MOVS {short_opcode = 0xB0;}
1086
1087 logical_shift_inst:
1088           ASL  {shift_reg_opcode = 0xC1; shift_imm_opcode = 0xD1;}
1089         | ASR  {shift_reg_opcode = 0xC2; shift_imm_opcode = 0xD2;}
1090         | LSR  {shift_reg_opcode = 0xC0; shift_imm_opcode = 0xD0;}
1091         | NORM {shift_reg_opcode = 0xC3; shift_imm_opcode = -1;}
1092
1093 rotate_inst:
1094           RL    {rotate_opcode = 0xD3;}
1095         | RLC   {rotate_opcode = 0xD7;}
1096         | RR    {rotate_opcode = 0xD0;}
1097         | RRC   {rotate_opcode = 0xD7;}
1098
1099 stack_inst:
1100           POP   {stack_addr_opcode = 0x8710; stack_reg_opcode = 0x27;}
1101         | POPU  {stack_addr_opcode = 0x8700; stack_reg_opcode = 0x37;}
1102         | PUSH  {stack_addr_opcode = 0x8730; stack_reg_opcode = 0x07;}
1103         | PUSHU {stack_addr_opcode = 0x8720; stack_reg_opcode = 0x17;}
1104
1105 no_opperand_inst:
1106           BKPT  {num_op = 1; opcode0 = 255; opcode1 = 0;}
1107         | NOP   {num_op = 1; opcode0 = 0; opcode1 = 0;}
1108         | RESET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x10;}
1109         | RET   {num_op = 2; opcode0 = 0xD6; opcode1 = 0x80;}
1110         | RETI  {num_op = 2; opcode0 = 0xD6; opcode1 = 0x90;}
1111
1112 branch_inst:
1113           BCC   {branch_opcode = 0xF0;}
1114         | BCS   {branch_opcode = 0xF1;}
1115         | BEQ   {branch_opcode = 0xF3;}
1116         | BG    {branch_opcode = 0xF8;}
1117         | BGE   {branch_opcode = 0xFA;}
1118         | BGT   {branch_opcode = 0xFC;}
1119         | BL    {branch_opcode = 0xF9;}
1120         | BLE   {branch_opcode = 0xFD;}
1121         | BLT   {branch_opcode = 0xFB;}
1122         | BMI   {branch_opcode = 0xF7;}
1123         | BNE   {branch_opcode = 0xF2;}
1124         | BNV   {branch_opcode = 0xF4;}
1125         | BOV   {branch_opcode = 0xF5;}
1126         | BPL   {branch_opcode = 0xF6;}
1127         | BR    {branch_opcode = 0xFE;}
1128         | JZ    {branch_opcode = 0xEC;}
1129         | JNZ   {branch_opcode = 0xEE;}
1130
1131
1132
1133 %%
1134
1135
1136 int reg(int reg_spec)
1137 {
1138         return reg_spec & 15;
1139 }
1140
1141 int reg_indirect(int reg_spec)
1142 {
1143         if (reg_spec & BYTE_REG)
1144                 error("Indirect addressing may not use byte registers");
1145         if ((reg_spec & 15) > 7)
1146                 error("Only R0 through R7 may be used for indirect addr");
1147         return reg_spec & 7;
1148 }
1149
1150 int rel16(int pos, int dest)
1151 {
1152         int rel;
1153
1154         if (!p3) return 0;      /* don't bother unless writing code */
1155         if (dest & (BRANCH_SPACING - 1))
1156                 error("Attempt to jump to unaligned location");
1157         pos &= ~(BRANCH_SPACING - 1);
1158         rel = (dest - pos) / BRANCH_SPACING;
1159         if (rel < -32768 || rel > 32767)
1160                 error("Attempt to jump out of 16 bit relative range");
1161         if (rel < 0) rel += 65536;
1162         return rel;
1163 }
1164
1165 int rel8(int pos, int dest)
1166 {
1167         int rel;
1168
1169         if (!p3) return 0;      /* don't bother unless writing code */
1170         if (dest & (BRANCH_SPACING - 1))
1171                 error("Attempt to jump to unaligned location");
1172         pos &= ~(BRANCH_SPACING - 1);
1173         rel = (dest - pos) / BRANCH_SPACING;
1174         if (rel < -128 || rel > 127)
1175                 error("Attempt to jump out of 16 bit relative range");
1176         if (rel < 0) rel += 256;
1177         return rel;
1178 }
1179
1180 int msb(int value)
1181 {
1182         return (value >> 8) & 255;
1183 }
1184
1185 int lsb(int value)
1186 {
1187         return value & 255;
1188 }
1189
1190 int direct_addr(int value)
1191 {
1192         char buf[250];
1193
1194         if (value < 0 || value > 2047) {
1195                 sprintf(buf, "illegal value (%d) for direct address", value);
1196                 error(buf);
1197         }
1198         return value;
1199 }
1200
1201 int imm_data4_signed(int value)
1202 {
1203         if (value < -8 || value > 7)
1204                 error("illegal 4 bit (signed) value");
1205         if (value >= 0) return value;
1206         else return (16 + value);
1207 }
1208
1209 int imm_data4_unsigned(int value)
1210 {
1211         if (value < 0 || value > 15)
1212                 error("illegal 4 bit (unsigned) value");
1213         return value;
1214 }
1215
1216 int imm_data5_unsigned(int value)
1217 {
1218         if (value < 0 || value > 31)
1219                 error("illegal 5 bit (unsigned) value");
1220         return value;
1221 }
1222
1223 int imm_data8(int value)
1224 {
1225         if (value < -128 || value > 255)
1226                 error("illegal 8 bit value");
1227         if (value >= 0) return value;
1228         else return (256 + value);
1229 }
1230
1231 int imm_data16(int value)
1232 {
1233         if (value < -32728 || value > 65535)
1234                 error("illegal 16 bit value");
1235         if (value >= 0) return value;
1236         else return (65536 + value);
1237 }
1238
1239 int bit_addr(int value)
1240 {
1241         if (value < 0 || value > 1023) {
1242                 fprintf(stderr, "bad bit addr of 0x%04X (%d dec)\n",
1243                         value, value);
1244                 error("illegal bit address");
1245         }
1246         return value;
1247 }
1248
1249
1250 int find_size_reg(int op1spec)
1251 {
1252         int op1size=UNKNOWN;
1253
1254         if (op1spec & BYTE_REG) op1size = SIZE8;
1255         if (op1spec & WORD_REG) op1size = SIZE16;
1256         if (op1size == UNKNOWN)
1257                 error("Register without implied size");
1258         return op1size;
1259 }
1260
1261 int find_size0(int isize)
1262 {
1263         if (isize == UNKNOWN)
1264                 error("Can't determine data size from instruction");
1265         return isize;
1266 }
1267
1268 int find_size1(int isize, int op1spec)
1269 {
1270         int op1size=UNKNOWN;
1271
1272         if (op1spec & BYTE_REG) op1size = SIZE8;
1273         if (op1spec & WORD_REG) op1size = SIZE16;
1274         if (op1size == UNKNOWN)
1275                 error("Register without implied size");
1276
1277         if (isize == SIZE32 && op1size == SIZE16) return SIZE32;
1278         if (isize == UNKNOWN) return op1size;
1279         else {
1280                 if (isize != op1size)
1281                         error("data size of register and inst don't agree");
1282                 return isize;
1283         }
1284 }
1285
1286 int find_size2(int isize, int op1spec, int op2spec)
1287 {
1288         int op1size=UNKNOWN, op2size=UNKNOWN;
1289
1290         if (op1spec & BYTE_REG) op1size = SIZE8;
1291         if (op1spec & WORD_REG) op1size = SIZE16;
1292         if (op1size == UNKNOWN)
1293                 error("Register without implied size");
1294         if (op2spec & BYTE_REG) op2size = SIZE8;
1295         if (op2spec & WORD_REG) op2size = SIZE16;
1296         if (op1size == UNKNOWN)
1297                 error("Register without implied size");
1298
1299         if (op1size != op2size)
1300                 error("data sizes of two registers don't agree");
1301         if (isize == UNKNOWN) return op1size;
1302         else {
1303                 if (isize != op1size)
1304                         error("data size of registers and inst don't agree");
1305                 return isize;
1306         }
1307 }
1308
1309
1310 int yyerror(char *s)
1311 {
1312         if (yytext[0] >= 32) {
1313                 fprintf(stderr, "%s near '%s', line %d\n",
1314                         s, yytext, lineno);
1315         } else {
1316                 fprintf(stderr, "%s, line %d\n", s, lineno - 1);
1317         }
1318         return 0;
1319 }
1320
1321 void error(char *s)
1322 {
1323         yyerror(s);
1324         exit(1);
1325 }
1326
1327 int yywrap()
1328 {
1329         return 1;
1330 }