struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / as8051 / i51mch.c
blob36184687a08b91d4e6641a4a0d79b71346d99839
1 /* i51mch.c */
3 /*
4 * Copyright (C) 1998-2011 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any 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/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
24 * This Assember Ported by
25 * John L. Hartman (JLH)
26 * jhartman at compuserve dot com
27 * noice at noicedebugger dot com
29 * Benny Kim (2011/07/21)
30 * bennykim at coreriver dot com
31 * Fixed bugs in relative address with "."
34 #include "asxxxx.h"
35 #include "i8051.h"
37 char *cpu = "Intel 8051";
38 char *dsft = "asm";
41 * Opcode Cycle Definitions
43 #define OPCY_SDP ((char) (0xFF))
44 #define OPCY_ERR ((char) (0xFE))
46 /* OPCY_NONE ((char) (0x80)) */
47 /* OPCY_MASK ((char) (0x7F)) */
49 #define UN ((char) (OPCY_NONE | 0x00))
52 * 8051 Cycle Count
54 * opcycles = i51pg1[opcode]
56 static char i51pg1[256] = {
57 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
58 /*--*--* - - - - - - - - - - - - - - - - */
59 /*00*/ 12,24,24,12,12,12,12,12,12,12,12,12,12,12,12,12,
60 /*10*/ 24,24,24,12,12,12,12,12,12,12,12,12,12,12,12,12,
61 /*20*/ 24,24,24,12,12,12,12,12,12,12,12,12,12,12,12,12,
62 /*30*/ 24,24,24,12,12,12,12,12,12,12,12,12,12,12,12,12,
63 /*40*/ 24,24,12,24,12,12,12,12,12,12,12,12,12,12,12,12,
64 /*50*/ 24,24,12,24,12,12,12,12,12,12,12,12,12,12,12,12,
65 /*60*/ 24,24,12,24,12,12,12,12,12,12,12,12,12,12,12,12,
66 /*70*/ 24,24,24,24,12,24,12,12,12,12,12,12,12,12,12,12,
67 /*80*/ 24,24,24,24,48,24,24,24,24,24,24,24,24,24,24,24,
68 /*90*/ 24,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12,
69 /*A0*/ 24,24,12,24,48,UN,24,24,24,24,24,24,24,24,24,24,
70 /*B0*/ 24,24,12,12,24,24,24,24,24,24,24,24,24,24,24,24,
71 /*C0*/ 24,24,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
72 /*D0*/ 24,24,12,12,12,24,12,12,24,24,24,24,24,24,24,24,
73 /*E0*/ 24,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12,
74 /*F0*/ 24,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12
78 * Process machine ops.
80 VOID
81 machine(struct mne *mp)
83 a_uint op;
84 int t, t1, v1;
85 struct expr e, e1, e2;
87 clrexpr(&e);
88 clrexpr(&e1);
89 clrexpr(&e2);
91 op = mp->m_valu;
92 switch (mp->m_type) {
94 case S_INH:
95 outab(op);
96 break;
98 case S_JMP11:
100 * 11 bit destination.
101 * Top 3 bits become the MSBs of the op-code.
103 expr(&e, 0);
104 outrwm(&e, R_J11, op);
105 break;
107 case S_JMP16:
108 expr(&e, 0);
109 outab(op);
110 outrw(&e, R_NORM);
111 break;
113 case S_ACC:
114 t = addr(&e);
115 if (t != S_A)
116 xerr('a', "Argument must be A.");
117 outab(op);
118 break;
120 case S_TYP1:
121 /* A, direct, @R0, @R1, R0 to R7. "INC" also allows DPTR */
122 t = addr(&e);
124 switch (t) {
125 case S_A:
126 outab(op + 4);
127 break;
129 case S_DIR:
130 case S_EXT:
131 /* Direct is also legal */
132 outab(op + 5);
133 outrb(&e, R_PAG0);
134 break;
136 case S_AT_R:
137 outab(op + 6 + e.e_addr);
138 break;
140 case S_REG:
141 outab(op + 8 + e.e_addr);
142 break;
144 case S_DPTR:
145 if (op != 0)
146 /* only INC (op=0) has DPTR mode */
147 xerr('a', "DPTR allowed only in INC instruction.");
148 else
149 outab( 0xA3);
150 break;
152 default:
153 xerr('a', "Invalid Addressing Mode.");
155 break;
157 case S_TYP2:
158 /* A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7 */
159 t = addr(&e);
160 if (t != S_A)
161 xerr('a', "First argument must be A.");
162 comma(1);
163 t1 = addr(&e1);
165 switch (t1) {
166 case S_IMMED:
167 outab(op + 4);
168 outrb(&e1, R_NORM);
169 break;
171 case S_DIR:
172 case S_EXT:
173 outab(op + 5);
174 outrb(&e1, R_PAG0);
175 break;
177 case S_AT_R:
178 outab(op + 6 + e1.e_addr);
179 break;
181 case S_REG:
182 outab(op + 8 + (e1.e_addr));
183 break;
185 default:
186 xerr('a', "Invalid Addressing Mode.");
188 break;
190 case S_TYP3:
191 /* dir,A; dir,#imm;
192 * A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7
193 * C,direct; C,/direct
195 t = addr(&e);
196 comma(1);
197 t1 = addr(&e1);
199 switch (t) {
200 case S_DIR:
201 case S_EXT:
202 switch (t1) {
203 case S_A:
204 outab(op + 2);
205 outrb(&e, R_PAG0);
206 break;
208 case S_IMMED:
209 outab(op + 3);
210 outrb(&e, R_PAG0);
211 outrb(&e1, R_NORM);
212 break;
214 default:
215 xerr('a', "Invalid Addressing Mode.");
217 break;
219 case S_A:
220 switch (t1) {
221 case S_IMMED:
222 outab(op + 4);
223 outrb(&e1, R_NORM);
224 break;
226 case S_DIR:
227 case S_EXT:
228 outab(op + 5);
229 outrb(&e1, R_PAG0);
230 break;
232 case S_AT_R:
233 outab(op + 6 + e1.e_addr);
234 break;
236 case S_REG:
237 outab(op + 8 + e1.e_addr);
238 break;
240 default:
241 xerr('a', "Invalid Addressing Mode.");
243 break;
245 case S_C:
246 /* XRL has no boolean version. Trap it */
247 if (op == 0x60)
248 xerr('a', "XRL does not support boolean.");
250 switch (t1) {
251 case S_DIR:
252 case S_EXT:
253 outab(op + 0x32);
254 outrb(&e1, R_PAG0);
255 break;
257 case S_NOT_BIT:
258 outab(op + 0x60);
259 outrb(&e1, R_PAG0);
260 break;
262 default:
263 xerr('a', "Invalid Addressing Mode.");
265 break;
267 default:
268 xerr('a', "Invalid Addressing Mode.");
270 break;
272 case S_TYP4:
273 /* A,direct; A,@R0; A,@R1; A,R0 to A,R7 */
274 t = addr(&e);
275 if (t != S_A)
276 xerr('a', "First argument must be A.");
277 comma(1);
278 t1 = addr(&e1);
280 switch (t1) {
281 case S_DIR:
282 case S_EXT:
283 outab(op + 5);
284 outrb(&e1, R_PAG0);
285 break;
287 case S_AT_R:
288 outab(op + 6 + e1.e_addr);
289 break;
291 case S_REG:
292 outab(op + 8 + e1.e_addr);
293 break;
295 default:
296 xerr('a', "Invalid Addressing Mode.");
298 break;
300 /* MOV instruction, all modes */
301 case S_MOV:
302 t = addr(&e);
303 comma(1);
304 t1 = addr(&e1);
306 switch (t) {
307 case S_A:
308 switch (t1) {
309 case S_IMMED:
310 outab(0x74);
311 outrb(&e1, R_NORM);
312 break;
314 case S_DIR:
315 case S_EXT:
316 outab(0xE5);
317 outrb(&e1, R_PAG0);
318 break;
320 case S_AT_R:
321 outab(0xE6 + e1.e_addr);
322 break;
324 case S_REG:
325 outab(0xE8 + e1.e_addr);
326 break;
328 default:
329 xerr('a', "Invalid Addressing Mode.");
331 break;
333 case S_REG:
334 switch (t1) {
335 case S_A:
336 outab(0xF8 + e.e_addr);
337 break;
339 case S_IMMED:
340 outab(0x78 + e.e_addr);
341 outrb(&e1, R_NORM);
342 break;
344 case S_DIR:
345 case S_EXT:
346 outab(0xA8 + e.e_addr);
347 outrb(&e1, R_PAG0);
348 break;
350 default:
351 xerr('a', "Invalid Addressing Mode.");
353 break;
355 case S_DIR:
356 case S_EXT:
357 switch (t1) {
358 case S_A:
359 outab(0xF5);
360 outrb(&e, R_PAG0);
361 break;
363 case S_IMMED:
364 outab(0x75);
365 outrb(&e, R_PAG0);
366 outrb(&e1, R_NORM);
367 break;
369 case S_DIR:
370 case S_EXT:
371 outab(0x85);
372 outrb(&e1, R_PAG0);
373 outrb(&e, R_PAG0);
374 break;
376 case S_AT_R:
377 outab(0x86 + e1.e_addr);
378 outrb(&e, R_PAG0);
379 break;
381 case S_REG:
382 outab(0x88 + e1.e_addr);
383 outrb(&e, R_PAG0);
384 break;
386 case S_C:
387 outab(0x92);
388 outrb(&e, R_PAG0);
389 break;
391 default:
392 xerr('a', "Invalid Addressing Mode.");
394 break;
396 case S_AT_R:
397 switch (t1) {
398 case S_IMMED:
399 outab(0x76 + e.e_addr);
400 outrb(&e1, R_NORM);
401 break;
403 case S_DIR:
404 case S_EXT:
405 outab(0xA6 + e.e_addr);
406 outrb(&e1, R_PAG0);
407 break;
409 case S_A:
410 outab(0xF6 + e.e_addr);
411 break;
413 default:
414 xerr('a', "Invalid Addressing Mode.");
416 break;
418 case S_C:
419 if ((t1 != S_DIR) && (t1 != S_EXT))
420 xerr('a', "Second argument must be an address.");
421 outab(0xA2);
422 outrb(&e1, R_PAG0);
423 break;
425 case S_DPTR:
426 if (t1 != S_IMMED)
427 xerr('a', "#__ is required second argument.");
428 outab(0x90);
429 outrw(&e1, R_NORM);
430 break;
432 default:
433 xerr('a', "Invalid Addressing Mode.");
435 break;
437 case S_BITBR: /* JB, JBC, JNB bit,rel */
438 /* Branch on bit set/clear */
439 t = addr(&e);
440 if ((t != S_DIR) && (t != S_EXT))
441 xerr('a', "Argument must be an address.");
442 /* sdcc svn rev #4994: fixed bug 1865114 */
443 comma(1);
444 expr(&e1, 0);
446 outab(op);
447 outrb(&e, R_PAG0);
449 if (mchpcr(&e1)) {
450 v1 = (int) (e1.e_addr - dot.s_addr - 1);
451 /* sdcc svn rev #602: Fix some path problems */
452 if (pass == 2 && ((v1 < -128) || (v1 > 127)))
453 xerr('a', "Branching Range Exceeded.");
454 outab(v1);
455 } else {
456 outrb(&e1, R_PCR);
458 if (e1.e_mode != S_USER)
459 rerr();
460 break;
462 case S_BR: /* JC, JNC, JZ, JNZ */
463 /* Relative branch */
464 /* sdcc svn rev #4994: fixed bug 1865114 */
465 expr(&e1, 0);
466 outab(op);
468 if (mchpcr(&e1)) {
469 v1 = (int) (e1.e_addr - dot.s_addr - 1);
470 /* sdcc svn rev #602: Fix some path problems */
471 if (pass == 2 && ((v1 < -128) || (v1 > 127)))
472 xerr('a', "Branching Range Exceeded.");
473 outab(v1);
474 } else {
475 outrb(&e1, R_PCR);
477 if (e1.e_mode != S_USER)
478 rerr();
479 break;
481 case S_CJNE:
482 /* A,#; A,dir; @R0,#; @R1,#; Rn,# */
483 t = addr(&e);
484 comma(1);
485 t1 = addr(&e1);
487 /* Benny */
488 comma(1);
489 expr(&e2, 0);
491 switch (t) {
492 case S_A:
493 if (t1 == S_IMMED) {
494 outab(op + 4);
495 outrb(&e1, R_NORM);
497 else if ((t1 == S_DIR) || (t1 == S_EXT)) {
498 outab(op + 5);
499 outrb(&e1, R_PAG0);
501 else
502 xerr('a', "Invalid Addressing Mode.");
503 break;
505 case S_AT_R:
506 outab(op + 6 + e.e_addr);
507 if (t1 != S_IMMED)
508 xerr('a', "#__ is required second argument.");
509 outrb(&e1, R_NORM);
510 break;
512 case S_REG:
513 outab(op + 8 + e.e_addr);
514 if (t1 != S_IMMED)
515 xerr('a', "#__ is required second argument.");
516 outrb(&e1, R_NORM);
517 break;
519 default:
520 xerr('a', "Invalid Addressing Mode.");
521 break;
524 /* branch destination */
525 if (mchpcr(&e2)) {
526 v1 = (int) (e2.e_addr - dot.s_addr - 1);
527 /* sdcc svn rev #602: Fix some path problems */
528 if (pass == 2 && ((v1 < -128) || (v1 > 127)))
529 xerr('a', "Branching Range Exceeded.");
530 outab(v1);
531 } else {
532 outrb(&e2, R_PCR);
534 if (e2.e_mode != S_USER)
535 rerr();
536 break;
538 case S_DJNZ:
539 /* Dir,dest; Reg,dest */
540 t = addr(&e);
541 /* sdcc svn rev #4994: fixed bug 1865114 */
542 comma(1);
543 expr(&e1, 0);
545 switch (t) {
546 case S_DIR:
547 case S_EXT:
548 outab(op + 5);
549 outrb(&e, R_PAG0);
550 break;
552 case S_REG:
553 outab(op + 8 + e.e_addr);
554 break;
556 default:
557 xerr('a', "Invalid Addressing Mode.");
560 /* branch destination */
561 /* sdcc svn rev #4994: fixed bug 1865114 */
562 if (mchpcr(&e1)) {
563 v1 = (int) (e1.e_addr - dot.s_addr - 1);
564 /* sdcc svn rev #602: Fix some path problems */
565 if (pass == 2 && ((v1 < -128) || (v1 > 127)))
566 xerr('a', "Branching Range Exceeded.");
567 outab(v1);
568 } else {
569 outrb(&e1, R_PCR);
571 if (e1.e_mode != S_USER)
572 rerr();
573 break;
575 case S_JMP:
576 /* @A+DPTR */
577 t = addr(&e);
578 if (t != S_AT_ADP)
579 xerr('a', "JMP @A+DPTR is the only allowed mode.");
580 outab(op);
581 break;
583 case S_MOVC:
584 /* A,@A+DPTR A,@A+PC */
585 t = addr(&e);
586 if (t != S_A)
587 xerr('a', "First argument must be A.");
588 comma(1);
589 t1 = addr(&e1);
590 if (t1 == S_AT_ADP)
591 outab(0x93);
592 else if (t1 == S_AT_APC)
593 outab(0x83);
594 else
595 xerr('a', "MOVC A,@A+DPTR; A,@A+PC are the allowed modes.");
596 break;
598 case S_MOVX:
599 /* A,@DPTR A,@R0 A,@R1 @DPTR,A @R0,A @R1,A */
600 t = addr(&e);
601 comma(1);
602 t1 = addr(&e1);
604 switch (t) {
605 case S_A:
606 switch (t1) {
607 case S_AT_DP:
608 outab(0xE0);
609 break;
611 case S_AT_R:
612 outab(0xE2 + e1.e_addr);
613 break;
615 default:
616 xerr('a', "Second argument must be @DPTR or @Rn.");
618 break;
620 case S_AT_DP:
621 if (t1 == S_A)
622 outab(0xF0);
623 else
624 xerr('a', "Second argument must A.");
625 break;
627 case S_AT_R:
628 if (t1 == S_A)
629 outab(0xF2 + e.e_addr);
630 else
631 xerr('a', "Second argument must A.");
632 break;
634 default:
635 xerr('a', "Invalid Addressing Mode.");
637 break;
639 /* MUL/DIV A,B */
640 case S_AB:
641 t = addr(&e);
642 if (t != S_RAB)
643 xerr('a', "A,B is the only valid argument.");
644 outab(op);
645 break;
647 /* CLR or CPL: A, C, or bit */
648 case S_ACBIT:
649 t = addr(&e);
650 switch (t) {
651 case S_A:
652 if (op == 0xB2)
653 outab(0xF4);
654 else
655 outab(0xE4);
656 break;
658 case S_C:
659 outab(op+1);
660 break;
662 case S_DIR:
663 case S_EXT:
664 outab(op);
665 outrb(&e, R_PAG0);
666 break;
668 default:
669 xerr('a', "Invalid Addressing Mode.");
671 break;
673 /* SETB C or bit */
674 case S_SETB:
675 t = addr(&e);
676 switch (t) {
677 case S_C:
678 outab(op+1);
679 break;
681 case S_DIR:
682 case S_EXT:
683 outab(op);
684 outrb(&e, R_PAG0);
685 break;
687 default:
688 xerr('a', "Invalid Addressing Mode.");
690 break;
692 /* direct */
693 case S_DIRECT:
694 t = addr(&e);
695 if (t == S_A) {
696 e.e_addr = 0xE0;
697 e.e_mode = S_DIR;
698 } else
699 if ((t != S_DIR) && (t != S_EXT)) {
700 xerr('a', "Argument must be an address.");
701 break;
703 outab(op);
704 outrb(&e, R_PAG0);
705 break;
707 /* XCHD A,@Rn */
708 case S_XCHD:
709 t = addr(&e);
710 if (t != S_A)
711 xerr('a', "First argument must A.");
712 comma(1);
713 t1 = addr(&e1);
714 switch (t1) {
715 case S_AT_R:
716 outab(op + e1.e_addr);
717 break;
719 default:
720 xerr('a', "Invalid Addressing Mode.");
722 break;
724 default:
725 opcycles = OPCY_ERR;
726 xerr('o', "Internal Opcode Error.");
727 break;
729 if (opcycles == OPCY_NONE) {
730 opcycles = i51pg1[cb[0] & 0xFF];
735 * Branch/Jump PCR Mode Check
738 mchpcr(struct expr *esp)
740 if (esp->e_base.e_ap == dot.s_area) {
741 return(1);
743 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
745 * Absolute Destination
747 * Use the global symbol '.__.ABS.'
748 * of value zero and force the assembler
749 * to use this absolute constant as the
750 * base value for the relocation.
752 esp->e_flag = 1;
753 esp->e_base.e_sp = &sym[1];
755 return(0);
759 * Machine specific initialization
762 static int beenHere = 0; /* set non-zero if we have done that... */
764 VOID
765 minit(void)
767 struct sym *sp;
768 struct PreDef *pd;
769 int i;
770 char pid[8];
771 char *p;
774 * Byte Order
776 hilo = 1;
779 * Address Space
781 exprmasks(3);
784 * First time only:
785 * add the pre-defined symbols to the table
786 * as local symbols.
788 if (beenHere == 0) {
789 pd = preDef;
790 while (pd->id) {
791 strcpy(pid, pd->id);
792 for (i=0; i<2; i++) {
794 * i == 0, Create Upper Case Symbols
795 * i == 1, Create Lower Case Symbols
797 if (i == 1) {
798 p = pid;
799 while (*p) {
800 *p = ccase[*p & 0x007F];
801 p++;
804 sp = lookup(pid);
805 if (sp->s_type == S_NEW) {
806 sp->s_addr = pd->value;
807 sp->s_type = S_USER;
808 sp->s_flag = S_LCL | S_ASG;
811 pd++;
813 beenHere = 1;