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