5c54496b086319f339701b46e0b4d899b8ce3675
[fw/sdcc] / as / hc08 / m08mch.c
1 /* m08mch.c */
2
3 /*
4  * (C) Copyright 1993-2002
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  */
11
12 #include <stdio.h>
13 #include <setjmp.h>
14 #include "asm.h"
15 #include "m6808.h"
16
17 /*
18  * Process a machine op.
19  */
20 VOID
21 machine(mp)
22 struct mne *mp;
23 {
24         register int op, t1, t2, type;
25         struct expr e1, e2, e3;
26         Addr_T espv;
27         struct area *espa;
28         char id[NCPS];
29         int c, v1;
30
31         clrexpr(&e1);
32         clrexpr(&e2);
33         clrexpr(&e3);
34         op = mp->m_valu;
35         type = mp->m_type;
36         switch (type) {
37
38         case S_SDP:
39                 espa = NULL;
40                 if (more()) {
41                         expr(&e1, 0);
42                         if (e1.e_flag == 0 && e1.e_base.e_ap == NULL) {
43                                 if (e1.e_addr) {
44                                         err('b');
45                                 }
46                         }
47                         if ((c = getnb()) == ',') {
48                                 getid(id, -1);
49                                 espa = alookup(id);
50                                 if (espa == NULL) {
51                                         err('u');
52                                 }
53                         } else {
54                                 unget(c);
55                         }
56                 }
57                 if (espa) {
58                         outdp(espa, &e1);
59                 } else {
60                         outdp(dot.s_area, &e1);
61                 }
62                 lmode = SLIST;
63                 break;
64
65         case S_INH:
66                 outab(op);
67                 break;
68
69         case S_BRA:
70                 expr(&e1, 0);
71                 outab(op);
72                 if (mchpcr(&e1)) {
73                         v1 = e1.e_addr - dot.s_addr - 1;
74                         if ((v1 < -128) || (v1 > 127))
75                                 aerr();
76                         outab(v1);
77                 } else {
78                         outrb(&e1, R_PCR);
79                 }
80                 if (e1.e_mode != S_USER)
81                         rerr();
82                 break;
83
84         case S_TYP1:
85                 t1 = addr(&e1);
86                 if (t1 == S_A) {
87                         outab(op+0x10);
88                         break;
89                 }
90                 if (t1 == S_X) {
91                         outab(op+0x20);
92                         break;
93                 }
94                 if (t1 == S_DIR || t1 == S_EXT) {
95                         outab(op);
96                         outrb(&e1, R_PAG0);
97                         break;
98                 }
99                 if (t1 == S_IX) {
100                         outab(op+0x40);
101                         break;
102                 }
103                 if (t1 == S_IX1 || t1 == S_IX2) {
104                         if (chkindx(&e1))
105                                 aerr();
106                         outab(op+0x30);
107                         outrb(&e1, R_USGN);
108                         break;
109                 }
110                 if (t1 == S_SP1 || t1 == S_SP2) {
111                         if (chkindx(&e1))
112                                 aerr();
113                         outab(0x9e);
114                         outab(op+0x30);
115                         outrb(&e1, R_USGN);
116                         break;
117                 }
118                 aerr();
119                 break;
120
121         case S_TYP2:
122                 t1 = addr(&e1);
123                 if (t1 == S_IMMED) {
124                         if ((op == 0xA7) || (op == 0xAC) ||
125                             (op == 0xAD) || (op == 0xAF))
126                                 aerr();
127                         outab(op);
128                         outrb(&e1, 0);
129                         break;
130                 }
131                 if (t1 == S_DIR) {
132                         outab(op+0x10);
133                         outrb(&e1, R_PAG0);
134                         break;
135                 }
136                 if (t1 == S_EXT) {
137                         outab(op+0x20);
138                         outrw(&e1, 0);
139                         break;
140                 }
141                 if (t1 == S_IX) {
142                         outab(op+0x50);
143                         break;
144                 }
145                 if (t1 == S_IX1) {
146                         outab(op+0x40);
147                         outrb(&e1, R_USGN);
148                         break;
149                 }
150                 if (t1 == S_IX2) {
151                         outab(op+0x30);
152                         outrw(&e1, 0);
153                         break;
154                 }
155                 if (t1 == S_SP1) {
156                         if (op == 0xAC || op == 0xAD)
157                                 aerr();
158                         outab(0x9e);
159                         outab(op+0x40);
160                         outrb(&e1, R_USGN);
161                         break;
162                 }
163                 if (t1 == S_SP2) {
164                         if (op == 0xAC || op == 0xAD)
165                                 aerr();
166                         outab(0x9e);
167                         outab(op+0x30);
168                         outrw(&e1, 0);
169                         break;
170                 }
171                 aerr();
172                 break;
173
174         case S_TYP3:
175                 t1 = addr(&e1);
176                 espv = e1.e_addr;
177                 if (t1 != S_IMMED || espv & ~0x07)
178                         aerr();
179                 comma();
180                 t2 = addr(&e2);
181                 if (t2 != S_DIR)
182                         aerr();
183                 outab(op + 2*(espv&0x07));
184                 outrb(&e2, R_PAG0);
185                 break;
186
187         case S_TYP4:
188                 t1 = addr(&e1);
189                 espv = e1.e_addr;
190                 if (t1 != S_IMMED || espv & ~0x07)
191                         aerr();
192                 comma();
193                 t2 = addr(&e2);
194                 if (t2 != S_DIR)
195                         aerr();
196                 comma();
197                 expr(&e3, 0);
198                 outab(op + 2*(espv&0x07));
199                 outrb(&e2, R_PAG0);
200                 if (mchpcr(&e3)) {
201                         v1 = e3.e_addr - dot.s_addr - 1;
202                         if ((v1 < -128) || (v1 > 127))
203                                 aerr();
204                         outab(v1);
205                 } else {
206                         outrb(&e3, R_PCR);
207                 }
208                 if (e3.e_mode != S_USER)
209                         rerr();
210                 break;
211
212         case S_TYPAI:
213                 t1 = addr(&e1);
214                 if (t1 == S_IMMED) {
215                         outab(op);
216                         if (e1.e_flag == 0 && e1.e_base.e_ap == NULL) {
217                                 v1 = e1.e_addr;
218                                 if ((v1 < -128) || (v1 > 127))
219                                         aerr();
220                                 outab(v1);
221                         } else {
222                                 outrb(&e1, 0);
223                         }
224                         break;
225                 }
226                 aerr();
227                 break;
228
229         case S_TYPHX:
230                 t1 = addr(&e1);
231                 if (t1 == S_IMMED) {
232                         if (op == 0x25)
233                                 aerr();
234                         outab(op);
235                         outrw(&e1, 0);
236                         break;
237                 }
238                 if (t1 == S_DIR || t1 == S_EXT) {
239                         outab(op | 0x10);
240                         outrb(&e1, R_PAG0);
241                         break;
242                 }
243                 aerr();
244                 break;
245
246         case S_CBEQ:
247                 t1 = addr(&e1);
248                 comma();
249                 expr(&e2, 0);
250                 if (t1 == S_IMMED) {
251                         outab(op);
252                         outrb(&e1, 0);
253                 } else
254                 if (t1 == S_DIR || t1 == S_EXT) {
255                         outab(op);
256                         outrb(&e1, R_PAG0);
257                 } else
258                 if (t1 == S_IXP) {
259                         outab(op+0x40);
260                 } else
261                 if (t1 == S_IX1P || t1 == S_IX2P) {
262                         if (chkindx(&e1))
263                                 aerr();
264                         outab(op+0x30);
265                         outrb(&e1, R_USGN);
266                 } else
267                 if (t1 == S_SP1 || t1 == S_SP2) {
268                         if (chkindx(&e1))
269                                 aerr();
270                         outab(0x9E);
271                         outab(op+0x30);
272                         outrb(&e1, R_USGN);
273                 } else {
274                         aerr();
275                         break;
276                 }
277                 if (mchpcr(&e2)) {
278                         v1 = e2.e_addr - dot.s_addr - 1;
279                         if ((v1 < -128) || (v1 > 127))
280                                 aerr();
281                         outab(v1);
282                 } else {
283                         outrb(&e2, R_PCR);
284                 }
285                 if (e2.e_mode != S_USER)
286                         rerr();
287                 break;
288
289         case S_CQAX:
290                 t1 = addr(&e1);
291                 if (t1 != S_IMMED)
292                         aerr();
293                 comma();
294                 expr(&e2, 0);
295                 outab(op);
296                 outrb(&e1, 0);
297                 if (mchpcr(&e2)) {
298                         v1 = e2.e_addr - dot.s_addr - 1;
299                         if ((v1 < -128) || (v1 > 127))
300                                 aerr();
301                         outab(v1);
302                 } else {
303                         outrb(&e2, R_PCR);
304                 }
305                 if (e2.e_mode != S_USER)
306                         rerr();
307                 break;
308
309         case S_DBNZ:
310                 t1 = addr(&e1);
311                 comma();
312                 expr(&e2, 0);
313                 if (t1 == S_DIR || t1 == S_EXT) {
314                         outab(op);
315                         outrb(&e1, R_PAG0);
316                 } else
317                 if (t1 == S_IX) {
318                         outab(op+0x40);
319                 } else
320                 if (t1 == S_IX1 || t1 == S_IX2) {
321                         if (chkindx(&e1))
322                                 aerr();
323                         outab(op+0x30);
324                         outrb(&e1, R_USGN);
325                 } else
326                 if (t1 == S_SP1 || t1 == S_SP2) {
327                         if (chkindx(&e1))
328                                 aerr();
329                         outab(0x9E);
330                         outab(op+0x30);
331                         outrb(&e1, R_USGN);
332                 } else {
333                         aerr();
334                         break;
335                 }
336                 if (mchpcr(&e2)) {
337                         v1 = e2.e_addr - dot.s_addr - 1;
338                         if ((v1 < -128) || (v1 > 127))
339                                 aerr();
340                         outab(v1);
341                 } else {
342                         outrb(&e2, R_PCR);
343                 }
344                 if (e2.e_mode != S_USER)
345                         rerr();
346                 break;
347
348         case S_DZAX:
349                 expr(&e1, 0);
350                 outab(op);
351                 if (mchpcr(&e1)) {
352                         v1 = e1.e_addr - dot.s_addr - 1;
353                         if ((v1 < -128) || (v1 > 127))
354                                 aerr();
355                         outab(v1);
356                 } else {
357                         outrb(&e1, R_PCR);
358                 }
359                 if (e1.e_mode != S_USER)
360                         rerr();
361                 break;
362
363         case S_MOV:
364                 t1 = addr(&e1);
365                 if (t1 == S_IX1P || t1 == S_IX2P) {
366                         if (chkindx(&e1))
367                                 aerr();
368                         outab(op+0x10);
369                         outrb(&e1, R_PAG0);
370                         break;
371                 }
372                 comma();
373                 t2 = addr(&e2);
374                 if (t1 == S_IMMED) {
375                         if (t2 == S_DIR || t2 == S_EXT) {
376                                 outab(op+0x20);
377                                 outrb(&e1, 0);
378                                 outrb(&e2, R_PAG0);
379                                 break;
380                         }
381                 }
382                 if (t1 == S_DIR || t1 == S_EXT) {
383                         if (t2 == S_DIR || t2 == S_EXT) {
384                                 outab(op);
385                                 outrb(&e1, R_PAG0);
386                                 outrb(&e2, R_PAG0);
387                                 break;
388                         }
389                 }
390                 if (t1 == S_IXP) {
391                         if (t2 == S_DIR || t2 == S_EXT) {
392                                 outab(op+0x30);
393                                 outrb(&e2, R_PAG0);
394                                 break;
395                         }
396                 }
397                 aerr();
398                 break;
399
400         default:
401                 err('o');
402         }
403 }
404
405 /*
406  * Check index byte
407  */
408 int
409 chkindx(exp)
410 struct expr *exp;
411 {
412         if (exp->e_flag == 0 && exp->e_base.e_ap == NULL) {
413                 if (exp->e_addr & ~0xFF) {
414                         return(1);
415                 }
416         }
417         return(0);
418 }
419
420 /*
421  * Branch/Jump PCR Mode Check
422  */
423 int
424 mchpcr(esp)
425 register struct expr *esp;
426 {
427         if (esp->e_base.e_ap == dot.s_area) {
428                 return(1);
429         }
430         if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
431                 /*
432                  * Absolute Destination
433                  *
434                  * Use the global symbol '.__.ABS.'
435                  * of value zero and force the assembler
436                  * to use this absolute constant as the
437                  * base value for the relocation.
438                  */
439                 esp->e_flag = 1;
440                 esp->e_base.e_sp = &sym[1];
441         }
442         return(0);
443 }
444
445 /*
446  * The next character must be a
447  * comma.
448  */
449 int
450 comma()
451 {
452         if (getnb() != ',')
453                 qerr();
454         return(1);
455 }
456
457 /*
458  * Machine specific initialization.
459  */
460 VOID
461 minit()
462 {
463 }