Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc / sdas / asf8 / f8mch.c
blob148cc93dc7d987dd8cd312218b4d5b04f3f48a38
1 /* stm8mch.c */
3 /*
4 * Copyright (C) 2010 Alan R. Baldwin
5 * Copyright (C) 2022-2023 Philipp K. Krause
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * Alan R. Baldwin
22 * 721 Berkeley St.
23 * Kent, Ohio 44240
27 #include "asxxxx.h"
28 #include "f8.h"
30 char *cpu = "f8";
31 char *dsft = "asm";
33 #define NB 512
35 int *bp;
36 int bm;
37 int bb[NB];
40 * Opcode Cycle Definitions
42 #define OPCY_SDP ((char) (0xFF))
43 #define OPCY_ERR ((char) (0xFE))
44 #define OPCY_SKP ((char) (0xFD))
46 /* OPCY_NONE ((char) (0x80)) */
47 /* OPCY_MASK ((char) (0x7F)) */
49 #define UN ((char) (OPCY_NONE | 0x00))
50 #define P1 ((char) (OPCY_NONE | 0x01))
51 #define P2 ((char) (OPCY_NONE | 0x02))
52 #define P3 ((char) (OPCY_NONE | 0x03))
53 #define P4 ((char) (OPCY_NONE | 0x04))
56 * stm8 Opcode Cycle Pages
59 static char stm8pg[256] = {
60 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
61 /*--*--* - - - - - - - - - - - - - - - - */
62 /*00*/ 1, 1, 1, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
63 /*10*/ 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2,
64 /*20*/ 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
65 /*30*/ 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
66 /*40*/ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
67 /*50*/ 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1,
68 /*60*/ 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
69 /*70*/ 1,UN,P1, 1, 1,UN, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
70 /*80*/ 11, 4,UN, 9, 1, 2, 1, 5, 1, 2, 1,UN, 1, 5,10,10,
71 /*90*/ P2,P3,P4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
72 /*A0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1,
73 /*B0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
74 /*C0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
75 /*D0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
76 /*E0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
77 /*F0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2
80 static char pg72[256] = { /* P1: PreByte == 72 */
81 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
82 /*--*--* - - - - - - - - - - - - - - - - */
83 /*00*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
84 /*10*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
85 /*20*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
86 /*30*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
87 /*40*/ 1,UN,UN, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
88 /*50*/ 1,UN,UN, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
89 /*60*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
90 /*70*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
91 /*80*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 1,
92 /*90*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
93 /*A0*/ UN,UN, 2,UN,UN,UN,UN,UN,UN, 2,UN,UN,UN,UN,UN,UN,
94 /*B0*/ 2,UN, 2,UN,UN,UN,UN,UN,UN, 2,UN, 2,UN,UN,UN,UN,
95 /*C0*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
96 /*D0*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
97 /*E0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
98 /*F0*/ 2,UN, 2,UN,UN,UN,UN,UN,UN, 2,UN, 2,UN,UN,UN,UN,
101 static char pg90[256] = { /* P2: PreByte == 90 */
102 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
103 /*--*--* - - - - - - - - - - - - - - - - */
104 /*00*/ UN, 1, 1,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
105 /*10*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
106 /*20*/ UN,UN,UN,UN,UN,UN,UN,UN, 1, 1,UN,UN, 1, 1, 1, 1,
107 /*30*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
108 /*40*/ 1,UN, 4, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
109 /*50*/ 2,UN,UN, 2, 2,UN, 2, 2, 2, 2, 2,UN, 1, 2, 1, 1,
110 /*60*/ 1,UN, 2, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
111 /*70*/ 1,UN,UN, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
112 /*80*/ UN,UN,UN,UN,UN, 2,UN,UN,UN, 2,UN,UN,UN,UN,UN,UN,
113 /*90*/ UN,UN,UN, 1, 1, 1, 1, 1,UN,UN,UN,UN,UN,UN, 1, 1,
114 /*A0*/ UN,UN,UN, 2,UN,UN,UN, 1,UN,UN,UN,UN,UN,UN, 2, 1,
115 /*B0*/ UN,UN,UN, 2,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 2, 2,
116 /*C0*/ UN,UN,UN, 2,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 2, 2,
117 /*D0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
118 /*E0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
119 /*F0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2
122 static char pg91[256] = { /* P3: PreByte == 91 */
123 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
124 /*--*--* - - - - - - - - - - - - - - - - */
125 /*00*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
126 /*10*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
127 /*20*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
128 /*30*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
129 /*40*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
130 /*50*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
131 /*60*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
132 /*70*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
133 /*80*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
134 /*90*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
135 /*A0*/ 10,UN,UN,UN,UN,UN,UN, 1,UN,UN,UN,UN,UN,UN,UN, 1,
136 /*B0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
137 /*C0*/ UN,UN,UN, 5,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 5, 5,
138 /*D0*/ 4, 4, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
139 /*E0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
140 /*F0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN
143 static char pg92[256] = { /* P4: PreByte == 92 */
144 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
145 /*--*--* - - - - - - - - - - - - - - - - */
146 /*00*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
147 /*10*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
148 /*20*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
149 /*30*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
150 /*40*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
151 /*50*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
152 /*60*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
153 /*70*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
154 /*80*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 8,UN,UN,
155 /*90*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
156 /*A0*/ UN,UN,UN,UN,UN,UN,UN, 4,UN,UN,UN,UN, 6,UN,UN, 5,
157 /*B0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 5, 4,UN,UN,
158 /*C0*/ 4, 4, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
159 /*D0*/ 4, 4, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
160 /*E0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
161 /*F0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN
164 static char *Page[5] = {
165 stm8pg, pg72, pg90, pg91, pg92
169 * Process a machine op.
171 VOID
172 machine(mp)
173 struct mne *mp;
175 struct expr e1, e2, e3;
176 int t1, t2, t3;
177 int r1, r2, r3;
178 int op, rf;
180 clrexpr(&e1);
181 clrexpr(&e2);
182 clrexpr(&e3);
183 op = (int) mp->m_valu;
184 rf = mp->m_type;
186 switch(rf) {
187 case S_2OP:
188 case S_2OPSUB:
189 t1 = addr(&e1);
190 r1 = rcode;
191 comma(1);
192 t2 = addr(&e2);
193 r2 = rcode;
195 if(t2 == S_REG && r2 == XL) { // swapped operand.
196 int tr = r1;
197 r1 = r2;
198 r2 = tr;
199 int tt = t1;
200 t1 = t2;
201 t2 = tt;
202 struct expr te = e1;
203 e1 = e2;
204 e2 = te;
205 outab(OPCODE_SWAPOP);
207 else if(t1 != S_REG)
208 aerr();
209 altacc(r1);
211 switch(t2) {
212 case S_IMM:
213 if(rf == S_2OPSUB) // Immediate operand invalid for sub and sbc.
214 aerr();
215 outab(op | 0x00);
216 outrb(&e2, R_NORM);
217 break;
218 case S_DIR:
219 outab(op | 0x01);
220 outrw(&e2, R_USGN);
221 break;
222 case S_SPREL:
223 outab(op | 0x02);
224 if(ls_mode(&e2))
225 aerr();
226 else
227 outrb(&e2, R_USGN);
228 break;
229 case S_ZREL:
230 outab(op | 0x03);
231 outrw(&e2, R_USGN);
232 break;
233 case S_REG:
234 switch(r2) {
235 case ZL:
236 outab(op | 0x04);
237 break;
238 case XH:
239 outab(op | 0x05);
240 break;
241 case YL:
242 outab(op | 0x06);
243 break;
244 case YH:
245 outab(op | 0x07);
246 break;
247 default:
248 aerr();
250 break;
251 default:
252 aerr();
254 break;
256 case S_1OP:
257 case S_1OPPUSH:
258 t1 = addr(&e1);
259 r1 = rcode;
261 if(rf == S_1OPPUSH && t1 == S_IMM) { // push #i
262 outab(0x90);
263 outrb(&e1, R_NORM);
264 break;
267 switch(t1) {
268 case S_DIR:
269 outab(op + 0x00);
270 outrw(&e1, R_USGN);
271 break;
272 case S_SPREL:
273 case S_YREL:
274 outab(op + (t1 == S_SPREL ? 0x01 : 0x03));
275 if(ls_mode(&e1))
276 aerr();
277 else
278 outrb(&e1, R_USGN);
279 break;
280 case S_REG:
281 altacc(r1);
282 outab(op + 0x02);
283 break;
285 default:
286 aerr();
288 break;
290 case S_2OPW:
291 case S_2OPWSUB:
292 case S_2OPWSBC:
293 case S_2OPWADD:
294 case S_2OPWADC:
295 t1 = addr(&e1);
296 r1 = rcode;
297 if(!comma(rf != S_2OPWSBC && rf != S_2OPWADC)) { // Handle 1-op variants of sbcw and adcw
298 if(rf == S_2OPWSBC)
299 op = 0xac;
300 else if(S_2OPWADC)
301 op = 0xa8;
302 else
303 aerr();
304 goto opw;
306 t2 = addr(&e2);
307 r2 = rcode;
309 if(rf == S_2OPWADD && t1 == S_REG && r1 == SP && t2 == S_IMM && !d_mode(&e2)) { // addw sp, #d
310 outab(0xea);
311 outab(e2.e_addr);
312 break;
314 else if(rf == S_2OPWADD && t1 == S_REG && t2 == S_IMM && !d_mode(&e2)) { // addw y, #d
315 altaccw(r1);
316 outab(0xeb);
317 outab(e2.e_addr);
318 break;
321 if(t2 == S_REG && r1 == X && r2 == Y || t1 == S_SPREL || t1 == S_DIR) { // swapped operands.
322 int tr = r1;
323 r1 = r2;
324 r2 = tr;
325 int tt = t1;
326 t1 = t2;
327 t2 = tt;
328 struct expr te = e1;
329 e1 = e2;
330 e2 = te;
331 outab(OPCODE_SWAPOP);
333 else if(t1 != S_REG)
334 aerr();
336 switch(t2) {
337 case S_IMM:
338 altaccw(r1);
339 if(rf == S_2OPWSUB || rf == S_2OPWSBC) // Immediate operand invalid for subw and sbcw.
340 aerr();
341 outab(op | 0x00);
342 outrw(&e2, R_USGN);
343 break;
344 case S_DIR:
345 altaccw(r1);
346 outab(op | 0x01);
347 outrw(&e2, R_USGN);
348 break;
349 case S_SPREL:
350 altaccw(r1);
351 outab(op | 0x02);
352 if(ls_mode(&e1))
353 aerr();
354 else
355 outrb(&e2, R_USGN);
356 break;
357 case S_REG:
358 altaccw2(r1, r2);
359 outab(op | 0x03);
360 break;
361 default:
362 aerr();
364 break;
366 case S_1OPW:
367 case S_1OPWPUSH:
368 t1 = addr(&e1);
369 r1 = rcode;
370 opw:
371 if(rf == S_1OPWPUSH && t1 == S_IMM) { // pushw #ii
372 outab(0xe8);
373 outrw(&e1, R_USGN);
374 break;
377 switch(t1) {
378 case S_DIR:
379 outab(op | 0x00);
380 outrw(&e1, R_USGN);
381 break;
382 case S_SPREL:
383 outab(op | 0x01);
384 if(ls_mode(&e1))
385 aerr();
386 else
387 outrb(&e1, R_USGN);
388 break;
389 case S_ZREL:
390 outab(op | 0x02);
391 outrw(&e1, R_USGN);
392 break;
393 case S_REG:
394 altaccw(r1);
395 outab(op | 0x03);
396 break;
397 default:
398 aerr();
400 break;
402 case S_LD:
403 t1 = addr(&e1);
404 r1 = rcode;
405 comma(1);
406 t2 = addr(&e2);
407 r2 = rcode;
409 if(t1 == S_REG && !(t2 == S_REG && r2 == XL)) {
410 altacc(r1);
411 switch(t2) {
412 case S_IMM:
413 outab(op | 0x00);
414 outrb(&e2, R_NORM);
415 break;
416 case S_DIR:
417 outab(op | 0x01);
418 outrw(&e2, R_USGN);
419 break;
420 case S_SPREL:
421 outab(op | 0x02);
422 if(ls_mode(&e2))
423 aerr();
424 else
425 outrb(&e2, R_USGN);
426 break;
427 case S_ZREL:
428 outab(op | 0x03);
429 outrw(&e2, R_USGN);
430 break;
431 case S_IX:
432 if(r2 == Y)
433 outab(op | 0x04);
434 else if (r1 == ZL && r2 == X || r1 == YL && r2 == Z)
435 outab(0x84);
436 else
437 aerr();
438 break;
439 case S_YREL:
440 outab(op | 0x05);
441 if(ls_mode(&e2))
442 aerr();
443 else
444 outrb(&e2, R_USGN);
445 break;
446 case S_REG:
447 if(r2 == XH)
448 outab(0x86);
449 else if(r2 == YL)
450 outab(0x87);
451 else if(r2 == YH)
452 outab(0x88);
453 else if(r2 == ZL)
454 outab(0x89);
455 else if(r2 == ZH)
456 outab(0x8a);
457 else
458 aerr();
459 break;
460 default:
461 aerr(); // todo
463 break;
465 else if(t1 == S_REG && t2 == S_REG && r2 == XL) { // Use swapop prefix
466 outab(OPCODE_SWAPOP);
467 if(r1 == XH)
468 outab(0x86);
469 else if(r1 == YL)
470 outab(0x87);
471 else if(r1 == YH)
472 outab(0x88);
473 else if(r1 == ZL)
474 outab(0x89);
475 else if(r1 == ZH)
476 outab(0x8a);
477 else
478 aerr();
479 break;
481 else if(t2 == S_REG) {
482 altacc(r2);
483 switch(t1) {
484 case S_DIR:
485 outab(op | 0x0b);
486 outrw(&e1, R_USGN);
487 break;
488 case S_SPREL:
489 outab(op | 0x0c);
490 if(ls_mode(&e1))
491 aerr();
492 else
493 outrb(&e1, R_USGN);
494 break;
495 case S_ZREL:
496 outab(op | 0x0d);
497 outrw(&e1, R_USGN);
498 break;
499 case S_IX:
500 if(r1 == Y && (r2 == XL || r2 == XH || r2 == ZL || r2 == ZH))
501 outab(op | 0x0e);
502 else if (r1 == Z && r2 == YL || r1 == X && r2 == ZL)
503 outab(0x8e);
504 else
505 aerr();
506 break;
507 case S_YREL:
508 outab(op | 0x0f);
509 if(ls_mode(&e1))
510 aerr();
511 else
512 outrb(&e1, R_USGN);
513 break;
514 default:
515 aerr();
517 break;
520 aerr(); // todo
521 break;
523 case S_LDI:
524 t1 = addr(&e1);
525 r1 = rcode;
526 comma(1);
527 t2 = addr(&e2);
528 r2 = rcode;
530 if (t1 == S_YREL && r2 == Z)
532 outab(op);
533 if(ls_mode(&e1))
534 aerr();
535 else
536 outrb(&e1, R_USGN);
538 else
539 aerr();
540 break;
542 case S_LDW:
543 t1 = addr(&e1);
544 r1 = rcode;
545 comma(1);
546 t2 = addr(&e2);
547 r2 = rcode;
549 if(t1 == S_REG && r1 == X && t2 == S_REG && r2 == Y) {
550 outab(op | 0x0b);
551 break;
553 else if(t1 == S_REG && r1 == Z && t2 == S_REG && r2 == Y) {
554 outab(op | 0x0c);
555 break;
557 else if(t1 == S_REG && r1 == X && t2 == S_REG && r2 == Z) {
558 outab(OPCODE_ALTACC3);
559 outab(0xdc);
560 break;
562 else if(t1 == S_REG && r1 == Z && t2 == S_REG && r2 == X) {
563 outab(OPCODE_ALTACC2);
564 outab(0xc6);
565 break;
567 else if(t1 == S_REG && r1 == SP && t2 == S_REG && r2 == Y) { // ldw sp, y
568 outab(OPCODE_SWAPOP);
569 outab(0x70);
570 break;
572 else if (t1 == S_REG && t2 == S_REG && r2 == SP) { // ldw y, sp
573 altaccw(r1);
574 outab(0x70);
575 break;
577 else if(t1 == S_REG && t2 == S_IX && (r1 == X && r2 == Y || r1 == Z && r2 == Y || r1 == Z && r2 == X || r1 == Y && r2 == Z)) { // ldw x, (y)
578 if (r1 == Z && r2 == Y)
579 outab (OPCODE_ALTACC5);
580 else if (r1 == Z && r2 == X)
581 outab (OPCODE_ALTACC3);
582 else if (r1 == Y && r2 == Z)
583 outab (OPCODE_ALTACC2);
584 outab (0xde);
585 break;
587 else if(t1 == S_REG) {
588 altaccw(r1);
589 switch(t2) {
590 case S_IMM:
591 if (!d_mode(&e2)) { // ldw y, #d
592 outab(op | 0x07);
593 outrb(&e2, R_USGN);
594 break;
596 outab(op | 0x00);
597 outrw(&e2, R_USGN);
598 break;
599 case S_DIR:
600 outab(op | 0x01);
601 outrw(&e2, R_USGN);
602 break;
603 case S_SPREL:
604 outab(op | 0x02);
605 if(ls_mode(&e2))
606 aerr();
607 else
608 outrb(&e2, R_USGN);
609 break;
610 case S_ZREL:
611 outab(op | 0x03);
612 outrw(&e2, R_USGN);
613 break;
614 case S_YREL:
615 outab(op | 0x04);
616 if(ls_mode(&e2))
617 aerr();
618 else
619 outrb(&e2, R_USGN);
620 break;
621 case S_IX:
622 if((r1 == Y || r1 == Z || r1 == X) && r1 == r2)
623 outab(0xc5);
624 else
625 aerr();
626 break;
627 case S_REG:
628 if(r2 == X)
629 outab(op | 0x06);
630 else if (r2 == Z)
631 outab(0xdc);
632 else
633 aerr();
634 break;
635 default:
636 aerr(); // todo
638 break;
640 else if(t1 == S_IX && t2 == S_REG && (r1 == Y && r2 == X || r1 == Z && r2 == Y || r1 == X && r2 == Z || r1 == Y && r2 == Z)) {
641 altaccw2(r1, r2);
642 outab(0xcd);
643 break;
645 else if(t1 == S_YREL && t2 == S_REG && (r2 == X || r2 == Z)) {
646 if (r2 == Z)
647 outab (OPCODE_ALTACC3);
648 if(!ls_mode(&e2)) {
649 outab(0xce);
650 outrb(&e1, R_USGN);
652 else
653 aerr();
654 break;
656 else if(t2 == S_REG) {
657 altaccw(r2);
658 switch(t1) {
659 case S_DIR:
660 outab(op | 0x08);
661 outrw(&e1, R_USGN);
662 break;
663 case S_SPREL:
664 outab(op | 0x09);
665 if(ls_mode(&e1))
666 aerr();
667 else
668 outrb(&e1, R_USGN);
669 break;
670 case S_ZREL:
671 outab(op | 0x0a);
672 outrw(&e1, R_USGN);
673 break;
674 case S_ISPREL:
675 outab(0x74);
676 if(ls_mode(&e1))
677 aerr();
678 else
679 outrb(&e1, R_USGN);
680 break;
681 default:
682 aerr(); // todo
684 break;
687 aerr(); // todo
688 break;
690 case S_0OP:
691 t1 = addr(&e1);
692 r1 = rcode;
694 if(t1 == S_REG) {
695 altacc(r1);
696 outab(op);
698 else
699 aerr();
701 break;
703 case S_0OPXCH:
704 t1 = addr(&e1);
705 r1 = rcode;
706 comma(1);
707 t2 = addr(&e2);
708 r2 = rcode;
710 if (t1 == S_REG && r1 == F && t2 == S_SPREL) { // xch f, (n, sp)
711 outab(0xec);
712 if(ls_mode(&e2))
713 aerr();
714 else
715 outrb(&e2, R_USGN);
716 break;
719 if (t1 != S_REG)
720 aerr();
721 switch(t2) {
722 case S_SPREL:
723 altacc(r1);
724 outab(0x91);
725 if(ls_mode(&e1))
726 aerr();
727 else
728 outrb(&e2, R_USGN);
729 break;
730 case S_IX:
731 altacc(r1);
732 if (!((r1 == XL || r1 == XH) && r2 == Y) && !(r1 == YL && r2 == Z) && !(r1 == ZL && r2 == X))
733 aerr();
734 outab(0x92);
735 break;
736 case S_REG:
737 if (r1 == YL && r2 == YH)
738 outab(0x93);
739 else if (r1 == XL && r2 == XH) {
740 outab(OPCODE_ALTACC3);
741 outab(0x93);
743 else if (r1 == ZL && r2 == ZH) {
744 outab(OPCODE_ALTACC2);
745 outab(0x93);
747 else
748 aerr();
749 break;
750 default:
751 aerr();
753 break;
755 case S_0OPROT:
756 t1 = addr(&e1);
757 r1 = rcode;
758 comma(1);
759 t2 = addr(&e2);
760 r2 = rcode;
762 if (t1 == S_REG && t2 == S_IMM) {
763 altacc(r1);
764 outab(op);
765 outrb(&e2, R_NORM);
767 else
768 aerr ();
769 break;
771 case S_0OPMAD:
772 t1 = addr(&e1);
773 r1 = rcode;
774 comma(1);
775 t2 = addr(&e2);
776 r2 = rcode;
777 comma(1);
778 t3 = addr(&e3);
779 r3 = rcode;
781 if(t1 != S_REG || r1 != X)
782 aerr();
783 if(t3 != S_REG || r3 != YL)
784 aerr();
786 switch(t2) {
787 case S_DIR:
788 outab(0xbc);
789 outrw(&e2, R_USGN);
790 break;
791 case S_SPREL:
792 outab(0xbd);
793 if(ls_mode(&e2))
794 aerr();
795 else
796 outrb(&e2, R_USGN);
797 break;
798 case S_ZREL:
799 outab(0xbe);
800 outrw(&e2, R_USGN);
801 break;
802 case S_IX:
803 if(r2 == Z)
804 outab(0xbf);
805 else
806 aerr();
807 break;
808 default:
809 aerr();
811 break;
813 case S_0OPWXCH:
814 t1 = addr(&e1);
815 r1 = rcode;
816 comma(1);
817 t2 = addr(&e2);
818 r2 = rcode;
819 if(t1 == S_REG && t2 == S_IX && (r1 == X && r2 == Y || r1 == Y && r2 == Z || r1 == Z && r2 == X)) {
820 altaccw(r2);
821 outab(0xf4);
823 else if(t1 == S_REG && t2 == S_IX && (r1 == Z && r2 == Y)) {
824 outab(OPCODE_ALTACC5);
825 outab(0xf4);
827 else if(t2 != S_SPREL || ls_mode(&e2))
828 aerr();
829 else {
830 altaccw(r1);
831 outab(0xf5);
832 outrb(&e2, R_USGN);
834 break;
837 case S_0OPW:
838 case S_0OPWSLL:
839 case S_0OPWRLC:
840 case S_0OPWDEC:
841 t1 = addr(&e1);
842 r1 = rcode;
844 if(rf == S_0OPWSLL && comma(0)) {
845 t2 = addr(&e2);
846 r2 = rcode;
847 op = 0xe5;
848 goto sex;
851 if(t1 == S_REG && rf != S_0OPWDEC) {
852 altaccw(r1);
853 outab(op);
855 else if((rf == S_0OPWRLC || rf == S_0OPWDEC) && t1 == S_SPREL) {
856 outab(op + 0x04);
857 if(ls_mode(&e1))
858 aerr();
859 else
860 outrb(&e1, R_USGN);
861 break;
863 else
864 aerr();
865 break;
867 case S_0OPWCP:
868 t1 = addr(&e1);
869 r1 = rcode;
870 comma(1);
871 t2 = addr(&e2);
872 r2 = rcode;
874 if(t1 == S_REG && t2 == S_IMM) {
875 altaccw(r1);
876 outab(op);
877 outrw(&e2, R_USGN);
879 else
880 aerr();
881 break;
883 case S_0OPWSEX:
884 t1 = addr(&e1);
885 r1 = rcode;
886 comma(1);
887 t2 = addr(&e2);
888 r2 = rcode;
889 sex:
890 altaccw2(r1, r2);
891 outab(op);
892 break;
894 case S_BIT:
895 t1 = addr(&e1);
896 r1 = rcode;
897 comma(1);
898 t2 = addr(&e2);
899 r2 = rcode;
900 comma(1);
901 t3 = addr(&e3);
902 int v3 = (int) e3.e_addr;
904 if(t1 == S_REG && t2 == S_DIR && t3 == S_IMM && (v3 <= 7)) {
905 altacc(r1);
906 outab(op | v3);
907 outrw(&e2, R_USGN);
909 else
910 aerr();
911 break;
913 case S_JR2:
914 outab(OPCODE_SWAPOP);
915 case S_JR:
916 expr(&e1, 0);
917 outab(op);
918 if(mchpcr(&e1)) {
919 int v1 = (int)(e1.e_addr - dot.s_addr + 1);
920 if((v1 < -128) || (v1 > 127))
921 aerr();
922 outab(v1);
923 } else {
924 e1.e_addr -= 1;
925 outrb(&e1, R_PCR);
927 if(e1.e_mode != S_USER) {
928 rerr();
930 break;
932 case S_DNJNZ:
933 t1 = addr(&e1);
934 r1 = rcode;
935 comma(1);
936 if (t1 == S_REG && r1 == YH)
937 altaccw(Y);
938 else if (t1 == S_REG && r1 == XH)
939 altaccw(X);
940 else if (t1 == S_REG && r1 == ZH)
941 altaccw(Z);
942 else
943 aerr();
944 expr(&e2, 0);
945 outab(op);
946 if(mchpcr(&e2)) {
947 int v2 = (int)(e2.e_addr - dot.s_addr + 1);
948 if((v2 < -128) || (v2 > 127))
949 aerr();
950 outab(v2);
951 } else {
952 e1.e_addr -= 1;
953 outrb(&e2, R_PCR);
955 if(e2.e_mode != S_USER) {
956 rerr();
958 break;
960 case S_JP:
961 t1 = addr(&e1);
962 r1 = rcode;
964 if(t1 == S_REG) {
965 altaccw(r1);
966 outab(op | 0x01);
968 else if(t1 == S_IMM) {
969 outab(op);
970 outrw(&e1, R_USGN);
972 else
973 aerr();
975 break;
977 case S_RET:
978 case S_NOP:
979 case S_TRAP:
980 outab(op);
981 break;
983 case S_0OPMSK:
984 t1 = addr(&e1);
985 r1 = rcode;
986 comma(1);
987 t2 = addr(&e2);
988 r2 = rcode;
989 comma(1);
990 t3 = addr(&e3);
991 r3 = rcode;
993 if(t1 == S_IX && t2 == S_REG && t3 == S_IMM &&
994 (r1 == Y && r2 == XL || r1 == Y && r2 == XH || r1 == Z && r2 == YL || r1 == X && r2 == ZL || r1 == Y && r2 == ZH)) {
995 altacc(r2);
996 outab(op);
997 outrb(&e3, R_NORM);
999 else
1000 aerr();
1002 break;
1004 case S_0OPCAX:
1005 t1 = addr(&e1);
1006 r1 = rcode;
1007 comma(1);
1008 t2 = addr(&e2);
1009 r2 = rcode;
1010 comma(1);
1011 t3 = addr(&e3);
1012 r3 = rcode;
1014 if(t1 == S_IX && r1 == Y && t2 == S_REG && r2 == ZL && t3 == S_REG && (r3 == XL || r3 == XH)) {
1015 altacc(r3);
1016 outab(op);
1018 else
1019 aerr();
1021 break;
1023 case S_0OPWCAX:
1024 t1 = addr(&e1);
1025 r1 = rcode;
1026 comma(1);
1027 t2 = addr(&e2);
1028 r2 = rcode;
1029 comma(1);
1030 t3 = addr(&e3);
1031 r3 = rcode;
1033 if(t1 == S_IX && r1 == Y && t2 == S_REG && r2 == Z && t3 == S_REG && r3 == X)
1034 outab(op);
1035 else
1036 aerr();
1038 break;
1040 default:
1041 opcycles = OPCY_ERR;
1042 err('o');
1043 break;
1046 if (opcycles == OPCY_NONE) {
1047 opcycles = stm8pg[cb[0] & 0xFF];
1048 if ((opcycles & OPCY_NONE) && (opcycles & OPCY_MASK)) {
1049 opcycles = Page[opcycles & OPCY_MASK][cb[1] & 0xFF];
1055 * Disable Opcode Cycles with aerr()
1057 VOID
1058 opcy_aerr()
1060 opcycles = OPCY_SKP;
1061 aerr();
1065 * Select the long or short addressing mode
1066 * based upon the expression type and value.
1067 * Return 1 for 16-bit offset, 0 for 8-bit offset.
1070 ls_mode(e)
1071 struct expr *e;
1073 int flag, v;
1075 v = (int) e->e_addr;
1077 * 1) area based arguments (e_base.e_ap != 0) use longer mode
1078 * 2) constant arguments (e_base.e_ap == 0) use
1079 * shorter mode if (arg & ~0xFF) == 0
1080 * longer mode if (arg & ~0xFF) != 0
1082 if (pass == 0) {
1084 } else
1085 if (e->e_base.e_ap) {
1087 } else
1088 if (pass == 1) {
1089 if (e->e_addr >= dot.s_addr) {
1090 e->e_addr -= fuzz;
1092 flag = (v & ~0xFF) ? 1 : 0;
1093 return(setbit(flag) ? 1 : 0);
1094 } else {
1095 return(getbit() ? 1 : 0);
1097 return(1);
1101 * Select the long or short immediate mode
1103 * based upon the expression type and value.
1104 * Return 1 for 16-bit, 0 for 8-bit.
1107 d_mode(e)
1108 struct expr *e;
1110 int flag, v;
1112 v = (int) e->e_addr;
1114 * 1) area based arguments (e_base.e_ap != 0) use longer mode
1115 * 2) constant arguments (e_base.e_ap == 0) use
1116 * shorter mode if (arg & ~0x7F) == 0 or ~0x7f
1117 * longer mode otherwise
1119 if (pass == 0) {
1121 } else
1122 if (e->e_base.e_ap) {
1124 } else
1125 if (pass == 1) {
1126 if (e->e_addr >= dot.s_addr) {
1127 e->e_addr -= fuzz;
1129 flag = (((v & ~0x7f) & 0xffff) == (~0x7f & 0xffff) || (v & ~0x7f) == 0) ? 0 : 1;
1130 return(setbit(flag) ? 1 : 0);
1131 } else {
1132 return(getbit() ? 1 : 0);
1134 return(1);
1138 * Generate an 'a' error if the absolute
1139 * value is not a valid unsigned or signed value.
1141 VOID
1142 valu_aerr(e, n)
1143 struct expr *e;
1144 int n;
1146 int v;
1148 if (is_abs(e)) {
1149 v = e->e_addr;
1150 switch(n) {
1151 default:
1152 #ifdef LONGINT
1153 case 1: if ((v & ~0x000000FFl) && ((v & ~0x000000FFl) != ~0x000000FFl)) aerr(); break;
1154 case 2: if ((v & ~0x0000FFFFl) && ((v & ~0x0000FFFFl) != ~0x0000FFFFl)) aerr(); break;
1155 case 3: if ((v & ~0x00FFFFFFl) && ((v & ~0x00FFFFFFl) != ~0x00FFFFFFl)) aerr(); break;
1156 case 4: if ((v & ~0xFFFFFFFFl) && ((v & ~0xFFFFFFFFl) != ~0xFFFFFFFFl)) aerr(); break;
1157 #else
1158 case 1: if ((v & ~0x000000FF) && ((v & ~0x000000FF) != ~0x000000FF)) aerr(); break;
1159 case 2: if ((v & ~0x0000FFFF) && ((v & ~0x0000FFFF) != ~0x0000FFFF)) aerr(); break;
1160 case 3: if ((v & ~0x00FFFFFF) && ((v & ~0x00FFFFFF) != ~0x00FFFFFF)) aerr(); break;
1161 case 4: if ((v & ~0xFFFFFFFF) && ((v & ~0xFFFFFFFF) != ~0xFFFFFFFF)) aerr(); break;
1162 #endif
1168 * Branch/Jump PCR Mode Check
1171 mchpcr(esp)
1172 struct expr *esp;
1174 if (esp->e_base.e_ap == dot.s_area) {
1175 return(1);
1177 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
1179 * Absolute Destination
1181 * Use the global symbol '.__.ABS.'
1182 * of value zero and force the assembler
1183 * to use this absolute constant as the
1184 * base value for the relocation.
1186 esp->e_flag = 1;
1187 esp->e_base.e_sp = &sym[1];
1189 return(0);
1193 * Machine specific initialization.
1195 VOID
1196 minit()
1199 * 24-Bit Machine
1201 exprmasks(3);
1204 * Byte Order
1206 hilo = 0; // Little-endian
1209 * Reset Bit Table
1211 bp = bb;
1212 bm = 1;
1216 * Store `b' in the next slot of the bit table.
1217 * If no room, force the longer form of the offset.
1220 setbit(b)
1221 int b;
1223 if (bp >= &bb[NB])
1224 return(1);
1225 if (b)
1226 *bp |= bm;
1227 bm <<= 1;
1228 if (bm == 0) {
1229 bm = 1;
1230 ++bp;
1232 return(b);
1236 * Get the next bit from the bit table.
1237 * If none left, return a `1'.
1238 * This will force the longer form of the offset.
1241 getbit()
1243 int f;
1245 if (bp >= &bb[NB])
1246 return (1);
1247 f = *bp & bm;
1248 bm <<= 1;
1249 if (bm == 0) {
1250 bm = 1;
1251 ++bp;
1253 return (f);
1256 /* Emit prefix byte for alternative accumulator */
1257 extern
1258 void altacc(int reg)
1260 if(reg != XL) {
1261 if(reg == XH)
1262 outab(OPCODE_ALTACC1);
1263 else if(reg == YL)
1264 outab(OPCODE_ALTACC2);
1265 else if(reg == ZL)
1266 outab(OPCODE_ALTACC3);
1267 else if(reg == YH)
1268 outab(OPCODE_ALTACC4);
1269 else if(reg == ZH)
1270 outab(OPCODE_ALTACC5);
1271 else
1272 aerr();
1276 extern
1277 void altaccw(int reg)
1279 if(reg != Y) {
1280 if(reg == X)
1281 outab(OPCODE_ALTACC3);
1282 else if(reg == Z)
1283 outab(OPCODE_ALTACC2);
1284 else
1285 aerr();
1289 extern
1290 void altaccw2(int reg0, int reg1)
1292 if(reg0 == Y && (reg1 == X || reg1 == XL))
1294 else if (reg0 == Y && (reg1 == XH))
1295 outab(OPCODE_ALTACC1);
1296 else if (reg0 == Z && (reg1 == Y || reg1 == YL))
1297 outab(OPCODE_ALTACC2);
1298 else if (reg0 == X && (reg1 == Z || reg1 == ZL))
1299 outab(OPCODE_ALTACC3);
1300 else if (reg0 == Z && (reg1 == YH))
1301 outab(OPCODE_ALTACC4);
1302 else if (reg0 == Y && (reg1 == Z || reg1 == ZH))
1303 outab(OPCODE_ALTACC5);
1304 else
1305 aerr ();