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 */
172 /* ignore global symbol declaration */
176 /* todo: if CSEG, emit some filler bytes */
180 db_directive: DB {db_count = 0;}
184 strcpy(symbol_name, lex_sym_name);
185 if (!strchr(lex_sym_name, ':')) {
186 /* non-local label, remember base name */
187 strcpy(base_symbol_name, lex_sym_name);
189 if (is_target(symbol_name)) pad_with_nop();
193 | bytes ',' byte_element
196 op[db_count] = $1 & 255;
197 if (++db_count >= MAX_DB) {
198 error("too many bytes, use two DB");
203 for(i=1; i < strlen(yytext)-1; i++) {
204 op[db_count++] = yytext[i];
205 if (db_count >= MAX_DB) {
206 error("too many bytes, use two DB");
212 dw_directive: DW {dw_count = 0;}
214 words: words ',' word_element
218 op[dw_count] = $1 & 255;
219 op[dw_count+1] = ($1 >> 8) & 255;
221 if (dw_count >= MAX_DB) {
222 error("too many bytes, use two DW");
230 strcpy(symbol_name, lex_sym_name);
233 bitsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
234 | BIT { strcpy(symbol_name, lex_sym_name); }
237 regsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
238 | REG { strcpy(symbol_name, lex_sym_name); }
241 if ($3 < 0 || $3 > 7) {
242 /* only 8 bits in a byte */
243 error("Only eight bits in a byte");
245 $$ = 100000; /* should really check $1 is valid */
246 if ($1 >= 0x20 && $1 <= 0x3F) {
249 if ($1 >= 0x400 && $1 <= 0x43F) {
250 $$ = ($1 - 0x400) * 8 + $3 + 0x200;
255 if (find_size_reg($1) == SIZE8) {
256 if ($3 < 0 || $3 > 7)
257 error("byte reg has only 8 bits");
258 $$ = reg($1) * 8 + $3;
260 if (find_size_reg($1) == SIZE16) {
261 if ($3 < 0 || $3 > 15)
262 error("word reg has only 16 bits");
263 $$ = reg($1) * 16 + $3;
270 if (p1) build_target_list(lex_sym_name);
273 if ($1 & 1) error("Jump target must be aligned");
278 expr: value {$$ = $1;}
279 | expr '+' expr {$$ = $1 + $3;}
280 | expr '-' expr {$$ = $1 - $3;}
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 RSHIFT expr {$$ = $1 >> $3;}
287 | expr LSHIFT expr {$$ = $1 << $3;}
288 | '-' expr %prec UNARY {$$ = $2 * -1;}
289 | '+' expr %prec UNARY {$$ = $2;}
290 | '(' expr ')' {$$ = $2;}
291 | LOW expr %prec UNARY {$$ = $2 & 255;}
292 | HIGH expr %prec UNARY {$$ = ($2 >> 8) & 255;}
295 value: NUMBER {$$ = $1;}
297 | WORD {$$ = $1; strcpy(expr_var, yytext);}
301 rlist_bitmask = bitmask[reg($1) % 8];
302 rlist_reg_bank = (reg($1) / 8) ? 1 : 0;
303 rlist_size = find_size_reg($1);
306 rlist_bitmask |= bitmask[reg($1) % 8];
307 if (rlist_reg_bank != ((reg($1) / 8) ? 1 : 0))
308 error("register list may not mix 0-7/8-15 regs");
309 if (rlist_size != find_size_reg($1))
310 error("register list may not mix 8/16 bit registers");
319 arith_inst REG ',' REG {
321 size = find_size2(inst_size, $2, $4);
322 op[0] = arith_opcode * 16 + size * 8 + 1;
323 op[1] = reg($2) * 16 + reg($4);
325 | arith_inst REG ',' '[' REG ']' {
327 size = find_size1(inst_size, $2);
328 op[0] = arith_opcode * 16 + size * 8 + 2;
329 op[1] = reg($2) * 16 + reg_indirect($5);
331 | arith_inst '[' REG ']' ',' REG {
333 size = find_size1(inst_size, $6);
334 op[0] = arith_opcode * 16 + size * 8 + 2;
335 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
337 | arith_inst REG ',' '[' REG '+' expr ']' {
338 size = find_size1(inst_size, $2);
339 if ($7 >= -128 && $7 <= 127) {
341 op[0] = arith_opcode * 16 + size * 8 + 4;
342 op[1] = reg($2) * 16 + reg_indirect($5);
343 op[2] = ($7 >= 0) ? $7 : 256 + $7;
346 op[0] = arith_opcode * 16 + size * 8 + 5;
347 op[1] = reg($2) * 16 + reg_indirect($5);
348 op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
349 op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
352 | arith_inst '[' REG '+' expr ']' ',' REG {
353 size = find_size1(inst_size, $8);
354 if ($5 >= -128 && $5 <= 127) {
356 op[0] = arith_opcode * 16 + size * 8 + 4;
357 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
358 op[2] = ($5 >= 0) ? $5 : 256 + $5;
361 op[0] = arith_opcode * 16 + size * 8 + 5;
362 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
363 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
364 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
367 | arith_inst REG ',' '[' REG '+' ']' {
369 size = find_size1(inst_size, $2);
370 op[0] = arith_opcode * 16 + size * 8 + 3;
371 op[1] = reg($2) * 16 + reg_indirect($5);
373 | arith_inst '[' REG '+' ']' ',' REG {
375 size = find_size1(inst_size, $7);
376 op[0] = arith_opcode * 16 + size * 8 + 3;
377 op[1] = reg($7) * 16 + 8 + reg_indirect($3);
379 | arith_inst expr ',' REG {
381 size = find_size1(inst_size, $4);
382 op[0] = arith_opcode * 16 + size * 8 + 6;
383 op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
384 op[2] = lsb(direct_addr($2));
386 | arith_inst REG ',' expr {
388 size = find_size1(inst_size, $2);
389 op[0] = arith_opcode * 16 + size * 8 + 6;
390 op[1] = reg($2) * 16 + msb(direct_addr($4));
391 op[2] = lsb(direct_addr($4));
393 | arith_inst REG ',' '#' expr {
394 size = find_size1(inst_size, $2);
398 op[1] = reg($2) * 16 + arith_opcode;
399 op[2] = imm_data8($5);
403 op[1] = reg($2) * 16 + arith_opcode;
404 op[2] = msb(imm_data16($5));
405 op[3] = lsb(imm_data16($5));
408 | arith_inst '[' REG ']' ',' '#' expr {
409 size = find_size0(inst_size);
413 op[1] = reg_indirect($3) * 16 + arith_opcode;
414 op[2] = imm_data8($7);
418 op[1] = reg_indirect($3) * 16 + arith_opcode;
419 op[2] = msb(imm_data16($7));
420 op[3] = lsb(imm_data16($7));
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($8);
433 op[1] = reg_indirect($3) * 16 + arith_opcode;
434 op[2] = msb(imm_data16($8));
435 op[3] = lsb(imm_data16($8));
438 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
439 size = find_size0(inst_size);
440 if ($5 >= -128 && $5 <= 127) {
444 op[1] = reg_indirect($3) * 16 + arith_opcode;
445 op[2] = ($5 >= 0) ? $5 : 256 + $5;
446 op[3] = imm_data8($9);
450 op[1] = reg_indirect($3) * 16 + arith_opcode;
451 op[2] = ($5 >= 0) ? $5 : 256 + $5;
452 op[3] = msb(imm_data16($9));
453 op[4] = lsb(imm_data16($9));
459 op[1] = reg_indirect($3) * 16 + arith_opcode;
460 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
461 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
462 op[4] = imm_data8($9);
466 op[1] = reg_indirect($3) * 16 + arith_opcode;
467 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
468 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
469 op[4] = msb(imm_data16($9));
470 op[5] = lsb(imm_data16($9));
474 | arith_inst expr ',' '#' expr {
475 size = find_size0(inst_size);
479 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
480 op[2] = lsb(direct_addr($2));
481 op[3] = imm_data8($5);
485 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
486 op[2] = lsb(direct_addr($2));
487 op[3] = msb(imm_data16($5));
488 op[4] = lsb(imm_data16($5));
492 /* the next 8 instructions are MOV, but because MOV was used in the */
493 /* arith_inst group, it will cause a shift/reduce conflict if used */
494 /* directly below... so we're forced to use arith_inst and then */
495 /* add a bit of code to make sure it was MOV and not the other ones */
497 | arith_inst '[' REG '+' ']' ',' '[' REG '+' ']' {
498 /* this addr mode is only valid for MOV */
499 if (arith_opcode != 8) error("Addr mode only valid for MOV (1)");
500 size = find_size0(inst_size);
502 op[0] = 0x90 + size * 8;
503 op[1] = reg_indirect($3) * 16 + reg_indirect($8);
505 | arith_inst expr ',' '[' REG ']' {
506 /* this addr mode is only valid for MOV */
507 if (arith_opcode != 8) error("Addr mode only valid for MOV (2)");
508 size = find_size0(inst_size);
510 op[0] = 0xA0 + size * 8;
511 op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
512 op[2] = lsb(direct_addr($2));
514 | arith_inst '[' REG ']' ',' expr {
515 /* this addr mode is only valid for MOV */
516 if (arith_opcode != 8) error("Addr mode only valid for MOV (3)");
517 size = find_size0(inst_size);
519 op[0] = 0xA0 + size * 8;
520 op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
521 op[2] = lsb(direct_addr($6));
523 | arith_inst expr ',' expr {
524 /* this addr mode is only valid for MOV */
525 if (arith_opcode != 8) error("Addr mode only valid for MOV (4)");
526 size = find_size0(inst_size);
528 op[0] = 0x97 + size * 8;
529 op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
530 op[2] = lsb(direct_addr($2));
531 op[3] = lsb(direct_addr($4));
533 | arith_inst REG ',' USP {
534 /* this addr mode is only valid for MOV */
535 if (arith_opcode != 8) error("Addr mode only valid for MOV (5)");
538 op[1] = reg($2) * 16 + 15;
540 | arith_inst USP ',' REG {
541 /* this addr mode is only valid for MOV */
542 if (arith_opcode != 8) error("Addr mode only valid for MOV (6)");
545 op[1] = reg($4) * 16 + 15;
547 | arith_inst C ',' bit {
548 /* this addr mode is only valid for MOV */
549 if (arith_opcode != 8) error("Addr mode only valid for MOV (7)");
552 op[1] = 0x20 + msb(bit_addr($4));
553 op[2] = lsb(bit_addr($4));
555 | arith_inst bit ',' C {
556 /* this addr mode is only valid for MOV */
557 if (arith_opcode != 8) error("Addr mode only valid for MOV (8)");
560 op[1] = 0x30 + msb(bit_addr($2));
561 op[2] = lsb(bit_addr($2));
564 | MOVC REG ',' '[' REG '+' ']' {
565 size = find_size1(inst_size, $2);
567 op[0] = 0x80 + size * 8;
568 op[1] = reg($2) * 16 + reg_indirect($5);
570 | MOVC A ',' '[' A '+' DPTR ']' {
575 | MOVC A ',' '[' A '+' PC ']' {
580 | MOVX REG ',' '[' REG ']' {
582 size = find_size1(inst_size, $2);
583 op[0] = 0xA7 + size * 8;
584 op[1] = reg($2) * 16 + reg_indirect($5);
586 | MOVX '[' REG ']' ',' REG {
588 size = find_size1(inst_size, $6);
589 op[0] = 0xA7 + size * 8;
590 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
594 size = find_size2(inst_size, $2, $4);
595 op[0] = 0x60 + size * 8;
596 op[1] = reg($2) * 16 + reg($4);
598 | XCH REG ',' '[' REG ']' {
600 size = find_size1(inst_size, $2);
601 op[0] = 0x50 + size * 8;
602 op[1] = reg($2) * 16 + reg_indirect($5);
606 size = find_size1(inst_size, $2);
607 op[0] = 0xA0 + size * 8;
608 op[1] = reg($2) * 16 + msb(direct_addr($4));
609 op[2] = lsb(direct_addr($4));
611 | short_data_inst REG ',' '#' expr {
613 size = find_size1(inst_size, $2);
614 op[0] = short_opcode + size * 8 + 1;
615 op[1] = reg($2) * 16 + imm_data4_signed($5);
617 | short_data_inst '[' REG ']' ',' '#' expr {
619 size = find_size0(inst_size);
620 op[0] = short_opcode + size * 8 + 2;
621 op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
623 | short_data_inst '[' REG '+' ']' ',' '#' expr {
625 size = find_size0(inst_size);
626 op[0] = short_opcode + size * 8 + 3;
627 op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
629 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
630 size = find_size0(inst_size);
631 if ($5 >= -128 && $5 <= 127) {
633 op[0] = short_opcode + size * 8 + 4;
634 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
635 op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
638 op[0] = short_opcode + size * 8 + 5;
639 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
640 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
641 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
644 | short_data_inst expr ',' '#' expr {
646 size = find_size0(inst_size);
647 op[0] = short_opcode + size * 8 + 6;
648 op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
649 op[2] = lsb(direct_addr($2));
657 op[1] = 0x40 + msb(bit_addr($4));
658 op[2] = lsb(bit_addr($4));
660 | ANL C ',' '/' bit {
663 op[1] = 0x50 + msb(bit_addr($5));
664 op[2] = lsb(bit_addr($5));
670 op[1] = 0x60 + msb(bit_addr($4));
671 op[2] = lsb(bit_addr($4));
673 | ORL C ',' '/' bit {
676 op[1] = 0x70 + msb(bit_addr($5));
677 op[2] = lsb(bit_addr($5));
682 op[1] = msb(bit_addr($2));
683 op[2] = lsb(bit_addr($2));
688 op[1] = 0x10 + msb(bit_addr($2));
689 op[2] = lsb(bit_addr($2));
691 | logical_shift_inst REG ',' REG {
692 size = find_size1(inst_size, $2);
693 if (find_size_reg($4) != SIZE8)
694 error("Second register in logical shift must be byte size");
696 op[0] = shift_reg_opcode;
698 case SIZE8: op[0] += 0; break;
699 case SIZE16: op[0] += 8; break;
700 case SIZE32: op[0] += 12; break;
702 op[1] = reg($2) * 16 + reg($4);
704 | logical_shift_inst REG ',' '#' expr {
705 size = find_size1(inst_size, $2);
707 if (shift_imm_opcode == -1)
708 error("NORM may not use a constant");
709 op[0] = shift_imm_opcode;
711 case SIZE8: op[0] += 0; break;
712 case SIZE16: op[0] += 8; break;
713 case SIZE32: op[0] += 12; break;
718 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
721 op[1] = (reg($2) / 2) * 32 + imm_data5_unsigned($5);
734 op[1] = 0x30 + imm_data4_unsigned($3);
738 size = find_size1(inst_size, $2);
739 op[0] = 0x90 + size * 8;
740 op[1] = reg($2) * 16 + 10;
745 op[1] = reg($2) * 16 + 8;
749 size = find_size1(inst_size, $2);
750 op[0] = 0x90 + size * 8;
751 op[1] = reg($2) * 16 + 11;
755 size = find_size1(inst_size, $2);
756 op[0] = 0x90 + size * 8;
757 op[1] = reg($2) * 16 + 9;
760 | rotate_inst REG ',' '#' expr {
762 size = find_size1(inst_size, $2);
763 op[0] = rotate_opcode + size * 8;
764 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
768 | LEA REG ',' REG '+' expr {
769 if ($6 >= -128 && $6 <= 127) {
772 op[1] = reg($2) * 16 + reg_indirect($4);
773 op[2] = ($6 >= 0) ? $6 : 256 + $6;
776 op[1] = reg($2) * 16 + reg_indirect($4);
777 op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
778 op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
783 size = find_size0(inst_size);
784 op[0] = msb(stack_addr_opcode) + size * 8;
785 op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
786 op[2] = lsb(direct_addr($2));
790 if (inst_size != UNKNOWN && find_size0(inst_size) != rlist_size)
791 error("inst specifies different size than registers used");
792 op[0] = stack_reg_opcode + rlist_reg_bank * 64 + rlist_size * 8;
793 op[1] = rlist_bitmask;
799 size = find_size2(inst_size, $2, $4);
801 op[1] = reg($2) * 16 + reg($4);
805 size = find_size2(inst_size, $2, $4);
808 op[1] = reg($2) * 16 + reg($4);
811 op[1] = reg($2) * 16 + reg($4);
814 | MUL REG ',' '#' expr {
816 size = find_size1(inst_size, $2);
819 op[2] = msb(imm_data16($5));
820 op[3] = lsb(imm_data16($5));
822 | MULU REG ',' '#' expr {
823 size = find_size2(inst_size, $2, $4);
827 op[1] = reg($2) * 16;
828 op[2] = imm_data8($5);
832 op[1] = reg($2) * 16;
833 op[2] = msb(imm_data16($5));
834 op[3] = lsb(imm_data16($5));
839 size = find_size2(inst_size, $2, $4);
842 error("Singed DIV can't be 8 bit size"); break;
845 op[1] = reg($2) * 16 + reg($4);
849 op[1] = (reg($2) / 2) * 32 + reg($4);
855 size = find_size2(inst_size, $2, $4);
859 op[1] = reg($2) * 16 + reg($4);
863 op[1] = reg($2) * 16 + reg($4);
867 op[1] = (reg($2) / 2) * 32 + reg($4);
871 | DIV REG ',' '#' expr {
872 size = find_size1(inst_size, $2);
875 error("Singed DIV can't be 8 bit size"); break;
879 op[1] = reg($2) * 16 + 11;
880 op[2] = imm_data8($5);
885 op[1] = (reg($2) / 2) * 32 + 9;
886 op[2] = msb(imm_data16($5));
887 op[3] = lsb(imm_data16($5));
891 | DIVU REG ',' '#' expr {
892 size = find_size1(inst_size, $2);
897 op[1] = reg($2) * 16 + 1;
898 op[2] = imm_data8($5);
903 op[1] = reg($2) * 16 + 3;
904 op[2] = imm_data8($5);
909 op[1] = (reg($2) / 2) * 32 + 1;
910 op[2] = msb(imm_data16($5));
911 op[3] = lsb(imm_data16($5));
923 op[1] = ($2 >> 8) & 255;
925 op[3] = ($2 >> 16) & 255;
930 op[1] = ($2 >> 8) & 255;
932 op[3] = ($2 >> 16) & 255;
937 op[1] = 0x70 + reg_indirect($3);
939 | JMP '[' A '+' DPTR ']' {
944 | JMP '[' '[' REG '+' ']' ']' {
947 op[1] = 0x60 + reg_indirect($4);
953 op[1] = msb(rel16(MEM_POS + $$, $2));
954 op[2] = lsb(rel16(MEM_POS + $$, $2));
960 op[1] = msb(rel16(MEM_POS + $$, $2));
961 op[2] = lsb(rel16(MEM_POS + $$, $2));
963 | branch_inst jmpaddr {
965 op[0] = branch_opcode;
966 op[1] = rel8(MEM_POS + $$, $2);
968 | CJNE REG ',' expr ',' jmpaddr {
970 size = find_size1(inst_size, $2);
971 op[0] = 0xE2 + size * 8;
972 op[1] = reg($2) * 16 + msb(direct_addr($4));
973 op[2] = lsb(direct_addr($4));
974 op[3] = rel8(MEM_POS + $$, $6);
976 | CJNE REG ',' '#' expr ',' jmpaddr {
977 size = find_size1(inst_size, $2);
981 op[1] = reg($2) * 16;
982 op[2] = rel8(MEM_POS + $$, $7);
983 op[3] = imm_data8($5);
987 op[1] = reg($2) * 16;
988 op[2] = rel8(MEM_POS + $$, $7);
989 op[3] = msb(imm_data16($5));
990 op[4] = lsb(imm_data16($5));
993 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
994 size = find_size0(inst_size);
998 op[1] = reg_indirect($3) * 16 + 8;
999 op[2] = rel8(MEM_POS + $$, $9);
1000 op[3] = imm_data8($7);
1004 op[1] = reg_indirect($3) * 16 + 8;
1005 op[2] = rel8(MEM_POS + $$, $9);
1006 op[3] = msb(imm_data16($7));
1007 op[4] = lsb(imm_data16($7));
1010 | DJNZ REG ',' jmpaddr {
1012 size = find_size1(inst_size, $2);
1013 op[0] = 0x87 + size * 8;
1014 op[1] = reg($2) * 16 + 8;
1015 op[2] = rel8(MEM_POS + $$, $4);
1019 | DJNZ expr ',' jmpaddr {
1021 size = find_size0(inst_size);
1022 op[0] = 0xE2 + size * 8;
1023 op[1] = msb(direct_addr($2)) + 8;
1024 op[2] = lsb(direct_addr($2));
1025 op[3] = rel8(MEM_POS + $$, $4);
1028 | JB bit ',' jmpaddr {
1031 op[1] = 0x80 + msb(bit_addr($2));
1032 op[2] = lsb(bit_addr($2));
1033 op[3] = rel8(MEM_POS + $$, $4);
1036 | JBC bit ',' jmpaddr {
1039 op[1] = 0xC0 + msb(bit_addr($2));
1040 op[2] = lsb(bit_addr($2));
1041 op[3] = rel8(MEM_POS + $$, $4);
1044 | JNB bit ',' jmpaddr {
1047 op[1] = 0xA0 + msb(bit_addr($2));
1048 op[2] = lsb(bit_addr($2));
1049 op[3] = rel8(MEM_POS + $$, $4);
1054 ADD {arith_opcode = 0;}
1055 | ADDC {arith_opcode = 1;}
1056 | AND {arith_opcode = 5;}
1057 | CMP {arith_opcode = 4;}
1058 | MOV {arith_opcode = 8;}
1059 | OR {arith_opcode = 6;}
1060 | SUB {arith_opcode = 2;}
1061 | SUBB {arith_opcode = 3;}
1062 | XOR {arith_opcode = 7;}
1065 ADDS {short_opcode = 0xA0;}
1066 | MOVS {short_opcode = 0xB0;}
1069 ASL {shift_reg_opcode = 0xC1; shift_imm_opcode = 0xD1;}
1070 | ASR {shift_reg_opcode = 0xC2; shift_imm_opcode = 0xD2;}
1071 | LSR {shift_reg_opcode = 0xC0; shift_imm_opcode = 0xD0;}
1072 | NORM {shift_reg_opcode = 0xC3; shift_imm_opcode = -1;}
1075 RL {rotate_opcode = 0xD3;}
1076 | RLC {rotate_opcode = 0xD7;}
1077 | RR {rotate_opcode = 0xD0;}
1078 | RRC {rotate_opcode = 0xD7;}
1081 POP {stack_addr_opcode = 0x8710; stack_reg_opcode = 0x27;}
1082 | POPU {stack_addr_opcode = 0x8700; stack_reg_opcode = 0x37;}
1083 | PUSH {stack_addr_opcode = 0x8730; stack_reg_opcode = 0x07;}
1084 | PUSHU {stack_addr_opcode = 0x8720; stack_reg_opcode = 0x17;}
1087 BKPT {num_op = 1; opcode0 = 255; opcode1 = 0;}
1088 | NOP {num_op = 1; opcode0 = 0; opcode1 = 0;}
1089 | RESET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x10;}
1090 | RET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x80;}
1091 | RETI {num_op = 2; opcode0 = 0xD6; opcode1 = 0x90;}
1094 BCC {branch_opcode = 0xF0;}
1095 | BCS {branch_opcode = 0xF1;}
1096 | BEQ {branch_opcode = 0xF3;}
1097 | BG {branch_opcode = 0xF8;}
1098 | BGE {branch_opcode = 0xFA;}
1099 | BGT {branch_opcode = 0xFC;}
1100 | BL {branch_opcode = 0xF9;}
1101 | BLE {branch_opcode = 0xFD;}
1102 | BLT {branch_opcode = 0xFB;}
1103 | BMI {branch_opcode = 0xF7;}
1104 | BNE {branch_opcode = 0xF2;}
1105 | BNV {branch_opcode = 0xF4;}
1106 | BOV {branch_opcode = 0xF5;}
1107 | BPL {branch_opcode = 0xF6;}
1108 | BR {branch_opcode = 0xFE;}
1109 | JZ {branch_opcode = 0xEC;}
1110 | JNZ {branch_opcode = 0xEE;}
1117 int reg(int reg_spec)
1119 return reg_spec & 15;
1122 int reg_indirect(int reg_spec)
1124 if (reg_spec & BYTE_REG)
1125 error("Imdirect addressing may not use byte registers");
1126 if ((reg_spec & 15) > 7)
1127 error("Only R0 through R7 may be used for indirect addr");
1128 return reg_spec & 7;
1131 int rel16(int pos, int dest)
1135 if (!p3) return 0; /* don't bother unless writing code */
1136 if (dest & (BRANCH_SPACING - 1))
1137 error("Attempt to jump to unaligned location");
1138 pos &= ~(BRANCH_SPACING - 1);
1139 rel = (dest - pos) / BRANCH_SPACING;
1140 if (rel < -32768 || rel > 32767)
1141 error("Attempt to jump out of 16 bit relative range");
1142 if (rel < 0) rel += 65536;
1146 int rel8(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 < -128 || rel > 127)
1156 error("Attempt to jump out of 16 bit relative range");
1157 if (rel < 0) rel += 256;
1163 return (value >> 8) & 255;
1171 int direct_addr(int value)
1175 if (value < 0 || value > 2047) {
1176 sprintf(buf, "illegal value (%d) for direct address", value);
1182 int imm_data4_signed(int value)
1184 if (value < -8 || value > 7)
1185 error("illegal 4 bit (signed) value");
1186 if (value >= 0) return value;
1187 else return (16 + value);
1190 int imm_data4_unsigned(int value)
1192 if (value < 0 || value > 15)
1193 error("illegal 4 bit (unsigned) value");
1197 int imm_data5_unsigned(int value)
1199 if (value < 0 || value > 31)
1200 error("illegal 5 bit (unsigned) value");
1204 int imm_data8(int value)
1206 if (value < -128 || value > 255)
1207 error("illegal 8 bit value");
1208 if (value >= 0) return value;
1209 else return (256 + value);
1212 int imm_data16(int value)
1214 if (value < -32728 || value > 65535)
1215 error("illegal 16 bit value");
1216 if (value >= 0) return value;
1217 else return (65536 + value);
1220 int bit_addr(int value)
1222 if (value < 0 || value > 1023) {
1223 fprintf(stderr, "bad bit addr of 0x%04X (%d dec)\n",
1225 error("illegal bit address");
1231 int find_size_reg(int op1spec)
1233 int op1size=UNKNOWN;
1235 if (op1spec & BYTE_REG) op1size = SIZE8;
1236 if (op1spec & WORD_REG) op1size = SIZE16;
1237 if (op1size == UNKNOWN)
1238 error("Register without implied size");
1242 int find_size0(int isize)
1244 if (isize == UNKNOWN)
1245 error("Can't determine data size from instruction");
1249 int find_size1(int isize, int op1spec)
1251 int op1size=UNKNOWN;
1253 if (op1spec & BYTE_REG) op1size = SIZE8;
1254 if (op1spec & WORD_REG) op1size = SIZE16;
1255 if (op1size == UNKNOWN)
1256 error("Register without implied size");
1258 if (isize == SIZE32 && op1size == SIZE16) return SIZE32;
1259 if (isize == UNKNOWN) return op1size;
1261 if (isize != op1size)
1262 error("data size of register and inst don't agree");
1267 int find_size2(int isize, int op1spec, int op2spec)
1269 int op1size=UNKNOWN, op2size=UNKNOWN;
1271 if (op1spec & BYTE_REG) op1size = SIZE8;
1272 if (op1spec & WORD_REG) op1size = SIZE16;
1273 if (op1size == UNKNOWN)
1274 error("Register without implied size");
1275 if (op2spec & BYTE_REG) op2size = SIZE8;
1276 if (op2spec & WORD_REG) op2size = SIZE16;
1277 if (op1size == UNKNOWN)
1278 error("Register without implied size");
1280 if (op1size != op2size)
1281 error("data sizes of two registers don't agree");
1282 if (isize == UNKNOWN) return op1size;
1284 if (isize != op1size)
1285 error("data size of registers and inst don't agree");
1291 int yyerror(char *s)
1293 if (yytext[0] >= 32) {
1294 fprintf(stderr, "%s near '%s', line %d\n",
1297 fprintf(stderr, "%s, line %d\n", s, lineno - 1);
1307 void fatal_error(char *s)