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 * Foobar is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
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);
43 void fatal_error(char *s);
45 static int bitmask[]={1, 2, 4, 8, 16, 32, 64, 128};
49 %token ADD ADDC ADDS AND ANL ASL ASR BCC BCS BEQ BG BGE BGT
50 %token BKPT BL BLE BLT BMI BNE BNV BOV BPL BR CALL CJNE CLR
51 %token CMP CPL DA DIV DIVU DJNZ FCALL FJMP JB JBC JMP JNB JNZ
52 %token JZ LEA LSR MOV MOVC MOVS MOVX MUL MULU NEG NOP NORM
53 %token OR ORL POP POPU PUSH PUSHU RESET RET RETI RL RLC RR RRC
54 %token SETB SEXT SUB SUBB TRAP XCH XOR
55 %token REG DPTR PC A C USP
56 %token WORD BIT NUMBER CHAR STRING EOL LOCAL_LABEL
57 %token ORG EQU DB DW BITDEF REGDEF LOW HIGH
59 %token AREA AREA_NAME AREA_DESC DS
73 line: linesymbol ':' linenosym {
75 build_sym_list(symbol_name);
76 if (current_area == AREA_BSEG) {
80 if (p1 || p2) assign_value(symbol_name, MEM_POS);
87 linenosym: directive EOL {
99 | error EOL /* try to recover from any parse error */
102 directive: '.' ORG expr {
110 | '.' EQU symbol ',' expr {
111 if (p1) build_sym_list(symbol_name);
112 if (p1 || p2) assign_value(symbol_name, $5);
116 if (p1) build_sym_list(symbol_name);
117 if (p1 || p2) assign_value(symbol_name, $3);
120 | '.' BITDEF bitsymbol ',' bit {
122 build_sym_list(symbol_name);
125 if (p1 || p2) assign_value(symbol_name, $5);
128 | bitsymbol BITDEF bit {
130 build_sym_list(symbol_name);
133 if (p1 || p2) assign_value(symbol_name, $3);
136 | '.' REGDEF regsymbol ',' REG {
138 build_sym_list(symbol_name);
141 if (p1 || p2) assign_value(symbol_name, $5);
144 | regsymbol REGDEF REG {
146 build_sym_list(symbol_name);
149 if (p1 || p2) assign_value(symbol_name, $3);
153 | db_directive bytes {
156 | dw_directive words {
159 | '.' AREA AREA_NAME AREA_DESC {
160 if ($3 < 0 || $3 >= NUM_AREAS) {
161 error("Illegal Area Directive");
163 symbol_name[0] = '\0';
168 /* ignore module definition */
169 build_sym_list(lex_sym_name);
170 assign_value(lex_sym_name, 0);
174 /* ignore global symbol declaration */
178 /* todo: if CSEG, emit some filler bytes */
182 db_directive: DB {db_count = 0;}
186 strcpy(symbol_name, lex_sym_name);
187 if (!strchr(lex_sym_name, ':')) {
188 /* non-local label, remember base name */
189 strcpy(base_symbol_name, lex_sym_name);
191 if (is_target(symbol_name)) pad_with_nop();
195 | bytes ',' byte_element
198 op[db_count] = $1 & 255;
199 if (++db_count >= MAX_DB) {
200 error("too many bytes, use two DB");
205 for(i=1; i < strlen(yytext)-1; i++) {
206 op[db_count++] = yytext[i];
207 if (db_count >= MAX_DB) {
208 error("too many bytes, use two DB");
214 dw_directive: DW {dw_count = 0;}
216 words: words ',' word_element
220 op[dw_count] = $1 & 255;
221 op[dw_count+1] = ($1 >> 8) & 255;
223 if (dw_count >= MAX_DB) {
224 error("too many bytes, use two DW");
232 strcpy(symbol_name, lex_sym_name);
235 bitsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
236 | BIT { strcpy(symbol_name, lex_sym_name); }
239 regsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
240 | REG { strcpy(symbol_name, lex_sym_name); }
243 if ($3 < 0 || $3 > 7) {
244 /* only 8 bits in a byte */
245 error("Only eight bits in a byte");
247 $$ = 100000; /* should really check $1 is valid */
248 if ($1 >= 0x20 && $1 <= 0x3F) {
251 if ($1 >= 0x400 && $1 <= 0x43F) {
252 $$ = ($1 - 0x400) * 8 + $3 + 0x200;
257 if (find_size_reg($1) == SIZE8) {
258 if ($3 < 0 || $3 > 7)
259 error("byte reg has only 8 bits");
260 $$ = reg($1) * 8 + $3;
262 if (find_size_reg($1) == SIZE16) {
263 if ($3 < 0 || $3 > 15)
264 error("word reg has only 16 bits");
265 $$ = reg($1) * 16 + $3;
272 if (p1) build_target_list(lex_sym_name);
275 if ($1 & 1) error("Jump target must be aligned");
280 expr: value {$$ = $1;}
281 | expr '+' expr {$$ = $1 + $3;}
282 | expr '-' expr {$$ = $1 - $3;}
283 | expr '*' expr {$$ = $1 * $3;}
284 | expr '/' expr {$$ = $1 / $3;}
285 | expr '&' expr {$$ = $1 & $3;}
286 | expr '|' expr {$$ = $1 | $3;}
287 | expr '^' expr {$$ = $1 ^ $3;}
288 | expr RSHIFT expr {$$ = $1 >> $3;}
289 | expr LSHIFT expr {$$ = $1 << $3;}
290 | '-' expr %prec UNARY {$$ = $2 * -1;}
291 | '+' expr %prec UNARY {$$ = $2;}
292 | '(' expr ')' {$$ = $2;}
293 | LOW expr %prec UNARY {$$ = $2 & 255;}
294 | HIGH expr %prec UNARY {$$ = ($2 >> 8) & 255;}
297 value: NUMBER {$$ = $1;}
299 | WORD {$$ = $1; strcpy(expr_var, yytext);}
303 rlist_bitmask = bitmask[reg($1) % 8];
304 rlist_reg_bank = (reg($1) / 8) ? 1 : 0;
305 rlist_size = find_size_reg($1);
308 rlist_bitmask |= bitmask[reg($1) % 8];
309 if (rlist_reg_bank != ((reg($1) / 8) ? 1 : 0))
310 error("register list may not mix 0-7/8-15 regs");
311 if (rlist_size != find_size_reg($1))
312 error("register list may not mix 8/16 bit registers");
321 arith_inst REG ',' REG {
323 size = find_size2(inst_size, $2, $4);
324 op[0] = arith_opcode * 16 + size * 8 + 1;
325 op[1] = reg($2) * 16 + reg($4);
327 | arith_inst REG ',' '[' REG ']' {
329 size = find_size1(inst_size, $2);
330 op[0] = arith_opcode * 16 + size * 8 + 2;
331 op[1] = reg($2) * 16 + reg_indirect($5);
333 | arith_inst '[' REG ']' ',' REG {
335 size = find_size1(inst_size, $6);
336 op[0] = arith_opcode * 16 + size * 8 + 2;
337 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
339 | arith_inst REG ',' '[' REG '+' expr ']' {
340 size = find_size1(inst_size, $2);
341 if ($7 >= -128 && $7 <= 127) {
343 op[0] = arith_opcode * 16 + size * 8 + 4;
344 op[1] = reg($2) * 16 + reg_indirect($5);
345 op[2] = ($7 >= 0) ? $7 : 256 + $7;
348 op[0] = arith_opcode * 16 + size * 8 + 5;
349 op[1] = reg($2) * 16 + reg_indirect($5);
350 op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
351 op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
354 | arith_inst '[' REG '+' expr ']' ',' REG {
355 size = find_size1(inst_size, $8);
356 if ($5 >= -128 && $5 <= 127) {
358 op[0] = arith_opcode * 16 + size * 8 + 4;
359 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
360 op[2] = ($5 >= 0) ? $5 : 256 + $5;
363 op[0] = arith_opcode * 16 + size * 8 + 5;
364 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
365 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
366 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
369 | arith_inst REG ',' '[' REG '+' ']' {
371 size = find_size1(inst_size, $2);
372 op[0] = arith_opcode * 16 + size * 8 + 3;
373 op[1] = reg($2) * 16 + reg_indirect($5);
375 | arith_inst '[' REG '+' ']' ',' REG {
377 size = find_size1(inst_size, $7);
378 op[0] = arith_opcode * 16 + size * 8 + 3;
379 op[1] = reg($7) * 16 + 8 + reg_indirect($3);
381 | arith_inst expr ',' REG {
383 size = find_size1(inst_size, $4);
384 op[0] = arith_opcode * 16 + size * 8 + 6;
385 op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
386 op[2] = lsb(direct_addr($2));
388 | arith_inst REG ',' expr {
390 size = find_size1(inst_size, $2);
391 op[0] = arith_opcode * 16 + size * 8 + 6;
392 op[1] = reg($2) * 16 + msb(direct_addr($4));
393 op[2] = lsb(direct_addr($4));
395 | arith_inst REG ',' '#' expr {
396 size = find_size1(inst_size, $2);
400 op[1] = reg($2) * 16 + arith_opcode;
401 op[2] = imm_data8($5);
405 op[1] = reg($2) * 16 + arith_opcode;
406 op[2] = msb(imm_data16($5));
407 op[3] = lsb(imm_data16($5));
410 | arith_inst '[' REG ']' ',' '#' expr {
411 size = find_size0(inst_size);
415 op[1] = reg_indirect($3) * 16 + arith_opcode;
416 op[2] = imm_data8($7);
420 op[1] = reg_indirect($3) * 16 + arith_opcode;
421 op[2] = msb(imm_data16($7));
422 op[3] = lsb(imm_data16($7));
425 | arith_inst '[' REG '+' ']' ',' '#' expr {
426 size = find_size0(inst_size);
430 op[1] = reg_indirect($3) * 16 + arith_opcode;
431 op[2] = imm_data8($8);
435 op[1] = reg_indirect($3) * 16 + arith_opcode;
436 op[2] = msb(imm_data16($8));
437 op[3] = lsb(imm_data16($8));
440 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
441 size = find_size0(inst_size);
442 if ($5 >= -128 && $5 <= 127) {
446 op[1] = reg_indirect($3) * 16 + arith_opcode;
447 op[2] = ($5 >= 0) ? $5 : 256 + $5;
448 op[3] = imm_data8($9);
452 op[1] = reg_indirect($3) * 16 + arith_opcode;
453 op[2] = ($5 >= 0) ? $5 : 256 + $5;
454 op[3] = msb(imm_data16($9));
455 op[4] = lsb(imm_data16($9));
461 op[1] = reg_indirect($3) * 16 + arith_opcode;
462 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
463 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
464 op[4] = imm_data8($9);
468 op[1] = reg_indirect($3) * 16 + arith_opcode;
469 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
470 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
471 op[4] = msb(imm_data16($9));
472 op[5] = lsb(imm_data16($9));
476 | arith_inst expr ',' '#' expr {
477 size = find_size0(inst_size);
481 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
482 op[2] = lsb(direct_addr($2));
483 op[3] = imm_data8($5);
487 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
488 op[2] = lsb(direct_addr($2));
489 op[3] = msb(imm_data16($5));
490 op[4] = lsb(imm_data16($5));
494 /* the next 8 instructions are MOV, but because MOV was used in the */
495 /* arith_inst group, it will cause a shift/reduce conflict if used */
496 /* directly below... so we're forced to use arith_inst and then */
497 /* add a bit of code to make sure it was MOV and not the other ones */
499 | arith_inst '[' REG '+' ']' ',' '[' REG '+' ']' {
500 /* this addr mode is only valid for MOV */
501 if (arith_opcode != 8) error("Addr mode only valid for MOV (1)");
502 size = find_size0(inst_size);
504 op[0] = 0x90 + size * 8;
505 op[1] = reg_indirect($3) * 16 + reg_indirect($8);
507 | arith_inst expr ',' '[' REG ']' {
508 /* this addr mode is only valid for MOV */
509 if (arith_opcode != 8) error("Addr mode only valid for MOV (2)");
510 size = find_size0(inst_size);
512 op[0] = 0xA0 + size * 8;
513 op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
514 op[2] = lsb(direct_addr($2));
516 | arith_inst '[' REG ']' ',' expr {
517 /* this addr mode is only valid for MOV */
518 if (arith_opcode != 8) error("Addr mode only valid for MOV (3)");
519 size = find_size0(inst_size);
521 op[0] = 0xA0 + size * 8;
522 op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
523 op[2] = lsb(direct_addr($6));
525 | arith_inst expr ',' expr {
526 /* this addr mode is only valid for MOV */
527 if (arith_opcode != 8) error("Addr mode only valid for MOV (4)");
528 size = find_size0(inst_size);
530 op[0] = 0x97 + size * 8;
531 op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
532 op[2] = lsb(direct_addr($2));
533 op[3] = lsb(direct_addr($4));
535 | arith_inst REG ',' USP {
536 /* this addr mode is only valid for MOV */
537 if (arith_opcode != 8) error("Addr mode only valid for MOV (5)");
540 op[1] = reg($2) * 16 + 15;
542 | arith_inst USP ',' REG {
543 /* this addr mode is only valid for MOV */
544 if (arith_opcode != 8) error("Addr mode only valid for MOV (6)");
547 op[1] = reg($4) * 16 + 15;
549 | arith_inst C ',' bit {
550 /* this addr mode is only valid for MOV */
551 if (arith_opcode != 8) error("Addr mode only valid for MOV (7)");
554 op[1] = 0x20 + msb(bit_addr($4));
555 op[2] = lsb(bit_addr($4));
557 | arith_inst bit ',' C {
558 /* this addr mode is only valid for MOV */
559 if (arith_opcode != 8) error("Addr mode only valid for MOV (8)");
562 op[1] = 0x30 + msb(bit_addr($2));
563 op[2] = lsb(bit_addr($2));
566 | MOVC REG ',' '[' REG '+' ']' {
567 size = find_size1(inst_size, $2);
569 op[0] = 0x80 + size * 8;
570 op[1] = reg($2) * 16 + reg_indirect($5);
572 | MOVC A ',' '[' A '+' DPTR ']' {
577 | MOVC A ',' '[' A '+' PC ']' {
582 | MOVX REG ',' '[' REG ']' {
584 size = find_size1(inst_size, $2);
585 op[0] = 0xA7 + size * 8;
586 op[1] = reg($2) * 16 + reg_indirect($5);
588 | MOVX '[' REG ']' ',' REG {
590 size = find_size1(inst_size, $6);
591 op[0] = 0xA7 + size * 8;
592 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
596 size = find_size2(inst_size, $2, $4);
597 op[0] = 0x60 + size * 8;
598 op[1] = reg($2) * 16 + reg($4);
600 | XCH REG ',' '[' REG ']' {
602 size = find_size1(inst_size, $2);
603 op[0] = 0x50 + size * 8;
604 op[1] = reg($2) * 16 + reg_indirect($5);
608 size = find_size1(inst_size, $2);
609 op[0] = 0xA0 + size * 8;
610 op[1] = reg($2) * 16 + msb(direct_addr($4));
611 op[2] = lsb(direct_addr($4));
613 | short_data_inst REG ',' '#' expr {
615 size = find_size1(inst_size, $2);
616 op[0] = short_opcode + size * 8 + 1;
617 op[1] = reg($2) * 16 + imm_data4_signed($5);
619 | short_data_inst '[' REG ']' ',' '#' expr {
621 size = find_size0(inst_size);
622 op[0] = short_opcode + size * 8 + 2;
623 op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
625 | short_data_inst '[' REG '+' ']' ',' '#' expr {
627 size = find_size0(inst_size);
628 op[0] = short_opcode + size * 8 + 3;
629 op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
631 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
632 size = find_size0(inst_size);
633 if ($5 >= -128 && $5 <= 127) {
635 op[0] = short_opcode + size * 8 + 4;
636 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
637 op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
640 op[0] = short_opcode + size * 8 + 5;
641 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
642 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
643 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
646 | short_data_inst expr ',' '#' expr {
648 size = find_size0(inst_size);
649 op[0] = short_opcode + size * 8 + 6;
650 op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
651 op[2] = lsb(direct_addr($2));
659 op[1] = 0x40 + msb(bit_addr($4));
660 op[2] = lsb(bit_addr($4));
662 | ANL C ',' '/' bit {
665 op[1] = 0x50 + msb(bit_addr($5));
666 op[2] = lsb(bit_addr($5));
672 op[1] = 0x60 + msb(bit_addr($4));
673 op[2] = lsb(bit_addr($4));
675 | ORL C ',' '/' bit {
678 op[1] = 0x70 + msb(bit_addr($5));
679 op[2] = lsb(bit_addr($5));
684 op[1] = msb(bit_addr($2));
685 op[2] = lsb(bit_addr($2));
690 op[1] = 0x10 + msb(bit_addr($2));
691 op[2] = lsb(bit_addr($2));
693 | logical_shift_inst REG ',' REG {
694 size = find_size1(inst_size, $2);
695 if (find_size_reg($4) != SIZE8)
696 error("Second register in logical shift must be byte size");
698 op[0] = shift_reg_opcode;
700 case SIZE8: op[0] += 0; break;
701 case SIZE16: op[0] += 8; break;
702 case SIZE32: op[0] += 12; break;
704 op[1] = reg($2) * 16 + reg($4);
706 | logical_shift_inst REG ',' '#' expr {
707 size = find_size1(inst_size, $2);
709 if (shift_imm_opcode == -1)
710 error("NORM may not use a constant");
711 op[0] = shift_imm_opcode;
713 case SIZE8: op[0] += 0; break;
714 case SIZE16: op[0] += 8; break;
715 case SIZE32: op[0] += 12; break;
720 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
723 op[1] = (reg($2) / 2) * 32 + imm_data5_unsigned($5);
736 op[1] = 0x30 + imm_data4_unsigned($3);
740 size = find_size1(inst_size, $2);
741 op[0] = 0x90 + size * 8;
742 op[1] = reg($2) * 16 + 10;
747 op[1] = reg($2) * 16 + 8;
751 size = find_size1(inst_size, $2);
752 op[0] = 0x90 + size * 8;
753 op[1] = reg($2) * 16 + 11;
757 size = find_size1(inst_size, $2);
758 op[0] = 0x90 + size * 8;
759 op[1] = reg($2) * 16 + 9;
762 | rotate_inst REG ',' '#' expr {
764 size = find_size1(inst_size, $2);
765 op[0] = rotate_opcode + size * 8;
766 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
770 | LEA REG ',' REG '+' expr {
771 if ($6 >= -128 && $6 <= 127) {
774 op[1] = reg($2) * 16 + reg_indirect($4);
775 op[2] = ($6 >= 0) ? $6 : 256 + $6;
778 op[1] = reg($2) * 16 + reg_indirect($4);
779 op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
780 op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
785 size = find_size0(inst_size);
786 op[0] = msb(stack_addr_opcode) + size * 8;
787 op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
788 op[2] = lsb(direct_addr($2));
792 if (inst_size != UNKNOWN && find_size0(inst_size) != rlist_size)
793 error("inst specifies different size than registers used");
794 op[0] = stack_reg_opcode + rlist_reg_bank * 64 + rlist_size * 8;
795 op[1] = rlist_bitmask;
801 size = find_size2(inst_size, $2, $4);
803 op[1] = reg($2) * 16 + reg($4);
807 size = find_size2(inst_size, $2, $4);
810 op[1] = reg($2) * 16 + reg($4);
813 op[1] = reg($2) * 16 + reg($4);
816 | MUL REG ',' '#' expr {
818 size = find_size1(inst_size, $2);
821 op[2] = msb(imm_data16($5));
822 op[3] = lsb(imm_data16($5));
824 | MULU REG ',' '#' expr {
825 size = find_size2(inst_size, $2, $4);
829 op[1] = reg($2) * 16;
830 op[2] = imm_data8($5);
834 op[1] = reg($2) * 16;
835 op[2] = msb(imm_data16($5));
836 op[3] = lsb(imm_data16($5));
841 size = find_size2(inst_size, $2, $4);
844 error("Singed DIV can't be 8 bit size"); break;
847 op[1] = reg($2) * 16 + reg($4);
851 op[1] = (reg($2) / 2) * 32 + reg($4);
857 size = find_size2(inst_size, $2, $4);
861 op[1] = reg($2) * 16 + reg($4);
865 op[1] = reg($2) * 16 + reg($4);
869 op[1] = (reg($2) / 2) * 32 + reg($4);
873 | DIV REG ',' '#' expr {
874 size = find_size1(inst_size, $2);
877 error("Singed DIV can't be 8 bit size"); break;
881 op[1] = reg($2) * 16 + 11;
882 op[2] = imm_data8($5);
887 op[1] = (reg($2) / 2) * 32 + 9;
888 op[2] = msb(imm_data16($5));
889 op[3] = lsb(imm_data16($5));
893 | DIVU REG ',' '#' expr {
894 size = find_size1(inst_size, $2);
899 op[1] = reg($2) * 16 + 1;
900 op[2] = imm_data8($5);
905 op[1] = reg($2) * 16 + 3;
906 op[2] = imm_data8($5);
911 op[1] = (reg($2) / 2) * 32 + 1;
912 op[2] = msb(imm_data16($5));
913 op[3] = lsb(imm_data16($5));
925 op[1] = ($2 >> 8) & 255;
927 op[3] = ($2 >> 16) & 255;
932 op[1] = ($2 >> 8) & 255;
934 op[3] = ($2 >> 16) & 255;
939 op[1] = 0x70 + reg_indirect($3);
941 | JMP '[' A '+' DPTR ']' {
946 | JMP '[' '[' REG '+' ']' ']' {
949 op[1] = 0x60 + reg_indirect($4);
955 op[1] = msb(rel16(MEM_POS + $$, $2));
956 op[2] = lsb(rel16(MEM_POS + $$, $2));
962 op[1] = msb(rel16(MEM_POS + $$, $2));
963 op[2] = lsb(rel16(MEM_POS + $$, $2));
965 | branch_inst jmpaddr {
967 op[0] = branch_opcode;
968 op[1] = rel8(MEM_POS + $$, $2);
970 | CJNE REG ',' expr ',' jmpaddr {
972 size = find_size1(inst_size, $2);
973 op[0] = 0xE2 + size * 8;
974 op[1] = reg($2) * 16 + msb(direct_addr($4));
975 op[2] = lsb(direct_addr($4));
976 op[3] = rel8(MEM_POS + $$, $6);
978 | CJNE REG ',' '#' expr ',' jmpaddr {
979 size = find_size1(inst_size, $2);
983 op[1] = reg($2) * 16;
984 op[2] = rel8(MEM_POS + $$, $7);
985 op[3] = imm_data8($5);
989 op[1] = reg($2) * 16;
990 op[2] = rel8(MEM_POS + $$, $7);
991 op[3] = msb(imm_data16($5));
992 op[4] = lsb(imm_data16($5));
995 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
996 size = find_size0(inst_size);
1000 op[1] = reg_indirect($3) * 16 + 8;
1001 op[2] = rel8(MEM_POS + $$, $9);
1002 op[3] = imm_data8($7);
1006 op[1] = reg_indirect($3) * 16 + 8;
1007 op[2] = rel8(MEM_POS + $$, $9);
1008 op[3] = msb(imm_data16($7));
1009 op[4] = lsb(imm_data16($7));
1012 | DJNZ REG ',' jmpaddr {
1014 size = find_size1(inst_size, $2);
1015 op[0] = 0x87 + size * 8;
1016 op[1] = reg($2) * 16 + 8;
1017 op[2] = rel8(MEM_POS + $$, $4);
1021 | DJNZ expr ',' jmpaddr {
1023 size = find_size0(inst_size);
1024 op[0] = 0xE2 + size * 8;
1025 op[1] = msb(direct_addr($2)) + 8;
1026 op[2] = lsb(direct_addr($2));
1027 op[3] = rel8(MEM_POS + $$, $4);
1030 | JB bit ',' jmpaddr {
1033 op[1] = 0x80 + msb(bit_addr($2));
1034 op[2] = lsb(bit_addr($2));
1035 op[3] = rel8(MEM_POS + $$, $4);
1038 | JBC bit ',' jmpaddr {
1041 op[1] = 0xC0 + msb(bit_addr($2));
1042 op[2] = lsb(bit_addr($2));
1043 op[3] = rel8(MEM_POS + $$, $4);
1046 | JNB bit ',' jmpaddr {
1049 op[1] = 0xA0 + msb(bit_addr($2));
1050 op[2] = lsb(bit_addr($2));
1051 op[3] = rel8(MEM_POS + $$, $4);
1056 ADD {arith_opcode = 0;}
1057 | ADDC {arith_opcode = 1;}
1058 | AND {arith_opcode = 5;}
1059 | CMP {arith_opcode = 4;}
1060 | MOV {arith_opcode = 8;}
1061 | OR {arith_opcode = 6;}
1062 | SUB {arith_opcode = 2;}
1063 | SUBB {arith_opcode = 3;}
1064 | XOR {arith_opcode = 7;}
1067 ADDS {short_opcode = 0xA0;}
1068 | MOVS {short_opcode = 0xB0;}
1071 ASL {shift_reg_opcode = 0xC1; shift_imm_opcode = 0xD1;}
1072 | ASR {shift_reg_opcode = 0xC2; shift_imm_opcode = 0xD2;}
1073 | LSR {shift_reg_opcode = 0xC0; shift_imm_opcode = 0xD0;}
1074 | NORM {shift_reg_opcode = 0xC3; shift_imm_opcode = -1;}
1077 RL {rotate_opcode = 0xD3;}
1078 | RLC {rotate_opcode = 0xD7;}
1079 | RR {rotate_opcode = 0xD0;}
1080 | RRC {rotate_opcode = 0xD7;}
1083 POP {stack_addr_opcode = 0x8710; stack_reg_opcode = 0x27;}
1084 | POPU {stack_addr_opcode = 0x8700; stack_reg_opcode = 0x37;}
1085 | PUSH {stack_addr_opcode = 0x8730; stack_reg_opcode = 0x07;}
1086 | PUSHU {stack_addr_opcode = 0x8720; stack_reg_opcode = 0x17;}
1089 BKPT {num_op = 1; opcode0 = 255; opcode1 = 0;}
1090 | NOP {num_op = 1; opcode0 = 0; opcode1 = 0;}
1091 | RESET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x10;}
1092 | RET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x80;}
1093 | RETI {num_op = 2; opcode0 = 0xD6; opcode1 = 0x90;}
1096 BCC {branch_opcode = 0xF0;}
1097 | BCS {branch_opcode = 0xF1;}
1098 | BEQ {branch_opcode = 0xF3;}
1099 | BG {branch_opcode = 0xF8;}
1100 | BGE {branch_opcode = 0xFA;}
1101 | BGT {branch_opcode = 0xFC;}
1102 | BL {branch_opcode = 0xF9;}
1103 | BLE {branch_opcode = 0xFD;}
1104 | BLT {branch_opcode = 0xFB;}
1105 | BMI {branch_opcode = 0xF7;}
1106 | BNE {branch_opcode = 0xF2;}
1107 | BNV {branch_opcode = 0xF4;}
1108 | BOV {branch_opcode = 0xF5;}
1109 | BPL {branch_opcode = 0xF6;}
1110 | BR {branch_opcode = 0xFE;}
1111 | JZ {branch_opcode = 0xEC;}
1112 | JNZ {branch_opcode = 0xEE;}
1119 int reg(int reg_spec)
1121 return reg_spec & 15;
1124 int reg_indirect(int reg_spec)
1126 if (reg_spec & BYTE_REG)
1127 error("Imdirect addressing may not use byte registers");
1128 if ((reg_spec & 15) > 7)
1129 error("Only R0 through R7 may be used for indirect addr");
1130 return reg_spec & 7;
1133 int rel16(int pos, int dest)
1137 if (!p3) return 0; /* don't bother unless writing code */
1138 if (dest & (BRANCH_SPACING - 1))
1139 error("Attempt to jump to unaligned location");
1140 pos &= ~(BRANCH_SPACING - 1);
1141 rel = (dest - pos) / BRANCH_SPACING;
1142 if (rel < -32768 || rel > 32767)
1143 error("Attempt to jump out of 16 bit relative range");
1144 if (rel < 0) rel += 65536;
1148 int rel8(int pos, int dest)
1152 if (!p3) return 0; /* don't bother unless writing code */
1153 if (dest & (BRANCH_SPACING - 1))
1154 error("Attempt to jump to unaligned location");
1155 pos &= ~(BRANCH_SPACING - 1);
1156 rel = (dest - pos) / BRANCH_SPACING;
1157 if (rel < -128 || rel > 127)
1158 error("Attempt to jump out of 16 bit relative range");
1159 if (rel < 0) rel += 256;
1165 return (value >> 8) & 255;
1173 int direct_addr(int value)
1177 if (value < 0 || value > 2047) {
1178 sprintf(buf, "illegal value (%d) for direct address", value);
1184 int imm_data4_signed(int value)
1186 if (value < -8 || value > 7)
1187 error("illegal 4 bit (signed) value");
1188 if (value >= 0) return value;
1189 else return (16 + value);
1192 int imm_data4_unsigned(int value)
1194 if (value < 0 || value > 15)
1195 error("illegal 4 bit (unsigned) value");
1199 int imm_data5_unsigned(int value)
1201 if (value < 0 || value > 31)
1202 error("illegal 5 bit (unsigned) value");
1206 int imm_data8(int value)
1208 if (value < -128 || value > 255)
1209 error("illegal 8 bit value");
1210 if (value >= 0) return value;
1211 else return (256 + value);
1214 int imm_data16(int value)
1216 if (value < -32728 || value > 65535)
1217 error("illegal 16 bit value");
1218 if (value >= 0) return value;
1219 else return (65536 + value);
1222 int bit_addr(int value)
1224 if (value < 0 || value > 1023) {
1225 fprintf(stderr, "bad bit addr of 0x%04X (%d dec)\n",
1227 error("illegal bit address");
1233 int find_size_reg(int op1spec)
1235 int op1size=UNKNOWN;
1237 if (op1spec & BYTE_REG) op1size = SIZE8;
1238 if (op1spec & WORD_REG) op1size = SIZE16;
1239 if (op1size == UNKNOWN)
1240 error("Register without implied size");
1244 int find_size0(int isize)
1246 if (isize == UNKNOWN)
1247 error("Can't determine data size from instruction");
1251 int find_size1(int isize, int op1spec)
1253 int op1size=UNKNOWN;
1255 if (op1spec & BYTE_REG) op1size = SIZE8;
1256 if (op1spec & WORD_REG) op1size = SIZE16;
1257 if (op1size == UNKNOWN)
1258 error("Register without implied size");
1260 if (isize == SIZE32 && op1size == SIZE16) return SIZE32;
1261 if (isize == UNKNOWN) return op1size;
1263 if (isize != op1size)
1264 error("data size of register and inst don't agree");
1269 int find_size2(int isize, int op1spec, int op2spec)
1271 int op1size=UNKNOWN, op2size=UNKNOWN;
1273 if (op1spec & BYTE_REG) op1size = SIZE8;
1274 if (op1spec & WORD_REG) op1size = SIZE16;
1275 if (op1size == UNKNOWN)
1276 error("Register without implied size");
1277 if (op2spec & BYTE_REG) op2size = SIZE8;
1278 if (op2spec & WORD_REG) op2size = SIZE16;
1279 if (op1size == UNKNOWN)
1280 error("Register without implied size");
1282 if (op1size != op2size)
1283 error("data sizes of two registers don't agree");
1284 if (isize == UNKNOWN) return op1size;
1286 if (isize != op1size)
1287 error("data size of registers and inst don't agree");
1293 int yyerror(char *s)
1295 if (yytext[0] >= 32) {
1296 fprintf(stderr, "%s near '%s', line %d\n",
1299 fprintf(stderr, "%s, line %d\n", s, lineno - 1);
1309 void fatal_error(char *s)