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