struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / xa51 / xa_rasm.y
blobbe78e10153fb81b2bf23d71a31aba2d14ad666c2
1 %{
2 /* xa_rasm.y - This file is part of Paul's XA51 Assembler
4 Copyright 1997,2002 Paul Stoffregen (paul at pjrc dot com)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 /* Author contact: paul@pjrc.com */
21 /* parser for the 51-XA assembler, Paul Stoffregen, July 1997 */
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
26 #include "xa_main.h"
28 int op[MAX_DB];
29 int size;
30 int inst_size;
31 int arith_opcode, short_opcode, num_op, opcode0, opcode1;
32 int shift_imm_opcode, shift_reg_opcode, rotate_opcode;
33 int stack_addr_opcode, stack_reg_opcode, branch_opcode;
34 int rlist_reg_bank, rlist_bitmask, rlist_size;
35 int db_count, dw_count, i;
36 char symbol_name[MAX_SYMBOL], base_symbol_name[MAX_SYMBOL]={'\0'};
37 char operand[2][MAX_SYMBOL]={{'\0'},{'\0'}};
39 extern char lex_sym_name[];
40 extern int yylex();
42 extern void yyrestart(FILE *new_file);
43 extern char * disasm(int byte, int memory_location);
44 void error(char *s);
47 void RELOC_FF(unsigned where, unsigned pc, short rl) {
48 // pc = PC of the next instruction
49 struct symbol *sym;
50 if ((sym=findSymbol(operand[0]))) {
51 if (sym->mode=='X' || sym->area!=current_area) {
52 sprintf (rel_line[rl], "R %04x REL_FF %s %04x",
53 where, sym->name, pc);
58 void RELOC_FFFF(unsigned where, unsigned pc, short rl) {
59 struct symbol *sym;
60 if ((sym=findSymbol(operand[0]))) {
61 if (sym->mode=='X' || sym->area!=current_area) {
62 sprintf (rel_line[rl], "R %04x REL_FFFF %s %04x",
63 where, sym->name, pc);
68 void RELOC_ABS_0F(unsigned where, int seq) {
69 struct symbol *sym;
70 if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
71 sprintf (rel_line[seq], "R %04x ABS_0F %s 0", where, sym->name);
75 void RELOC_BIT_03FF(unsigned where, int seq) {
76 struct symbol *sym;
77 if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
78 sprintf (rel_line[seq], "R %04x BIT_03FF %s 0", where, sym->name);
82 void RELOC_DIR_07FF(unsigned where, int seq) {
83 struct symbol *sym;
84 if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
85 sprintf (rel_line[seq], "R %04x DIR_07FF %s 0", where, sym->name);
89 void RELOC_DIR_70FF(unsigned where, int seq) {
90 struct symbol *sym;
91 if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
92 sprintf (rel_line[seq], "R %04x DIR_70FF %s 0", where, sym->name);
96 void RELOC_ABS_FF(unsigned where, int seq) {
97 struct symbol *sym;
98 if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
99 sprintf (rel_line[seq], "R %04x DIR_FF %s 0", where, sym->name);
103 void RELOC_ABS_FFFF(unsigned where, int seq) {
104 struct symbol *sym;
105 if ((sym=findSymbol(operand[seq]))) {
106 switch (sym->mode) {
107 case 'A':
108 // sfr or sbit, already in instruction
109 case '=':
110 // equat, already in instruction
111 break;
112 case 'X':
113 // external reference
114 sprintf (rel_line[seq], "R %04x ABS_FFFF %s %04x", where, sym->name,
115 sym->value);
116 break;
117 case 'R':
118 // absolute in current segment
119 sprintf (rel_line[seq], "R %04x ABS_PC PC %04x", where, sym->value);
120 break;
121 default:
122 fprintf (stderr, "unknown ABS_FFFF\n");
123 exit (1);
128 void RELOC_DIR_0700FF(unsigned where, int seq) {
129 struct symbol *sym;
130 if ((sym=findSymbol(operand[seq])) && sym->mode!='A') {
131 sprintf (rel_line[seq], "R %04x ABS_0700FF %s 0", where, sym->name);
137 %token ADD ADDC ADDS AND ANL ASL ASR BCC BCS BEQ BG BGE BGT
138 %token BKPT BL BLE BLT BMI BNE BNV BOV BPL BR CALL CJNE CLR
139 %token CMP CPL DA DIV DIVU DJNZ FCALL FJMP JB JBC JMP JNB JNZ
140 %token JZ LEA LSR MOV MOVC MOVS MOVX MUL MULU NEG NOP NORM
141 %token OR ORL POP POPU PUSH PUSHU RESET RET RETI RL RLC RR RRC
142 %token SETB SEXT SUB SUBB TRAP XCH XOR
143 %token REG DPTR PC A C USP
144 %token WORD BIT NUMBER CHAR STRING EOL LOCAL_LABEL
145 %token ORG EQU SFR DB DW BITDEF REGDEF LOW HIGH
146 %token RSHIFT LSHIFT
147 %token AREA AREA_NAME AREA_DESC DS
148 %token MODULE GLOBL
150 %left '&' '|' '^'
151 %left RSHIFT LSHIFT
152 %left '+' '-'
153 %left '*' '/'
154 %nonassoc UNARY
157 all: line
158 | line all;
160 line: linesymbol ':' linenosym {
161 if (p1) {
162 build_sym_list(symbol_name);
163 if (current_area == AREA_BSEG) {
164 mk_bit(symbol_name, current_area);
167 if (p1 || p2) assign_value(symbol_name, MEM_POS, 'R');
168 MEM_POS += $3;
170 | linenosym {
171 if (!is_abs(symbol_name)) {
172 MEM_POS += $1;
176 linenosym: directive EOL {
177 if (p3) out(op, $1);
178 $$ = $1;
180 | instruction EOL {
181 if (p3) out(op, $1);
182 $$ = $1;
184 | EOL {
185 if (p3) out(NULL, 0);
186 $$ = 0;
188 | error EOL /* try to recover from any parse error */
191 directive: '.' ORG expr {
192 MEM_POS = $3;
193 $$ = 0;
195 | ORG expr {
196 MEM_POS = $2;
197 $$ = 0;
199 | '.' EQU symbol ',' expr {
200 if (p1) build_sym_list(symbol_name);
201 if (p1 || p2) assign_value(symbol_name, $5, '?');
202 $$ = 0;
204 | symbol '=' expr {
205 if (p1) build_sym_list(symbol_name);
206 if (p1 || p2) assign_value(symbol_name, $3, '=');
208 | symbol SFR expr {
209 if (p1) build_sym_list(symbol_name);
210 if (p1 || p2) assign_value(symbol_name, $3, 'A');
211 if (p1 || p2) mk_sfr(symbol_name);
212 $$ = 0;
214 | '.' BITDEF bitsymbol ',' bit {
215 if (p1) {
216 build_sym_list(symbol_name);
217 mk_bit(symbol_name, 0);
219 if (p1 || p2) assign_value(symbol_name, $5, '?');
220 $$ = 0;
222 | bitsymbol BITDEF bit {
223 if (p1) {
224 build_sym_list(symbol_name);
225 mk_bit(symbol_name, 0);
227 if (p1 || p2) assign_value(symbol_name, $3, '?');
228 $$ = 0;
230 | bitsymbol BITDEF expr {
231 if (p1) {
232 build_sym_list(symbol_name);
233 mk_bit(symbol_name, 0);
235 if (p1 || p2) assign_value(symbol_name, $3, 'A');
236 $$ = 0;
238 | '.' REGDEF regsymbol ',' REG {
239 if (p1) {
240 build_sym_list(symbol_name);
241 mk_reg(symbol_name);
243 if (p1 || p2) assign_value(symbol_name, $5, '?');
244 $$ = 0;
246 | regsymbol REGDEF REG {
247 if (p1) {
248 build_sym_list(symbol_name);
249 mk_reg(symbol_name);
251 if (p1 || p2) assign_value(symbol_name, $3, '?');
252 $$ = 0;
255 | '.' db_directive bytes {
256 $$ = db_count;
258 | '.' dw_directive words {
259 $$ = dw_count;
261 | '.' AREA AREA_NAME AREA_DESC {
262 if ($3 < 0 || $3 > NUM_AREAS) {
263 error("Illegal Area Directive");
265 symbol_name[0] = '\0';
266 current_area = $3;
267 $$ = 0;
269 | '.' MODULE WORD {
270 /* ignore module definition */
271 $$ = 0;
273 | '.' GLOBL WORD {
274 mk_global(lex_sym_name);
275 /* ignore global symbol declaration */
276 $$ = 0;
278 | '.' GLOBL bit {
279 /* ignore bit symbol declaration */
280 $$ = 0;
282 | '.' DS expr {
283 /* todo: if CSEG, emit some filler bytes */
284 $$ = $3;
287 db_directive: DB {db_count = 0;}
290 linesymbol: normal_or_bit_symbol {
291 strcpy(symbol_name, lex_sym_name);
292 if (!strchr(lex_sym_name, ':')) {
293 /* non-local label, remember base name */
294 strcpy(base_symbol_name, lex_sym_name);
296 if (is_target(symbol_name)) pad_with_nop();
299 normal_or_bit_symbol: WORD {$$ = $1;}
300 | BIT {$$ = $1;}
302 bytes: byte_element
303 | bytes ',' byte_element
305 byte_element: expr {
306 op[db_count] = $1 & 255;
307 if (++db_count >= MAX_DB) {
308 error("too many bytes, use two DB");
309 db_count--;
312 | STRING {
313 for(i=1; i < strlen(yytext)-1; i++) {
314 op[db_count++] = yytext[i];
315 if (db_count >= MAX_DB) {
316 error("too many bytes, use two DB");
317 db_count--;
322 dw_directive: DW {dw_count = 0;}
324 words: words ',' word_element
325 | word_element
327 word_element: expr {
328 op[dw_count] = $1 & 255;
329 op[dw_count+1] = ($1 >> 8) & 255;
330 dw_count += 2;
331 if (dw_count >= MAX_DB) {
332 error("too many bytes, use two DW");
333 db_count -= 2;
339 symbol: WORD {
340 strcpy(symbol_name, lex_sym_name);
343 bitsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
344 | BIT { strcpy(symbol_name, lex_sym_name); }
347 regsymbol: WORD { strcpy(symbol_name, lex_sym_name); }
348 | REG { strcpy(symbol_name, lex_sym_name); }
350 bit: expr '.' expr {
351 if ($3 < 0 || $3 > 7) {
352 /* only 8 bits in a byte */
353 error("Only eight bits in a byte");
355 $$ = 100000; /* should really check $1 is valid */
356 if ($1 >= 0x20 && $1 <= 0x3F) {
357 $$ = $1 * 8 + $3;
359 if ($1 >= 0x400 && $1 <= 0x43F) {
360 $$ = ($1 - 0x400) * 8 + $3 + 0x200;
363 | REG '.' expr {
364 $$ = 100000;
365 if (find_size_reg($1) == SIZE8) {
366 if ($3 < 0 || $3 > 7)
367 error("byte reg has only 8 bits");
368 $$ = reg($1) * 8 + $3;
370 if (find_size_reg($1) == SIZE16) {
371 if ($3 < 0 || $3 > 15)
372 error("word reg has only 16 bits");
373 $$ = reg($1) * 16 + $3;
376 | BIT {$$ = $1;}
378 jmpaddr: WORD {
379 $$ = $1;
380 if (p1) build_target_list(lex_sym_name);
382 | NUMBER {
383 if ($1 & 1) error("Jump target must be aligned");
384 $$ = $1;
388 expr: value {$$ = $1;}
389 | expr '+' expr {$$ = $1 + $3;}
390 | expr '-' expr {$$ = $1 - $3;}
391 | expr '*' expr {$$ = $1 * $3;}
392 | expr '/' expr {$$ = $1 / $3;}
393 | expr '&' expr {$$ = $1 & $3;}
394 | expr '|' expr {$$ = $1 | $3;}
395 | expr '^' expr {$$ = $1 ^ $3;}
396 | expr RSHIFT expr {$$ = $1 >> $3;}
397 | expr LSHIFT expr {$$ = $1 << $3;}
398 | '-' expr %prec UNARY {$$ = $2 * -1;}
399 | '+' expr %prec UNARY {$$ = $2;}
400 | '(' expr ')' {$$ = $2;}
401 | LOW expr %prec UNARY {$$ = $2 & 255;}
402 | HIGH expr %prec UNARY {$$ = ($2 >> 8) & 255;}
405 value: NUMBER {$$ = $1;}
406 | CHAR {$$ = $1;}
407 | WORD { $$ = $1;}
409 rlist: REG {
410 rlist_bitmask = 1<<(reg($1) % 8);
411 rlist_reg_bank = (reg($1) / 8) ? 1 : 0;
412 rlist_size = find_size_reg($1);
414 | REG ',' rlist {
415 rlist_bitmask |= 1<<(reg($1) % 8);
416 if (rlist_reg_bank != ((reg($1) / 8) ? 1 : 0))
417 error("register list may not mix 0-7/8-15 regs");
418 if (rlist_size != find_size_reg($1))
419 error("register list may not mix 8/16 bit registers");
426 instruction:
428 arith_inst REG ',' REG {
429 $$ = 2;
430 size = find_size2(inst_size, $2, $4);
431 op[0] = arith_opcode * 16 + size * 8 + 1;
432 op[1] = reg($2) * 16 + reg($4);
434 | arith_inst REG ',' '[' REG ']' {
435 $$ = 2;
436 size = find_size1(inst_size, $2);
437 op[0] = arith_opcode * 16 + size * 8 + 2;
438 op[1] = reg($2) * 16 + reg_indirect($5);
440 | arith_inst '[' REG ']' ',' REG {
441 $$ = 2;
442 size = find_size1(inst_size, $6);
443 op[0] = arith_opcode * 16 + size * 8 + 2;
444 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
446 | arith_inst REG ',' '[' REG '+' expr ']' {
447 size = find_size1(inst_size, $2);
448 if ($7 >= -128 && $7 <= 127) {
449 $$ = 3;
450 op[0] = arith_opcode * 16 + size * 8 + 4;
451 op[1] = reg($2) * 16 + reg_indirect($5);
452 op[2] = ($7 >= 0) ? $7 : 256 + $7;
453 RELOC_ABS_FF(MEM_POS+2,0);
454 } else {
455 $$ = 4;
456 op[0] = arith_opcode * 16 + size * 8 + 5;
457 op[1] = reg($2) * 16 + reg_indirect($5);
458 op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
459 op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
460 RELOC_ABS_FFFF(MEM_POS+2,0);
463 | arith_inst '[' REG '+' expr ']' ',' REG {
464 size = find_size1(inst_size, $8);
465 if ($5 >= -128 && $5 <= 127) {
466 $$ = 3;
467 op[0] = arith_opcode * 16 + size * 8 + 4;
468 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
469 op[2] = ($5 >= 0) ? $5 : 256 + $5;
470 RELOC_ABS_FF(MEM_POS+2,0);
471 } else {
472 $$ = 4;
473 op[0] = arith_opcode * 16 + size * 8 + 5;
474 op[1] = reg($8) * 16 + 8 + reg_indirect($3);
475 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
476 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
477 RELOC_ABS_FFFF(MEM_POS+2,0);
480 | arith_inst REG ',' '[' REG '+' ']' {
481 $$ = 2;
482 size = find_size1(inst_size, $2);
483 op[0] = arith_opcode * 16 + size * 8 + 3;
484 op[1] = reg($2) * 16 + reg_indirect($5);
486 | arith_inst '[' REG '+' ']' ',' REG {
487 $$ = 2;
488 size = find_size1(inst_size, $7);
489 op[0] = arith_opcode * 16 + size * 8 + 3;
490 op[1] = reg($7) * 16 + 8 + reg_indirect($3);
492 | arith_inst WORD ',' REG {
493 $$ = 3;
494 size = find_size1(inst_size, $4);
495 op[0] = arith_opcode * 16 + size * 8 + 6;
496 op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
497 op[2] = lsb(direct_addr($2));
498 RELOC_DIR_07FF(MEM_POS+1, 0);
500 | arith_inst REG ',' WORD {
501 $$ = 3;
502 size = find_size1(inst_size, $2);
503 op[0] = arith_opcode * 16 + size * 8 + 6;
504 op[1] = reg($2) * 16 + msb(direct_addr($4));
505 op[2] = lsb(direct_addr($4));
506 RELOC_DIR_07FF(MEM_POS+1, 0);
508 | arith_inst REG ',' '#' expr {
509 size = find_size1(inst_size, $2);
510 if (size == SIZE8) {
511 $$ = 3;
512 op[0] = 0x91;
513 op[1] = reg($2) * 16 + arith_opcode;
514 op[2] = imm_data8($5);
515 RELOC_ABS_FF(MEM_POS+2, 0);
516 } else {
517 $$ = 4;
518 op[0] = 0x99;
519 op[1] = reg($2) * 16 + arith_opcode;
520 op[2] = msb(imm_data16($5));
521 op[3] = lsb(imm_data16($5));
522 RELOC_ABS_FFFF (MEM_POS+2, 0);
525 | arith_inst '[' REG ']' ',' '#' expr {
526 size = find_size0(inst_size);
527 if (size == SIZE8) {
528 $$ = 3;
529 op[0] = 0x92;
530 op[1] = reg_indirect($3) * 16 + arith_opcode;
531 op[2] = imm_data8($7);
532 RELOC_ABS_FF(MEM_POS+2, 0);
533 } else {
534 $$ = 4;
535 op[0] = 0x9A;
536 op[1] = reg_indirect($3) * 16 + arith_opcode;
537 op[2] = msb(imm_data16($7));
538 op[3] = lsb(imm_data16($7));
539 RELOC_ABS_FFFF (MEM_POS+2, 0);
542 | arith_inst '[' REG '+' ']' ',' '#' expr {
543 size = find_size0(inst_size);
544 if (size == SIZE8) {
545 $$ = 3;
546 op[0] = 0x93;
547 op[1] = reg_indirect($3) * 16 + arith_opcode;
548 op[2] = imm_data8($8);
549 RELOC_ABS_FF(MEM_POS+2, 0);
550 } else {
551 $$ = 4;
552 op[0] = 0x9B;
553 op[1] = reg_indirect($3) * 16 + arith_opcode;
554 op[2] = msb(imm_data16($8));
555 op[3] = lsb(imm_data16($8));
556 RELOC_ABS_FFFF (MEM_POS+2, 0);
559 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
560 size = find_size0(inst_size);
561 if ($5 >= -128 && $5 <= 127) {
562 if (size == SIZE8) {
563 $$ = 4;
564 op[0] = 0x94;
565 op[1] = reg_indirect($3) * 16 + arith_opcode;
566 op[2] = ($5 >= 0) ? $5 : 256 + $5;
567 op[3] = imm_data8($9);
568 RELOC_ABS_FF(MEM_POS+2, 0);
569 RELOC_ABS_FF(MEM_POS+3, 1);
570 } else {
571 $$ = 5;
572 op[0] = 0x9C;
573 op[1] = reg_indirect($3) * 16 + arith_opcode;
574 op[2] = ($5 >= 0) ? $5 : 256 + $5;
575 op[3] = msb(imm_data16($9));
576 op[4] = lsb(imm_data16($9));
577 RELOC_ABS_FF(MEM_POS+2, 0);
578 RELOC_ABS_FFFF(MEM_POS+3, 1);
580 } else {
581 if (size == SIZE8) {
582 $$ = 5;
583 op[0] = 0x95;
584 op[1] = reg_indirect($3) * 16 + arith_opcode;
585 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
586 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
587 op[4] = imm_data8($9);
588 RELOC_ABS_FFFF(MEM_POS+2,0);
589 RELOC_ABS_FF(MEM_POS+4,1);
590 } else {
591 $$ = 6;
592 op[0] = 0x9D;
593 op[1] = reg_indirect($3) * 16 + arith_opcode;
594 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
595 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
596 op[4] = msb(imm_data16($9));
597 op[5] = lsb(imm_data16($9));
598 RELOC_ABS_FFFF(MEM_POS+2, 0);
599 RELOC_ABS_FFFF(MEM_POS+4, 1);
603 | arith_inst WORD ',' '#' expr {
604 size = find_size0(inst_size);
605 if (size == SIZE8) {
606 $$ = 4;
607 op[0] = 0x96;
608 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
609 op[2] = lsb(direct_addr($2));
610 op[3] = imm_data8($5);
611 RELOC_DIR_70FF(MEM_POS+1,0);
612 RELOC_ABS_FF(MEM_POS+3,1);
613 } else {
614 $$ = 5;
615 op[0] = 0x9E;
616 op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
617 op[2] = lsb(direct_addr($2));
618 op[3] = msb(imm_data16($5));
619 op[4] = lsb(imm_data16($5));
620 RELOC_DIR_70FF(MEM_POS+1,0);
621 RELOC_ABS_FFFF (MEM_POS+3,1);
625 /* the next 8 instructions are MOV, but because MOV was used in the */
626 /* arith_inst group, it will cause a shift/reduce conflict if used */
627 /* directly below... so we're forced to use arith_inst and then */
628 /* add a bit of code to make sure it was MOV and not the other ones */
630 | arith_inst '[' REG '+' ']' ',' '[' REG '+' ']' {
631 /* this addr mode is only valid for MOV */
632 if (arith_opcode != 8) error("Addr mode only valid for MOV (1)");
633 size = find_size0(inst_size);
634 $$ = 2;
635 op[0] = 0x90 + size * 8;
636 op[1] = reg_indirect($3) * 16 + reg_indirect($8);
638 | arith_inst WORD ',' '[' REG ']' {
639 /* this addr mode is only valid for MOV */
640 if (arith_opcode != 8) error("Addr mode only valid for MOV (2)");
641 size = find_size0(inst_size);
642 $$ = 3;
643 op[0] = 0xA0 + size * 8;
644 op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
645 op[2] = lsb(direct_addr($2));
646 RELOC_DIR_07FF(MEM_POS+1, 0);
648 | arith_inst '[' REG ']' ',' WORD {
649 /* this addr mode is only valid for MOV */
650 if (arith_opcode != 8) error("Addr mode only valid for MOV (3)");
651 size = find_size0(inst_size);
652 $$ = 3;
653 op[0] = 0xA0 + size * 8;
654 op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
655 op[2] = lsb(direct_addr($6));
656 RELOC_DIR_07FF(MEM_POS+1, 0);
658 | arith_inst WORD ',' WORD {
659 /* this addr mode is only valid for MOV */
660 if (arith_opcode != 8) error("Addr mode only valid for MOV (4)");
661 size = find_size0(inst_size);
662 $$ = 4;
663 op[0] = 0x97 + size * 8;
664 op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
665 op[2] = lsb(direct_addr($2));
666 op[3] = lsb(direct_addr($4));
667 RELOC_DIR_70FF(MEM_POS+1, 0);
668 RELOC_DIR_0700FF(MEM_POS+1, 1);
670 | arith_inst REG ',' USP {
671 /* this addr mode is only valid for MOV */
672 if (arith_opcode != 8) error("Addr mode only valid for MOV (5)");
673 $$ = 2;
674 op[0] = 0x90;
675 op[1] = reg($2) * 16 + 15;
677 | arith_inst USP ',' REG {
678 /* this addr mode is only valid for MOV */
679 if (arith_opcode != 8) error("Addr mode only valid for MOV (6)");
680 $$ = 2;
681 op[0] = 0x98;
682 op[1] = reg($4) * 16 + 15;
684 | arith_inst C ',' bit {
685 /* this addr mode is only valid for MOV */
686 if (arith_opcode != 8) error("Addr mode only valid for MOV (7)");
687 $$ = 3;
688 op[0] = 0x08;
689 op[1] = 0x20 + msb(bit_addr($4));
690 op[2] = lsb(bit_addr($4));
691 RELOC_BIT_03FF(MEM_POS+1, 0);
693 | arith_inst bit ',' C {
694 /* this addr mode is only valid for MOV */
695 if (arith_opcode != 8) error("Addr mode only valid for MOV (8)");
696 $$ = 3;
697 op[0] = 0x08;
698 op[1] = 0x30 + msb(bit_addr($2));
699 op[2] = lsb(bit_addr($2));
700 RELOC_BIT_03FF(MEM_POS+1, 0);
703 | MOVC REG ',' '[' REG '+' ']' {
704 size = find_size1(inst_size, $2);
705 $$ = 2;
706 op[0] = 0x80 + size * 8;
707 op[1] = reg($2) * 16 + reg_indirect($5);
709 | MOVC A ',' '[' A '+' DPTR ']' {
710 $$ = 2;
711 op[0] = 0x90;
712 op[1] = 0x4E;
714 | MOVC A ',' '[' A '+' PC ']' {
715 $$ = 2;
716 op[0] = 0x90;
717 op[1] = 0x4C;
719 | MOVX REG ',' '[' REG ']' {
720 $$ = 2;
721 size = find_size1(inst_size, $2);
722 op[0] = 0xA7 + size * 8;
723 op[1] = reg($2) * 16 + reg_indirect($5);
725 | MOVX '[' REG ']' ',' REG {
726 $$ = 2;
727 size = find_size1(inst_size, $6);
728 op[0] = 0xA7 + size * 8;
729 op[1] = reg($6) * 16 + 8 + reg_indirect($3);
731 | XCH REG ',' REG {
732 $$ = 2;
733 size = find_size2(inst_size, $2, $4);
734 op[0] = 0x60 + size * 8;
735 op[1] = reg($2) * 16 + reg($4);
737 | XCH REG ',' '[' REG ']' {
738 $$ = 2;
739 size = find_size1(inst_size, $2);
740 op[0] = 0x50 + size * 8;
741 op[1] = reg($2) * 16 + reg_indirect($5);
743 | XCH REG ',' WORD {
744 $$ = 3;
745 size = find_size1(inst_size, $2);
746 op[0] = 0xA0 + size * 8;
747 op[1] = reg($2) * 16 + msb(direct_addr($4));
748 op[2] = lsb(direct_addr($4));
749 RELOC_DIR_07FF(MEM_POS+1, 0);
751 | short_data_inst REG ',' '#' expr {
752 $$ = 2;
753 size = find_size1(inst_size, $2);
754 op[0] = short_opcode + size * 8 + 1;
755 op[1] = reg($2) * 16 + imm_data4_signed($5);
756 RELOC_ABS_0F(MEM_POS+1, 0);
758 | short_data_inst '[' REG ']' ',' '#' expr {
759 $$ = 2;
760 size = find_size0(inst_size);
761 op[0] = short_opcode + size * 8 + 2;
762 op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
763 RELOC_ABS_0F(MEM_POS+1, 0);
765 | short_data_inst '[' REG '+' ']' ',' '#' expr {
766 $$ = 2;
767 size = find_size0(inst_size);
768 op[0] = short_opcode + size * 8 + 3;
769 op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
770 RELOC_ABS_0F(MEM_POS+1, 0);
772 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
773 size = find_size0(inst_size);
774 if ($5 >= -128 && $5 <= 127) {
775 $$ = 3;
776 op[0] = short_opcode + size * 8 + 4;
777 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
778 op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
779 RELOC_ABS_0F(MEM_POS+1, 1);
780 RELOC_ABS_FF(MEM_POS+2, 0);
781 } else {
782 $$ = 4;
783 op[0] = short_opcode + size * 8 + 5;
784 op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
785 op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
786 op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
787 RELOC_ABS_0F(MEM_POS+1, 1);
788 RELOC_ABS_FFFF(MEM_POS+2, 0);
791 | short_data_inst expr ',' '#' expr {
792 $$ = 3;
793 size = find_size0(inst_size);
794 op[0] = short_opcode + size * 8 + 6;
795 op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
796 op[2] = lsb(direct_addr($2));
797 RELOC_ABS_0F(MEM_POS+1, 0);
799 | ANL C ',' bit {
800 $$ = 3;
801 op[0] = 0x08;
802 op[1] = 0x40 + msb(bit_addr($4));
803 op[2] = lsb(bit_addr($4));
804 RELOC_BIT_03FF(MEM_POS+1, 0);
806 | ANL C ',' '/' bit {
807 $$ = 3;
808 op[0] = 0x08;
809 op[1] = 0x50 + msb(bit_addr($5));
810 op[2] = lsb(bit_addr($5));
811 RELOC_BIT_03FF(MEM_POS+1, 0);
814 | ORL C ',' bit {
815 $$ = 3;
816 op[0] = 0x08;
817 op[1] = 0x60 + msb(bit_addr($4));
818 op[2] = lsb(bit_addr($4));
819 RELOC_BIT_03FF(MEM_POS+1, 0);
821 | ORL C ',' '/' bit {
822 $$ = 3;
823 op[0] = 0x08;
824 op[1] = 0x70 + msb(bit_addr($5));
825 op[2] = lsb(bit_addr($5));
826 RELOC_BIT_03FF(MEM_POS+1, 0);
828 | CLR bit {
829 $$ = 3;
830 op[0] = 0x08;
831 op[1] = msb(bit_addr($2));
832 op[2] = lsb(bit_addr($2));
833 RELOC_BIT_03FF(MEM_POS+1, 0);
835 | SETB bit {
836 $$ = 3;
837 op[0] = 0x08;
838 op[1] = 0x10 + msb(bit_addr($2));
839 op[2] = lsb(bit_addr($2));
840 RELOC_BIT_03FF(MEM_POS+1, 0);
842 | logical_shift_inst REG ',' REG {
843 size = find_size1(inst_size, $2);
844 if (find_size_reg($4) != SIZE8)
845 error("Second register in logical shift must be byte size");
846 $$ = 2;
847 op[0] = shift_reg_opcode;
848 switch (size) {
849 case SIZE8: op[0] += 0; break;
850 case SIZE16: op[0] += 8; break;
851 case SIZE32: op[0] += 12; break;
853 op[1] = reg($2) * 16 + reg($4);
855 | logical_shift_inst REG ',' '#' NUMBER {
856 size = find_size1(inst_size, $2);
857 $$ = 2;
858 if (shift_imm_opcode == -1)
859 error("NORM may not use a constant");
860 op[0] = shift_imm_opcode;
861 switch (size) {
862 case SIZE8: op[0] += 0; break;
863 case SIZE16: op[0] += 8; break;
864 case SIZE32: op[0] += 12; break;
866 switch (size) {
867 case SIZE8:
868 case SIZE16:
869 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
870 break;
871 case SIZE32:
872 op[1] = (reg($2) / 2) * 32 + imm_data5_unsigned($5);
873 break;
876 | no_opperand_inst {
877 $$ = num_op;
878 op[0] = opcode0;
879 op[1] = opcode1;
882 | TRAP '#' NUMBER {
883 $$ = 2;
884 op[0] = 0xD6;
885 op[1] = 0x30 + imm_data4_unsigned($3);
887 | CPL REG {
888 $$ = 2;
889 size = find_size1(inst_size, $2);
890 op[0] = 0x90 + size * 8;
891 op[1] = reg($2) * 16 + 10;
893 | DA REG {
894 $$ = 2;
895 op[0] = 0x90;
896 op[1] = reg($2) * 16 + 8;
898 | NEG REG {
899 $$ = 2;
900 size = find_size1(inst_size, $2);
901 op[0] = 0x90 + size * 8;
902 op[1] = reg($2) * 16 + 11;
904 | SEXT REG {
905 $$ = 2;
906 size = find_size1(inst_size, $2);
907 op[0] = 0x90 + size * 8;
908 op[1] = reg($2) * 16 + 9;
911 | rotate_inst REG ',' '#' NUMBER {
912 $$ = 2;
913 size = find_size1(inst_size, $2);
914 op[0] = rotate_opcode + size * 8;
915 op[1] = reg($2) * 16 + imm_data4_unsigned($5);
919 | LEA REG ',' REG '+' expr {
920 if ($6 >= -128 && $6 <= 127) {
921 $$ = 3;
922 op[0] = 0x40;
923 op[1] = reg($2) * 16 + reg_indirect($4);
924 op[2] = ($6 >= 0) ? $6 : 256 + $6;
925 RELOC_ABS_FF(MEM_POS+2, 0);
926 } else {
927 op[0] = 0x48;
928 op[1] = reg($2) * 16 + reg_indirect($4);
929 op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
930 op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
931 RELOC_ABS_FFFF(MEM_POS+2, 0);
934 | stack_inst WORD {
935 $$ = 3;
936 size = find_size0(inst_size);
937 op[0] = msb(stack_addr_opcode) + size * 8;
938 op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
939 op[2] = lsb(direct_addr($2));
940 RELOC_DIR_07FF(MEM_POS+1, 0);
942 | stack_inst rlist {
943 $$ = 2;
944 if (inst_size != UNKNOWN && find_size0(inst_size) != rlist_size)
945 error("inst specifies different size than registers used");
946 op[0] = stack_reg_opcode + rlist_reg_bank * 64 + rlist_size * 8;
947 op[1] = rlist_bitmask;
951 | MUL REG ',' REG {
952 $$ = 2;
953 size = find_size2(inst_size, $2, $4);
954 op[0] = 0xE6;
955 op[1] = reg($2) * 16 + reg($4);
957 | MULU REG ',' REG {
958 $$ = 2;
959 size = find_size2(inst_size, $2, $4);
960 if (size == SIZE8) {
961 op[0] = 0xE0;
962 op[1] = reg($2) * 16 + reg($4);
963 } else {
964 op[0] = 0xE4;
965 op[1] = reg($2) * 16 + reg($4);
968 | MUL REG ',' '#' expr {
969 $$ = 2;
970 size = find_size1(inst_size, $2);
971 op[0] = 0xE9;
972 op[1] = reg($2) + 8;
973 op[2] = msb(imm_data16($5));
974 op[3] = lsb(imm_data16($5));
975 RELOC_ABS_FFFF(MEM_POS+2, 0);
977 | MULU REG ',' '#' expr {
978 size = find_size2(inst_size, $2, $4);
979 if (size == SIZE8) {
980 $$ = 3;
981 op[0] = 0xE8;
982 op[1] = reg($2) * 16;
983 op[2] = imm_data8($5);
984 RELOC_ABS_FF(MEM_POS+2, 0);
985 } else {
986 $$ = 4;
987 op[0] = 0xE9;
988 op[1] = reg($2) * 16;
989 op[2] = msb(imm_data16($5));
990 op[3] = lsb(imm_data16($5));
991 RELOC_ABS_FFFF(MEM_POS+2, 0);
994 | DIV REG ',' REG {
995 $$ = 2;
996 size = find_size2(inst_size, $2, $4);
997 switch (size) {
998 case SIZE8:
999 error("Signed DIV can't be 8 bit size"); break;
1000 case SIZE16:
1001 op[0] = 0xE7;
1002 op[1] = reg($2) * 16 + reg($4);
1003 break;
1004 case SIZE32:
1005 op[0] = 0xEF;
1006 op[1] = (reg($2) / 2) * 32 + reg($4);
1007 break;
1010 | DIVU REG ',' REG {
1011 $$ = 2;
1012 size = find_size2(inst_size, $2, $4);
1013 switch (size) {
1014 case SIZE8:
1015 op[0] = 0xE1;
1016 op[1] = reg($2) * 16 + reg($4);
1017 break;
1018 case SIZE16:
1019 op[0] = 0xE5;
1020 op[1] = reg($2) * 16 + reg($4);
1021 break;
1022 case SIZE32:
1023 op[0] = 0xED;
1024 op[1] = (reg($2) / 2) * 32 + reg($4);
1025 break;
1028 | DIV REG ',' '#' expr {
1029 size = find_size1(inst_size, $2);
1030 switch (size) {
1031 case SIZE8:
1032 error("Singed DIV can't be 8 bit size"); break;
1033 case SIZE16:
1034 $$ = 3;
1035 op[0] = 0xE8;
1036 op[1] = reg($2) * 16 + 11;
1037 op[2] = imm_data8($5);
1038 RELOC_ABS_FF(MEM_POS+2, 0);
1039 break;
1040 case SIZE32:
1041 $$ = 4;
1042 op[0] = 0xE9;
1043 op[1] = (reg($2) / 2) * 32 + 9;
1044 op[2] = msb(imm_data16($5));
1045 op[3] = lsb(imm_data16($5));
1046 RELOC_ABS_FFFF(MEM_POS+2, 0);
1047 break;
1050 | DIVU REG ',' '#' expr {
1051 size = find_size1(inst_size, $2);
1052 switch (size) {
1053 case SIZE8:
1054 $$ = 3;
1055 op[0] = 0xE8;
1056 op[1] = reg($2) * 16 + 1;
1057 op[2] = imm_data8($5);
1058 RELOC_ABS_FF(MEM_POS+2, 0);
1059 break;
1060 case SIZE16:
1061 $$ = 3;
1062 op[0] = 0xE8;
1063 op[1] = reg($2) * 16 + 3;
1064 op[2] = imm_data8($5);
1065 RELOC_ABS_FF(MEM_POS+2, 0);
1066 break;
1067 case SIZE32:
1068 $$ = 4;
1069 op[0] = 0xE9;
1070 op[1] = (reg($2) / 2) * 32 + 1;
1071 op[2] = msb(imm_data16($5));
1072 op[3] = lsb(imm_data16($5));
1073 RELOC_ABS_FFFF(MEM_POS+2, 0);
1074 break;
1077 | CALL '[' REG ']' {
1078 $$ = 2;
1079 op[0] = 0xC6;
1080 op[1] = reg($3);
1082 | FCALL jmpaddr {
1083 $$ = 4;
1084 op[0] = 0xC4;
1085 op[1] = ($2 >> 8) & 255;
1086 op[2] = $2 & 255;
1087 op[3] = ($2 >> 16) & 255;
1089 | FJMP jmpaddr {
1090 $$ = 4;
1091 op[0] = 0xD4;
1092 op[1] = ($2 >> 8) & 255;
1093 op[2] = $2 & 255;
1094 op[3] = ($2 >> 16) & 255;
1096 | JMP '[' REG ']' {
1097 $$ = 2;
1098 op[0] = 0xD6;
1099 op[1] = 0x70 + reg_indirect($3);
1101 | JMP '[' A '+' DPTR ']' {
1102 $$ = 2;
1103 op[0] = 0xD6;
1104 op[1] = 0x46;
1106 | JMP '[' '[' REG '+' ']' ']' {
1107 $$ = 2;
1108 op[0] = 0xD6;
1109 op[1] = 0x60 + reg_indirect($4);
1112 | JMP jmpaddr {
1113 $$ = 3;
1114 op[0] = 0xD5;
1115 op[1] = msb(rel16(MEM_POS + $$, $2));
1116 op[2] = lsb(rel16(MEM_POS + $$, $2));
1117 RELOC_FFFF(MEM_POS+1,MEM_POS+$$,0);
1120 | CALL jmpaddr {
1121 $$ = 3;
1122 op[0] = 0xC5;
1123 op[1] = msb(rel16(MEM_POS + $$, $2));
1124 op[2] = lsb(rel16(MEM_POS + $$, $2));
1125 RELOC_FFFF(MEM_POS+1, MEM_POS+$$, 0);
1127 | branch_inst jmpaddr {
1128 $$ = 2;
1129 op[0] = branch_opcode;
1130 op[1] = rel8(MEM_POS + $$, $2);
1131 RELOC_FF(MEM_POS+1,MEM_POS + $$, 0);
1133 | CJNE REG ',' expr ',' jmpaddr {
1134 $$ = 4;
1135 size = find_size1(inst_size, $2);
1136 op[0] = 0xE2 + size * 8;
1137 op[1] = reg($2) * 16 + msb(direct_addr($4));
1138 op[2] = lsb(direct_addr($4));
1139 op[3] = rel8(MEM_POS + $$, $6);
1140 RELOC_DIR_07FF(MEM_POS+1, 0);
1141 RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
1143 | CJNE REG ',' '#' expr ',' jmpaddr {
1144 size = find_size1(inst_size, $2);
1145 if (size == SIZE8) {
1146 $$ = 4;
1147 op[0] = 0xE3;
1148 op[1] = reg($2) * 16;
1149 op[2] = rel8(MEM_POS + $$, $7);
1150 op[3] = imm_data8($5);
1151 RELOC_ABS_FF(MEM_POS+3, 0);
1152 } else {
1153 $$ = 5;
1154 op[0] = 0xEB;
1155 op[1] = reg($2) * 16;
1156 op[2] = rel8(MEM_POS + $$, $7);
1157 op[3] = msb(imm_data16($5));
1158 op[4] = lsb(imm_data16($5));
1159 RELOC_ABS_FFFF(MEM_POS+3, 0);
1162 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
1163 size = find_size0(inst_size);
1164 if (size == SIZE8) {
1165 $$ = 4;
1166 op[0] = 0xE3;
1167 op[1] = reg_indirect($3) * 16 + 8;
1168 op[2] = rel8(MEM_POS + $$, $9);
1169 op[3] = imm_data8($7);
1170 RELOC_ABS_FF(MEM_POS+3, 0);
1171 } else {
1172 $$ = 5;
1173 op[0] = 0xEB;
1174 op[1] = reg_indirect($3) * 16 + 8;
1175 op[2] = rel8(MEM_POS + $$, $9);
1176 op[3] = msb(imm_data16($7));
1177 op[4] = lsb(imm_data16($7));
1178 RELOC_ABS_FFFF(MEM_POS+3, 0);
1181 | DJNZ REG ',' jmpaddr {
1182 $$ = 3;
1183 size = find_size1(inst_size, $2);
1184 op[0] = 0x87 + size * 8;
1185 op[1] = reg($2) * 16 + 8;
1186 op[2] = rel8(MEM_POS + $$, $4);
1187 RELOC_FF(MEM_POS+2, MEM_POS+$$, 0);
1191 | DJNZ WORD ',' jmpaddr {
1192 $$ = 4;
1193 size = find_size0(inst_size);
1194 op[0] = 0xE2 + size * 8;
1195 op[1] = msb(direct_addr($2)) + 8;
1196 op[2] = lsb(direct_addr($2));
1197 op[3] = rel8(MEM_POS + $$, $4);
1198 RELOC_DIR_07FF(MEM_POS+1, 0);
1199 RELOC_FF(MEM_POS+3, MEM_POS + $$, 1)
1202 | JB bit ',' jmpaddr {
1203 $$ = 4;
1204 op[0] = 0x97;
1205 op[1] = 0x80 + msb(bit_addr($2));
1206 op[2] = lsb(bit_addr($2));
1207 op[3] = rel8(MEM_POS + $$, $4);
1208 RELOC_BIT_03FF(MEM_POS+1, 0);
1209 RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
1212 | JBC bit ',' jmpaddr {
1213 $$ = 4;
1214 op[0] = 0x97;
1215 op[1] = 0xC0 + msb(bit_addr($2));
1216 op[2] = lsb(bit_addr($2));
1217 op[3] = rel8(MEM_POS + $$, $4);
1218 RELOC_BIT_03FF(MEM_POS+1, 0);
1219 RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
1222 | JNB bit ',' jmpaddr {
1223 $$ = 4;
1224 op[0] = 0x97;
1225 op[1] = 0xA0 + msb(bit_addr($2));
1226 op[2] = lsb(bit_addr($2));
1227 op[3] = rel8(MEM_POS + $$, $4);
1228 RELOC_BIT_03FF(MEM_POS+1, 0);
1229 RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
1233 arith_inst:
1234 ADD {arith_opcode = 0;}
1235 | ADDC {arith_opcode = 1;}
1236 | AND {arith_opcode = 5;}
1237 | CMP {arith_opcode = 4;}
1238 | MOV {arith_opcode = 8;}
1239 | OR {arith_opcode = 6;}
1240 | SUB {arith_opcode = 2;}
1241 | SUBB {arith_opcode = 3;}
1242 | XOR {arith_opcode = 7;}
1244 short_data_inst:
1245 ADDS {short_opcode = 0xA0;}
1246 | MOVS {short_opcode = 0xB0;}
1248 logical_shift_inst:
1249 ASL {shift_reg_opcode = 0xC1; shift_imm_opcode = 0xD1;}
1250 | ASR {shift_reg_opcode = 0xC2; shift_imm_opcode = 0xD2;}
1251 | LSR {shift_reg_opcode = 0xC0; shift_imm_opcode = 0xD0;}
1252 | NORM {shift_reg_opcode = 0xC3; shift_imm_opcode = -1;}
1254 rotate_inst:
1255 RL {rotate_opcode = 0xD3;}
1256 | RLC {rotate_opcode = 0xD7;}
1257 | RR {rotate_opcode = 0xD0;}
1258 | RRC {rotate_opcode = 0xD7;}
1260 stack_inst:
1261 POP {stack_addr_opcode = 0x8710; stack_reg_opcode = 0x27;}
1262 | POPU {stack_addr_opcode = 0x8700; stack_reg_opcode = 0x37;}
1263 | PUSH {stack_addr_opcode = 0x8730; stack_reg_opcode = 0x07;}
1264 | PUSHU {stack_addr_opcode = 0x8720; stack_reg_opcode = 0x17;}
1266 no_opperand_inst:
1267 BKPT {num_op = 1; opcode0 = 255; opcode1 = 0;}
1268 | NOP {num_op = 1; opcode0 = 0; opcode1 = 0;}
1269 | RESET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x10;}
1270 | RET {num_op = 2; opcode0 = 0xD6; opcode1 = 0x80;}
1271 | RETI {num_op = 2; opcode0 = 0xD6; opcode1 = 0x90;}
1273 branch_inst:
1274 BCC {branch_opcode = 0xF0;}
1275 | BCS {branch_opcode = 0xF1;}
1276 | BEQ {branch_opcode = 0xF3;}
1277 | BG {branch_opcode = 0xF8;}
1278 | BGE {branch_opcode = 0xFA;}
1279 | BGT {branch_opcode = 0xFC;}
1280 | BL {branch_opcode = 0xF9;}
1281 | BLE {branch_opcode = 0xFD;}
1282 | BLT {branch_opcode = 0xFB;}
1283 | BMI {branch_opcode = 0xF7;}
1284 | BNE {branch_opcode = 0xF2;}
1285 | BNV {branch_opcode = 0xF4;}
1286 | BOV {branch_opcode = 0xF5;}
1287 | BPL {branch_opcode = 0xF6;}
1288 | BR {branch_opcode = 0xFE;}
1289 | JZ {branch_opcode = 0xEC;}
1290 | JNZ {branch_opcode = 0xEE;}
1297 int reg(int reg_spec)
1299 return reg_spec & 15;
1302 int reg_indirect(int reg_spec)
1304 if (reg_spec & BYTE_REG)
1305 error("Indirect addressing may not use byte registers");
1306 if ((reg_spec & 15) > 7)
1307 error("Only R0 through R7 may be used for indirect addr");
1308 return reg_spec & 7;
1311 int rel16(int pos, int dest)
1313 int rel;
1315 if (!p3) return 0; /* don't bother unless writing code */
1316 if (dest & (BRANCH_SPACING - 1))
1317 error("Attempt to jump to unaligned location");
1318 pos &= ~(BRANCH_SPACING - 1);
1319 rel = (dest - pos) / BRANCH_SPACING;
1320 if (rel < -32768 || rel > 32767)
1321 error("Attempt to jump out of 16 bit relative range");
1322 if (rel < 0) rel += 65536;
1323 return rel;
1326 int rel8(int pos, int dest)
1328 int rel;
1330 if (!p3) return 0; /* don't bother unless writing code */
1331 if (dest & (BRANCH_SPACING - 1))
1332 error("Attempt to jump to unaligned location");
1333 pos &= ~(BRANCH_SPACING - 1);
1334 rel = (dest - pos) / BRANCH_SPACING;
1335 if (rel < -128 || rel > 127)
1336 error("Attempt to jump out of 16 bit relative range");
1337 if (rel < 0) rel += 256;
1338 return rel;
1341 int msb(int value)
1343 return (value >> 8) & 255;
1346 int lsb(int value)
1348 return value & 255;
1351 int direct_addr(int value)
1353 char buf[250];
1355 if (value < 0 || value > 2047) {
1356 sprintf(buf, "illegal value (%d) for direct address", value);
1357 error(buf);
1359 return value;
1362 int imm_data4_signed(int value)
1364 if (value < -8 || value > 7)
1365 error("illegal 4 bit (signed) value");
1366 if (value >= 0) return value;
1367 else return (16 + value);
1370 int imm_data4_unsigned(int value)
1372 if (value < 0 || value > 15)
1373 error("illegal 4 bit (unsigned) value");
1374 return value;
1377 int imm_data5_unsigned(int value)
1379 if (value < 0 || value > 31)
1380 error("illegal 5 bit (unsigned) value");
1381 return value;
1384 int imm_data8(int value)
1386 if (value < -128 || value > 255)
1387 error("illegal 8 bit value");
1388 if (value >= 0) return value;
1389 else return (256 + value);
1392 int imm_data16(int value)
1394 if (value < -32728 || value > 65535)
1395 error("illegal 16 bit value");
1396 if (value >= 0) return value;
1397 else return (65536 + value);
1400 int bit_addr(int value)
1402 if (value < 0 || value > 1023) {
1403 fprintf(stderr, "bad bit addr of 0x%04X (%d dec)\n",
1404 value, value);
1405 error("illegal bit address");
1407 return value;
1411 int find_size_reg(int op1spec)
1413 int op1size=UNKNOWN;
1415 if (op1spec & BYTE_REG) op1size = SIZE8;
1416 if (op1spec & WORD_REG) op1size = SIZE16;
1417 if (op1size == UNKNOWN)
1418 error("Register without implied size");
1419 return op1size;
1422 int find_size0(int isize)
1424 if (isize == UNKNOWN)
1425 error("Can't determine data size from instruction");
1426 return isize;
1429 int find_size1(int isize, int op1spec)
1431 int op1size=UNKNOWN;
1433 if (op1spec & BYTE_REG) op1size = SIZE8;
1434 if (op1spec & WORD_REG) op1size = SIZE16;
1435 if (op1size == UNKNOWN)
1436 error("Register without implied size");
1438 if (isize == SIZE32 && op1size == SIZE16) return SIZE32;
1439 if (isize == UNKNOWN) return op1size;
1440 else {
1441 if (isize != op1size)
1442 error("data size of register and inst don't agree");
1443 return isize;
1447 int find_size2(int isize, int op1spec, int op2spec)
1449 int op1size=UNKNOWN, op2size=UNKNOWN;
1451 if (op1spec & BYTE_REG) op1size = SIZE8;
1452 if (op1spec & WORD_REG) op1size = SIZE16;
1453 if (op1size == UNKNOWN)
1454 error("Register without implied size");
1455 if (op2spec & BYTE_REG) op2size = SIZE8;
1456 if (op2spec & WORD_REG) op2size = SIZE16;
1457 if (op1size == UNKNOWN)
1458 error("Register without implied size");
1460 if (op1size != op2size)
1461 error("data sizes of two registers don't agree");
1462 if (isize == UNKNOWN) return op1size;
1463 else {
1464 if (isize != op1size)
1465 error("data size of registers and inst don't agree");
1466 return isize;
1470 int yyerror(char *s)
1472 if (yytext[0] >= 32) {
1473 fprintf(stderr, "%s near '%s', line %d\n",
1474 s, yytext, lineno);
1475 } else {
1476 fprintf(stderr, "%s, line %d\n", s, lineno - 1);
1478 return 0;
1481 void error(char *s)
1483 yyerror(s);
1484 exit(1);
1487 int yywrap()
1489 return 1;