2 /* This file is part of Paul's XA51 Assembler, Copyright 1997,2002 Paul Stoffregen
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.
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.
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
18 /* Author contact: paul@pjrc.com */
20 /* parser for the 51-XA assembler, Paul Stoffregen, July 1997 */
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'};
36 extern char lex_sym_name[];
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);
44 static int bitmask[]={1, 2, 4, 8, 16, 32, 64, 128};
48 %token ADD ADDC ADDS AND ANL ASL ASR BCC BCS BEQ BG BGE BGT
49 %token BKPT BL BLE BLT BMI BNE BNV BOV BPL BR CALL CJNE CLR
50 %token CMP CPL DA DIV DIVU DJNZ FCALL FJMP JB JBC JMP JNB JNZ
51 %token JZ LEA LSR MOV MOVC MOVS MOVX MUL MULU NEG NOP NORM
52 %token OR ORL POP POPU PUSH PUSHU RESET RET RETI RL RLC RR RRC
53 %token SETB SEXT SUB SUBB TRAP XCH XOR
54 %token REG DPTR PC A C USP
55 %token WORD BIT NUMBER CHAR STRING EOL LOCAL_LABEL
56 %token ORG EQU SFR DB DW BITDEF REGDEF LOW HIGH
58 %token AREA AREA_NAME AREA_DESC DS
72 line: linesymbol ':' linenosym {
74 build_sym_list(symbol_name);
75 if (current_area == AREA_BSEG) {
79 if (p1 || p2) assign_value(symbol_name, MEM_POS);
86 linenosym: directive EOL {
98 | error EOL /* try to recover from any parse error */
101 directive: '.' ORG expr {
109 | '.' EQU symbol ',' expr {
110 if (p1) build_sym_list(symbol_name);
111 if (p1 || p2) assign_value(symbol_name, $5);
114 | normal_or_bit_symbol '=' expr {
115 if (p1) build_sym_list(symbol_name);
116 if (p1 || p2) assign_value(symbol_name, $3);
119 if (p1) build_sym_list(symbol_name);
120 if (p1 || p2) assign_value(symbol_name, $3);
121 if (p1 || p2) mk_sfr(symbol_name);
124 | '.' BITDEF bitsymbol ',' bit {
126 build_sym_list(symbol_name);
129 if (p1 || p2) assign_value(symbol_name, $5);
132 | bitsymbol BITDEF bit {
134 build_sym_list(symbol_name);
137 if (p1 || p2) assign_value(symbol_name, $3);
140 | bitsymbol BITDEF expr {
142 build_sym_list(symbol_name);
145 if (p1 || p2) assign_value(symbol_name, $3);
148 | '.' REGDEF regsymbol ',' REG {
150 build_sym_list(symbol_name);
153 if (p1 || p2) assign_value(symbol_name, $5);
156 | regsymbol REGDEF REG {
158 build_sym_list(symbol_name);
161 if (p1 || p2) assign_value(symbol_name, $3);
165 | '.' db_directive bytes {
168 | '.' dw_directive words {
171 | '.' AREA AREA_NAME AREA_DESC {
172 if ($3 < 0 || $3 >= NUM_AREAS) {
173 error("Illegal Area Directive");
175 symbol_name[0] = '\0';
180 /* ignore module definition */
184 /* ignore global symbol declaration */
188 /* todo: if CSEG, emit some filler bytes */
192 db_directive: DB {db_count = 0;}
195 linesymbol: normal_or_bit_symbol {
196 strcpy(symbol_name, lex_sym_name);
197 if (!strchr(lex_sym_name, ':')) {
198 /* non-local label, remember base name */
199 strcpy(base_symbol_name, lex_sym_name);
201 if (is_target(symbol_name)) pad_with_nop();
204 normal_or_bit_symbol: WORD {$$ = $1;}
208 | bytes ',' byte_element
211 op[db_count] = $1 & 255;
212 if (++db_count >= MAX_DB) {
213 error("too many bytes, use two DB");
218 for(i=1; i < strlen(yytext)-1; i++) {
219 op[db_count++] = yytext[i];
220 if (db_count >= MAX_DB) {
221 error("too many bytes, use two DB");
227 dw_directive: DW {dw_count = 0;}
229 words: words ',' word_element
233 op[dw_count] = $1 & 255;
234 op[dw_count+1] = ($1 >> 8) & 255;
236 if (dw_count >= MAX_DB) {
237 error("too many bytes, use two DW");
245 strcpy(symbol_name, lex_sym_name);
248 bitsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
249 | BIT { strcpy(symbol_name, lex_sym_name); }
252 regsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
253 | REG { strcpy(symbol_name, lex_sym_name); }
256 if ($3 < 0 || $3 > 7) {
257 /* only 8 bits in a byte */
258 error("Only eight bits in a byte");
260 $$ = 100000; /* should really check $1 is valid */
261 if ($1 >= 0x20 && $1 <= 0x3F) {
264 if ($1 >= 0x400 && $1 <= 0x43F) {
265 $$ = ($1 - 0x400) * 8 + $3 + 0x200;
270 if (find_size_reg($1) == SIZE8) {
271 if ($3 < 0 || $3 > 7)
272 error("byte reg has only 8 bits");
273 $$ = reg($1) * 8 + $3;
275 if (find_size_reg($1) == SIZE16) {
276 if ($3 < 0 || $3 > 15)
277 error("word reg has only 16 bits");
278 $$ = reg($1) * 16 + $3;
285 if (p1) build_target_list(lex_sym_name);
288 if ($1 & 1) error("Jump target must be aligned");
293 expr: value {$$ = $1;}
294 | expr '+' expr {$$ = $1 + $3;}
295 | expr '-' expr {$$ = $1 - $3;}
296 | expr '*' expr {$$ = $1 * $3;}
297 | expr '/' expr {$$ = $1 / $3;}
298 | expr '&' expr {$$ = $1 & $3;}
299 | expr '|' expr {$$ = $1 | $3;}
300 | expr '^' expr {$$ = $1 ^ $3;}
301 | expr RSHIFT expr {$$ = $1 >> $3;}
302 | expr LSHIFT expr {$$ = $1 << $3;}
303 | '-' expr %prec UNARY {$$ = $2 * -1;}
304 | '+' expr %prec UNARY {$$ = $2;}
305 | '(' expr ')' {$$ = $2;}
306 | LOW expr %prec UNARY {$$ = $2 & 255;}
307 | HIGH expr %prec UNARY {$$ = ($2 >> 8) & 255;}
310 value: NUMBER {$$ = $1;}
312 | WORD {$$ = $1; strcpy(expr_var, yytext);}
316 rlist_bitmask = bitmask[reg($1) % 8];
317 rlist_reg_bank = (reg($1) / 8) ? 1 : 0;
318 rlist_size = find_size_reg($1);
321 rlist_bitmask |= bitmask[reg($1) % 8];
322 if (rlist_reg_bank != ((reg($1) / 8) ? 1 : 0))
323 error("register list may not mix 0-7/8-15 regs");
324 if (rlist_size != find_size_reg($1))
325 error("register list may not mix 8/16 bit registers");
334 arith_inst REG ',' REG {
336 size = find_size2(inst_size, $2, $4);
337 op[0] = arith_opcode * 16 + size * 8 + 1;
338 op[1] = reg($2) * 16 + reg($4);
340 | arith_inst REG ',' '[' REG ']' {
342 size = find_size1(inst_size, $2);
343 op[0] = arith_opcode * 16 + size * 8 + 2;
344 op[1] = reg($2) * 16 + reg_indirect($5);
346 | arith_inst '[' REG ']' ',' REG {
348 size = find_size1(inst_size, $6);
349 op[0] = arith_opcode * 16 + size * 8 + 2;
350 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
352 | arith_inst REG ',' '[' REG '+' expr ']' {
353 size = find_size1(inst_size, $2);
354 if ($7 >= -128 && $7 <= 127) {
356 op[0] = arith_opcode * 16 + size * 8 + 4;
357 op[1] = reg($2) * 16 + reg_indirect($5);
358 op[2] = ($7 >= 0) ? $7 : 256 + $7;
361 op[0] = arith_opcode * 16 + size * 8 + 5;
362 op[1] = reg($2) * 16 + reg_indirect($5);
363 op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
364 op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
367 | arith_inst '[' REG '+' expr ']' ',' REG {
368 size = find_size1(inst_size, $8);
369 if ($5 >= -128 && $5 <= 127) {
371 op[0] = arith_opcode * 16 + size * 8 + 4;
372 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
373 op[2] = ($5 >= 0) ? $5 : 256 + $5;
376 op[0] = arith_opcode * 16 + size * 8 + 5;
377 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
378 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
379 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
382 | arith_inst REG ',' '[' REG '+' ']' {
384 size = find_size1(inst_size, $2);
385 op[0] = arith_opcode * 16 + size * 8 + 3;
386 op[1] = reg($2) * 16 + reg_indirect($5);
388 | arith_inst '[' REG '+' ']' ',' REG {
390 size = find_size1(inst_size, $7);
391 op[0] = arith_opcode * 16 + size * 8 + 3;
392 op[1] = reg($7) * 16 + 8 + reg_indirect($3);
394 | arith_inst expr ',' REG {
396 size = find_size1(inst_size, $4);
397 op[0] = arith_opcode * 16 + size * 8 + 6;
398 op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
399 op[2] = lsb(direct_addr($2));
401 | arith_inst REG ',' expr {
403 size = find_size1(inst_size, $2);
404 op[0] = arith_opcode * 16 + size * 8 + 6;
405 op[1] = reg($2) * 16 + msb(direct_addr($4));
406 op[2] = lsb(direct_addr($4));
408 | arith_inst REG ',' '#' expr {
409 size = find_size1(inst_size, $2);
413 op[1] = reg($2) * 16 + arith_opcode;
414 op[2] = imm_data8($5);
418 op[1] = reg($2) * 16 + arith_opcode;
419 op[2] = msb(imm_data16($5));
420 op[3] = lsb(imm_data16($5));
423 | arith_inst '[' REG ']' ',' '#' expr {
424 size = find_size0(inst_size);
428 op[1] = reg_indirect($3) * 16 + arith_opcode;
429 op[2] = imm_data8($7);
433 op[1] = reg_indirect($3) * 16 + arith_opcode;
434 op[2] = msb(imm_data16($7));
435 op[3] = lsb(imm_data16($7));
438 | arith_inst '[' REG '+' ']' ',' '#' expr {
439 size = find_size0(inst_size);
443 op[1] = reg_indirect($3) * 16 + arith_opcode;
444 op[2] = imm_data8($8);
448 op[1] = reg_indirect($3) * 16 + arith_opcode;
449 op[2] = msb(imm_data16($8));
450 op[3] = lsb(imm_data16($8));
453 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
454 size = find_size0(inst_size);
455 if ($5 >= -128 && $5 <= 127) {
459 op[1] = reg_indirect($3) * 16 + arith_opcode;
460 op[2] = ($5 >= 0) ? $5 : 256 + $5;
461 op[3] = imm_data8($9);
465 op[1] = reg_indirect($3) * 16 + arith_opcode;
466 op[2] = ($5 >= 0) ? $5 : 256 + $5;
467 op[3] = msb(imm_data16($9));
468 op[4] = lsb(imm_data16($9));
474 op[1] = reg_indirect($3) * 16 + arith_opcode;
475 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
476 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
477 op[4] = imm_data8($9);
481 op[1] = reg_indirect($3) * 16 + arith_opcode;
482 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
483 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
484 op[4] = msb(imm_data16($9));
485 op[5] = lsb(imm_data16($9));
489 | arith_inst expr ',' '#' expr {
490 size = find_size0(inst_size);
494 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
495 op[2] = lsb(direct_addr($2));
496 op[3] = imm_data8($5);
500 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
501 op[2] = lsb(direct_addr($2));
502 op[3] = msb(imm_data16($5));
503 op[4] = lsb(imm_data16($5));
507 /* the next 8 instructions are MOV, but because MOV was used in the */
508 /* arith_inst group, it will cause a shift/reduce conflict if used */
509 /* directly below... so we're forced to use arith_inst and then */
510 /* add a bit of code to make sure it was MOV and not the other ones */
512 | arith_inst '[' REG '+' ']' ',' '[' REG '+' ']' {
513 /* this addr mode is only valid for MOV */
514 if (arith_opcode != 8) error("Addr mode only valid for MOV (1)");
515 size = find_size0(inst_size);
517 op[0] = 0x90 + size * 8;
518 op[1] = reg_indirect($3) * 16 + reg_indirect($8);
520 | arith_inst expr ',' '[' REG ']' {
521 /* this addr mode is only valid for MOV */
522 if (arith_opcode != 8) error("Addr mode only valid for MOV (2)");
523 size = find_size0(inst_size);
525 op[0] = 0xA0 + size * 8;
526 op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
527 op[2] = lsb(direct_addr($2));
529 | arith_inst '[' REG ']' ',' expr {
530 /* this addr mode is only valid for MOV */
531 if (arith_opcode != 8) error("Addr mode only valid for MOV (3)");
532 size = find_size0(inst_size);
534 op[0] = 0xA0 + size * 8;
535 op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
536 op[2] = lsb(direct_addr($6));
538 | arith_inst expr ',' expr {
539 /* this addr mode is only valid for MOV */
540 if (arith_opcode != 8) error("Addr mode only valid for MOV (4)");
541 size = find_size0(inst_size);
543 op[0] = 0x97 + size * 8;
544 op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
545 op[2] = lsb(direct_addr($2));
546 op[3] = lsb(direct_addr($4));
548 | arith_inst REG ',' USP {
549 /* this addr mode is only valid for MOV */
550 if (arith_opcode != 8) error("Addr mode only valid for MOV (5)");
553 op[1] = reg($2) * 16 + 15;
555 | arith_inst USP ',' REG {
556 /* this addr mode is only valid for MOV */
557 if (arith_opcode != 8) error("Addr mode only valid for MOV (6)");
560 op[1] = reg($4) * 16 + 15;
562 | arith_inst C ',' bit {
563 /* this addr mode is only valid for MOV */
564 if (arith_opcode != 8) error("Addr mode only valid for MOV (7)");
567 op[1] = 0x20 + msb(bit_addr($4));
568 op[2] = lsb(bit_addr($4));
570 | arith_inst bit ',' C {
571 /* this addr mode is only valid for MOV */
572 if (arith_opcode != 8) error("Addr mode only valid for MOV (8)");
575 op[1] = 0x30 + msb(bit_addr($2));
576 op[2] = lsb(bit_addr($2));
579 | MOVC REG ',' '[' REG '+' ']' {
580 size = find_size1(inst_size, $2);
582 op[0] = 0x80 + size * 8;
583 op[1] = reg($2) * 16 + reg_indirect($5);
585 | MOVC A ',' '[' A '+' DPTR ']' {
590 | MOVC A ',' '[' A '+' PC ']' {
595 | MOVX REG ',' '[' REG ']' {
597 size = find_size1(inst_size, $2);
598 op[0] = 0xA7 + size * 8;
599 op[1] = reg($2) * 16 + reg_indirect($5);
601 | MOVX '[' REG ']' ',' REG {
603 size = find_size1(inst_size, $6);
604 op[0] = 0xA7 + size * 8;
605 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
609 size = find_size2(inst_size, $2, $4);
610 op[0] = 0x60 + size * 8;
611 op[1] = reg($2) * 16 + reg($4);
613 | XCH REG ',' '[' REG ']' {
615 size = find_size1(inst_size, $2);
616 op[0] = 0x50 + size * 8;
617 op[1] = reg($2) * 16 + reg_indirect($5);
621 size = find_size1(inst_size, $2);
622 op[0] = 0xA0 + size * 8;
623 op[1] = reg($2) * 16 + msb(direct_addr($4));
624 op[2] = lsb(direct_addr($4));
626 | short_data_inst REG ',' '#' expr {
628 size = find_size1(inst_size, $2);
629 op[0] = short_opcode + size * 8 + 1;
630 op[1] = reg($2) * 16 + imm_data4_signed($5);
632 | short_data_inst '[' REG ']' ',' '#' expr {
634 size = find_size0(inst_size);
635 op[0] = short_opcode + size * 8 + 2;
636 op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
638 | short_data_inst '[' REG '+' ']' ',' '#' expr {
640 size = find_size0(inst_size);
641 op[0] = short_opcode + size * 8 + 3;
642 op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
644 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
645 size = find_size0(inst_size);
646 if ($5 >= -128 && $5 <= 127) {
648 op[0] = short_opcode + size * 8 + 4;
649 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
650 op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
653 op[0] = short_opcode + size * 8 + 5;
654 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
655 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
656 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
659 | short_data_inst expr ',' '#' expr {
661 size = find_size0(inst_size);
662 op[0] = short_opcode + size * 8 + 6;
663 op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
664 op[2] = lsb(direct_addr($2));
672 op[1] = 0x40 + msb(bit_addr($4));
673 op[2] = lsb(bit_addr($4));
675 | ANL C ',' '/' bit {
678 op[1] = 0x50 + msb(bit_addr($5));
679 op[2] = lsb(bit_addr($5));
685 op[1] = 0x60 + msb(bit_addr($4));
686 op[2] = lsb(bit_addr($4));
688 | ORL C ',' '/' bit {
691 op[1] = 0x70 + msb(bit_addr($5));
692 op[2] = lsb(bit_addr($5));
697 op[1] = msb(bit_addr($2));
698 op[2] = lsb(bit_addr($2));
703 op[1] = 0x10 + msb(bit_addr($2));
704 op[2] = lsb(bit_addr($2));
706 | logical_shift_inst REG ',' REG {
707 size = find_size1(inst_size, $2);
708 if (find_size_reg($4) != SIZE8)
709 error("Second register in logical shift must be byte size");
711 op[0] = shift_reg_opcode;
713 case SIZE8: op[0] += 0; break;
714 case SIZE16: op[0] += 8; break;
715 case SIZE32: op[0] += 12; break;
717 op[1] = reg($2) * 16 + reg($4);
719 | logical_shift_inst REG ',' '#' expr {
720 size = find_size1(inst_size, $2);
722 if (shift_imm_opcode == -1)
723 error("NORM may not use a constant");
724 op[0] = shift_imm_opcode;
726 case SIZE8: op[0] += 0; break;
727 case SIZE16: op[0] += 8; break;
728 case SIZE32: op[0] += 12; break;
733 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
736 op[1] = (reg($2) / 2) * 32 + imm_data5_unsigned($5);
749 op[1] = 0x30 + imm_data4_unsigned($3);
753 size = find_size1(inst_size, $2);
754 op[0] = 0x90 + size * 8;
755 op[1] = reg($2) * 16 + 10;
760 op[1] = reg($2) * 16 + 8;
764 size = find_size1(inst_size, $2);
765 op[0] = 0x90 + size * 8;
766 op[1] = reg($2) * 16 + 11;
770 size = find_size1(inst_size, $2);
771 op[0] = 0x90 + size * 8;
772 op[1] = reg($2) * 16 + 9;
775 | rotate_inst REG ',' '#' expr {
777 size = find_size1(inst_size, $2);
778 op[0] = rotate_opcode + size * 8;
779 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
783 | LEA REG ',' REG '+' expr {
784 if ($6 >= -128 && $6 <= 127) {
787 op[1] = reg($2) * 16 + reg_indirect($4);
788 op[2] = ($6 >= 0) ? $6 : 256 + $6;
791 op[1] = reg($2) * 16 + reg_indirect($4);
792 op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
793 op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
798 size = find_size0(inst_size);
799 op[0] = msb(stack_addr_opcode) + size * 8;
800 op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
801 op[2] = lsb(direct_addr($2));
805 if (inst_size != UNKNOWN && find_size0(inst_size) != rlist_size)
806 error("inst specifies different size than registers used");
807 op[0] = stack_reg_opcode + rlist_reg_bank * 64 + rlist_size * 8;
808 op[1] = rlist_bitmask;
814 size = find_size2(inst_size, $2, $4);
816 op[1] = reg($2) * 16 + reg($4);
820 size = find_size2(inst_size, $2, $4);
823 op[1] = reg($2) * 16 + reg($4);
826 op[1] = reg($2) * 16 + reg($4);
829 | MUL REG ',' '#' expr {
831 size = find_size1(inst_size, $2);
834 op[2] = msb(imm_data16($5));
835 op[3] = lsb(imm_data16($5));
837 | MULU REG ',' '#' expr {
838 size = find_size2(inst_size, $2, $4);
842 op[1] = reg($2) * 16;
843 op[2] = imm_data8($5);
847 op[1] = reg($2) * 16;
848 op[2] = msb(imm_data16($5));
849 op[3] = lsb(imm_data16($5));
854 size = find_size2(inst_size, $2, $4);
857 error("Singed DIV can't be 8 bit size"); break;
860 op[1] = reg($2) * 16 + reg($4);
864 op[1] = (reg($2) / 2) * 32 + reg($4);
870 size = find_size2(inst_size, $2, $4);
874 op[1] = reg($2) * 16 + reg($4);
878 op[1] = reg($2) * 16 + reg($4);
882 op[1] = (reg($2) / 2) * 32 + reg($4);
886 | DIV REG ',' '#' expr {
887 size = find_size1(inst_size, $2);
890 error("Singed DIV can't be 8 bit size"); break;
894 op[1] = reg($2) * 16 + 11;
895 op[2] = imm_data8($5);
900 op[1] = (reg($2) / 2) * 32 + 9;
901 op[2] = msb(imm_data16($5));
902 op[3] = lsb(imm_data16($5));
906 | DIVU REG ',' '#' expr {
907 size = find_size1(inst_size, $2);
912 op[1] = reg($2) * 16 + 1;
913 op[2] = imm_data8($5);
918 op[1] = reg($2) * 16 + 3;
919 op[2] = imm_data8($5);
924 op[1] = (reg($2) / 2) * 32 + 1;
925 op[2] = msb(imm_data16($5));
926 op[3] = lsb(imm_data16($5));
938 op[1] = ($2 >> 8) & 255;
940 op[3] = ($2 >> 16) & 255;
945 op[1] = ($2 >> 8) & 255;
947 op[3] = ($2 >> 16) & 255;
952 op[1] = 0x70 + reg_indirect($3);
954 | JMP '[' A '+' DPTR ']' {
959 | JMP '[' '[' REG '+' ']' ']' {
962 op[1] = 0x60 + reg_indirect($4);
968 op[1] = msb(rel16(MEM_POS + $$, $2));
969 op[2] = lsb(rel16(MEM_POS + $$, $2));
975 op[1] = msb(rel16(MEM_POS + $$, $2));
976 op[2] = lsb(rel16(MEM_POS + $$, $2));
978 | branch_inst jmpaddr {
980 op[0] = branch_opcode;
981 op[1] = rel8(MEM_POS + $$, $2);
983 | CJNE REG ',' expr ',' jmpaddr {
985 size = find_size1(inst_size, $2);
986 op[0] = 0xE2 + size * 8;
987 op[1] = reg($2) * 16 + msb(direct_addr($4));
988 op[2] = lsb(direct_addr($4));
989 op[3] = rel8(MEM_POS + $$, $6);
991 | CJNE REG ',' '#' expr ',' jmpaddr {
992 size = find_size1(inst_size, $2);
996 op[1] = reg($2) * 16;
997 op[2] = rel8(MEM_POS + $$, $7);
998 op[3] = imm_data8($5);
1002 op[1] = reg($2) * 16;
1003 op[2] = rel8(MEM_POS + $$, $7);
1004 op[3] = msb(imm_data16($5));
1005 op[4] = lsb(imm_data16($5));
1008 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
1009 size = find_size0(inst_size);
1010 if (size == SIZE8) {
1013 op[1] = reg_indirect($3) * 16 + 8;
1014 op[2] = rel8(MEM_POS + $$, $9);
1015 op[3] = imm_data8($7);
1019 op[1] = reg_indirect($3) * 16 + 8;
1020 op[2] = rel8(MEM_POS + $$, $9);
1021 op[3] = msb(imm_data16($7));
1022 op[4] = lsb(imm_data16($7));
1025 | DJNZ REG ',' jmpaddr {
1027 size = find_size1(inst_size, $2);
1028 op[0] = 0x87 + size * 8;
1029 op[1] = reg($2) * 16 + 8;
1030 op[2] = rel8(MEM_POS + $$, $4);
1034 | DJNZ expr ',' jmpaddr {
1036 size = find_size0(inst_size);
1037 op[0] = 0xE2 + size * 8;
1038 op[1] = msb(direct_addr($2)) + 8;
1039 op[2] = lsb(direct_addr($2));
1040 op[3] = rel8(MEM_POS + $$, $4);
1043 | JB bit ',' jmpaddr {
1046 op[1] = 0x80 + msb(bit_addr($2));
1047 op[2] = lsb(bit_addr($2));
1048 op[3] = rel8(MEM_POS + $$, $4);
1051 | JBC bit ',' jmpaddr {
1054 op[1] = 0xC0 + msb(bit_addr($2));
1055 op[2] = lsb(bit_addr($2));
1056 op[3] = rel8(MEM_POS + $$, $4);
1059 | JNB bit ',' jmpaddr {
1062 op[1] = 0xA0 + msb(bit_addr($2));
1063 op[2] = lsb(bit_addr($2));
1064 op[3] = rel8(MEM_POS + $$, $4);
1069 ADD {arith_opcode = 0;}
1070 | ADDC {arith_opcode = 1;}
1071 | AND {arith_opcode = 5;}
1072 | CMP {arith_opcode = 4;}
1073 | MOV {arith_opcode = 8;}
1074 | OR {arith_opcode = 6;}
1075 | SUB {arith_opcode = 2;}
1076 | SUBB {arith_opcode = 3;}
1077 | XOR {arith_opcode = 7;}
1080 ADDS {short_opcode = 0xA0;}
1081 | MOVS {short_opcode = 0xB0;}
1084 ASL {shift_reg_opcode = 0xC1; shift_imm_opcode = 0xD1;}
1085 | ASR {shift_reg_opcode = 0xC2; shift_imm_opcode = 0xD2;}
1086 | LSR {shift_reg_opcode = 0xC0; shift_imm_opcode = 0xD0;}
1087 | NORM {shift_reg_opcode = 0xC3; shift_imm_opcode = -1;}
1090 RL {rotate_opcode = 0xD3;}
1091 | RLC {rotate_opcode = 0xD7;}
1092 | RR {rotate_opcode = 0xD0;}
1093 | RRC {rotate_opcode = 0xD7;}
1096 POP {stack_addr_opcode = 0x8710; stack_reg_opcode = 0x27;}
1097 | POPU {stack_addr_opcode = 0x8700; stack_reg_opcode = 0x37;}
1098 | PUSH {stack_addr_opcode = 0x8730; stack_reg_opcode = 0x07;}
1099 | PUSHU {stack_addr_opcode = 0x8720; stack_reg_opcode = 0x17;}
1102 BKPT {num_op = 1; opcode0 = 255; opcode1 = 0;}
1103 | NOP {num_op = 1; opcode0 = 0; opcode1 = 0;}
1104 | RESET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x10;}
1105 | RET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x80;}
1106 | RETI {num_op = 2; opcode0 = 0xD6; opcode1 = 0x90;}
1109 BCC {branch_opcode = 0xF0;}
1110 | BCS {branch_opcode = 0xF1;}
1111 | BEQ {branch_opcode = 0xF3;}
1112 | BG {branch_opcode = 0xF8;}
1113 | BGE {branch_opcode = 0xFA;}
1114 | BGT {branch_opcode = 0xFC;}
1115 | BL {branch_opcode = 0xF9;}
1116 | BLE {branch_opcode = 0xFD;}
1117 | BLT {branch_opcode = 0xFB;}
1118 | BMI {branch_opcode = 0xF7;}
1119 | BNE {branch_opcode = 0xF2;}
1120 | BNV {branch_opcode = 0xF4;}
1121 | BOV {branch_opcode = 0xF5;}
1122 | BPL {branch_opcode = 0xF6;}
1123 | BR {branch_opcode = 0xFE;}
1124 | JZ {branch_opcode = 0xEC;}
1125 | JNZ {branch_opcode = 0xEE;}
1132 int reg(int reg_spec)
1134 return reg_spec & 15;
1137 int reg_indirect(int reg_spec)
1139 if (reg_spec & BYTE_REG)
1140 error("Indirect addressing may not use byte registers");
1141 if ((reg_spec & 15) > 7)
1142 error("Only R0 through R7 may be used for indirect addr");
1143 return reg_spec & 7;
1146 int rel16(int pos, int dest)
1150 if (!p3) return 0; /* don't bother unless writing code */
1151 if (dest & (BRANCH_SPACING - 1))
1152 error("Attempt to jump to unaligned location");
1153 pos &= ~(BRANCH_SPACING - 1);
1154 rel = (dest - pos) / BRANCH_SPACING;
1155 if (rel < -32768 || rel > 32767)
1156 error("Attempt to jump out of 16 bit relative range");
1157 if (rel < 0) rel += 65536;
1161 int rel8(int pos, int dest)
1165 if (!p3) return 0; /* don't bother unless writing code */
1166 if (dest & (BRANCH_SPACING - 1))
1167 error("Attempt to jump to unaligned location");
1168 pos &= ~(BRANCH_SPACING - 1);
1169 rel = (dest - pos) / BRANCH_SPACING;
1170 if (rel < -128 || rel > 127)
1171 error("Attempt to jump out of 16 bit relative range");
1172 if (rel < 0) rel += 256;
1178 return (value >> 8) & 255;
1186 int direct_addr(int value)
1190 if (value < 0 || value > 2047) {
1191 sprintf(buf, "illegal value (%d) for direct address", value);
1197 int imm_data4_signed(int value)
1199 if (value < -8 || value > 7)
1200 error("illegal 4 bit (signed) value");
1201 if (value >= 0) return value;
1202 else return (16 + value);
1205 int imm_data4_unsigned(int value)
1207 if (value < 0 || value > 15)
1208 error("illegal 4 bit (unsigned) value");
1212 int imm_data5_unsigned(int value)
1214 if (value < 0 || value > 31)
1215 error("illegal 5 bit (unsigned) value");
1219 int imm_data8(int value)
1221 if (value < -128 || value > 255)
1222 error("illegal 8 bit value");
1223 if (value >= 0) return value;
1224 else return (256 + value);
1227 int imm_data16(int value)
1229 if (value < -32728 || value > 65535)
1230 error("illegal 16 bit value");
1231 if (value >= 0) return value;
1232 else return (65536 + value);
1235 int bit_addr(int value)
1237 if (value < 0 || value > 1023) {
1238 fprintf(stderr, "bad bit addr of 0x%04X (%d dec)\n",
1240 error("illegal bit address");
1246 int find_size_reg(int op1spec)
1248 int op1size=UNKNOWN;
1250 if (op1spec & BYTE_REG) op1size = SIZE8;
1251 if (op1spec & WORD_REG) op1size = SIZE16;
1252 if (op1size == UNKNOWN)
1253 error("Register without implied size");
1257 int find_size0(int isize)
1259 if (isize == UNKNOWN)
1260 error("Can't determine data size from instruction");
1264 int find_size1(int isize, int op1spec)
1266 int op1size=UNKNOWN;
1268 if (op1spec & BYTE_REG) op1size = SIZE8;
1269 if (op1spec & WORD_REG) op1size = SIZE16;
1270 if (op1size == UNKNOWN)
1271 error("Register without implied size");
1273 if (isize == SIZE32 && op1size == SIZE16) return SIZE32;
1274 if (isize == UNKNOWN) return op1size;
1276 if (isize != op1size)
1277 error("data size of register and inst don't agree");
1282 int find_size2(int isize, int op1spec, int op2spec)
1284 int op1size=UNKNOWN, op2size=UNKNOWN;
1286 if (op1spec & BYTE_REG) op1size = SIZE8;
1287 if (op1spec & WORD_REG) op1size = SIZE16;
1288 if (op1size == UNKNOWN)
1289 error("Register without implied size");
1290 if (op2spec & BYTE_REG) op2size = SIZE8;
1291 if (op2spec & WORD_REG) op2size = SIZE16;
1292 if (op1size == UNKNOWN)
1293 error("Register without implied size");
1295 if (op1size != op2size)
1296 error("data sizes of two registers don't agree");
1297 if (isize == UNKNOWN) return op1size;
1299 if (isize != op1size)
1300 error("data size of registers and inst don't agree");
1306 int yyerror(char *s)
1308 if (yytext[0] >= 32) {
1309 fprintf(stderr, "%s near '%s', line %d\n",
1312 fprintf(stderr, "%s, line %d\n", s, lineno - 1);