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