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