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