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
71 line: linesymbol ':' linenosym {
72 if (p1) build_sym_list(symbol_name);
73 if (p2) assign_value(symbol_name, mem);
75 | linenosym {mem += $1;}
77 linenosym: directive EOL {
89 | error EOL /* try to recover from any parse error */
91 directive: '.' ORG expr {
99 | '.' EQU symbol ',' expr {
100 if (p1) build_sym_list(symbol_name);
101 if (p1 || p2) assign_value(symbol_name, $5);
105 if (p1) build_sym_list(symbol_name);
106 if (p1 || p2) assign_value(symbol_name, $3);
109 | '.' BITDEF bitsymbol ',' bit {
111 build_sym_list(symbol_name);
114 if (p1 || p2) assign_value(symbol_name, $5);
117 | bitsymbol BITDEF bit {
119 build_sym_list(symbol_name);
122 if (p1 || p2) assign_value(symbol_name, $3);
125 | '.' REGDEF regsymbol ',' REG {
127 build_sym_list(symbol_name);
130 if (p1 || p2) assign_value(symbol_name, $5);
133 | regsymbol REGDEF REG {
135 build_sym_list(symbol_name);
138 if (p1 || p2) assign_value(symbol_name, $3);
142 | db_directive bytes {
145 | dw_directive words {
149 db_directive: DB {db_count = 0;}
152 | bytes ',' byte_element
155 op[db_count] = $1 & 255;
156 if (++db_count >= MAX_DB) {
157 error("too many bytes, use two DB");
162 for(i=1; i < strlen(yytext)-1; i++) {
163 op[db_count++] = yytext[i];
164 if (db_count >= MAX_DB) {
165 error("too many bytes, use two DB");
171 dw_directive: DW {dw_count = 0;}
173 words: words ',' word_element
177 op[dw_count] = $1 & 255;
178 op[dw_count+1] = ($1 >> 8) & 255;
180 if (dw_count >= MAX_DB) {
181 error("too many bytes, use two DW");
188 strcpy(symbol_name, lex_sym_name);
189 if (!strchr(lex_sym_name, ':')) {
190 /* non-local label, remember base name */
191 strcpy(base_symbol_name, lex_sym_name);
193 if (is_target(symbol_name)) pad_with_nop();
197 strcpy(symbol_name, lex_sym_name);
200 bitsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
201 | BIT { strcpy(symbol_name, lex_sym_name); }
204 regsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
205 | REG { strcpy(symbol_name, lex_sym_name); }
208 if ($3 < 0 || $3 > 7) {
209 /* only 8 bits in a byte */
210 error("Only eight bits in a byte");
212 $$ = 100000; /* should really check $1 is valid */
213 if ($1 >= 0x20 && $1 <= 0x3F) {
216 if ($1 >= 0x400 && $1 <= 0x43F) {
217 $$ = ($1 - 0x400) * 8 + $3 + 0x200;
222 if (find_size_reg($1) == SIZE8) {
223 if ($3 < 0 || $3 > 7)
224 error("byte reg has only 8 bits");
225 $$ = reg($1) * 8 + $3;
227 if (find_size_reg($1) == SIZE16) {
228 if ($3 < 0 || $3 > 15)
229 error("word reg has only 16 bits");
230 $$ = reg($1) * 16 + $3;
237 if (p1) build_target_list(lex_sym_name);
240 if ($1 & 1) error("Jump target must be aligned");
245 expr: value {$$ = $1;}
246 | expr '+' expr {$$ = $1 + $3;}
247 | expr '-' expr {$$ = $1 - $3;}
248 | expr '*' expr {$$ = $1 * $3;}
249 | expr '/' expr {$$ = $1 / $3;}
250 | expr '&' expr {$$ = $1 & $3;}
251 | expr '|' expr {$$ = $1 | $3;}
252 | expr '^' expr {$$ = $1 ^ $3;}
253 | expr RSHIFT expr {$$ = $1 >> $3;}
254 | expr LSHIFT expr {$$ = $1 << $3;}
255 | '-' expr %prec UNARY {$$ = $2 * -1;}
256 | '+' expr %prec UNARY {$$ = $2;}
257 | '(' expr ')' {$$ = $2;}
258 | LOW expr %prec UNARY {$$ = $2 & 255;}
259 | HIGH expr %prec UNARY {$$ = ($2 >> 8) & 255;}
262 value: NUMBER {$$ = $1;}
264 | WORD {$$ = $1; strcpy(expr_var, yytext);}
268 rlist_bitmask = bitmask[reg($1) % 8];
269 rlist_reg_bank = (reg($1) / 8) ? 1 : 0;
270 rlist_size = find_size_reg($1);
273 rlist_bitmask |= bitmask[reg($1) % 8];
274 if (rlist_reg_bank != ((reg($1) / 8) ? 1 : 0))
275 error("register list may not mix 0-7/8-15 regs");
276 if (rlist_size != find_size_reg($1))
277 error("register list may not mix 8/16 bit registers");
286 arith_inst REG ',' REG {
288 size = find_size2(inst_size, $2, $4);
289 op[0] = arith_opcode * 16 + size * 8 + 1;
290 op[1] = reg($2) * 16 + reg($4);
292 | arith_inst REG ',' '[' REG ']' {
294 size = find_size1(inst_size, $2);
295 op[0] = arith_opcode * 16 + size * 8 + 2;
296 op[1] = reg($2) * 16 + reg_indirect($5);
298 | arith_inst '[' REG ']' ',' REG {
300 size = find_size1(inst_size, $6);
301 op[0] = arith_opcode * 16 + size * 8 + 2;
302 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
304 | arith_inst REG ',' '[' REG '+' expr ']' {
305 size = find_size1(inst_size, $2);
306 if ($7 >= -128 && $7 <= 127) {
308 op[0] = arith_opcode * 16 + size * 8 + 4;
309 op[1] = reg($2) * 16 + reg_indirect($5);
310 op[2] = ($7 >= 0) ? $7 : 256 + $7;
313 op[0] = arith_opcode * 16 + size * 8 + 5;
314 op[1] = reg($2) * 16 + reg_indirect($5);
315 op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
316 op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
319 | arith_inst '[' REG '+' expr ']' ',' REG {
320 size = find_size1(inst_size, $8);
321 if ($5 >= -128 && $5 <= 127) {
323 op[0] = arith_opcode * 16 + size * 8 + 4;
324 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
325 op[2] = ($5 >= 0) ? $5 : 256 + $5;
328 op[0] = arith_opcode * 16 + size * 8 + 5;
329 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
330 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
331 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
334 | arith_inst REG ',' '[' REG '+' ']' {
336 size = find_size1(inst_size, $2);
337 op[0] = arith_opcode * 16 + size * 8 + 3;
338 op[1] = reg($2) * 16 + reg_indirect($5);
340 | arith_inst '[' REG '+' ']' ',' REG {
342 size = find_size1(inst_size, $7);
343 op[0] = arith_opcode * 16 + size * 8 + 3;
344 op[1] = reg($7) * 16 + 8 + reg_indirect($3);
346 | arith_inst expr ',' REG {
348 size = find_size1(inst_size, $4);
349 op[0] = arith_opcode * 16 + size * 8 + 6;
350 op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
351 op[2] = lsb(direct_addr($2));
353 | arith_inst REG ',' expr {
355 size = find_size1(inst_size, $2);
356 op[0] = arith_opcode * 16 + size * 8 + 6;
357 op[1] = reg($2) * 16 + msb(direct_addr($4));
358 op[2] = lsb(direct_addr($4));
360 | arith_inst REG ',' '#' expr {
361 size = find_size1(inst_size, $2);
365 op[1] = reg($2) * 16 + arith_opcode;
366 op[2] = imm_data8($5);
370 op[1] = reg($2) * 16 + arith_opcode;
371 op[2] = msb(imm_data16($5));
372 op[3] = lsb(imm_data16($5));
375 | arith_inst '[' REG ']' ',' '#' expr {
376 size = find_size0(inst_size);
380 op[1] = reg_indirect($3) * 16 + arith_opcode;
381 op[2] = imm_data8($7);
385 op[1] = reg_indirect($3) * 16 + arith_opcode;
386 op[2] = msb(imm_data16($7));
387 op[3] = lsb(imm_data16($7));
390 | arith_inst '[' REG '+' ']' ',' '#' expr {
391 size = find_size0(inst_size);
395 op[1] = reg_indirect($3) * 16 + arith_opcode;
396 op[2] = imm_data8($8);
400 op[1] = reg_indirect($3) * 16 + arith_opcode;
401 op[2] = msb(imm_data16($8));
402 op[3] = lsb(imm_data16($8));
405 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
406 size = find_size0(inst_size);
407 if ($5 >= -128 && $5 <= 127) {
411 op[1] = reg_indirect($3) * 16 + arith_opcode;
412 op[2] = ($5 >= 0) ? $5 : 256 + $5;
413 op[3] = imm_data8($9);
417 op[1] = reg_indirect($3) * 16 + arith_opcode;
418 op[2] = ($5 >= 0) ? $5 : 256 + $5;
419 op[3] = msb(imm_data16($9));
420 op[4] = lsb(imm_data16($9));
426 op[1] = reg_indirect($3) * 16 + arith_opcode;
427 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
428 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
429 op[4] = imm_data8($9);
433 op[1] = reg_indirect($3) * 16 + arith_opcode;
434 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
435 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
436 op[4] = msb(imm_data16($9));
437 op[5] = lsb(imm_data16($9));
441 | arith_inst expr ',' '#' expr {
442 size = find_size0(inst_size);
446 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
447 op[2] = lsb(direct_addr($2));
448 op[3] = imm_data8($5);
452 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
453 op[2] = lsb(direct_addr($2));
454 op[3] = msb(imm_data16($5));
455 op[4] = lsb(imm_data16($5));
459 /* the next 8 instructions are MOV, but because MOV was used in the */
460 /* arith_inst group, it will cause a shift/reduce conflict if used */
461 /* directly below... so we're forced to use arith_inst and then */
462 /* add a bit of code to make sure it was MOV and not the other ones */
464 | arith_inst '[' REG '+' ']' ',' '[' REG '+' ']' {
465 /* this addr mode is only valid for MOV */
466 if (arith_opcode != 8) error("Addr mode only valid for MOV (1)");
467 size = find_size0(inst_size);
469 op[0] = 0x90 + size * 8;
470 op[1] = reg_indirect($3) * 16 + reg_indirect($8);
472 | arith_inst expr ',' '[' REG ']' {
473 /* this addr mode is only valid for MOV */
474 if (arith_opcode != 8) error("Addr mode only valid for MOV (2)");
475 size = find_size0(inst_size);
477 op[0] = 0xA0 + size * 8;
478 op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
479 op[2] = lsb(direct_addr($2));
481 | arith_inst '[' REG ']' ',' expr {
482 /* this addr mode is only valid for MOV */
483 if (arith_opcode != 8) error("Addr mode only valid for MOV (3)");
484 size = find_size0(inst_size);
486 op[0] = 0xA0 + size * 8;
487 op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
488 op[2] = lsb(direct_addr($6));
490 | arith_inst expr ',' expr {
491 /* this addr mode is only valid for MOV */
492 if (arith_opcode != 8) error("Addr mode only valid for MOV (4)");
493 size = find_size0(inst_size);
495 op[0] = 0x97 + size * 8;
496 op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
497 op[2] = lsb(direct_addr($2));
498 op[3] = lsb(direct_addr($4));
500 | arith_inst REG ',' USP {
501 /* this addr mode is only valid for MOV */
502 if (arith_opcode != 8) error("Addr mode only valid for MOV (5)");
505 op[1] = reg($2) * 16 + 15;
507 | arith_inst USP ',' REG {
508 /* this addr mode is only valid for MOV */
509 if (arith_opcode != 8) error("Addr mode only valid for MOV (6)");
512 op[1] = reg($4) * 16 + 15;
514 | arith_inst C ',' bit {
515 /* this addr mode is only valid for MOV */
516 if (arith_opcode != 8) error("Addr mode only valid for MOV (7)");
519 op[1] = 0x20 + msb(bit_addr($4));
520 op[2] = lsb(bit_addr($4));
522 | arith_inst bit ',' C {
523 /* this addr mode is only valid for MOV */
524 if (arith_opcode != 8) error("Addr mode only valid for MOV (8)");
527 op[1] = 0x30 + msb(bit_addr($2));
528 op[2] = lsb(bit_addr($2));
531 | MOVC REG ',' '[' REG '+' ']' {
532 size = find_size1(inst_size, $2);
534 op[0] = 0x80 + size * 8;
535 op[1] = reg($2) * 16 + reg_indirect($5);
537 | MOVC A ',' '[' A '+' DPTR ']' {
542 | MOVC A ',' '[' A '+' PC ']' {
547 | MOVX REG ',' '[' REG ']' {
549 size = find_size1(inst_size, $2);
550 op[0] = 0xA7 + size * 8;
551 op[1] = reg($2) * 16 + reg_indirect($5);
553 | MOVX '[' REG ']' ',' REG {
555 size = find_size1(inst_size, $6);
556 op[0] = 0xA7 + size * 8;
557 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
561 size = find_size2(inst_size, $2, $4);
562 op[0] = 0x60 + size * 8;
563 op[1] = reg($2) * 16 + reg($4);
565 | XCH REG ',' '[' REG ']' {
567 size = find_size1(inst_size, $2);
568 op[0] = 0x50 + size * 8;
569 op[1] = reg($2) * 16 + reg_indirect($5);
573 size = find_size1(inst_size, $2);
574 op[0] = 0xA0 + size * 8;
575 op[1] = reg($2) * 16 + msb(direct_addr($4));
576 op[2] = lsb(direct_addr($4));
578 | short_data_inst REG ',' '#' expr {
580 size = find_size1(inst_size, $2);
581 op[0] = short_opcode + size * 8 + 1;
582 op[1] = reg($2) * 16 + imm_data4_signed($5);
584 | short_data_inst '[' REG ']' ',' '#' expr {
586 size = find_size0(inst_size);
587 op[0] = short_opcode + size * 8 + 2;
588 op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
590 | short_data_inst '[' REG '+' ']' ',' '#' expr {
592 size = find_size0(inst_size);
593 op[0] = short_opcode + size * 8 + 3;
594 op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
596 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
597 size = find_size0(inst_size);
598 if ($5 >= -128 && $5 <= 127) {
600 op[0] = short_opcode + size * 8 + 4;
601 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
602 op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
605 op[0] = short_opcode + size * 8 + 5;
606 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
607 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
608 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
611 | short_data_inst expr ',' '#' expr {
613 size = find_size0(inst_size);
614 op[0] = short_opcode + size * 8 + 6;
615 op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
616 op[2] = lsb(direct_addr($2));
624 op[1] = 0x40 + msb(bit_addr($4));
625 op[2] = lsb(bit_addr($4));
627 | ANL C ',' '/' bit {
630 op[1] = 0x50 + msb(bit_addr($5));
631 op[2] = lsb(bit_addr($5));
637 op[1] = 0x60 + msb(bit_addr($4));
638 op[2] = lsb(bit_addr($4));
640 | ORL C ',' '/' bit {
643 op[1] = 0x70 + msb(bit_addr($5));
644 op[2] = lsb(bit_addr($5));
649 op[1] = msb(bit_addr($2));
650 op[2] = lsb(bit_addr($2));
655 op[1] = 0x10 + msb(bit_addr($2));
656 op[2] = lsb(bit_addr($2));
658 | logical_shift_inst REG ',' REG {
659 size = find_size1(inst_size, $2);
660 if (find_size_reg($4) != SIZE8)
661 error("Second register in logical shift must be byte size");
663 op[0] = shift_reg_opcode;
665 case SIZE8: op[0] += 0; break;
666 case SIZE16: op[0] += 8; break;
667 case SIZE32: op[0] += 12; break;
669 op[1] = reg($2) * 16 + reg($4);
671 | logical_shift_inst REG ',' '#' expr {
672 size = find_size1(inst_size, $2);
674 if (shift_imm_opcode == -1)
675 error("NORM may not use a constant");
676 op[0] = shift_imm_opcode;
678 case SIZE8: op[0] += 0; break;
679 case SIZE16: op[0] += 8; break;
680 case SIZE32: op[0] += 12; break;
685 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
688 op[1] = (reg($2) / 2) * 32 + imm_data5_unsigned($5);
701 op[1] = 0x30 + imm_data4_unsigned($3);
705 size = find_size1(inst_size, $2);
706 op[0] = 0x90 + size * 8;
707 op[1] = reg($2) * 16 + 10;
712 op[1] = reg($2) * 16 + 8;
716 size = find_size1(inst_size, $2);
717 op[0] = 0x90 + size * 8;
718 op[1] = reg($2) * 16 + 11;
722 size = find_size1(inst_size, $2);
723 op[0] = 0x90 + size * 8;
724 op[1] = reg($2) * 16 + 9;
727 | rotate_inst REG ',' '#' expr {
729 size = find_size1(inst_size, $2);
730 op[0] = rotate_opcode + size * 8;
731 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
735 | LEA REG ',' REG '+' expr {
736 if ($6 >= -128 && $6 <= 127) {
739 op[1] = reg($2) * 16 + reg_indirect($4);
740 op[2] = ($6 >= 0) ? $6 : 256 + $6;
743 op[1] = reg($2) * 16 + reg_indirect($4);
744 op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
745 op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
750 size = find_size0(inst_size);
751 op[0] = msb(stack_addr_opcode) + size * 8;
752 op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
753 op[2] = lsb(direct_addr($2));
757 if (inst_size != UNKNOWN && find_size0(inst_size) != rlist_size)
758 error("inst specifies different size than registers used");
759 op[0] = stack_reg_opcode + rlist_reg_bank * 64 + rlist_size * 8;
760 op[1] = rlist_bitmask;
766 size = find_size2(inst_size, $2, $4);
768 op[1] = reg($2) * 16 + reg($4);
772 size = find_size2(inst_size, $2, $4);
775 op[1] = reg($2) * 16 + reg($4);
778 op[1] = reg($2) * 16 + reg($4);
781 | MUL REG ',' '#' expr {
783 size = find_size1(inst_size, $2);
786 op[2] = msb(imm_data16($5));
787 op[3] = lsb(imm_data16($5));
789 | MULU REG ',' '#' expr {
790 size = find_size2(inst_size, $2, $4);
794 op[1] = reg($2) * 16;
795 op[2] = imm_data8($5);
799 op[1] = reg($2) * 16;
800 op[2] = msb(imm_data16($5));
801 op[3] = lsb(imm_data16($5));
806 size = find_size2(inst_size, $2, $4);
809 error("Singed DIV can't be 8 bit size"); break;
812 op[1] = reg($2) * 16 + reg($4);
816 op[1] = (reg($2) / 2) * 32 + reg($4);
822 size = find_size2(inst_size, $2, $4);
826 op[1] = reg($2) * 16 + reg($4);
830 op[1] = reg($2) * 16 + reg($4);
834 op[1] = (reg($2) / 2) * 32 + reg($4);
838 | DIV REG ',' '#' expr {
839 size = find_size1(inst_size, $2);
842 error("Singed DIV can't be 8 bit size"); break;
846 op[1] = reg($2) * 16 + 11;
847 op[2] = imm_data8($5);
852 op[1] = (reg($2) / 2) * 32 + 9;
853 op[2] = msb(imm_data16($5));
854 op[3] = lsb(imm_data16($5));
858 | DIVU REG ',' '#' expr {
859 size = find_size1(inst_size, $2);
864 op[1] = reg($2) * 16 + 1;
865 op[2] = imm_data8($5);
870 op[1] = reg($2) * 16 + 3;
871 op[2] = imm_data8($5);
876 op[1] = (reg($2) / 2) * 32 + 1;
877 op[2] = msb(imm_data16($5));
878 op[3] = lsb(imm_data16($5));
890 op[1] = ($2 >> 8) & 255;
892 op[3] = ($2 >> 16) & 255;
897 op[1] = ($2 >> 8) & 255;
899 op[3] = ($2 >> 16) & 255;
904 op[1] = 0x70 + reg_indirect($3);
906 | JMP '[' A '+' DPTR ']' {
911 | JMP '[' '[' REG '+' ']' ']' {
914 op[1] = 0x60 + reg_indirect($4);
920 op[1] = msb(rel16(mem + $$, $2));
921 op[2] = lsb(rel16(mem + $$, $2));
927 op[1] = msb(rel16(mem + $$, $2));
928 op[2] = lsb(rel16(mem + $$, $2));
930 | branch_inst jmpaddr {
932 op[0] = branch_opcode;
933 op[1] = rel8(mem + $$, $2);
935 | CJNE REG ',' expr ',' jmpaddr {
937 size = find_size1(inst_size, $2);
938 op[0] = 0xE2 + size * 8;
939 op[1] = reg($2) * 16 + msb(direct_addr($4));
940 op[2] = lsb(direct_addr($4));
941 op[3] = rel8(mem + $$, $6);
943 | CJNE REG ',' '#' expr ',' jmpaddr {
944 size = find_size1(inst_size, $2);
948 op[1] = reg($2) * 16;
949 op[2] = rel8(mem + $$, $7);
950 op[3] = imm_data8($5);
954 op[1] = reg($2) * 16;
955 op[2] = rel8(mem + $$, $7);
956 op[3] = msb(imm_data16($5));
957 op[4] = lsb(imm_data16($5));
960 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
961 size = find_size0(inst_size);
965 op[1] = reg_indirect($3) * 16 + 8;
966 op[2] = rel8(mem + $$, $9);
967 op[3] = imm_data8($7);
971 op[1] = reg_indirect($3) * 16 + 8;
972 op[2] = rel8(mem + $$, $9);
973 op[3] = msb(imm_data16($7));
974 op[4] = lsb(imm_data16($7));
977 | DJNZ REG ',' jmpaddr {
979 size = find_size1(inst_size, $2);
980 op[0] = 0x87 + size * 8;
981 op[1] = reg($2) * 16 + 8;
982 op[2] = rel8(mem + $$, $4);
986 | DJNZ expr ',' jmpaddr {
988 size = find_size0(inst_size);
989 op[0] = 0xE2 + size * 8;
990 op[1] = msb(direct_addr($2)) + 8;
991 op[2] = lsb(direct_addr($2));
992 op[3] = rel8(mem + $$, $4);
995 | JB bit ',' jmpaddr {
998 op[1] = 0x80 + msb(bit_addr($2));
999 op[2] = lsb(bit_addr($2));
1000 op[3] = rel8(mem + $$, $4);
1003 | JBC bit ',' jmpaddr {
1006 op[1] = 0xC0 + msb(bit_addr($2));
1007 op[2] = lsb(bit_addr($2));
1008 op[3] = rel8(mem + $$, $4);
1011 | JNB bit ',' jmpaddr {
1014 op[1] = 0xA0 + msb(bit_addr($2));
1015 op[2] = lsb(bit_addr($2));
1016 op[3] = rel8(mem + $$, $4);
1021 ADD {arith_opcode = 0;}
1022 | ADDC {arith_opcode = 1;}
1023 | AND {arith_opcode = 5;}
1024 | CMP {arith_opcode = 4;}
1025 | MOV {arith_opcode = 8;}
1026 | OR {arith_opcode = 6;}
1027 | SUB {arith_opcode = 2;}
1028 | SUBB {arith_opcode = 3;}
1029 | XOR {arith_opcode = 7;}
1032 ADDS {short_opcode = 0xA0;}
1033 | MOVS {short_opcode = 0xB0;}
1036 ASL {shift_reg_opcode = 0xC1; shift_imm_opcode = 0xD1;}
1037 | ASR {shift_reg_opcode = 0xC2; shift_imm_opcode = 0xD2;}
1038 | LSR {shift_reg_opcode = 0xC0; shift_imm_opcode = 0xD0;}
1039 | NORM {shift_reg_opcode = 0xC3; shift_imm_opcode = -1;}
1042 RL {rotate_opcode = 0xD3;}
1043 | RLC {rotate_opcode = 0xD7;}
1044 | RR {rotate_opcode = 0xD0;}
1045 | RRC {rotate_opcode = 0xD7;}
1048 POP {stack_addr_opcode = 0x8710; stack_reg_opcode = 0x27;}
1049 | POPU {stack_addr_opcode = 0x8700; stack_reg_opcode = 0x37;}
1050 | PUSH {stack_addr_opcode = 0x8730; stack_reg_opcode = 0x07;}
1051 | PUSHU {stack_addr_opcode = 0x8720; stack_reg_opcode = 0x17;}
1054 BKPT {num_op = 1; opcode0 = 255; opcode1 = 0;}
1055 | NOP {num_op = 1; opcode0 = 0; opcode1 = 0;}
1056 | RESET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x10;}
1057 | RET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x80;}
1058 | RETI {num_op = 2; opcode0 = 0xD6; opcode1 = 0x90;}
1061 BCC {branch_opcode = 0xF0;}
1062 | BCS {branch_opcode = 0xF1;}
1063 | BEQ {branch_opcode = 0xF3;}
1064 | BG {branch_opcode = 0xF8;}
1065 | BGE {branch_opcode = 0xFA;}
1066 | BGT {branch_opcode = 0xFC;}
1067 | BL {branch_opcode = 0xF9;}
1068 | BLE {branch_opcode = 0xFD;}
1069 | BLT {branch_opcode = 0xFB;}
1070 | BMI {branch_opcode = 0xF7;}
1071 | BNE {branch_opcode = 0xF2;}
1072 | BNV {branch_opcode = 0xF4;}
1073 | BOV {branch_opcode = 0xF5;}
1074 | BPL {branch_opcode = 0xF6;}
1075 | BR {branch_opcode = 0xFE;}
1076 | JZ {branch_opcode = 0xEC;}
1077 | JNZ {branch_opcode = 0xEE;}
1084 int reg(int reg_spec)
1086 return reg_spec & 15;
1089 int reg_indirect(int reg_spec)
1091 if (reg_spec & BYTE_REG)
1092 error("Imdirect addressing may not use byte registers");
1093 if ((reg_spec & 15) > 7)
1094 error("Only R0 through R7 may be used for indirect addr");
1095 return reg_spec & 7;
1098 int rel16(int pos, int dest)
1102 if (!p3) return 0; /* don't bother unless writing code */
1103 if (dest & (BRANCH_SPACING - 1))
1104 error("Attempt to jump to unaligned location");
1105 pos &= ~(BRANCH_SPACING - 1);
1106 rel = (dest - pos) / BRANCH_SPACING;
1107 if (rel < -32768 || rel > 32767)
1108 error("Attempt to jump out of 16 bit relative range");
1109 if (rel < 0) rel += 65536;
1113 int rel8(int pos, int dest)
1117 if (!p3) return 0; /* don't bother unless writing code */
1118 if (dest & (BRANCH_SPACING - 1))
1119 error("Attempt to jump to unaligned location");
1120 pos &= ~(BRANCH_SPACING - 1);
1121 rel = (dest - pos) / BRANCH_SPACING;
1122 if (rel < -128 || rel > 127)
1123 error("Attempt to jump out of 16 bit relative range");
1124 if (rel < 0) rel += 256;
1130 return (value >> 8) & 255;
1138 int direct_addr(int value)
1142 if (value < 0 || value > 2047) {
1143 sprintf(buf, "illegal value (%d) for direct address", value);
1149 int imm_data4_signed(int value)
1151 if (value < -8 || value > 7)
1152 error("illegal 4 bit (signed) value");
1153 if (value >= 0) return value;
1154 else return (16 + value);
1157 int imm_data4_unsigned(int value)
1159 if (value < 0 || value > 15)
1160 error("illegal 4 bit (unsigned) value");
1164 int imm_data5_unsigned(int value)
1166 if (value < 0 || value > 31)
1167 error("illegal 5 bit (unsigned) value");
1171 int imm_data8(int value)
1173 if (value < -128 || value > 255)
1174 error("illegal 8 bit value");
1175 if (value >= 0) return value;
1176 else return (256 + value);
1179 int imm_data16(int value)
1181 if (value < -32728 || value > 65535)
1182 error("illegal 16 bit value");
1183 if (value >= 0) return value;
1184 else return (65536 + value);
1187 int bit_addr(int value)
1189 if (value < 0 || value > 1023) {
1190 fprintf(stderr, "bad bit addr of 0x%04X (%d dec)\n",
1192 error("illegal bit address");
1198 int find_size_reg(int op1spec)
1200 int op1size=UNKNOWN;
1202 if (op1spec & BYTE_REG) op1size = SIZE8;
1203 if (op1spec & WORD_REG) op1size = SIZE16;
1204 if (op1size == UNKNOWN)
1205 error("Register without implied size");
1209 int find_size0(int isize)
1211 if (isize == UNKNOWN)
1212 error("Can't determine data size from instruction");
1216 int find_size1(int isize, int op1spec)
1218 int op1size=UNKNOWN;
1220 if (op1spec & BYTE_REG) op1size = SIZE8;
1221 if (op1spec & WORD_REG) op1size = SIZE16;
1222 if (op1size == UNKNOWN)
1223 error("Register without implied size");
1225 if (isize == SIZE32 && op1size == SIZE16) return SIZE32;
1226 if (isize == UNKNOWN) return op1size;
1228 if (isize != op1size)
1229 error("data size of register and inst don't agree");
1234 int find_size2(int isize, int op1spec, int op2spec)
1236 int op1size=UNKNOWN, op2size=UNKNOWN;
1238 if (op1spec & BYTE_REG) op1size = SIZE8;
1239 if (op1spec & WORD_REG) op1size = SIZE16;
1240 if (op1size == UNKNOWN)
1241 error("Register without implied size");
1242 if (op2spec & BYTE_REG) op2size = SIZE8;
1243 if (op2spec & WORD_REG) op2size = SIZE16;
1244 if (op1size == UNKNOWN)
1245 error("Register without implied size");
1247 if (op1size != op2size)
1248 error("data sizes of two registers don't agree");
1249 if (isize == UNKNOWN) return op1size;
1251 if (isize != op1size)
1252 error("data size of registers and inst don't agree");
1258 int yyerror(char *s)
1260 if (yytext[0] >= 32) {
1261 fprintf(stderr, "%s near '%s', line %d\n",
1264 fprintf(stderr, "%s, line %d\n", s, lineno - 1);
1274 void fatal_error(char *s)