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);
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;}
185 linesymbol: normal_or_bit_symbol {
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();
194 normal_or_bit_symbol: WORD {$$ = $1;}
198 | bytes ',' byte_element
201 op[db_count] = $1 & 255;
202 if (++db_count >= MAX_DB) {
203 error("too many bytes, use two DB");
208 for(i=1; i < strlen(yytext)-1; i++) {
209 op[db_count++] = yytext[i];
210 if (db_count >= MAX_DB) {
211 error("too many bytes, use two DB");
217 dw_directive: DW {dw_count = 0;}
219 words: words ',' word_element
223 op[dw_count] = $1 & 255;
224 op[dw_count+1] = ($1 >> 8) & 255;
226 if (dw_count >= MAX_DB) {
227 error("too many bytes, use two DW");
235 strcpy(symbol_name, lex_sym_name);
238 bitsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
239 | BIT { strcpy(symbol_name, lex_sym_name); }
242 regsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
243 | REG { strcpy(symbol_name, lex_sym_name); }
246 if ($3 < 0 || $3 > 7) {
247 /* only 8 bits in a byte */
248 error("Only eight bits in a byte");
250 $$ = 100000; /* should really check $1 is valid */
251 if ($1 >= 0x20 && $1 <= 0x3F) {
254 if ($1 >= 0x400 && $1 <= 0x43F) {
255 $$ = ($1 - 0x400) * 8 + $3 + 0x200;
260 if (find_size_reg($1) == SIZE8) {
261 if ($3 < 0 || $3 > 7)
262 error("byte reg has only 8 bits");
263 $$ = reg($1) * 8 + $3;
265 if (find_size_reg($1) == SIZE16) {
266 if ($3 < 0 || $3 > 15)
267 error("word reg has only 16 bits");
268 $$ = reg($1) * 16 + $3;
275 if (p1) build_target_list(lex_sym_name);
278 if ($1 & 1) error("Jump target must be aligned");
283 expr: value {$$ = $1;}
284 | expr '+' expr {$$ = $1 + $3;}
285 | expr '-' expr {$$ = $1 - $3;}
286 | expr '*' expr {$$ = $1 * $3;}
287 | expr '/' expr {$$ = $1 / $3;}
288 | expr '&' expr {$$ = $1 & $3;}
289 | expr '|' expr {$$ = $1 | $3;}
290 | expr '^' expr {$$ = $1 ^ $3;}
291 | expr RSHIFT expr {$$ = $1 >> $3;}
292 | expr LSHIFT expr {$$ = $1 << $3;}
293 | '-' expr %prec UNARY {$$ = $2 * -1;}
294 | '+' expr %prec UNARY {$$ = $2;}
295 | '(' expr ')' {$$ = $2;}
296 | LOW expr %prec UNARY {$$ = $2 & 255;}
297 | HIGH expr %prec UNARY {$$ = ($2 >> 8) & 255;}
300 value: NUMBER {$$ = $1;}
302 | WORD {$$ = $1; strcpy(expr_var, yytext);}
306 rlist_bitmask = bitmask[reg($1) % 8];
307 rlist_reg_bank = (reg($1) / 8) ? 1 : 0;
308 rlist_size = find_size_reg($1);
311 rlist_bitmask |= bitmask[reg($1) % 8];
312 if (rlist_reg_bank != ((reg($1) / 8) ? 1 : 0))
313 error("register list may not mix 0-7/8-15 regs");
314 if (rlist_size != find_size_reg($1))
315 error("register list may not mix 8/16 bit registers");
324 arith_inst REG ',' REG {
326 size = find_size2(inst_size, $2, $4);
327 op[0] = arith_opcode * 16 + size * 8 + 1;
328 op[1] = reg($2) * 16 + reg($4);
330 | arith_inst REG ',' '[' REG ']' {
332 size = find_size1(inst_size, $2);
333 op[0] = arith_opcode * 16 + size * 8 + 2;
334 op[1] = reg($2) * 16 + reg_indirect($5);
336 | arith_inst '[' REG ']' ',' REG {
338 size = find_size1(inst_size, $6);
339 op[0] = arith_opcode * 16 + size * 8 + 2;
340 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
342 | arith_inst REG ',' '[' REG '+' expr ']' {
343 size = find_size1(inst_size, $2);
344 if ($7 >= -128 && $7 <= 127) {
346 op[0] = arith_opcode * 16 + size * 8 + 4;
347 op[1] = reg($2) * 16 + reg_indirect($5);
348 op[2] = ($7 >= 0) ? $7 : 256 + $7;
351 op[0] = arith_opcode * 16 + size * 8 + 5;
352 op[1] = reg($2) * 16 + reg_indirect($5);
353 op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
354 op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
357 | arith_inst '[' REG '+' expr ']' ',' REG {
358 size = find_size1(inst_size, $8);
359 if ($5 >= -128 && $5 <= 127) {
361 op[0] = arith_opcode * 16 + size * 8 + 4;
362 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
363 op[2] = ($5 >= 0) ? $5 : 256 + $5;
366 op[0] = arith_opcode * 16 + size * 8 + 5;
367 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
368 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
369 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
372 | arith_inst REG ',' '[' REG '+' ']' {
374 size = find_size1(inst_size, $2);
375 op[0] = arith_opcode * 16 + size * 8 + 3;
376 op[1] = reg($2) * 16 + reg_indirect($5);
378 | arith_inst '[' REG '+' ']' ',' REG {
380 size = find_size1(inst_size, $7);
381 op[0] = arith_opcode * 16 + size * 8 + 3;
382 op[1] = reg($7) * 16 + 8 + reg_indirect($3);
384 | arith_inst expr ',' REG {
386 size = find_size1(inst_size, $4);
387 op[0] = arith_opcode * 16 + size * 8 + 6;
388 op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
389 op[2] = lsb(direct_addr($2));
391 | arith_inst REG ',' expr {
393 size = find_size1(inst_size, $2);
394 op[0] = arith_opcode * 16 + size * 8 + 6;
395 op[1] = reg($2) * 16 + msb(direct_addr($4));
396 op[2] = lsb(direct_addr($4));
398 | arith_inst REG ',' '#' expr {
399 size = find_size1(inst_size, $2);
403 op[1] = reg($2) * 16 + arith_opcode;
404 op[2] = imm_data8($5);
408 op[1] = reg($2) * 16 + arith_opcode;
409 op[2] = msb(imm_data16($5));
410 op[3] = lsb(imm_data16($5));
413 | arith_inst '[' REG ']' ',' '#' expr {
414 size = find_size0(inst_size);
418 op[1] = reg_indirect($3) * 16 + arith_opcode;
419 op[2] = imm_data8($7);
423 op[1] = reg_indirect($3) * 16 + arith_opcode;
424 op[2] = msb(imm_data16($7));
425 op[3] = lsb(imm_data16($7));
428 | arith_inst '[' REG '+' ']' ',' '#' expr {
429 size = find_size0(inst_size);
433 op[1] = reg_indirect($3) * 16 + arith_opcode;
434 op[2] = imm_data8($8);
438 op[1] = reg_indirect($3) * 16 + arith_opcode;
439 op[2] = msb(imm_data16($8));
440 op[3] = lsb(imm_data16($8));
443 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
444 size = find_size0(inst_size);
445 if ($5 >= -128 && $5 <= 127) {
449 op[1] = reg_indirect($3) * 16 + arith_opcode;
450 op[2] = ($5 >= 0) ? $5 : 256 + $5;
451 op[3] = imm_data8($9);
455 op[1] = reg_indirect($3) * 16 + arith_opcode;
456 op[2] = ($5 >= 0) ? $5 : 256 + $5;
457 op[3] = msb(imm_data16($9));
458 op[4] = lsb(imm_data16($9));
464 op[1] = reg_indirect($3) * 16 + arith_opcode;
465 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
466 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
467 op[4] = imm_data8($9);
471 op[1] = reg_indirect($3) * 16 + arith_opcode;
472 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
473 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
474 op[4] = msb(imm_data16($9));
475 op[5] = lsb(imm_data16($9));
479 | arith_inst expr ',' '#' expr {
480 size = find_size0(inst_size);
484 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
485 op[2] = lsb(direct_addr($2));
486 op[3] = imm_data8($5);
490 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
491 op[2] = lsb(direct_addr($2));
492 op[3] = msb(imm_data16($5));
493 op[4] = lsb(imm_data16($5));
497 /* the next 8 instructions are MOV, but because MOV was used in the */
498 /* arith_inst group, it will cause a shift/reduce conflict if used */
499 /* directly below... so we're forced to use arith_inst and then */
500 /* add a bit of code to make sure it was MOV and not the other ones */
502 | arith_inst '[' REG '+' ']' ',' '[' REG '+' ']' {
503 /* this addr mode is only valid for MOV */
504 if (arith_opcode != 8) error("Addr mode only valid for MOV (1)");
505 size = find_size0(inst_size);
507 op[0] = 0x90 + size * 8;
508 op[1] = reg_indirect($3) * 16 + reg_indirect($8);
510 | arith_inst expr ',' '[' REG ']' {
511 /* this addr mode is only valid for MOV */
512 if (arith_opcode != 8) error("Addr mode only valid for MOV (2)");
513 size = find_size0(inst_size);
515 op[0] = 0xA0 + size * 8;
516 op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
517 op[2] = lsb(direct_addr($2));
519 | arith_inst '[' REG ']' ',' expr {
520 /* this addr mode is only valid for MOV */
521 if (arith_opcode != 8) error("Addr mode only valid for MOV (3)");
522 size = find_size0(inst_size);
524 op[0] = 0xA0 + size * 8;
525 op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
526 op[2] = lsb(direct_addr($6));
528 | arith_inst expr ',' expr {
529 /* this addr mode is only valid for MOV */
530 if (arith_opcode != 8) error("Addr mode only valid for MOV (4)");
531 size = find_size0(inst_size);
533 op[0] = 0x97 + size * 8;
534 op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
535 op[2] = lsb(direct_addr($2));
536 op[3] = lsb(direct_addr($4));
538 | arith_inst REG ',' USP {
539 /* this addr mode is only valid for MOV */
540 if (arith_opcode != 8) error("Addr mode only valid for MOV (5)");
543 op[1] = reg($2) * 16 + 15;
545 | arith_inst USP ',' REG {
546 /* this addr mode is only valid for MOV */
547 if (arith_opcode != 8) error("Addr mode only valid for MOV (6)");
550 op[1] = reg($4) * 16 + 15;
552 | arith_inst C ',' bit {
553 /* this addr mode is only valid for MOV */
554 if (arith_opcode != 8) error("Addr mode only valid for MOV (7)");
557 op[1] = 0x20 + msb(bit_addr($4));
558 op[2] = lsb(bit_addr($4));
560 | arith_inst bit ',' C {
561 /* this addr mode is only valid for MOV */
562 if (arith_opcode != 8) error("Addr mode only valid for MOV (8)");
565 op[1] = 0x30 + msb(bit_addr($2));
566 op[2] = lsb(bit_addr($2));
569 | MOVC REG ',' '[' REG '+' ']' {
570 size = find_size1(inst_size, $2);
572 op[0] = 0x80 + size * 8;
573 op[1] = reg($2) * 16 + reg_indirect($5);
575 | MOVC A ',' '[' A '+' DPTR ']' {
580 | MOVC A ',' '[' A '+' PC ']' {
585 | MOVX REG ',' '[' REG ']' {
587 size = find_size1(inst_size, $2);
588 op[0] = 0xA7 + size * 8;
589 op[1] = reg($2) * 16 + reg_indirect($5);
591 | MOVX '[' REG ']' ',' REG {
593 size = find_size1(inst_size, $6);
594 op[0] = 0xA7 + size * 8;
595 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
599 size = find_size2(inst_size, $2, $4);
600 op[0] = 0x60 + size * 8;
601 op[1] = reg($2) * 16 + reg($4);
603 | XCH REG ',' '[' REG ']' {
605 size = find_size1(inst_size, $2);
606 op[0] = 0x50 + size * 8;
607 op[1] = reg($2) * 16 + reg_indirect($5);
611 size = find_size1(inst_size, $2);
612 op[0] = 0xA0 + size * 8;
613 op[1] = reg($2) * 16 + msb(direct_addr($4));
614 op[2] = lsb(direct_addr($4));
616 | short_data_inst REG ',' '#' expr {
618 size = find_size1(inst_size, $2);
619 op[0] = short_opcode + size * 8 + 1;
620 op[1] = reg($2) * 16 + imm_data4_signed($5);
622 | short_data_inst '[' REG ']' ',' '#' expr {
624 size = find_size0(inst_size);
625 op[0] = short_opcode + size * 8 + 2;
626 op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
628 | short_data_inst '[' REG '+' ']' ',' '#' expr {
630 size = find_size0(inst_size);
631 op[0] = short_opcode + size * 8 + 3;
632 op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
634 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
635 size = find_size0(inst_size);
636 if ($5 >= -128 && $5 <= 127) {
638 op[0] = short_opcode + size * 8 + 4;
639 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
640 op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
643 op[0] = short_opcode + size * 8 + 5;
644 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
645 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
646 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
649 | short_data_inst expr ',' '#' expr {
651 size = find_size0(inst_size);
652 op[0] = short_opcode + size * 8 + 6;
653 op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
654 op[2] = lsb(direct_addr($2));
662 op[1] = 0x40 + msb(bit_addr($4));
663 op[2] = lsb(bit_addr($4));
665 | ANL C ',' '/' bit {
668 op[1] = 0x50 + msb(bit_addr($5));
669 op[2] = lsb(bit_addr($5));
675 op[1] = 0x60 + msb(bit_addr($4));
676 op[2] = lsb(bit_addr($4));
678 | ORL C ',' '/' bit {
681 op[1] = 0x70 + msb(bit_addr($5));
682 op[2] = lsb(bit_addr($5));
687 op[1] = msb(bit_addr($2));
688 op[2] = lsb(bit_addr($2));
693 op[1] = 0x10 + msb(bit_addr($2));
694 op[2] = lsb(bit_addr($2));
696 | logical_shift_inst REG ',' REG {
697 size = find_size1(inst_size, $2);
698 if (find_size_reg($4) != SIZE8)
699 error("Second register in logical shift must be byte size");
701 op[0] = shift_reg_opcode;
703 case SIZE8: op[0] += 0; break;
704 case SIZE16: op[0] += 8; break;
705 case SIZE32: op[0] += 12; break;
707 op[1] = reg($2) * 16 + reg($4);
709 | logical_shift_inst REG ',' '#' expr {
710 size = find_size1(inst_size, $2);
712 if (shift_imm_opcode == -1)
713 error("NORM may not use a constant");
714 op[0] = shift_imm_opcode;
716 case SIZE8: op[0] += 0; break;
717 case SIZE16: op[0] += 8; break;
718 case SIZE32: op[0] += 12; break;
723 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
726 op[1] = (reg($2) / 2) * 32 + imm_data5_unsigned($5);
739 op[1] = 0x30 + imm_data4_unsigned($3);
743 size = find_size1(inst_size, $2);
744 op[0] = 0x90 + size * 8;
745 op[1] = reg($2) * 16 + 10;
750 op[1] = reg($2) * 16 + 8;
754 size = find_size1(inst_size, $2);
755 op[0] = 0x90 + size * 8;
756 op[1] = reg($2) * 16 + 11;
760 size = find_size1(inst_size, $2);
761 op[0] = 0x90 + size * 8;
762 op[1] = reg($2) * 16 + 9;
765 | rotate_inst REG ',' '#' expr {
767 size = find_size1(inst_size, $2);
768 op[0] = rotate_opcode + size * 8;
769 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
773 | LEA REG ',' REG '+' expr {
774 if ($6 >= -128 && $6 <= 127) {
777 op[1] = reg($2) * 16 + reg_indirect($4);
778 op[2] = ($6 >= 0) ? $6 : 256 + $6;
781 op[1] = reg($2) * 16 + reg_indirect($4);
782 op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
783 op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
788 size = find_size0(inst_size);
789 op[0] = msb(stack_addr_opcode) + size * 8;
790 op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
791 op[2] = lsb(direct_addr($2));
795 if (inst_size != UNKNOWN && find_size0(inst_size) != rlist_size)
796 error("inst specifies different size than registers used");
797 op[0] = stack_reg_opcode + rlist_reg_bank * 64 + rlist_size * 8;
798 op[1] = rlist_bitmask;
804 size = find_size2(inst_size, $2, $4);
806 op[1] = reg($2) * 16 + reg($4);
810 size = find_size2(inst_size, $2, $4);
813 op[1] = reg($2) * 16 + reg($4);
816 op[1] = reg($2) * 16 + reg($4);
819 | MUL REG ',' '#' expr {
821 size = find_size1(inst_size, $2);
824 op[2] = msb(imm_data16($5));
825 op[3] = lsb(imm_data16($5));
827 | MULU REG ',' '#' expr {
828 size = find_size2(inst_size, $2, $4);
832 op[1] = reg($2) * 16;
833 op[2] = imm_data8($5);
837 op[1] = reg($2) * 16;
838 op[2] = msb(imm_data16($5));
839 op[3] = lsb(imm_data16($5));
844 size = find_size2(inst_size, $2, $4);
847 error("Singed DIV can't be 8 bit size"); break;
850 op[1] = reg($2) * 16 + reg($4);
854 op[1] = (reg($2) / 2) * 32 + reg($4);
860 size = find_size2(inst_size, $2, $4);
864 op[1] = reg($2) * 16 + reg($4);
868 op[1] = reg($2) * 16 + reg($4);
872 op[1] = (reg($2) / 2) * 32 + reg($4);
876 | DIV REG ',' '#' expr {
877 size = find_size1(inst_size, $2);
880 error("Singed DIV can't be 8 bit size"); break;
884 op[1] = reg($2) * 16 + 11;
885 op[2] = imm_data8($5);
890 op[1] = (reg($2) / 2) * 32 + 9;
891 op[2] = msb(imm_data16($5));
892 op[3] = lsb(imm_data16($5));
896 | DIVU REG ',' '#' expr {
897 size = find_size1(inst_size, $2);
902 op[1] = reg($2) * 16 + 1;
903 op[2] = imm_data8($5);
908 op[1] = reg($2) * 16 + 3;
909 op[2] = imm_data8($5);
914 op[1] = (reg($2) / 2) * 32 + 1;
915 op[2] = msb(imm_data16($5));
916 op[3] = lsb(imm_data16($5));
928 op[1] = ($2 >> 8) & 255;
930 op[3] = ($2 >> 16) & 255;
935 op[1] = ($2 >> 8) & 255;
937 op[3] = ($2 >> 16) & 255;
942 op[1] = 0x70 + reg_indirect($3);
944 | JMP '[' A '+' DPTR ']' {
949 | JMP '[' '[' REG '+' ']' ']' {
952 op[1] = 0x60 + reg_indirect($4);
958 op[1] = msb(rel16(MEM_POS + $$, $2));
959 op[2] = lsb(rel16(MEM_POS + $$, $2));
965 op[1] = msb(rel16(MEM_POS + $$, $2));
966 op[2] = lsb(rel16(MEM_POS + $$, $2));
968 | branch_inst jmpaddr {
970 op[0] = branch_opcode;
971 op[1] = rel8(MEM_POS + $$, $2);
973 | CJNE REG ',' expr ',' jmpaddr {
975 size = find_size1(inst_size, $2);
976 op[0] = 0xE2 + size * 8;
977 op[1] = reg($2) * 16 + msb(direct_addr($4));
978 op[2] = lsb(direct_addr($4));
979 op[3] = rel8(MEM_POS + $$, $6);
981 | CJNE REG ',' '#' expr ',' jmpaddr {
982 size = find_size1(inst_size, $2);
986 op[1] = reg($2) * 16;
987 op[2] = rel8(MEM_POS + $$, $7);
988 op[3] = imm_data8($5);
992 op[1] = reg($2) * 16;
993 op[2] = rel8(MEM_POS + $$, $7);
994 op[3] = msb(imm_data16($5));
995 op[4] = lsb(imm_data16($5));
998 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
999 size = find_size0(inst_size);
1000 if (size == SIZE8) {
1003 op[1] = reg_indirect($3) * 16 + 8;
1004 op[2] = rel8(MEM_POS + $$, $9);
1005 op[3] = imm_data8($7);
1009 op[1] = reg_indirect($3) * 16 + 8;
1010 op[2] = rel8(MEM_POS + $$, $9);
1011 op[3] = msb(imm_data16($7));
1012 op[4] = lsb(imm_data16($7));
1015 | DJNZ REG ',' jmpaddr {
1017 size = find_size1(inst_size, $2);
1018 op[0] = 0x87 + size * 8;
1019 op[1] = reg($2) * 16 + 8;
1020 op[2] = rel8(MEM_POS + $$, $4);
1024 | DJNZ expr ',' jmpaddr {
1026 size = find_size0(inst_size);
1027 op[0] = 0xE2 + size * 8;
1028 op[1] = msb(direct_addr($2)) + 8;
1029 op[2] = lsb(direct_addr($2));
1030 op[3] = rel8(MEM_POS + $$, $4);
1033 | JB bit ',' jmpaddr {
1036 op[1] = 0x80 + msb(bit_addr($2));
1037 op[2] = lsb(bit_addr($2));
1038 op[3] = rel8(MEM_POS + $$, $4);
1041 | JBC bit ',' jmpaddr {
1044 op[1] = 0xC0 + msb(bit_addr($2));
1045 op[2] = lsb(bit_addr($2));
1046 op[3] = rel8(MEM_POS + $$, $4);
1049 | JNB bit ',' jmpaddr {
1052 op[1] = 0xA0 + msb(bit_addr($2));
1053 op[2] = lsb(bit_addr($2));
1054 op[3] = rel8(MEM_POS + $$, $4);
1059 ADD {arith_opcode = 0;}
1060 | ADDC {arith_opcode = 1;}
1061 | AND {arith_opcode = 5;}
1062 | CMP {arith_opcode = 4;}
1063 | MOV {arith_opcode = 8;}
1064 | OR {arith_opcode = 6;}
1065 | SUB {arith_opcode = 2;}
1066 | SUBB {arith_opcode = 3;}
1067 | XOR {arith_opcode = 7;}
1070 ADDS {short_opcode = 0xA0;}
1071 | MOVS {short_opcode = 0xB0;}
1074 ASL {shift_reg_opcode = 0xC1; shift_imm_opcode = 0xD1;}
1075 | ASR {shift_reg_opcode = 0xC2; shift_imm_opcode = 0xD2;}
1076 | LSR {shift_reg_opcode = 0xC0; shift_imm_opcode = 0xD0;}
1077 | NORM {shift_reg_opcode = 0xC3; shift_imm_opcode = -1;}
1080 RL {rotate_opcode = 0xD3;}
1081 | RLC {rotate_opcode = 0xD7;}
1082 | RR {rotate_opcode = 0xD0;}
1083 | RRC {rotate_opcode = 0xD7;}
1086 POP {stack_addr_opcode = 0x8710; stack_reg_opcode = 0x27;}
1087 | POPU {stack_addr_opcode = 0x8700; stack_reg_opcode = 0x37;}
1088 | PUSH {stack_addr_opcode = 0x8730; stack_reg_opcode = 0x07;}
1089 | PUSHU {stack_addr_opcode = 0x8720; stack_reg_opcode = 0x17;}
1092 BKPT {num_op = 1; opcode0 = 255; opcode1 = 0;}
1093 | NOP {num_op = 1; opcode0 = 0; opcode1 = 0;}
1094 | RESET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x10;}
1095 | RET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x80;}
1096 | RETI {num_op = 2; opcode0 = 0xD6; opcode1 = 0x90;}
1099 BCC {branch_opcode = 0xF0;}
1100 | BCS {branch_opcode = 0xF1;}
1101 | BEQ {branch_opcode = 0xF3;}
1102 | BG {branch_opcode = 0xF8;}
1103 | BGE {branch_opcode = 0xFA;}
1104 | BGT {branch_opcode = 0xFC;}
1105 | BL {branch_opcode = 0xF9;}
1106 | BLE {branch_opcode = 0xFD;}
1107 | BLT {branch_opcode = 0xFB;}
1108 | BMI {branch_opcode = 0xF7;}
1109 | BNE {branch_opcode = 0xF2;}
1110 | BNV {branch_opcode = 0xF4;}
1111 | BOV {branch_opcode = 0xF5;}
1112 | BPL {branch_opcode = 0xF6;}
1113 | BR {branch_opcode = 0xFE;}
1114 | JZ {branch_opcode = 0xEC;}
1115 | JNZ {branch_opcode = 0xEE;}
1122 int reg(int reg_spec)
1124 return reg_spec & 15;
1127 int reg_indirect(int reg_spec)
1129 if (reg_spec & BYTE_REG)
1130 error("Imdirect addressing may not use byte registers");
1131 if ((reg_spec & 15) > 7)
1132 error("Only R0 through R7 may be used for indirect addr");
1133 return reg_spec & 7;
1136 int rel16(int pos, int dest)
1140 if (!p3) return 0; /* don't bother unless writing code */
1141 if (dest & (BRANCH_SPACING - 1))
1142 error("Attempt to jump to unaligned location");
1143 pos &= ~(BRANCH_SPACING - 1);
1144 rel = (dest - pos) / BRANCH_SPACING;
1145 if (rel < -32768 || rel > 32767)
1146 error("Attempt to jump out of 16 bit relative range");
1147 if (rel < 0) rel += 65536;
1151 int rel8(int pos, int dest)
1155 if (!p3) return 0; /* don't bother unless writing code */
1156 if (dest & (BRANCH_SPACING - 1))
1157 error("Attempt to jump to unaligned location");
1158 pos &= ~(BRANCH_SPACING - 1);
1159 rel = (dest - pos) / BRANCH_SPACING;
1160 if (rel < -128 || rel > 127)
1161 error("Attempt to jump out of 16 bit relative range");
1162 if (rel < 0) rel += 256;
1168 return (value >> 8) & 255;
1176 int direct_addr(int value)
1180 if (value < 0 || value > 2047) {
1181 sprintf(buf, "illegal value (%d) for direct address", value);
1187 int imm_data4_signed(int value)
1189 if (value < -8 || value > 7)
1190 error("illegal 4 bit (signed) value");
1191 if (value >= 0) return value;
1192 else return (16 + value);
1195 int imm_data4_unsigned(int value)
1197 if (value < 0 || value > 15)
1198 error("illegal 4 bit (unsigned) value");
1202 int imm_data5_unsigned(int value)
1204 if (value < 0 || value > 31)
1205 error("illegal 5 bit (unsigned) value");
1209 int imm_data8(int value)
1211 if (value < -128 || value > 255)
1212 error("illegal 8 bit value");
1213 if (value >= 0) return value;
1214 else return (256 + value);
1217 int imm_data16(int value)
1219 if (value < -32728 || value > 65535)
1220 error("illegal 16 bit value");
1221 if (value >= 0) return value;
1222 else return (65536 + value);
1225 int bit_addr(int value)
1227 if (value < 0 || value > 1023) {
1228 fprintf(stderr, "bad bit addr of 0x%04X (%d dec)\n",
1230 error("illegal bit address");
1236 int find_size_reg(int op1spec)
1238 int op1size=UNKNOWN;
1240 if (op1spec & BYTE_REG) op1size = SIZE8;
1241 if (op1spec & WORD_REG) op1size = SIZE16;
1242 if (op1size == UNKNOWN)
1243 error("Register without implied size");
1247 int find_size0(int isize)
1249 if (isize == UNKNOWN)
1250 error("Can't determine data size from instruction");
1254 int find_size1(int isize, int op1spec)
1256 int op1size=UNKNOWN;
1258 if (op1spec & BYTE_REG) op1size = SIZE8;
1259 if (op1spec & WORD_REG) op1size = SIZE16;
1260 if (op1size == UNKNOWN)
1261 error("Register without implied size");
1263 if (isize == SIZE32 && op1size == SIZE16) return SIZE32;
1264 if (isize == UNKNOWN) return op1size;
1266 if (isize != op1size)
1267 error("data size of register and inst don't agree");
1272 int find_size2(int isize, int op1spec, int op2spec)
1274 int op1size=UNKNOWN, op2size=UNKNOWN;
1276 if (op1spec & BYTE_REG) op1size = SIZE8;
1277 if (op1spec & WORD_REG) op1size = SIZE16;
1278 if (op1size == UNKNOWN)
1279 error("Register without implied size");
1280 if (op2spec & BYTE_REG) op2size = SIZE8;
1281 if (op2spec & WORD_REG) op2size = SIZE16;
1282 if (op1size == UNKNOWN)
1283 error("Register without implied size");
1285 if (op1size != op2size)
1286 error("data sizes of two registers don't agree");
1287 if (isize == UNKNOWN) return op1size;
1289 if (isize != op1size)
1290 error("data size of registers and inst don't agree");
1296 int yyerror(char *s)
1298 if (yytext[0] >= 32) {
1299 fprintf(stderr, "%s near '%s', line %d\n",
1302 fprintf(stderr, "%s, line %d\n", s, lineno - 1);
1312 void fatal_error(char *s)