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