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 /* ignore bit symbol declaration */
192 /* todo: if CSEG, emit some filler bytes */
196 db_directive: DB {db_count = 0;}
199 linesymbol: normal_or_bit_symbol {
200 strcpy(symbol_name, lex_sym_name);
201 if (!strchr(lex_sym_name, ':')) {
202 /* non-local label, remember base name */
203 strcpy(base_symbol_name, lex_sym_name);
205 if (is_target(symbol_name)) pad_with_nop();
208 normal_or_bit_symbol: WORD {$$ = $1;}
212 | bytes ',' byte_element
215 op[db_count] = $1 & 255;
216 if (++db_count >= MAX_DB) {
217 error("too many bytes, use two DB");
222 for(i=1; i < strlen(yytext)-1; i++) {
223 op[db_count++] = yytext[i];
224 if (db_count >= MAX_DB) {
225 error("too many bytes, use two DB");
231 dw_directive: DW {dw_count = 0;}
233 words: words ',' word_element
237 op[dw_count] = $1 & 255;
238 op[dw_count+1] = ($1 >> 8) & 255;
240 if (dw_count >= MAX_DB) {
241 error("too many bytes, use two DW");
249 strcpy(symbol_name, lex_sym_name);
252 bitsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
253 | BIT { strcpy(symbol_name, lex_sym_name); }
256 regsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
257 | REG { strcpy(symbol_name, lex_sym_name); }
260 if ($3 < 0 || $3 > 7) {
261 /* only 8 bits in a byte */
262 error("Only eight bits in a byte");
264 $$ = 100000; /* should really check $1 is valid */
265 if ($1 >= 0x20 && $1 <= 0x3F) {
268 if ($1 >= 0x400 && $1 <= 0x43F) {
269 $$ = ($1 - 0x400) * 8 + $3 + 0x200;
274 if (find_size_reg($1) == SIZE8) {
275 if ($3 < 0 || $3 > 7)
276 error("byte reg has only 8 bits");
277 $$ = reg($1) * 8 + $3;
279 if (find_size_reg($1) == SIZE16) {
280 if ($3 < 0 || $3 > 15)
281 error("word reg has only 16 bits");
282 $$ = reg($1) * 16 + $3;
289 if (p1) build_target_list(lex_sym_name);
292 if ($1 & 1) error("Jump target must be aligned");
297 expr: value {$$ = $1;}
298 | expr '+' expr {$$ = $1 + $3;}
299 | expr '-' expr {$$ = $1 - $3;}
300 | expr '*' expr {$$ = $1 * $3;}
301 | expr '/' expr {$$ = $1 / $3;}
302 | expr '&' expr {$$ = $1 & $3;}
303 | expr '|' expr {$$ = $1 | $3;}
304 | expr '^' expr {$$ = $1 ^ $3;}
305 | expr RSHIFT expr {$$ = $1 >> $3;}
306 | expr LSHIFT expr {$$ = $1 << $3;}
307 | '-' expr %prec UNARY {$$ = $2 * -1;}
308 | '+' expr %prec UNARY {$$ = $2;}
309 | '(' expr ')' {$$ = $2;}
310 | LOW expr %prec UNARY {$$ = $2 & 255;}
311 | HIGH expr %prec UNARY {$$ = ($2 >> 8) & 255;}
314 value: NUMBER {$$ = $1;}
316 | WORD {$$ = $1; strcpy(expr_var, yytext);}
320 rlist_bitmask = bitmask[reg($1) % 8];
321 rlist_reg_bank = (reg($1) / 8) ? 1 : 0;
322 rlist_size = find_size_reg($1);
325 rlist_bitmask |= bitmask[reg($1) % 8];
326 if (rlist_reg_bank != ((reg($1) / 8) ? 1 : 0))
327 error("register list may not mix 0-7/8-15 regs");
328 if (rlist_size != find_size_reg($1))
329 error("register list may not mix 8/16 bit registers");
338 arith_inst REG ',' REG {
340 size = find_size2(inst_size, $2, $4);
341 op[0] = arith_opcode * 16 + size * 8 + 1;
342 op[1] = reg($2) * 16 + reg($4);
344 | arith_inst REG ',' '[' REG ']' {
346 size = find_size1(inst_size, $2);
347 op[0] = arith_opcode * 16 + size * 8 + 2;
348 op[1] = reg($2) * 16 + reg_indirect($5);
350 | arith_inst '[' REG ']' ',' REG {
352 size = find_size1(inst_size, $6);
353 op[0] = arith_opcode * 16 + size * 8 + 2;
354 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
356 | arith_inst REG ',' '[' REG '+' expr ']' {
357 size = find_size1(inst_size, $2);
358 if ($7 >= -128 && $7 <= 127) {
360 op[0] = arith_opcode * 16 + size * 8 + 4;
361 op[1] = reg($2) * 16 + reg_indirect($5);
362 op[2] = ($7 >= 0) ? $7 : 256 + $7;
365 op[0] = arith_opcode * 16 + size * 8 + 5;
366 op[1] = reg($2) * 16 + reg_indirect($5);
367 op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
368 op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
371 | arith_inst '[' REG '+' expr ']' ',' REG {
372 size = find_size1(inst_size, $8);
373 if ($5 >= -128 && $5 <= 127) {
375 op[0] = arith_opcode * 16 + size * 8 + 4;
376 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
377 op[2] = ($5 >= 0) ? $5 : 256 + $5;
380 op[0] = arith_opcode * 16 + size * 8 + 5;
381 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
382 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
383 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
386 | arith_inst REG ',' '[' REG '+' ']' {
388 size = find_size1(inst_size, $2);
389 op[0] = arith_opcode * 16 + size * 8 + 3;
390 op[1] = reg($2) * 16 + reg_indirect($5);
392 | arith_inst '[' REG '+' ']' ',' REG {
394 size = find_size1(inst_size, $7);
395 op[0] = arith_opcode * 16 + size * 8 + 3;
396 op[1] = reg($7) * 16 + 8 + reg_indirect($3);
398 | arith_inst expr ',' REG {
400 size = find_size1(inst_size, $4);
401 op[0] = arith_opcode * 16 + size * 8 + 6;
402 op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
403 op[2] = lsb(direct_addr($2));
405 | arith_inst REG ',' expr {
407 size = find_size1(inst_size, $2);
408 op[0] = arith_opcode * 16 + size * 8 + 6;
409 op[1] = reg($2) * 16 + msb(direct_addr($4));
410 op[2] = lsb(direct_addr($4));
412 | arith_inst REG ',' '#' expr {
413 size = find_size1(inst_size, $2);
417 op[1] = reg($2) * 16 + arith_opcode;
418 op[2] = imm_data8($5);
422 op[1] = reg($2) * 16 + arith_opcode;
423 op[2] = msb(imm_data16($5));
424 op[3] = lsb(imm_data16($5));
427 | arith_inst '[' REG ']' ',' '#' expr {
428 size = find_size0(inst_size);
432 op[1] = reg_indirect($3) * 16 + arith_opcode;
433 op[2] = imm_data8($7);
437 op[1] = reg_indirect($3) * 16 + arith_opcode;
438 op[2] = msb(imm_data16($7));
439 op[3] = lsb(imm_data16($7));
442 | arith_inst '[' REG '+' ']' ',' '#' expr {
443 size = find_size0(inst_size);
447 op[1] = reg_indirect($3) * 16 + arith_opcode;
448 op[2] = imm_data8($8);
452 op[1] = reg_indirect($3) * 16 + arith_opcode;
453 op[2] = msb(imm_data16($8));
454 op[3] = lsb(imm_data16($8));
457 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
458 size = find_size0(inst_size);
459 if ($5 >= -128 && $5 <= 127) {
463 op[1] = reg_indirect($3) * 16 + arith_opcode;
464 op[2] = ($5 >= 0) ? $5 : 256 + $5;
465 op[3] = imm_data8($9);
469 op[1] = reg_indirect($3) * 16 + arith_opcode;
470 op[2] = ($5 >= 0) ? $5 : 256 + $5;
471 op[3] = msb(imm_data16($9));
472 op[4] = lsb(imm_data16($9));
478 op[1] = reg_indirect($3) * 16 + arith_opcode;
479 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
480 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
481 op[4] = imm_data8($9);
485 op[1] = reg_indirect($3) * 16 + arith_opcode;
486 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
487 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
488 op[4] = msb(imm_data16($9));
489 op[5] = lsb(imm_data16($9));
493 | arith_inst expr ',' '#' expr {
494 size = find_size0(inst_size);
498 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
499 op[2] = lsb(direct_addr($2));
500 op[3] = imm_data8($5);
504 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
505 op[2] = lsb(direct_addr($2));
506 op[3] = msb(imm_data16($5));
507 op[4] = lsb(imm_data16($5));
511 /* the next 8 instructions are MOV, but because MOV was used in the */
512 /* arith_inst group, it will cause a shift/reduce conflict if used */
513 /* directly below... so we're forced to use arith_inst and then */
514 /* add a bit of code to make sure it was MOV and not the other ones */
516 | arith_inst '[' REG '+' ']' ',' '[' REG '+' ']' {
517 /* this addr mode is only valid for MOV */
518 if (arith_opcode != 8) error("Addr mode only valid for MOV (1)");
519 size = find_size0(inst_size);
521 op[0] = 0x90 + size * 8;
522 op[1] = reg_indirect($3) * 16 + reg_indirect($8);
524 | arith_inst expr ',' '[' REG ']' {
525 /* this addr mode is only valid for MOV */
526 if (arith_opcode != 8) error("Addr mode only valid for MOV (2)");
527 size = find_size0(inst_size);
529 op[0] = 0xA0 + size * 8;
530 op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
531 op[2] = lsb(direct_addr($2));
533 | arith_inst '[' REG ']' ',' expr {
534 /* this addr mode is only valid for MOV */
535 if (arith_opcode != 8) error("Addr mode only valid for MOV (3)");
536 size = find_size0(inst_size);
538 op[0] = 0xA0 + size * 8;
539 op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
540 op[2] = lsb(direct_addr($6));
542 | arith_inst expr ',' expr {
543 /* this addr mode is only valid for MOV */
544 if (arith_opcode != 8) error("Addr mode only valid for MOV (4)");
545 size = find_size0(inst_size);
547 op[0] = 0x97 + size * 8;
548 op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
549 op[2] = lsb(direct_addr($2));
550 op[3] = lsb(direct_addr($4));
552 | arith_inst REG ',' USP {
553 /* this addr mode is only valid for MOV */
554 if (arith_opcode != 8) error("Addr mode only valid for MOV (5)");
557 op[1] = reg($2) * 16 + 15;
559 | arith_inst USP ',' REG {
560 /* this addr mode is only valid for MOV */
561 if (arith_opcode != 8) error("Addr mode only valid for MOV (6)");
564 op[1] = reg($4) * 16 + 15;
566 | arith_inst C ',' bit {
567 /* this addr mode is only valid for MOV */
568 if (arith_opcode != 8) error("Addr mode only valid for MOV (7)");
571 op[1] = 0x20 + msb(bit_addr($4));
572 op[2] = lsb(bit_addr($4));
574 | arith_inst bit ',' C {
575 /* this addr mode is only valid for MOV */
576 if (arith_opcode != 8) error("Addr mode only valid for MOV (8)");
579 op[1] = 0x30 + msb(bit_addr($2));
580 op[2] = lsb(bit_addr($2));
583 | MOVC REG ',' '[' REG '+' ']' {
584 size = find_size1(inst_size, $2);
586 op[0] = 0x80 + size * 8;
587 op[1] = reg($2) * 16 + reg_indirect($5);
589 | MOVC A ',' '[' A '+' DPTR ']' {
594 | MOVC A ',' '[' A '+' PC ']' {
599 | MOVX REG ',' '[' REG ']' {
601 size = find_size1(inst_size, $2);
602 op[0] = 0xA7 + size * 8;
603 op[1] = reg($2) * 16 + reg_indirect($5);
605 | MOVX '[' REG ']' ',' REG {
607 size = find_size1(inst_size, $6);
608 op[0] = 0xA7 + size * 8;
609 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
613 size = find_size2(inst_size, $2, $4);
614 op[0] = 0x60 + size * 8;
615 op[1] = reg($2) * 16 + reg($4);
617 | XCH REG ',' '[' REG ']' {
619 size = find_size1(inst_size, $2);
620 op[0] = 0x50 + size * 8;
621 op[1] = reg($2) * 16 + reg_indirect($5);
625 size = find_size1(inst_size, $2);
626 op[0] = 0xA0 + size * 8;
627 op[1] = reg($2) * 16 + msb(direct_addr($4));
628 op[2] = lsb(direct_addr($4));
630 | short_data_inst REG ',' '#' expr {
632 size = find_size1(inst_size, $2);
633 op[0] = short_opcode + size * 8 + 1;
634 op[1] = reg($2) * 16 + imm_data4_signed($5);
636 | short_data_inst '[' REG ']' ',' '#' expr {
638 size = find_size0(inst_size);
639 op[0] = short_opcode + size * 8 + 2;
640 op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
642 | short_data_inst '[' REG '+' ']' ',' '#' expr {
644 size = find_size0(inst_size);
645 op[0] = short_opcode + size * 8 + 3;
646 op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
648 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
649 size = find_size0(inst_size);
650 if ($5 >= -128 && $5 <= 127) {
652 op[0] = short_opcode + size * 8 + 4;
653 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
654 op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
657 op[0] = short_opcode + size * 8 + 5;
658 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
659 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
660 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
663 | short_data_inst expr ',' '#' expr {
665 size = find_size0(inst_size);
666 op[0] = short_opcode + size * 8 + 6;
667 op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
668 op[2] = lsb(direct_addr($2));
676 op[1] = 0x40 + msb(bit_addr($4));
677 op[2] = lsb(bit_addr($4));
679 | ANL C ',' '/' bit {
682 op[1] = 0x50 + msb(bit_addr($5));
683 op[2] = lsb(bit_addr($5));
689 op[1] = 0x60 + msb(bit_addr($4));
690 op[2] = lsb(bit_addr($4));
692 | ORL C ',' '/' bit {
695 op[1] = 0x70 + msb(bit_addr($5));
696 op[2] = lsb(bit_addr($5));
701 op[1] = msb(bit_addr($2));
702 op[2] = lsb(bit_addr($2));
707 op[1] = 0x10 + msb(bit_addr($2));
708 op[2] = lsb(bit_addr($2));
710 | logical_shift_inst REG ',' REG {
711 size = find_size1(inst_size, $2);
712 if (find_size_reg($4) != SIZE8)
713 error("Second register in logical shift must be byte size");
715 op[0] = shift_reg_opcode;
717 case SIZE8: op[0] += 0; break;
718 case SIZE16: op[0] += 8; break;
719 case SIZE32: op[0] += 12; break;
721 op[1] = reg($2) * 16 + reg($4);
723 | logical_shift_inst REG ',' '#' expr {
724 size = find_size1(inst_size, $2);
726 if (shift_imm_opcode == -1)
727 error("NORM may not use a constant");
728 op[0] = shift_imm_opcode;
730 case SIZE8: op[0] += 0; break;
731 case SIZE16: op[0] += 8; break;
732 case SIZE32: op[0] += 12; break;
737 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
740 op[1] = (reg($2) / 2) * 32 + imm_data5_unsigned($5);
753 op[1] = 0x30 + imm_data4_unsigned($3);
757 size = find_size1(inst_size, $2);
758 op[0] = 0x90 + size * 8;
759 op[1] = reg($2) * 16 + 10;
764 op[1] = reg($2) * 16 + 8;
768 size = find_size1(inst_size, $2);
769 op[0] = 0x90 + size * 8;
770 op[1] = reg($2) * 16 + 11;
774 size = find_size1(inst_size, $2);
775 op[0] = 0x90 + size * 8;
776 op[1] = reg($2) * 16 + 9;
779 | rotate_inst REG ',' '#' expr {
781 size = find_size1(inst_size, $2);
782 op[0] = rotate_opcode + size * 8;
783 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
787 | LEA REG ',' REG '+' expr {
788 if ($6 >= -128 && $6 <= 127) {
791 op[1] = reg($2) * 16 + reg_indirect($4);
792 op[2] = ($6 >= 0) ? $6 : 256 + $6;
795 op[1] = reg($2) * 16 + reg_indirect($4);
796 op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
797 op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
802 size = find_size0(inst_size);
803 op[0] = msb(stack_addr_opcode) + size * 8;
804 op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
805 op[2] = lsb(direct_addr($2));
809 if (inst_size != UNKNOWN && find_size0(inst_size) != rlist_size)
810 error("inst specifies different size than registers used");
811 op[0] = stack_reg_opcode + rlist_reg_bank * 64 + rlist_size * 8;
812 op[1] = rlist_bitmask;
818 size = find_size2(inst_size, $2, $4);
820 op[1] = reg($2) * 16 + reg($4);
824 size = find_size2(inst_size, $2, $4);
827 op[1] = reg($2) * 16 + reg($4);
830 op[1] = reg($2) * 16 + reg($4);
833 | MUL REG ',' '#' expr {
835 size = find_size1(inst_size, $2);
838 op[2] = msb(imm_data16($5));
839 op[3] = lsb(imm_data16($5));
841 | MULU REG ',' '#' expr {
842 size = find_size2(inst_size, $2, $4);
846 op[1] = reg($2) * 16;
847 op[2] = imm_data8($5);
851 op[1] = reg($2) * 16;
852 op[2] = msb(imm_data16($5));
853 op[3] = lsb(imm_data16($5));
858 size = find_size2(inst_size, $2, $4);
861 error("Singed DIV can't be 8 bit size"); break;
864 op[1] = reg($2) * 16 + reg($4);
868 op[1] = (reg($2) / 2) * 32 + reg($4);
874 size = find_size2(inst_size, $2, $4);
878 op[1] = reg($2) * 16 + reg($4);
882 op[1] = reg($2) * 16 + reg($4);
886 op[1] = (reg($2) / 2) * 32 + reg($4);
890 | DIV REG ',' '#' expr {
891 size = find_size1(inst_size, $2);
894 error("Singed DIV can't be 8 bit size"); break;
898 op[1] = reg($2) * 16 + 11;
899 op[2] = imm_data8($5);
904 op[1] = (reg($2) / 2) * 32 + 9;
905 op[2] = msb(imm_data16($5));
906 op[3] = lsb(imm_data16($5));
910 | DIVU REG ',' '#' expr {
911 size = find_size1(inst_size, $2);
916 op[1] = reg($2) * 16 + 1;
917 op[2] = imm_data8($5);
922 op[1] = reg($2) * 16 + 3;
923 op[2] = imm_data8($5);
928 op[1] = (reg($2) / 2) * 32 + 1;
929 op[2] = msb(imm_data16($5));
930 op[3] = lsb(imm_data16($5));
942 op[1] = ($2 >> 8) & 255;
944 op[3] = ($2 >> 16) & 255;
949 op[1] = ($2 >> 8) & 255;
951 op[3] = ($2 >> 16) & 255;
956 op[1] = 0x70 + reg_indirect($3);
958 | JMP '[' A '+' DPTR ']' {
963 | JMP '[' '[' REG '+' ']' ']' {
966 op[1] = 0x60 + reg_indirect($4);
972 op[1] = msb(rel16(MEM_POS + $$, $2));
973 op[2] = lsb(rel16(MEM_POS + $$, $2));
979 op[1] = msb(rel16(MEM_POS + $$, $2));
980 op[2] = lsb(rel16(MEM_POS + $$, $2));
982 | branch_inst jmpaddr {
984 op[0] = branch_opcode;
985 op[1] = rel8(MEM_POS + $$, $2);
987 | CJNE REG ',' expr ',' jmpaddr {
989 size = find_size1(inst_size, $2);
990 op[0] = 0xE2 + size * 8;
991 op[1] = reg($2) * 16 + msb(direct_addr($4));
992 op[2] = lsb(direct_addr($4));
993 op[3] = rel8(MEM_POS + $$, $6);
995 | CJNE REG ',' '#' expr ',' jmpaddr {
996 size = find_size1(inst_size, $2);
1000 op[1] = reg($2) * 16;
1001 op[2] = rel8(MEM_POS + $$, $7);
1002 op[3] = imm_data8($5);
1006 op[1] = reg($2) * 16;
1007 op[2] = rel8(MEM_POS + $$, $7);
1008 op[3] = msb(imm_data16($5));
1009 op[4] = lsb(imm_data16($5));
1012 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
1013 size = find_size0(inst_size);
1014 if (size == SIZE8) {
1017 op[1] = reg_indirect($3) * 16 + 8;
1018 op[2] = rel8(MEM_POS + $$, $9);
1019 op[3] = imm_data8($7);
1023 op[1] = reg_indirect($3) * 16 + 8;
1024 op[2] = rel8(MEM_POS + $$, $9);
1025 op[3] = msb(imm_data16($7));
1026 op[4] = lsb(imm_data16($7));
1029 | DJNZ REG ',' jmpaddr {
1031 size = find_size1(inst_size, $2);
1032 op[0] = 0x87 + size * 8;
1033 op[1] = reg($2) * 16 + 8;
1034 op[2] = rel8(MEM_POS + $$, $4);
1038 | DJNZ expr ',' jmpaddr {
1040 size = find_size0(inst_size);
1041 op[0] = 0xE2 + size * 8;
1042 op[1] = msb(direct_addr($2)) + 8;
1043 op[2] = lsb(direct_addr($2));
1044 op[3] = rel8(MEM_POS + $$, $4);
1047 | JB bit ',' jmpaddr {
1050 op[1] = 0x80 + msb(bit_addr($2));
1051 op[2] = lsb(bit_addr($2));
1052 op[3] = rel8(MEM_POS + $$, $4);
1055 | JBC bit ',' jmpaddr {
1058 op[1] = 0xC0 + msb(bit_addr($2));
1059 op[2] = lsb(bit_addr($2));
1060 op[3] = rel8(MEM_POS + $$, $4);
1063 | JNB bit ',' jmpaddr {
1066 op[1] = 0xA0 + msb(bit_addr($2));
1067 op[2] = lsb(bit_addr($2));
1068 op[3] = rel8(MEM_POS + $$, $4);
1073 ADD {arith_opcode = 0;}
1074 | ADDC {arith_opcode = 1;}
1075 | AND {arith_opcode = 5;}
1076 | CMP {arith_opcode = 4;}
1077 | MOV {arith_opcode = 8;}
1078 | OR {arith_opcode = 6;}
1079 | SUB {arith_opcode = 2;}
1080 | SUBB {arith_opcode = 3;}
1081 | XOR {arith_opcode = 7;}
1084 ADDS {short_opcode = 0xA0;}
1085 | MOVS {short_opcode = 0xB0;}
1088 ASL {shift_reg_opcode = 0xC1; shift_imm_opcode = 0xD1;}
1089 | ASR {shift_reg_opcode = 0xC2; shift_imm_opcode = 0xD2;}
1090 | LSR {shift_reg_opcode = 0xC0; shift_imm_opcode = 0xD0;}
1091 | NORM {shift_reg_opcode = 0xC3; shift_imm_opcode = -1;}
1094 RL {rotate_opcode = 0xD3;}
1095 | RLC {rotate_opcode = 0xD7;}
1096 | RR {rotate_opcode = 0xD0;}
1097 | RRC {rotate_opcode = 0xD7;}
1100 POP {stack_addr_opcode = 0x8710; stack_reg_opcode = 0x27;}
1101 | POPU {stack_addr_opcode = 0x8700; stack_reg_opcode = 0x37;}
1102 | PUSH {stack_addr_opcode = 0x8730; stack_reg_opcode = 0x07;}
1103 | PUSHU {stack_addr_opcode = 0x8720; stack_reg_opcode = 0x17;}
1106 BKPT {num_op = 1; opcode0 = 255; opcode1 = 0;}
1107 | NOP {num_op = 1; opcode0 = 0; opcode1 = 0;}
1108 | RESET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x10;}
1109 | RET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x80;}
1110 | RETI {num_op = 2; opcode0 = 0xD6; opcode1 = 0x90;}
1113 BCC {branch_opcode = 0xF0;}
1114 | BCS {branch_opcode = 0xF1;}
1115 | BEQ {branch_opcode = 0xF3;}
1116 | BG {branch_opcode = 0xF8;}
1117 | BGE {branch_opcode = 0xFA;}
1118 | BGT {branch_opcode = 0xFC;}
1119 | BL {branch_opcode = 0xF9;}
1120 | BLE {branch_opcode = 0xFD;}
1121 | BLT {branch_opcode = 0xFB;}
1122 | BMI {branch_opcode = 0xF7;}
1123 | BNE {branch_opcode = 0xF2;}
1124 | BNV {branch_opcode = 0xF4;}
1125 | BOV {branch_opcode = 0xF5;}
1126 | BPL {branch_opcode = 0xF6;}
1127 | BR {branch_opcode = 0xFE;}
1128 | JZ {branch_opcode = 0xEC;}
1129 | JNZ {branch_opcode = 0xEE;}
1136 int reg(int reg_spec)
1138 return reg_spec & 15;
1141 int reg_indirect(int reg_spec)
1143 if (reg_spec & BYTE_REG)
1144 error("Indirect addressing may not use byte registers");
1145 if ((reg_spec & 15) > 7)
1146 error("Only R0 through R7 may be used for indirect addr");
1147 return reg_spec & 7;
1150 int rel16(int pos, int dest)
1154 if (!p3) return 0; /* don't bother unless writing code */
1155 if (dest & (BRANCH_SPACING - 1))
1156 error("Attempt to jump to unaligned location");
1157 pos &= ~(BRANCH_SPACING - 1);
1158 rel = (dest - pos) / BRANCH_SPACING;
1159 if (rel < -32768 || rel > 32767)
1160 error("Attempt to jump out of 16 bit relative range");
1161 if (rel < 0) rel += 65536;
1165 int rel8(int pos, int dest)
1169 if (!p3) return 0; /* don't bother unless writing code */
1170 if (dest & (BRANCH_SPACING - 1))
1171 error("Attempt to jump to unaligned location");
1172 pos &= ~(BRANCH_SPACING - 1);
1173 rel = (dest - pos) / BRANCH_SPACING;
1174 if (rel < -128 || rel > 127)
1175 error("Attempt to jump out of 16 bit relative range");
1176 if (rel < 0) rel += 256;
1182 return (value >> 8) & 255;
1190 int direct_addr(int value)
1194 if (value < 0 || value > 2047) {
1195 sprintf(buf, "illegal value (%d) for direct address", value);
1201 int imm_data4_signed(int value)
1203 if (value < -8 || value > 7)
1204 error("illegal 4 bit (signed) value");
1205 if (value >= 0) return value;
1206 else return (16 + value);
1209 int imm_data4_unsigned(int value)
1211 if (value < 0 || value > 15)
1212 error("illegal 4 bit (unsigned) value");
1216 int imm_data5_unsigned(int value)
1218 if (value < 0 || value > 31)
1219 error("illegal 5 bit (unsigned) value");
1223 int imm_data8(int value)
1225 if (value < -128 || value > 255)
1226 error("illegal 8 bit value");
1227 if (value >= 0) return value;
1228 else return (256 + value);
1231 int imm_data16(int value)
1233 if (value < -32728 || value > 65535)
1234 error("illegal 16 bit value");
1235 if (value >= 0) return value;
1236 else return (65536 + value);
1239 int bit_addr(int value)
1241 if (value < 0 || value > 1023) {
1242 fprintf(stderr, "bad bit addr of 0x%04X (%d dec)\n",
1244 error("illegal bit address");
1250 int find_size_reg(int op1spec)
1252 int op1size=UNKNOWN;
1254 if (op1spec & BYTE_REG) op1size = SIZE8;
1255 if (op1spec & WORD_REG) op1size = SIZE16;
1256 if (op1size == UNKNOWN)
1257 error("Register without implied size");
1261 int find_size0(int isize)
1263 if (isize == UNKNOWN)
1264 error("Can't determine data size from instruction");
1268 int find_size1(int isize, int op1spec)
1270 int op1size=UNKNOWN;
1272 if (op1spec & BYTE_REG) op1size = SIZE8;
1273 if (op1spec & WORD_REG) op1size = SIZE16;
1274 if (op1size == UNKNOWN)
1275 error("Register without implied size");
1277 if (isize == SIZE32 && op1size == SIZE16) return SIZE32;
1278 if (isize == UNKNOWN) return op1size;
1280 if (isize != op1size)
1281 error("data size of register and inst don't agree");
1286 int find_size2(int isize, int op1spec, int op2spec)
1288 int op1size=UNKNOWN, op2size=UNKNOWN;
1290 if (op1spec & BYTE_REG) op1size = SIZE8;
1291 if (op1spec & WORD_REG) op1size = SIZE16;
1292 if (op1size == UNKNOWN)
1293 error("Register without implied size");
1294 if (op2spec & BYTE_REG) op2size = SIZE8;
1295 if (op2spec & WORD_REG) op2size = SIZE16;
1296 if (op1size == UNKNOWN)
1297 error("Register without implied size");
1299 if (op1size != op2size)
1300 error("data sizes of two registers don't agree");
1301 if (isize == UNKNOWN) return op1size;
1303 if (isize != op1size)
1304 error("data size of registers and inst don't agree");
1310 int yyerror(char *s)
1312 if (yytext[0] >= 32) {
1313 fprintf(stderr, "%s near '%s', line %d\n",
1316 fprintf(stderr, "%s, line %d\n", s, lineno - 1);