Initial revision
[fw/sdcc] / as / mcs51 / i51mch.c
1 /* i85mch.c */
2
3 /*
4  * (C) Copyright 1989,1990
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  *
11  * 28-Oct-97 Ported from 8085 to 8051 by John Hartman
12  */
13
14 #include <stdio.h>
15 #include <setjmp.h>
16 #include "asm.h"
17 #include "i8051.h"
18
19 extern int addr(struct expr *);
20 /*
21  * Process machine ops.
22  */
23 VOID
24 machine(mp)
25 struct mne *mp;
26 {
27         register unsigned op;
28         register int t, t1, v1;
29         struct expr e, e1;
30
31         clrexpr(&e);
32         clrexpr(&e1);
33
34         op = mp->m_valu;
35         switch (mp->m_type) {
36
37         case S_INH:
38                 outab(op);
39                 break;
40
41         case S_JMP11:
42                 /* 11 bit destination.  Top 3 bits become the MSBs of
43                 /  the op-code.
44                 */
45                 expr(&e, 0);
46                 outr11(&e, op, R_J11);
47                 break;
48
49         case S_JMP16:
50                 expr(&e, 0);
51                 outab(op);
52                 outrw(&e, 0);
53                 break;
54
55         case S_ACC:
56                 t = addr(&e);
57                 if (t != S_A)
58                         aerr();
59                 outab(op);
60                 break;
61
62         case S_TYP1:
63                 /* A, direct, @R0, @R1, R0 to R7.  "INC" also allows DPTR */
64                 t = addr(&e);
65                 
66                 switch (t) {
67                 case S_A:
68                         outab(op + 4);
69                         break;
70
71                 case S_DIR:
72                 case S_EXT:
73                         /* Direct is also legal */
74                         outab(op + 5);
75                         outrb(&e, R_PAG0);
76                         break;
77
78                 case S_AT_R:
79                         outab(op + 6 + e.e_addr);
80                         break;
81
82                 case S_REG:
83                         outab(op + 8 + e.e_addr);
84                         break;
85
86                 case S_DPTR:
87                         if (op != 0)
88                                 /* only INC (op=0) has DPTR mode */
89                                 aerr();
90                         else
91                                 outab( 0xA3);
92                         break;
93
94                 default:
95                         aerr();
96                 }
97                 break;
98
99         case S_TYP2:
100                 /* A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7 */
101                 t = addr(&e);
102                 if (t != S_A)
103                         aerr();
104                 comma();
105                 t1 = addr(&e1);
106                 
107                 switch (t1) {
108                 case S_IMMED:
109                         outab(op + 4);
110                         outrb(&e1, 0);
111                         break;
112
113                 case S_DIR:
114                 case S_EXT:
115                         outab(op + 5);
116                         outrb(&e1, R_PAG0);
117                         break;
118
119                 case S_AT_R:
120                         outab(op + 6 + e1.e_addr);
121                         break;
122
123                 case S_REG:
124                         outab(op + 8 + (e1.e_addr));
125                         break;
126
127                 default:
128                         aerr();
129                 }
130                 break;
131
132         case S_TYP3:
133                 /* dir,A; dir,#imm; 
134                  * A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7 
135                  * C,direct;  C,/direct
136                  */
137                 t = addr(&e);
138                 comma();
139                 t1 = addr(&e1);
140
141                 switch (t) {
142                 case S_DIR:
143                 case S_EXT:
144                         switch (t1) {
145                         case S_A:
146                                 outab(op + 2);
147                                 outrb(&e, R_PAG0);
148                                 break;
149                         
150                         case S_IMMED:
151                                 outab(op + 3);
152                                 outrb(&e, 0);
153                                 outrb(&e1, 0);
154                                 break;
155                         default:
156                                 aerr();
157                         }
158                         break;
159
160                 case S_A:
161                         switch (t1) {
162                         case S_IMMED:
163                                 outab(op + 4);
164                                 outrb(&e1, 0);
165                                 break;
166         
167                         case S_DIR:
168                         case S_EXT:
169                                 outab(op + 5);
170                                 outrb(&e1, R_PAG0);
171                                 break;
172
173                         case S_AT_R:
174                                 outab(op + 6 + e1.e_addr);
175                                 break;
176
177                         case S_REG:
178                                 outab(op + 8 + e1.e_addr);
179                                 break;
180
181                         default:
182                                 aerr();
183                         }
184                         break;
185
186                 case S_C:
187                         /* XRL has no boolean version.  Trap it */
188                         if (op == 0x60)
189                                 aerr();
190
191                         switch (t1) {
192                         case S_DIR:
193                         case S_EXT:
194                                 outab(op + 0x32);
195                                 outrb(&e1, R_PAG0);
196                                 break;
197                         
198                         case S_NOT_BIT:
199                                 outab(op + 0x60);
200                                 outrb(&e1, 0);
201                                 break;
202                         
203                         default:
204                                 aerr();
205                         }
206                         break;
207
208                 default:
209                         aerr();
210                 }
211                 break;
212
213         case S_TYP4:
214                 /* A,direct; A,@R0; A,@R1; A,R0 to A,R7 */
215                 t = addr(&e);
216                 if (t != S_A)
217                         aerr();
218                 comma();
219                 t1 = addr(&e1);
220
221                 switch (t1) {
222                 case S_DIR:
223                 case S_EXT:
224                         outab(op + 5);
225                         outrb(&e1, R_PAG0);
226                         break;
227
228                 case S_AT_R:
229                         outab(op + 6 + e1.e_addr);
230                         break;
231
232                 case S_REG:
233                         outab(op + 8 + e1.e_addr);
234                         break;
235
236                 default:
237                         aerr();
238                 }
239                 break;
240
241         /* MOV instruction, all modes */
242         case S_MOV:
243                 t = addr(&e);
244                 comma();
245                 t1 = addr(&e1);
246
247                 switch (t) {
248                 case S_A:
249                         switch (t1) {
250                         case S_IMMED:
251                                 outab(0x74);
252                                 outrb(&e1, 0);
253                                 break;
254         
255                         case S_DIR:
256                         case S_EXT:
257                                 outab(0xE5);
258                                 outrb(&e1, R_PAG0);
259                                 break;
260
261                         case S_AT_R:
262                                 outab(0xE6 + e1.e_addr);
263                                 break;
264
265                         case S_REG:
266                                 outab(0xE8 + e1.e_addr);
267                                 break;
268
269                         default:
270                                 aerr();
271                         }
272                         break;
273
274                 case S_REG:
275                         switch (t1) {
276                         case S_A:
277                                 outab(0xF8 + e.e_addr);
278                                 break;
279
280                         case S_IMMED:
281                                 outab(0x78 + e.e_addr);
282                                 outrb(&e1, 0);
283                                 break;
284         
285                         case S_DIR:
286                         case S_EXT:
287                                 outab(0xA8 + e.e_addr);
288                                 outrb(&e1, R_PAG0);
289                                 break;
290
291                         default:
292                                 aerr();
293                         }
294                         break;
295
296                 case S_DIR:
297                 case S_EXT:
298                         switch (t1) {
299                         case S_A:
300                                 outab(0xF5);
301                                 outrb(&e, R_PAG0);
302                                 break;
303
304                         case S_IMMED:
305                                 outab(0x75);
306                                 outrb(&e, R_PAG0);
307                                 outrb(&e1, 0);
308                                 break;
309         
310                         case S_DIR:
311                         case S_EXT:
312                                 outab(0x85);
313                                 outrb(&e1, R_PAG0);
314                                 outrb(&e, R_PAG0);
315                                 break;
316
317                         case S_AT_R:
318                                 outab(0x86 + e1.e_addr);
319                                 outrb(&e, R_PAG0);
320                                 break;
321
322                         case S_REG:
323                                 outab(0x88 + e1.e_addr);
324                                 outrb(&e, R_PAG0);
325                                 break;
326
327                         case S_C:
328                                 outab(0x92);
329                                 outrb(&e, R_PAG0);
330                                 break;
331
332                         default:
333                                 aerr();
334                         }
335                         break;
336
337                 case S_AT_R:
338                         switch (t1) {
339                         case S_IMMED:
340                                 outab(0x76 + e.e_addr);
341                                 outrb(&e1, 0);
342                                 break;
343         
344                         case S_DIR:
345                         case S_EXT:
346                                 outab(0xA6 + e.e_addr);
347                                 outrb(&e1, R_PAG0);
348                                 break;
349
350                         case S_A:
351                                 outab(0xF6 + e.e_addr);
352                                 break;
353
354                         default:
355                                 aerr();
356                         }
357                         break;
358
359                 case S_C:
360                         if ((t1 != S_DIR) && (t1 != S_EXT))
361                                 aerr();
362                         outab(0xA2);
363                         outrb(&e1, R_PAG0);
364                         break;
365
366                 case S_DPTR:
367                         if (t1 != S_IMMED)
368                                 aerr();
369                         outab(0x90);
370                         outrw(&e1, 0);
371                         break;
372
373                 default:
374                         aerr();
375                 }
376                 break;
377
378         case S_BITBR:
379                 /* Branch on bit set/clear */
380                 t = addr(&e);
381                 if ((t != S_DIR) && (t != S_EXT))
382                         aerr();
383                 outab(op);
384                 outrb(&e, R_PAG0);
385
386                 comma();
387                 expr(&e1, 0);
388                 if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
389                     if ( e1.e_addr == dot.s_addr)
390                         v1 = -3;
391                     else
392                         v1 = e1.e_addr - dot.s_addr - 1;
393                         /* if ((v1 < -128) || (v1 > 127))
394                                 aerr(); */
395                         outab(v1);
396                 } else {
397                         outrb(&e1, R_PCR);
398                 }
399                 if (e1.e_mode != S_USER)
400                         rerr();
401                 break;
402
403         case S_BR:
404                 /* Relative branch */
405                 outab(op);
406                 expr(&e1, 0);
407                 if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
408                     if ( e1.e_addr == dot.s_addr)
409                         v1 = -2;
410                     else   
411                         v1 = e1.e_addr - dot.s_addr - 1;
412                         /* if ((v1 < -128) || (v1 > 127))
413                                 aerr();*/
414                         outab(v1);
415                 } else {
416                         outrb(&e1, R_PCR);
417                 }
418                 if (e1.e_mode != S_USER)
419                         rerr();
420                 break;
421
422         case S_CJNE:
423                 /* A,#;  A,dir;  @R0,#;  @R1,#;  Rn,# */
424                 t = addr(&e);
425                 comma();
426                 t1 = addr(&e1);
427                 switch (t) {
428                 case S_A:
429                         if (t1 == S_IMMED) {
430                                 outab(op + 4);
431                                 outrb(&e1, 0);
432                         }
433                         else if ((t1 == S_DIR) || (t1 == S_EXT)) {
434                                 outab(op + 5);
435                                 outrb(&e1, R_PAG0);
436                         }
437                         else
438                                 aerr();
439                 break;
440
441                 case S_AT_R:
442                         outab(op + 6 + e.e_addr);
443                         if (t1 != S_IMMED)
444                                 aerr();
445                         outrb(&e1, 0);
446                         break;
447         
448                 case S_REG:
449                         outab(op + 8 + e.e_addr);
450                         if (t1 != S_IMMED)
451                                 aerr();
452                         outrb(&e1, 0);
453                         break;
454         
455                 default:
456                         aerr();
457                 }
458
459                 /* branch destination */
460                 comma();
461                 expr(&e1, 0);
462                 if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
463                     if ( e1.e_addr == dot.s_addr)
464                         v1 = -3;
465                     else   
466                         v1 = e1.e_addr - dot.s_addr - 1;
467                         /* if ((v1 < -128) || (v1 > 127))
468                                 aerr(); */
469                         outab(v1);
470                 } else {
471                         outrb(&e1, R_PCR);
472                 }
473                 if (e1.e_mode != S_USER)
474                         rerr();
475                 break;
476
477         case S_DJNZ:
478                 /* Dir,dest;  Reg,dest */
479                 t = addr(&e);
480                 switch (t) {
481
482                 case S_DIR:
483                 case S_EXT:
484                         outab(op + 5);
485                         outrb(&e, R_PAG0);
486                         break;
487          
488                 case S_REG:
489                         outab(op + 8 + e.e_addr);
490                         break;
491
492                 default:
493                         aerr();
494                 }
495
496                 /* branch destination */
497                 comma();
498                 expr(&e1, 0);
499                 if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
500                     if ( e1.e_addr == dot.s_addr)
501                         v1 = -2;
502                     else   
503                         v1 = e1.e_addr - dot.s_addr - 1;
504                         /* if ((v1 < -128) || (v1 > 127))
505                                 aerr(); */
506                         outab(v1);
507                 } else {
508                         outrb(&e1, R_PCR);
509                 }
510                 if (e1.e_mode != S_USER)
511                         rerr();
512                 break;
513
514         case S_JMP: 
515                 /* @A+DPTR */
516                 t = addr(&e);
517                 if (t != S_AT_ADP)
518                         aerr();
519                 outab(op);
520                 break;
521
522         case S_MOVC:
523                 /* A,@A+DPTR  A,@A+PC */
524                 t = addr(&e);
525                 if (t != S_A)
526                         aerr();
527                 comma();
528                 t1 = addr(&e1);
529                 if (t1 == S_AT_ADP)
530                         outab(0x93);
531                 else if (t1 == S_AT_APC)
532                         outab(0x83);
533                 else
534                         aerr();
535                 break;
536
537         case S_MOVX:
538                 /* A,@DPTR  A,@R0  A,@R1  @DPTR,A  @R0,A  @R1,A */
539                 t = addr(&e);
540                 comma();
541                 t1 = addr(&e1);
542
543                 switch (t) {
544                 case S_A:
545                         switch (t1) {
546                         case S_AT_DP:
547                                 outab(0xE0);
548                                 break;
549                         case S_AT_R:
550                                 outab(0xE2 + e1.e_addr);
551                                 break;
552                         default:
553                                 aerr();
554                         }
555                         break;
556
557                 case S_AT_DP:
558                         if (t1 == S_A)
559                                 outab(0xF0);
560                         else
561                                 aerr();
562                         break;
563
564                 case S_AT_R:
565                         if (t1 == S_A)
566                                 outab(0xF2 + e.e_addr);
567                         else
568                                 aerr();
569                         break;
570
571                 default:
572                         aerr();
573                 }
574                 break;
575
576         /* MUL/DIV A,B */
577         case S_AB:  
578                 t = addr(&e);
579                 if (t != S_RAB) aerr();
580                 outab(op);
581                 break;
582
583         /* CLR or CPL:  A, C, or bit */
584         case S_ACBIT:
585                 t = addr(&e);
586                 switch (t) {
587                 case S_A:
588                         if (op == 0xB2)
589                                 outab(0xF4);
590                         else
591                                 outab(0xE4);
592                         break;
593
594                 case S_C:
595                         outab(op+1);
596                         break;
597
598                 case S_DIR:
599                 case S_EXT:
600                         outab(op);
601                         outrb(&e, R_PAG0);
602                         break;
603
604                 default:
605                         aerr();
606                 }
607                 break;
608
609         /* SETB C or bit */
610         case S_SETB:
611                 t = addr(&e);
612                 switch (t) {
613                 case S_C:
614                         outab(op+1);
615                         break;
616
617                 case S_DIR:
618                 case S_EXT:
619                         outab(op);
620                         outrb(&e, R_PAG0);
621                         break;
622
623                 default:
624                         aerr();
625                 }
626                 break;
627
628         /* direct */
629         case S_DIRECT: 
630                 t = addr(&e);
631                 if ((t != S_DIR) && (t != S_EXT)) {
632                         aerr();
633                         break;
634                 }
635                 outab(op);
636                 outrb(&e, R_PAG0);
637                 break;
638
639         /* XCHD A,@Rn */
640         case S_XCHD:
641                 t = addr(&e);
642                 if (t != S_A)
643                         aerr();
644                 comma();
645                 t1 = addr(&e1);
646                 switch (t1) {
647                 case S_AT_R:
648                         outab(op + e1.e_addr);
649                         break;
650                 default:
651                         aerr();
652                 }
653                 break;
654
655         default:
656                 err('o');
657         }
658 }
659
660 /*
661  * Is the next character a comma ?
662  */
663 int
664 comma()
665 {
666         if (getnb() != ',')
667                 qerr();
668         return(1);
669 }
670
671  /*
672   * Machine specific initialization
673   */
674  VOID
675  minit()
676  {
677          static int beenHere=0;      /* set non-zero if we have done that... */
678          struct sym    *sp;
679          struct PreDef *pd;
680                                                                               
681          /*  First time only, add the pe-defined symbols to the symbol table*/
682          if (beenHere == 0) {
683                  pd = preDef;
684                  while (*pd->id) {
685                          sp = lookup(pd->id);
686                          if (sp->s_type == S_NEW) {
687                                  sp->s_addr = pd->value;
688                                  sp->s_type = S_DIR;
689                          }
690                          pd++;
691                 }
692                 beenHere = 1;
693         }
694 }