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