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