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