Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1186 | savelij | 1 | /* coderx.c */ |
2 | /*****************************************************************************/ |
||
3 | /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */ |
||
4 | /* */ |
||
5 | /* AS-Portierung */ |
||
6 | /* */ |
||
7 | /* Codegenerator Renesas RX */ |
||
8 | /* */ |
||
9 | /*****************************************************************************/ |
||
10 | |||
11 | #include "stdinc.h" |
||
12 | #include <ctype.h> |
||
13 | #include <string.h> |
||
14 | |||
15 | #include "nls.h" |
||
16 | #include "strutil.h" |
||
17 | #include "chunks.h" |
||
18 | #include "asmdef.h" |
||
19 | #include "asmsub.h" |
||
20 | #include "asmpars.h" |
||
21 | #include "asmitree.h" |
||
22 | #include "codevars.h" |
||
23 | #include "codepseudo.h" |
||
24 | #include "headids.h" |
||
25 | #include "errmsg.h" |
||
26 | #include "ieeefloat.h" |
||
27 | #include "onoff_common.h" |
||
28 | #include "intpseudo.h" |
||
29 | #include "be_le.h" |
||
30 | |||
31 | #include "coderx.h" |
||
32 | |||
33 | /*---------------------------------------------------------------------------*/ |
||
34 | |||
35 | /* Define this to use Renesas Assembler like pseudo instructions */ |
||
36 | #define COMPAT |
||
37 | |||
38 | /*---------------------------------------------------------------------------*/ |
||
39 | |||
40 | typedef enum |
||
41 | { |
||
42 | eRn, |
||
43 | eDRn, |
||
44 | eDRHn, |
||
45 | eDRLn, |
||
46 | eDCRn |
||
47 | } tRegType; |
||
48 | |||
49 | typedef enum |
||
50 | { |
||
51 | eRXv1, |
||
52 | eRXv2, |
||
53 | eRXv3 |
||
54 | } tInstSet; |
||
55 | |||
56 | typedef struct |
||
57 | { |
||
58 | char Name[7]; |
||
59 | tInstSet InstSet; |
||
60 | Boolean hasFloat; |
||
61 | Boolean hasDouble; |
||
62 | Word RegBank; |
||
63 | Boolean hasMVTIPL; |
||
64 | } tCPUProps; |
||
65 | |||
66 | /*---------------------------------------------------------------------------*/ |
||
67 | |||
68 | static const tCPUProps *pCurrCPUProps; |
||
69 | |||
70 | static tStrComp Temp1; |
||
71 | static tStrComp Temp2; |
||
72 | |||
73 | /*---------------------------------------------------------------------------*/ |
||
74 | |||
75 | static Boolean ChkNoAttr(void) |
||
76 | { |
||
77 | if (AttrPart.str.p_str[0]) |
||
78 | { |
||
79 | WrError(ErrNum_UseLessAttr); |
||
80 | return False; |
||
81 | } |
||
82 | |||
83 | return True; |
||
84 | } |
||
85 | |||
86 | static Boolean CheckSup(void) |
||
87 | { |
||
88 | if (SupAllowed) return True; |
||
89 | |||
90 | WrStrErrorPos(ErrNum_PrivOrder, &OpPart); |
||
91 | return False; |
||
92 | } |
||
93 | |||
94 | static Boolean CheckV2(void) |
||
95 | { |
||
96 | if (pCurrCPUProps->InstSet >= eRXv2) return True; |
||
97 | |||
98 | WrError(ErrNum_InstructionNotSupported); |
||
99 | return False; |
||
100 | } |
||
101 | |||
102 | static Boolean CheckV3(void) |
||
103 | { |
||
104 | if (pCurrCPUProps->InstSet >= eRXv3) return True; |
||
105 | |||
106 | WrError(ErrNum_InstructionNotSupported); |
||
107 | return False; |
||
108 | } |
||
109 | |||
110 | static Boolean CheckFloat(void) |
||
111 | { |
||
112 | if (pCurrCPUProps->hasFloat) return True; |
||
113 | |||
114 | WrError(ErrNum_FPUNotEnabled); |
||
115 | return False; |
||
116 | } |
||
117 | |||
118 | static Boolean CheckDouble(void) |
||
119 | { |
||
120 | if (pCurrCPUProps->hasDouble) return True; |
||
121 | |||
122 | WrError(ErrNum_FPUNotEnabled); |
||
123 | return False; |
||
124 | } |
||
125 | |||
126 | static const char *DCReg[] = { |
||
127 | "DPSW", |
||
128 | "DCMR", |
||
129 | "DECNT", |
||
130 | "DEPC" |
||
131 | }; |
||
132 | |||
133 | static Boolean DecodeReg(const tStrComp *pArg, Byte *pResult, tRegType type) |
||
134 | { |
||
135 | const char *str = pArg->str.p_str; |
||
136 | const int len = strlen(str); |
||
137 | int i; |
||
138 | int num = 16; |
||
139 | |||
140 | switch (type) |
||
141 | { |
||
142 | case eRn: |
||
143 | if (as_strncasecmp(str, "R", 1)) return False; |
||
144 | i = 1; |
||
145 | break; |
||
146 | case eDRn: |
||
147 | if (as_strncasecmp(str, "DR", 2)) return False; |
||
148 | i = 2; |
||
149 | break; |
||
150 | case eDRHn: |
||
151 | if (as_strncasecmp(str, "DRH", 3)) return False; |
||
152 | i = 3; |
||
153 | break; |
||
154 | case eDRLn: |
||
155 | if (as_strncasecmp(str, "DRL", 3)) return False; |
||
156 | i = 3; |
||
157 | break; |
||
158 | case eDCRn: |
||
159 | for (i = 0; i < 4; i++) |
||
160 | { |
||
161 | if (!as_strcasecmp(str, DCReg[i])) |
||
162 | { |
||
163 | *pResult = i; |
||
164 | return True; |
||
165 | } |
||
166 | } |
||
167 | if (as_strncasecmp(str, "DCR", 3)) return False; |
||
168 | i = 3; |
||
169 | num = 4; |
||
170 | break; |
||
171 | default: |
||
172 | return False; |
||
173 | } |
||
174 | *pResult = 0; |
||
175 | for (; i < len; i++) |
||
176 | { |
||
177 | if (!isdigit(str[i])) return False; |
||
178 | *pResult = *pResult * 10 + (str[i] - '0'); |
||
179 | } |
||
180 | |||
181 | return *pResult < num; |
||
182 | } |
||
183 | |||
184 | static Boolean DecodeImm(const tStrComp *pArg, LongInt *pResult, tSymbolFlags *pFlags) |
||
185 | { |
||
186 | const char *str = pArg->str.p_str; |
||
187 | tStrComp ImmArg; |
||
188 | Boolean ValOK; |
||
189 | tSymbolFlags flags; |
||
190 | |||
191 | if (str[0] != '#') return False; |
||
192 | |||
193 | StrCompRefRight(&ImmArg, pArg, 1); |
||
194 | *pResult = EvalStrIntExpressionWithFlags(&ImmArg, Int32, &ValOK, &flags); |
||
195 | if (pFlags) *pFlags = flags; |
||
196 | |||
197 | return ValOK; |
||
198 | } |
||
199 | |||
200 | static Byte ImmSize32(LongInt value, tSymbolFlags flags) |
||
201 | { |
||
202 | if (mFirstPassUnknown(flags)) return 0x00; /* Temporarily return maximum size */ |
||
203 | |||
204 | if ((value & 0xFFFFFF80) == 0xFFFFFF80 || |
||
205 | (value & 0xFFFFFF80) == 0x00000000) return 0x01; /* SIMM:8 */ |
||
206 | |||
207 | if ((value & 0xFFFF8000) == 0xFFFF8000 || |
||
208 | (value & 0xFFFF8000) == 0x00000000) return 0x02; /* SIMM:16 */ |
||
209 | |||
210 | if ((value & 0xFF800000) == 0xFF800000 || |
||
211 | (value & 0xFF800000) == 0x00000000) return 0x03; /* SIMM:24 */ |
||
212 | |||
213 | return 0x00; /* IMM:32 */ |
||
214 | } |
||
215 | |||
216 | static Byte ImmSize16(LongInt value, tSymbolFlags flags) |
||
217 | { |
||
218 | if (mFirstPassUnknown(flags)) return 0x02; /* Temporarily return maximum size */ |
||
219 | |||
220 | if ((value & 0xFFFFFF80) == 0xFFFFFF80 || |
||
221 | (value & 0xFFFFFF80) == 0x00000000) return 0x01; /* SIMM:8 */ |
||
222 | |||
223 | return 0x02; /* IMM:16 */ |
||
224 | } |
||
225 | |||
226 | static int ImmOut(int pos, Byte size, LongInt imm) |
||
227 | { |
||
228 | int i; |
||
229 | |||
230 | if (size == 0x00) size = 4; |
||
231 | for (i = 0; i < size; i++) |
||
232 | { |
||
233 | BAsmCode[pos+i] = imm & 0xFF; |
||
234 | imm >>= 8; |
||
235 | } |
||
236 | return pos + size; |
||
237 | } |
||
238 | |||
239 | static Boolean DecodeIndirectADC(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags) |
||
240 | { |
||
241 | const char *str = pArg->str.p_str; |
||
242 | const int len = strlen(str); |
||
243 | int pos; |
||
244 | Boolean ValOK; |
||
245 | |||
246 | if (str[len-1] != ']') return False; |
||
247 | for (pos = len - 2; pos >= 0; pos--) |
||
248 | { |
||
249 | if (str[pos] == '[') break; |
||
250 | } |
||
251 | if (pos < 0) return False; |
||
252 | |||
253 | StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 2); |
||
254 | if (!DecodeReg(&Temp1, reg, eRn)) return False; |
||
255 | |||
256 | if (pos == 0) |
||
257 | { |
||
258 | *flags = eSymbolFlag_None; |
||
259 | *disp = 0; |
||
260 | return True; |
||
261 | } |
||
262 | |||
263 | StrCompCopySub(&Temp1, pArg, 0, pos); |
||
264 | *disp = EvalStrIntExpressionWithFlags(&Temp1, UInt20, &ValOK, flags); |
||
265 | |||
266 | return ValOK; |
||
267 | } |
||
268 | |||
269 | static Byte DispSize(LongInt disp, tSymbolFlags flags, Byte scale) |
||
270 | { |
||
271 | Byte size = 0; |
||
272 | Byte mask = scale - 1; |
||
273 | |||
274 | UNUSED(flags); |
||
275 | |||
276 | if (disp & mask) |
||
277 | { |
||
278 | WrStrErrorPos(ErrNum_NotAligned, &ArgStr[1]); |
||
279 | return 0; |
||
280 | } |
||
281 | disp /= scale; |
||
282 | |||
283 | if (disp == 0) size = 0x00; |
||
284 | else if (disp < 0) size = 0xFF; |
||
285 | else if (disp < 256) size = 0x01; |
||
286 | else if (disp < 65536) size = 0x02; |
||
287 | else size = 0xFF; |
||
288 | |||
289 | return size; |
||
290 | } |
||
291 | |||
292 | static int DispOut(int pos, Byte size, LongInt disp, Byte scale) |
||
293 | { |
||
294 | int i; |
||
295 | |||
296 | disp /= scale; |
||
297 | |||
298 | if (size > 0x02) size = 0x00; |
||
299 | for (i = 0; i < size; i++ ) |
||
300 | { |
||
301 | BAsmCode[pos+i] = disp & 0xFF; |
||
302 | disp >>= 8; |
||
303 | } |
||
304 | return pos + size; |
||
305 | } |
||
306 | |||
307 | static Boolean DecodeIndirectADD(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags, Byte *memex, Byte *scale) |
||
308 | { |
||
309 | const char *str = pArg->str.p_str; |
||
310 | const int len = strlen(str); |
||
311 | |||
312 | if (len > 2 && str[len-2] == '.') |
||
313 | { |
||
314 | switch (as_toupper(str[len-1])) |
||
315 | { |
||
316 | case 'B': |
||
317 | *memex = 0x00; |
||
318 | *scale = 1; |
||
319 | break; |
||
320 | case 'W': |
||
321 | *memex = 0x01; |
||
322 | *scale = 2; |
||
323 | break; |
||
324 | case 'L': |
||
325 | *memex = 0x02; |
||
326 | *scale = 4; |
||
327 | break; |
||
328 | default: |
||
329 | return False; |
||
330 | } |
||
331 | StrCompCopySub(&Temp2, pArg, 0, len - 2); |
||
332 | pArg = &Temp2; |
||
333 | } |
||
334 | else if (len > 3 && str[len-3] == '.' && as_toupper(str[len-2]) == 'U') |
||
335 | { |
||
336 | switch (as_toupper(str[len-1])) |
||
337 | { |
||
338 | case 'B': |
||
339 | *memex = 0x80; |
||
340 | *scale = 1; |
||
341 | break; |
||
342 | case 'W': |
||
343 | *memex = 0x03; |
||
344 | *scale = 2; |
||
345 | break; |
||
346 | default: |
||
347 | return False; |
||
348 | } |
||
349 | StrCompCopySub(&Temp2, pArg, 0, len - 3); |
||
350 | pArg = &Temp2; |
||
351 | } |
||
352 | |||
353 | return DecodeIndirectADC(pArg, reg, disp, flags); |
||
354 | } |
||
355 | |||
356 | static Boolean DecodeFloat(const tStrComp *pArg, LongInt *pResult) |
||
357 | { |
||
358 | const char *str = pArg->str.p_str; |
||
359 | tStrComp ImmArg; |
||
360 | TempResult temp; |
||
361 | Boolean Result = True; |
||
362 | |||
363 | if (str[0] != '#') return False; |
||
364 | |||
365 | StrCompRefRight(&ImmArg, pArg, 1); |
||
366 | as_tempres_ini(&temp); |
||
367 | EvalStrExpression(&ImmArg, &temp); |
||
368 | switch (temp.Typ) |
||
369 | { |
||
370 | case TempInt: |
||
371 | *pResult = temp.Contents.Int; |
||
372 | break; |
||
373 | case TempFloat: |
||
374 | as_float_2_ieee4(temp.Contents.Float, (unsigned char *)pResult, False); |
||
375 | /* TODO: rework this - we should better pass in a byte array as pResult */ |
||
376 | if (HostBigEndian) |
||
377 | DSwap(pResult, 4); |
||
378 | break; |
||
379 | default: |
||
380 | Result = False; |
||
381 | } |
||
382 | as_tempres_free(&temp); |
||
383 | |||
384 | return Result; |
||
385 | } |
||
386 | |||
387 | static Boolean DecodeIndirectL(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags) |
||
388 | { |
||
389 | Boolean result; |
||
390 | Byte memex = 0x02; /* L */ |
||
391 | Byte scale; |
||
392 | |||
393 | result = DecodeIndirectADD(pArg, reg, disp, flags, &memex, &scale); |
||
394 | |||
395 | if (result && memex != 0x02) result = False; |
||
396 | |||
397 | return result; |
||
398 | } |
||
399 | |||
400 | static tSymbolSize DecodeAttrSize(void) |
||
401 | { |
||
402 | switch (strlen(AttrPart.str.p_str)) |
||
403 | { |
||
404 | case 0: |
||
405 | WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); |
||
406 | return eSymbolSizeUnknown; |
||
407 | case 1: |
||
408 | switch (AttrPart.str.p_str[0]) |
||
409 | { |
||
410 | case 'B': |
||
411 | return eSymbolSize8Bit; |
||
412 | case 'W': |
||
413 | return eSymbolSize16Bit; |
||
414 | case 'L': |
||
415 | return eSymbolSize32Bit; |
||
416 | default: |
||
417 | WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); |
||
418 | return eSymbolSizeUnknown; |
||
419 | } |
||
420 | default: |
||
421 | WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart); |
||
422 | return eSymbolSizeUnknown; |
||
423 | } |
||
424 | } |
||
425 | |||
426 | static Boolean DecodeRelative(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags) |
||
427 | { /* dsp:5[Rn] (R0-R7) */ |
||
428 | const char *str = pArg->str.p_str; |
||
429 | const int len = strlen(str); |
||
430 | int pos; |
||
431 | Boolean ValOK; |
||
432 | |||
433 | if (str[len-1] != ']') return False; |
||
434 | for (pos = len - 2; pos > 0; pos--) |
||
435 | { |
||
436 | if (str[pos] == '[') break; |
||
437 | } |
||
438 | if (pos < 1) return False; |
||
439 | |||
440 | StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 2); |
||
441 | if (!DecodeReg(&Temp1, reg, eRn)) return False; |
||
442 | if (*reg > 7) return False; |
||
443 | |||
444 | StrCompCopySub(&Temp1, pArg, 0, pos); |
||
445 | *disp = EvalStrIntExpressionWithFlags(&Temp1, UInt20, &ValOK, flags); |
||
446 | |||
447 | return ValOK; |
||
448 | } |
||
449 | |||
450 | static int Size2Scale(Byte size) |
||
451 | { |
||
452 | Byte scale; |
||
453 | |||
454 | switch (size) |
||
455 | { |
||
456 | case 0x00: /* B */ |
||
457 | scale = 1; |
||
458 | break; |
||
459 | case 0x01: /* W */ |
||
460 | scale = 2; |
||
461 | break; |
||
462 | case 0x02: /* L */ |
||
463 | scale = 4; |
||
464 | break; |
||
465 | default: |
||
466 | return -1; |
||
467 | } |
||
468 | |||
469 | return scale; |
||
470 | } |
||
471 | |||
472 | static Boolean ChkDisp5(Byte size, LongInt disp, tSymbolFlags flags) |
||
473 | { |
||
474 | const int scale = Size2Scale(size); |
||
475 | |||
476 | if (scale < 0) return False; |
||
477 | |||
478 | if (!mFirstPassUnknown(flags)) |
||
479 | { |
||
480 | if (disp & (scale - 1)) |
||
481 | { |
||
482 | WrError(ErrNum_AddrMustBeAligned); |
||
483 | return False; |
||
484 | } |
||
485 | |||
486 | if (disp / scale > 31 || disp < 0) return False; |
||
487 | } |
||
488 | |||
489 | return True; |
||
490 | } |
||
491 | |||
492 | static Byte DispSize5(Byte size, LongInt disp) |
||
493 | { |
||
494 | const Byte scale = Size2Scale(size); |
||
495 | |||
496 | return disp / scale; |
||
497 | } |
||
498 | |||
499 | static Boolean DecodeIndexed(tStrComp *pArg, Byte *regi, Byte *regb) |
||
500 | { /* [Ri,Rb] */ |
||
501 | const char *str = pArg->str.p_str; |
||
502 | const int len = strlen(str); |
||
503 | int pos; |
||
504 | |||
505 | if (str[0] != '[' || str[len-1] != ']') return False; |
||
506 | |||
507 | for (pos = 2; pos < len - 2; pos++) |
||
508 | { |
||
509 | if (str[pos] == ',') break; |
||
510 | } |
||
511 | |||
512 | StrCompCopySub(&Temp1, pArg, 1, pos - 1); |
||
513 | if (!DecodeReg(&Temp1, regi, eRn)) return False; |
||
514 | |||
515 | StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 2); |
||
516 | if (!DecodeReg(&Temp1, regb, eRn)) return False; |
||
517 | |||
518 | return True; |
||
519 | } |
||
520 | |||
521 | static Boolean DecodeIncDec(tStrComp *pArg, Byte *reg, Byte *id) |
||
522 | { /* [Rn+] / [-Rn]] */ |
||
523 | const char *str = pArg->str.p_str; |
||
524 | const int len = strlen(str); |
||
525 | |||
526 | if (len < 5) return False; |
||
527 | if (str[0] != '[' || str[len-1] != ']') return False; |
||
528 | |||
529 | if (str[len-2] == '+') |
||
530 | { |
||
531 | *id = 0x00; |
||
532 | StrCompCopySub(&Temp1, pArg, 1, len - 3); |
||
533 | } |
||
534 | else if (str[1] == '-') |
||
535 | { |
||
536 | *id = 0x01; |
||
537 | StrCompCopySub(&Temp1, pArg, 2, len - 3); |
||
538 | } |
||
539 | else return False; |
||
540 | |||
541 | return DecodeReg(&Temp1, reg, eRn); |
||
542 | } |
||
543 | |||
544 | static Boolean DecodeRegRange(tStrComp *pArg, Byte *range) |
||
545 | { |
||
546 | const char *str = pArg->str.p_str; |
||
547 | const int len = strlen(str); |
||
548 | Byte reg1; |
||
549 | Byte reg2; |
||
550 | int pos; |
||
551 | |||
552 | if (len < 5) return False; |
||
553 | for (pos = 2; pos < len - 2; pos++) |
||
554 | { |
||
555 | if (str[pos] == '-') break; |
||
556 | } |
||
557 | if (pos >= len - 2) return False; |
||
558 | |||
559 | StrCompCopySub(&Temp1, pArg, 0, pos); |
||
560 | if (!DecodeReg(&Temp1, ®1, eRn)) return False; |
||
561 | |||
562 | StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 1); |
||
563 | if (!DecodeReg(&Temp1, ®2, eRn)) return False; |
||
564 | |||
565 | if (reg1 == 0 || reg1 >= reg2) return False; |
||
566 | |||
567 | *range = (reg1 << 4) | reg2; |
||
568 | return True; |
||
569 | } |
||
570 | |||
571 | static Boolean DecodeIndirect(tStrComp *pArg, Byte *reg) |
||
572 | { |
||
573 | const char *str = pArg->str.p_str; |
||
574 | const int len = strlen(str); |
||
575 | |||
576 | if (str[0] != '[') return False; |
||
577 | if (str[len-1] != ']') return False; |
||
578 | |||
579 | StrCompCopySub(&Temp1, pArg, 1, len - 2); |
||
580 | if (!DecodeReg(&Temp1, reg, eRn)) return False; |
||
581 | |||
582 | return True; |
||
583 | } |
||
584 | |||
585 | static Boolean DecodeAcc(tStrComp *pArg, Byte *acc) |
||
586 | { |
||
587 | const char *str = pArg->str.p_str; |
||
588 | const int len = strlen(str); |
||
589 | |||
590 | if (len != 2) return False; |
||
591 | if (as_toupper(str[0]) != 'A') return False; |
||
592 | if (str[1] != '0' && str[1] != '1') return False; |
||
593 | |||
594 | *acc = str[1] - '0'; |
||
595 | return True; |
||
596 | } |
||
597 | |||
598 | static Boolean DecodeAttrDouble(Byte *size) |
||
599 | { |
||
600 | if (strlen(AttrPart.str.p_str) != 1) |
||
601 | { |
||
602 | WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart); |
||
603 | return False; |
||
604 | } |
||
605 | switch (as_toupper(AttrPart.str.p_str[0])) |
||
606 | { |
||
607 | case 'L': |
||
608 | *size = 0; |
||
609 | break; |
||
610 | case 'D': |
||
611 | *size = 1; |
||
612 | break; |
||
613 | default: |
||
614 | WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); |
||
615 | return False; |
||
616 | } |
||
617 | |||
618 | return True; |
||
619 | } |
||
620 | |||
621 | /*---------------------------------------------------------------------------*/ |
||
622 | |||
623 | static void DecodeABS(Word Index) |
||
624 | { |
||
625 | if (!ChkNoAttr()) return; |
||
626 | if (!ChkArgCnt(1,2)) return; |
||
627 | |||
628 | if (ArgCnt == 1) |
||
629 | { |
||
630 | Byte reg; |
||
631 | |||
632 | if (!DecodeReg(&ArgStr[1], ®, eRn)) |
||
633 | { |
||
634 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]); |
||
635 | return; |
||
636 | } |
||
637 | |||
638 | BAsmCode[0] = 0x7E; |
||
639 | BAsmCode[1] = (Index >> 8) | reg; |
||
640 | CodeLen = 2; |
||
641 | } |
||
642 | else |
||
643 | { |
||
644 | Byte regs; |
||
645 | Byte regd; |
||
646 | |||
647 | if (!DecodeReg(&ArgStr[1], ®s, eRn)) |
||
648 | { |
||
649 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]); |
||
650 | return; |
||
651 | } |
||
652 | if (!DecodeReg(&ArgStr[2], ®d, eRn)) |
||
653 | { |
||
654 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]); |
||
655 | return; |
||
656 | } |
||
657 | |||
658 | BAsmCode[0] = 0xFC; |
||
659 | BAsmCode[1] = Index & 0xFF; |
||
660 | BAsmCode[2] = (regs << 4) | regd; |
||
661 | CodeLen = 3; |
||
662 | } |
||
663 | } |
||
664 | |||
665 | static void DecodeADC(Word Index) |
||
666 | { |
||
667 | Byte regs; |
||
668 | Byte regd; |
||
669 | Byte size; |
||
670 | LongInt imm; |
||
671 | tSymbolFlags flags; |
||
672 | LongInt disp; |
||
673 | |||
674 | if (!ChkNoAttr()) return; |
||
675 | if (!ChkArgCnt(2,2)) return; |
||
676 | |||
677 | if (!DecodeReg(&ArgStr[2], ®d, eRn)) |
||
678 | { |
||
679 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]); |
||
680 | return; |
||
681 | } |
||
682 | |||
683 | if ((Index & 0x0800) && DecodeImm(&ArgStr[1], &imm, &flags)) /* ADC only */ |
||
684 | { |
||
685 | size = ImmSize32(imm, flags); |
||
686 | |||
687 | BAsmCode[0] = 0xFD; |
||
688 | BAsmCode[1] = 0x70 | (size << 2); |
||
689 | BAsmCode[2] = 0x20 | regd; |
||
690 | CodeLen = ImmOut(3, size, imm); |
||
691 | |||
692 | return; |
||
693 | } |
||
694 | |||
695 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
696 | { |
||
697 | BAsmCode[0] = 0xFC; |
||
698 | BAsmCode[1] = 0x03 | (Index >> 8); |
||
699 | BAsmCode[2] = (regs << 4) | regd; |
||
700 | CodeLen = 3; |
||
701 | |||
702 | return; |
||
703 | } |
||
704 | |||
705 | if (DecodeIndirectL(&ArgStr[1], ®s, &disp, &flags)) |
||
706 | { |
||
707 | if (mFirstPassUnknown(flags)) size = 0x02; |
||
708 | else size = DispSize(disp, flags, 4); |
||
709 | |||
710 | BAsmCode[0] = 0x06; |
||
711 | BAsmCode[1] = 0xA0 | size; |
||
712 | BAsmCode[2] = Index & 0xFF; |
||
713 | BAsmCode[3] = (regs << 4) | regd; |
||
714 | CodeLen = DispOut(4, size, disp, 4); |
||
715 | } |
||
716 | } |
||
717 | |||
718 | static const struct { |
||
719 | Byte OpcImm4; /* #IMM:4,Rd */ |
||
720 | Byte OpcImm1; /* #IMM:*(,Rs),Rd 1st byte */ |
||
721 | Byte OpcImm2; /* 2nd byte */ |
||
722 | Byte Opc2; /* Rs,Rd / [Rs].UB,Rd */ |
||
723 | Byte Opc3; /* Rs,Rs2,Rd */ |
||
724 | Byte Opc4; /* [Rs],Rd */ |
||
725 | Byte flags; /* 1<<0:, 1<<1:, 1<<2:#UIMM8 1<<3:Rs,Rs,Rd */ |
||
726 | } OpTabADD[] = { |
||
727 | { 0x62, 0x70, 0x00, 0x48, 0x20, 0x08, 0x0B }, /* ADD */ |
||
728 | { 0x64, 0x74, 0x20, 0x50, 0x40, 0x10, 0x09 }, /* AND */ |
||
729 | { 0x61, 0x74, 0x00, 0x44, 0, 0x04, 0x05 }, /* CMP */ |
||
730 | { 0x63, 0x74, 0x10, 0x4C, 0x30, 0x0C, 0x09 }, /* MUL */ |
||
731 | { 0x65, 0x74, 0x30, 0x54, 0x50, 0x14, 0x09 }, /* OR */ |
||
732 | { 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x08 }, /* SUB */ |
||
733 | }; |
||
734 | |||
735 | static void DecodeADD(Word Index) |
||
736 | { |
||
737 | Byte regs1; |
||
738 | Byte regs2; |
||
739 | Byte regd; |
||
740 | Byte size; |
||
741 | LongInt imm; |
||
742 | tSymbolFlags flags; |
||
743 | LongInt disp; |
||
744 | Byte memex; |
||
745 | Byte scale; |
||
746 | |||
747 | if (!ChkNoAttr()) return; |
||
748 | if (!ChkArgCnt(2,3)) return; |
||
749 | |||
750 | if (!DecodeReg(&ArgStr[2], ®s2, eRn)) |
||
751 | { |
||
752 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]); |
||
753 | return; |
||
754 | } |
||
755 | if (ArgCnt == 2) |
||
756 | regd = regs2; |
||
757 | else |
||
758 | { |
||
759 | if (!DecodeReg(&ArgStr[3], ®d, eRn)) |
||
760 | { |
||
761 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[3]); |
||
762 | return; |
||
763 | } |
||
764 | } |
||
765 | |||
766 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
767 | { |
||
768 | if (ArgCnt == 2 && !mFirstPassUnknown(flags) && imm >= 0 && imm < 16 ) |
||
769 | { /* #UIMM:4 */ |
||
770 | BAsmCode[0] = OpTabADD[Index].OpcImm4; |
||
771 | BAsmCode[1] = (imm << 4) | regd; |
||
772 | CodeLen = 2; |
||
773 | return; |
||
774 | } |
||
775 | |||
776 | if ((OpTabADD[Index].flags & 0x04) && ArgCnt == 2 && |
||
777 | !mFirstPassUnknown(flags) && imm >= 0 && imm < 256) |
||
778 | { /* #UIMM:8 */ |
||
779 | BAsmCode[0] = 0x75; |
||
780 | BAsmCode[1] = 0x50 | regd; |
||
781 | BAsmCode[2] = imm; |
||
782 | CodeLen = 3; |
||
783 | return; |
||
784 | } |
||
785 | |||
786 | if (((OpTabADD[Index].flags & 0x01) && ArgCnt == 2) || (OpTabADD[Index].flags & 0x02)) |
||
787 | { /* #SIMM:* */ |
||
788 | size = ImmSize32(imm, flags); |
||
789 | |||
790 | BAsmCode[0] = OpTabADD[Index].OpcImm1 | size; |
||
791 | if (OpTabADD[Index].flags & 0x02) |
||
792 | if (ArgCnt == 2) |
||
793 | BAsmCode[1] = (regd << 4) | regd; /* #Imm,Rd */ |
||
794 | else |
||
795 | BAsmCode[1] = (regs2 << 4) | regd; /* #imm,Rs,Rd */ |
||
796 | else |
||
797 | BAsmCode[1] = OpTabADD[Index].OpcImm2 | regd; |
||
798 | CodeLen = ImmOut(2, size, imm); |
||
799 | return; |
||
800 | } |
||
801 | } |
||
802 | |||
803 | if (DecodeReg(&ArgStr[1], ®s1, eRn)) |
||
804 | { /* Rs */ |
||
805 | if (ArgCnt == 2) |
||
806 | { |
||
807 | BAsmCode[0] = OpTabADD[Index].Opc2 | 0x03; |
||
808 | BAsmCode[1] = (regs1 << 4) | regd; |
||
809 | CodeLen = 2; |
||
810 | } |
||
811 | else if (OpTabADD[Index].flags & 0x08) |
||
812 | { |
||
813 | BAsmCode[0] = 0xFF; |
||
814 | BAsmCode[1] = OpTabADD[Index].Opc3 | regd; |
||
815 | BAsmCode[2] = (regs1 << 4) | regs2; |
||
816 | CodeLen = 3; |
||
817 | } |
||
818 | else WrStrErrorPos(ErrNum_TooManyArgs, &ArgStr[3]); |
||
819 | return; |
||
820 | } |
||
821 | |||
822 | if (ArgCnt == 2 && DecodeIndirectADD(&ArgStr[1], ®s1, &disp, &flags, &memex, &scale)) |
||
823 | { |
||
824 | if (memex == 0x80) |
||
825 | { |
||
826 | size = DispSize(disp, flags, 1); |
||
827 | |||
828 | BAsmCode[0] = OpTabADD[Index].Opc2 | size; |
||
829 | BAsmCode[1] = (regs1 << 4) | regd; |
||
830 | CodeLen = DispOut(2, size, disp, 1); |
||
831 | return; |
||
832 | } |
||
833 | |||
834 | size = DispSize(disp, flags, scale); |
||
835 | |||
836 | BAsmCode[0] = 0x06; |
||
837 | BAsmCode[1] = OpTabADD[Index].Opc4 | (memex << 6) | size; |
||
838 | BAsmCode[2] = (regs1 << 4) | regd; |
||
839 | CodeLen = DispOut(3, size, disp, scale); |
||
840 | return; |
||
841 | } |
||
842 | |||
843 | WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]); |
||
844 | } |
||
845 | |||
846 | static const struct { |
||
847 | Byte OpcIM1; /* Imm3,[Rd] */ |
||
848 | Byte OpcIM2; |
||
849 | Byte OpcRM; /* Rs,[Rd] / Rs,Rd */ |
||
850 | Byte OpcIR; /* #Imm5,Rd */ |
||
851 | Byte flags; |
||
852 | } OpTabBCLR[] = { |
||
853 | { 0xF0, 0x08, 0x64, 0x7A, 0x00 }, /* BCLR */ |
||
854 | { 0xF0, 0x00, 0x6C, 0, 0x01 }, /* BNOT */ |
||
855 | { 0xF0, 0x00, 0x60, 0x78, 0x00 }, /* BSET */ |
||
856 | { 0xF4, 0x00, 0x68, 0x7C, 0x00 }, /* BTST */ |
||
857 | }; |
||
858 | |||
859 | static void DecodeBCLR(Word Index) |
||
860 | { |
||
861 | Byte regs; |
||
862 | Byte regd; |
||
863 | Byte size; |
||
864 | Byte memex; |
||
865 | Byte scale; |
||
866 | LongInt imm; |
||
867 | LongInt disp; |
||
868 | tSymbolFlags flags; |
||
869 | |||
870 | if (!ChkNoAttr()) return; |
||
871 | if (!ChkArgCnt(2,2)) return; |
||
872 | |||
873 | memex = 0; |
||
874 | if (DecodeIndirectADD(&ArgStr[2], ®d, &disp, &flags, &memex, &scale)) |
||
875 | { |
||
876 | if (memex) |
||
877 | { |
||
878 | WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]); |
||
879 | return; |
||
880 | } |
||
881 | size = DispSize(disp, flags, 1); |
||
882 | if (size > 0x02){ |
||
883 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]); |
||
884 | return; |
||
885 | } |
||
886 | |||
887 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
888 | { |
||
889 | if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 7)) |
||
890 | { |
||
891 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]); |
||
892 | return; |
||
893 | } |
||
894 | |||
895 | if (OpTabBCLR[Index].flags & 0x01) |
||
896 | { /* BNOT */ |
||
897 | BAsmCode[0] = 0xFC; |
||
898 | BAsmCode[1] = 0xE0 | (imm << 2) | size; |
||
899 | BAsmCode[2] = 0x0F | (regd << 4); |
||
900 | CodeLen = DispOut(3, size, disp, 1); |
||
901 | } |
||
902 | else |
||
903 | { /* BCLR, BSET, BTST */ |
||
904 | BAsmCode[0] = OpTabBCLR[Index].OpcIM1 | size; |
||
905 | BAsmCode[1] = OpTabBCLR[Index].OpcIM2 | (regd << 4) | imm; |
||
906 | CodeLen = DispOut(2, size, disp, 1); |
||
907 | } |
||
908 | return; |
||
909 | } |
||
910 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
911 | { |
||
912 | BAsmCode[0] = 0xFC; |
||
913 | BAsmCode[1] = OpTabBCLR[Index].OpcRM | size; |
||
914 | BAsmCode[2] = regs | (regd << 4); |
||
915 | CodeLen = DispOut(3, size, disp, 1); |
||
916 | return; |
||
917 | } |
||
918 | |||
919 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]); |
||
920 | } |
||
921 | else if (DecodeReg(&ArgStr[2], ®d, eRn)) |
||
922 | { |
||
923 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
924 | { |
||
925 | if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 31)) |
||
926 | { |
||
927 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]); |
||
928 | return; |
||
929 | } |
||
930 | |||
931 | if (OpTabBCLR[Index].flags & 0x01) |
||
932 | { |
||
933 | BAsmCode[0] = 0xFD; |
||
934 | BAsmCode[1] = 0xE0 | imm; |
||
935 | BAsmCode[2] = 0xF0 | regd; |
||
936 | CodeLen = 3; |
||
937 | } |
||
938 | else |
||
939 | { |
||
940 | BAsmCode[0] = OpTabBCLR[Index].OpcIR | (imm >> 4); |
||
941 | BAsmCode[1] = ((imm & 0x0F) << 4) | regd; |
||
942 | CodeLen = 2; |
||
943 | } |
||
944 | return; |
||
945 | } |
||
946 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
947 | { |
||
948 | BAsmCode[0] = 0xFC; |
||
949 | BAsmCode[1] = OpTabBCLR[Index].OpcRM | 0x03; |
||
950 | BAsmCode[2] = regs | (regd << 4); |
||
951 | CodeLen = 3; |
||
952 | return; |
||
953 | } |
||
954 | |||
955 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]); |
||
956 | } |
||
957 | |||
958 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]); |
||
959 | } |
||
960 | |||
961 | static void DecodeBCnd(Word Index) |
||
962 | { |
||
963 | const char *str = AttrPart.str.p_str; |
||
964 | const int len = strlen(str); |
||
965 | Byte attr = 0; |
||
966 | Byte reg; |
||
967 | LongInt addr; |
||
968 | tSymbolFlags flags; |
||
969 | Boolean ValOK; |
||
970 | LongInt disp; |
||
971 | |||
972 | if (len > 1) |
||
973 | { |
||
974 | WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart); |
||
975 | return; |
||
976 | } |
||
977 | if (len == 1) |
||
978 | { |
||
979 | attr = as_toupper(str[0]); |
||
980 | switch (attr) |
||
981 | { |
||
982 | case 'S': |
||
983 | break; |
||
984 | case 'B': |
||
985 | break; |
||
986 | case 'W': |
||
987 | break; |
||
988 | case 'A': |
||
989 | case 'L': |
||
990 | if (Index != 14) |
||
991 | { |
||
992 | WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); |
||
993 | return; |
||
994 | } |
||
995 | break; |
||
996 | default: |
||
997 | WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); |
||
998 | return; |
||
999 | } |
||
1000 | } |
||
1001 | |||
1002 | if (!ChkArgCnt(1,1)) return; |
||
1003 | |||
1004 | if ((attr == 0 || attr == 'L') && DecodeReg(&ArgStr[1], ®, eRn)) |
||
1005 | { |
||
1006 | BAsmCode[0] = 0x7F; |
||
1007 | BAsmCode[1] = 0x40 | reg; |
||
1008 | CodeLen = 2; |
||
1009 | return; |
||
1010 | } |
||
1011 | |||
1012 | addr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &flags); |
||
1013 | if (ValOK) |
||
1014 | { |
||
1015 | if (attr == 'L') |
||
1016 | { |
||
1017 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]); |
||
1018 | return; |
||
1019 | } |
||
1020 | |||
1021 | disp = addr - EProgCounter(); |
||
1022 | |||
1023 | /* Try 3 bit */ |
||
1024 | if ((attr == 0 || attr == 'S') && disp >= 3 && disp <= 10) |
||
1025 | { |
||
1026 | if (disp > 7) disp -= 8; |
||
1027 | |||
1028 | if (Index == 0 || Index == 1) |
||
1029 | { |
||
1030 | |||
1031 | BAsmCode[0] = 0x10 | (Index << 3) | disp; |
||
1032 | CodeLen = 1; |
||
1033 | return; |
||
1034 | } |
||
1035 | |||
1036 | if (Index == 14) |
||
1037 | { |
||
1038 | BAsmCode[0] = 0x08 | disp; |
||
1039 | CodeLen = 1; |
||
1040 | return; |
||
1041 | } |
||
1042 | |||
1043 | WrError(ErrNum_InternalError); |
||
1044 | } |
||
1045 | |||
1046 | if (attr == 'S' && !mFirstPassUnknownOrQuestionable(flags)) |
||
1047 | { |
||
1048 | WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]); |
||
1049 | return; |
||
1050 | } |
||
1051 | |||
1052 | /* Try 8 bit */ |
||
1053 | if ((attr == 0 || attr == 'B') && |
||
1054 | ((disp & 0xFFFFFF80) == 0xFFFFFF80 || |
||
1055 | (disp & 0xFFFFFF80) == 0x00000000)) |
||
1056 | { |
||
1057 | BAsmCode[0] = 0x20 | Index; |
||
1058 | BAsmCode[1] = disp & 0xFF; |
||
1059 | CodeLen = 2; |
||
1060 | return; |
||
1061 | } |
||
1062 | |||
1063 | if (attr == 'B' && !mFirstPassUnknownOrQuestionable(flags)) |
||
1064 | { |
||
1065 | WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]); |
||
1066 | return; |
||
1067 | } |
||
1068 | |||
1069 | /* Try 16 bit */ |
||
1070 | if ((attr == 0 || attr == 'W') && |
||
1071 | ((disp & 0xFFFF8000) == 0xFFFF8000 || |
||
1072 | (disp & 0xFFFF8000) == 0x00000000)) |
||
1073 | { |
||
1074 | if (Index == 0 || Index == 1) |
||
1075 | { |
||
1076 | BAsmCode[0] = 0x3A | Index; |
||
1077 | BAsmCode[1] = disp & 0xFF; |
||
1078 | BAsmCode[2] = (disp >> 8) & 0xFF; |
||
1079 | CodeLen = 3; |
||
1080 | return; |
||
1081 | } |
||
1082 | |||
1083 | if (Index == 14) |
||
1084 | { |
||
1085 | BAsmCode[0] = 0x38; |
||
1086 | BAsmCode[1] = disp & 0xFF; |
||
1087 | BAsmCode[2] = (disp >> 8) & 0xFF; |
||
1088 | CodeLen = 3; |
||
1089 | return; |
||
1090 | } |
||
1091 | |||
1092 | WrError(ErrNum_JmpDistTooBig); |
||
1093 | return; |
||
1094 | } |
||
1095 | |||
1096 | if (attr == 'W' && !mFirstPassUnknownOrQuestionable(flags)) |
||
1097 | { |
||
1098 | WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]); |
||
1099 | return; |
||
1100 | } |
||
1101 | |||
1102 | /* Try 24 bit */ |
||
1103 | if ((disp & 0xFF800000) == 0xFF800000 || |
||
1104 | (disp & 0xFF800000) == 0x00000000) |
||
1105 | { |
||
1106 | if (Index == 14) |
||
1107 | { |
||
1108 | BAsmCode[0] = 0x04; |
||
1109 | BAsmCode[1] = disp & 0xFF; |
||
1110 | BAsmCode[2] = (disp >> 8) & 0xFF; |
||
1111 | BAsmCode[3] = (disp >> 16) & 0xFF; |
||
1112 | CodeLen = 4; |
||
1113 | return; |
||
1114 | } |
||
1115 | } |
||
1116 | |||
1117 | WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]); |
||
1118 | } |
||
1119 | } |
||
1120 | |||
1121 | static void DecodeBMCnd(Word Index) |
||
1122 | { |
||
1123 | Byte regd; |
||
1124 | Byte size; |
||
1125 | Byte memex; |
||
1126 | Byte scale; |
||
1127 | LongInt imm; |
||
1128 | LongInt disp; |
||
1129 | tSymbolFlags flags; |
||
1130 | |||
1131 | if (!ChkNoAttr()) return; |
||
1132 | if (!ChkArgCnt(2,2)) return; |
||
1133 | |||
1134 | memex = 0; |
||
1135 | if (DecodeIndirectADD(&ArgStr[2], ®d, &disp, &flags, &memex, &scale)) |
||
1136 | { |
||
1137 | if (memex) |
||
1138 | { |
||
1139 | WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]); |
||
1140 | return; |
||
1141 | } |
||
1142 | size = DispSize(disp, flags, 1); |
||
1143 | if (size > 0x02){ |
||
1144 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]); |
||
1145 | return; |
||
1146 | } |
||
1147 | } |
||
1148 | else if (DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1149 | { |
||
1150 | size = 0x03; |
||
1151 | } |
||
1152 | else |
||
1153 | { |
||
1154 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]); |
||
1155 | return; |
||
1156 | } |
||
1157 | |||
1158 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
1159 | { |
||
1160 | if (size < 0x03) |
||
1161 | { |
||
1162 | /* #imm,disp[Rd] */ |
||
1163 | if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 7)) |
||
1164 | { |
||
1165 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]); |
||
1166 | return; |
||
1167 | } |
||
1168 | |||
1169 | BAsmCode[0] = 0xFC; |
||
1170 | BAsmCode[1] = 0xE0 | (imm << 2) | size; |
||
1171 | BAsmCode[2] = (regd << 4) | Index; |
||
1172 | CodeLen = DispOut(3, size, disp, 1); |
||
1173 | return; |
||
1174 | } |
||
1175 | else |
||
1176 | { |
||
1177 | /* #imm,Rd */ |
||
1178 | if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 31)) |
||
1179 | { |
||
1180 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]); |
||
1181 | return; |
||
1182 | } |
||
1183 | |||
1184 | BAsmCode[0] = 0xFD; |
||
1185 | BAsmCode[1] = 0xE0 | imm; |
||
1186 | BAsmCode[2] = (Index << 4) | regd; |
||
1187 | CodeLen = 3; |
||
1188 | return; |
||
1189 | } |
||
1190 | } |
||
1191 | |||
1192 | WrError(ErrNum_OverRange); |
||
1193 | } |
||
1194 | |||
1195 | static void DecodeBRK(Word Index) |
||
1196 | { |
||
1197 | if (!ChkNoAttr()) return; |
||
1198 | if (!ChkArgCnt(0,0)) return; |
||
1199 | |||
1200 | BAsmCode[0] = Index; |
||
1201 | CodeLen = 1; |
||
1202 | } |
||
1203 | |||
1204 | static void DecodeBSR(Word Index) |
||
1205 | { |
||
1206 | const char *str = AttrPart.str.p_str; |
||
1207 | const int len = strlen(str); |
||
1208 | Byte attr = 0; |
||
1209 | Byte reg; |
||
1210 | LongInt addr; |
||
1211 | tSymbolFlags flags; |
||
1212 | Boolean ValOK; |
||
1213 | LongInt disp; |
||
1214 | |||
1215 | UNUSED(Index); |
||
1216 | |||
1217 | if (len > 1) |
||
1218 | { |
||
1219 | WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart); |
||
1220 | return; |
||
1221 | } |
||
1222 | if (len == 1) |
||
1223 | { |
||
1224 | attr = as_toupper(str[0]); |
||
1225 | switch (attr) |
||
1226 | { |
||
1227 | case 'W': |
||
1228 | case 'A': |
||
1229 | case 'L': |
||
1230 | break; |
||
1231 | default: |
||
1232 | WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); |
||
1233 | return; |
||
1234 | } |
||
1235 | } |
||
1236 | |||
1237 | if (!ChkArgCnt(1,1)) return; |
||
1238 | |||
1239 | if ((attr == 0 || attr == 'L') && DecodeReg(&ArgStr[1], ®, eRn)) |
||
1240 | { |
||
1241 | BAsmCode[0] = 0x7F; |
||
1242 | BAsmCode[1] = 0x50 | reg; |
||
1243 | CodeLen = 2; |
||
1244 | return; |
||
1245 | } |
||
1246 | |||
1247 | addr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &flags); |
||
1248 | if (ValOK) |
||
1249 | { |
||
1250 | if (attr == 'L') |
||
1251 | { |
||
1252 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]); |
||
1253 | return; |
||
1254 | } |
||
1255 | |||
1256 | disp = addr - EProgCounter(); |
||
1257 | |||
1258 | /* Try 16 bit */ |
||
1259 | if ((attr == 0 || attr == 'W') && |
||
1260 | ((disp & 0xFFFF8000) == 0xFFFF8000 || |
||
1261 | (disp & 0xFFFF8000) == 0x00000000)) |
||
1262 | { |
||
1263 | BAsmCode[0] = 0x39; |
||
1264 | BAsmCode[1] = disp & 0xFF; |
||
1265 | BAsmCode[2] = (disp >> 8) & 0xFF; |
||
1266 | CodeLen = 3; |
||
1267 | return; |
||
1268 | } |
||
1269 | |||
1270 | if (attr == 'W' && !mFirstPassUnknownOrQuestionable(flags)) |
||
1271 | { |
||
1272 | WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]); |
||
1273 | return; |
||
1274 | } |
||
1275 | |||
1276 | /* Try 24 bit */ |
||
1277 | if ((disp & 0xFF800000) == 0xFF800000 || |
||
1278 | (disp & 0xFF800000) == 0x00000000) |
||
1279 | { |
||
1280 | BAsmCode[0] = 0x05; |
||
1281 | BAsmCode[1] = disp & 0xFF; |
||
1282 | BAsmCode[2] = (disp >> 8) & 0xFF; |
||
1283 | BAsmCode[3] = (disp >> 16) & 0xFF; |
||
1284 | CodeLen = 4; |
||
1285 | return; |
||
1286 | } |
||
1287 | |||
1288 | WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]); |
||
1289 | } |
||
1290 | } |
||
1291 | |||
1292 | static const char *BitPSW[] = { |
||
1293 | "C", "Z", "S", "O", NULL, NULL, NULL, NULL, |
||
1294 | "I", "U", NULL, NULL, NULL, NULL, NULL, NULL }; |
||
1295 | |||
1296 | static void DecodeCLRPSW(Word Index) |
||
1297 | { |
||
1298 | int i; |
||
1299 | |||
1300 | if (!ChkNoAttr()) return; |
||
1301 | if (!ChkArgCnt(1,1)) return; |
||
1302 | |||
1303 | for (i = 0; i < 16; i++) |
||
1304 | { |
||
1305 | if (BitPSW[i] && !as_strcasecmp(ArgStr[1].str.p_str, BitPSW[i])) break; |
||
1306 | } |
||
1307 | |||
1308 | if (i < 16) |
||
1309 | { |
||
1310 | BAsmCode[0] = 0x7F; |
||
1311 | BAsmCode[1] = Index | i; |
||
1312 | CodeLen = 2; |
||
1313 | } |
||
1314 | else WrStrErrorPos(ErrNum_UnknownFlag, &ArgStr[1]); |
||
1315 | } |
||
1316 | |||
1317 | static const struct { |
||
1318 | Byte OpcI; |
||
1319 | Byte Opc2; |
||
1320 | Byte OpcM; |
||
1321 | } OpTabDIV[] = { |
||
1322 | { 0x80, 0x20, 0x08 }, /* DIV */ |
||
1323 | { 0x90, 0x24, 0x09 }, /* DIVU */ |
||
1324 | { 0x60, 0x18, 0x06 }, /* EMUL */ |
||
1325 | { 0x70, 0x1C, 0x07 }, /* EMULU */ |
||
1326 | { 0x40, 0x10, 0x04 }, /* MAX */ |
||
1327 | { 0x50, 0x14, 0x05 }, /* MIN */ |
||
1328 | }; |
||
1329 | |||
1330 | static void DecodeDIV(Word Index) |
||
1331 | { |
||
1332 | Byte regs; |
||
1333 | Byte regd; |
||
1334 | Byte size; |
||
1335 | LongInt imm; |
||
1336 | tSymbolFlags flags; |
||
1337 | LongInt disp; |
||
1338 | Byte memex; |
||
1339 | Byte scale; |
||
1340 | |||
1341 | if (!ChkNoAttr()) return; |
||
1342 | if (!ChkArgCnt(2,2)) return; |
||
1343 | |||
1344 | if (!DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1345 | { |
||
1346 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]); |
||
1347 | return; |
||
1348 | } |
||
1349 | |||
1350 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
1351 | { |
||
1352 | size = ImmSize32(imm, flags); |
||
1353 | |||
1354 | BAsmCode[0] = 0xFD; |
||
1355 | BAsmCode[1] = 0x70 | (size << 2); |
||
1356 | BAsmCode[2] = OpTabDIV[Index].OpcI | regd; |
||
1357 | CodeLen = ImmOut(3, size, imm); |
||
1358 | return; |
||
1359 | } |
||
1360 | |||
1361 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
1362 | { |
||
1363 | BAsmCode[0] = 0xFC; |
||
1364 | BAsmCode[1] = OpTabDIV[Index].Opc2 | 0x03; |
||
1365 | BAsmCode[2] = (regs << 4) | regd; |
||
1366 | CodeLen = 3; |
||
1367 | return; |
||
1368 | } |
||
1369 | |||
1370 | if (DecodeIndirectADD(&ArgStr[1], ®s, &disp, &flags, &memex, &scale)) |
||
1371 | { |
||
1372 | if (memex == 0x80) |
||
1373 | { |
||
1374 | size = DispSize(disp, flags, 1); |
||
1375 | |||
1376 | BAsmCode[0] = 0xFC; |
||
1377 | BAsmCode[1] = OpTabDIV[Index].Opc2 | size; |
||
1378 | BAsmCode[2] = (regs << 4) | regd; |
||
1379 | CodeLen = DispOut(3, size, disp, 1); |
||
1380 | return; |
||
1381 | } |
||
1382 | |||
1383 | size = DispSize(disp, flags, scale); |
||
1384 | |||
1385 | BAsmCode[0] = 0x06; |
||
1386 | BAsmCode[1] = 0x20 | (memex << 6) | size; |
||
1387 | BAsmCode[2] = OpTabDIV[Index].OpcM; |
||
1388 | BAsmCode[3] = (regs << 4) | regd; |
||
1389 | CodeLen = DispOut(4, size, disp, scale); |
||
1390 | return; |
||
1391 | } |
||
1392 | |||
1393 | WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]); |
||
1394 | } |
||
1395 | |||
1396 | static const struct { |
||
1397 | Byte OpcI; |
||
1398 | Byte OpcM; |
||
1399 | Byte Opc3; |
||
1400 | Byte flags; |
||
1401 | } OpTabFADD[] = { |
||
1402 | { 0x20, 0x88, 0xA0, 0x03 }, /* FADD */ |
||
1403 | { 0x10, 0x84, 0, 0x01 }, /* FCMP */ |
||
1404 | { 0x40, 0x90, 0, 0x01 }, /* FDIV */ |
||
1405 | { 0x30, 0x8C, 0xB0, 0x03 }, /* FMUL */ |
||
1406 | { 0x00, 0x80, 0x80, 0x03 }, /* FSUB */ |
||
1407 | { 0, 0x94, 0, 0x00 }, /* FTOI */ |
||
1408 | { 0, 0x98, 0, 0x00 }, /* ROUND */ |
||
1409 | { 0, 0xA0, 0, 0x10 }, /* FSQRT */ |
||
1410 | { 0, 0xA4, 0, 0x10 }, /* FTOU */ |
||
1411 | }; |
||
1412 | |||
1413 | static void DecodeFADD(Word Index) |
||
1414 | { |
||
1415 | Byte regs; |
||
1416 | Byte regd; |
||
1417 | Byte size; |
||
1418 | LongInt imm; |
||
1419 | LongInt disp; |
||
1420 | tSymbolFlags flags; |
||
1421 | |||
1422 | if (!ChkNoAttr()) return; |
||
1423 | if (!CheckFloat()) return; |
||
1424 | |||
1425 | if ((OpTabFADD[Index].flags & 0x02) && ArgCnt == 3) |
||
1426 | { |
||
1427 | Byte regs2; |
||
1428 | |||
1429 | if (!DecodeReg(&ArgStr[1], ®s, eRn)) |
||
1430 | { |
||
1431 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]); |
||
1432 | return; |
||
1433 | } |
||
1434 | if (!DecodeReg(&ArgStr[2], ®s2, eRn)) |
||
1435 | { |
||
1436 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]); |
||
1437 | return; |
||
1438 | } |
||
1439 | if (!DecodeReg(&ArgStr[3], ®d, eRn)) |
||
1440 | { |
||
1441 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[3]); |
||
1442 | return; |
||
1443 | } |
||
1444 | |||
1445 | BAsmCode[0] = 0xFF; |
||
1446 | BAsmCode[1] = OpTabFADD[Index].Opc3 | regd; |
||
1447 | BAsmCode[2] = (regs << 4) | regs2; |
||
1448 | CodeLen = 3; |
||
1449 | return; |
||
1450 | } |
||
1451 | |||
1452 | if (!ChkArgCnt(2,2)) return; |
||
1453 | |||
1454 | if (OpTabFADD[Index].flags & 0x10) |
||
1455 | { |
||
1456 | if (!CheckV2()) return; |
||
1457 | } |
||
1458 | |||
1459 | if (!DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1460 | { |
||
1461 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]); |
||
1462 | return; |
||
1463 | } |
||
1464 | |||
1465 | if ((OpTabFADD[Index].flags & 0x01) && |
||
1466 | DecodeFloat(&ArgStr[1], &imm)) |
||
1467 | { |
||
1468 | BAsmCode[0] = 0xFD; |
||
1469 | BAsmCode[1] = 0x72; |
||
1470 | BAsmCode[2] = OpTabFADD[Index].OpcI | regd; |
||
1471 | CodeLen = ImmOut(3, 0, imm); /* size==0 means 4 byte */ |
||
1472 | return; |
||
1473 | } |
||
1474 | |||
1475 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
1476 | { |
||
1477 | size = 0x03; |
||
1478 | disp = 0; |
||
1479 | } |
||
1480 | else if (DecodeIndirectL(&ArgStr[1], ®s, &disp, &flags)) |
||
1481 | { |
||
1482 | if (mFirstPassUnknown(flags)) size = 0x02; |
||
1483 | else size = DispSize(disp, flags, 4); |
||
1484 | } |
||
1485 | else |
||
1486 | { |
||
1487 | WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]); |
||
1488 | return; |
||
1489 | } |
||
1490 | |||
1491 | BAsmCode[0] = 0xFC; |
||
1492 | BAsmCode[1] = OpTabFADD[Index].OpcM | size; |
||
1493 | BAsmCode[2] = (regs << 4) | regd; |
||
1494 | CodeLen = DispOut(3, size, disp, 4); |
||
1495 | } |
||
1496 | |||
1497 | static void DecodeINT(Word Index) |
||
1498 | { |
||
1499 | LongInt imm; |
||
1500 | tSymbolFlags flags; |
||
1501 | |||
1502 | UNUSED(Index); |
||
1503 | |||
1504 | if (!ChkNoAttr()) return; |
||
1505 | if (!ChkArgCnt(1,1)) return; |
||
1506 | |||
1507 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
1508 | { |
||
1509 | if (!mFirstPassUnknown(flags) && (imm < -128 || imm > 255)) |
||
1510 | { |
||
1511 | WrStrErrorPos(ErrNum_ArgOutOfRange, &ArgStr[1]); |
||
1512 | return; |
||
1513 | } |
||
1514 | |||
1515 | BAsmCode[0] = 0x75; |
||
1516 | BAsmCode[1] = 0x60; |
||
1517 | BAsmCode[2] = imm & 0xFF; |
||
1518 | CodeLen = 3; |
||
1519 | return; |
||
1520 | } |
||
1521 | |||
1522 | WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]); |
||
1523 | } |
||
1524 | |||
1525 | static const struct { |
||
1526 | Byte Opc1; |
||
1527 | Byte Opc2; |
||
1528 | Byte flags; |
||
1529 | } OpTabITOF[] = { |
||
1530 | { 0x44, 0x11, 0x00 }, /* ITOF */ |
||
1531 | { 0x54, 0x15, 0x10 }, /* UTOF */ |
||
1532 | }; |
||
1533 | |||
1534 | static void DecodeITOF(Word Index) |
||
1535 | { |
||
1536 | Byte regs; |
||
1537 | Byte regd; |
||
1538 | Byte size; |
||
1539 | Byte memex; |
||
1540 | Byte scale; |
||
1541 | LongInt disp; |
||
1542 | tSymbolFlags flags; |
||
1543 | |||
1544 | if (!ChkNoAttr()) return; |
||
1545 | if (!ChkArgCnt(2,2)) return; |
||
1546 | if (!CheckFloat()) return; |
||
1547 | |||
1548 | if ((OpTabITOF[Index].flags & 0x10) && !CheckV2()) return; |
||
1549 | |||
1550 | if (!DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1551 | { |
||
1552 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]); |
||
1553 | return; |
||
1554 | } |
||
1555 | |||
1556 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
1557 | { |
||
1558 | size = 0x03; |
||
1559 | disp = 0; |
||
1560 | memex = 0; |
||
1561 | } |
||
1562 | else if (DecodeIndirectADD(&ArgStr[1], ®s, &disp, &flags, &memex, &scale)) |
||
1563 | { |
||
1564 | if (mFirstPassUnknown(flags)) size = 0x02; |
||
1565 | else size = DispSize(disp, flags, scale); |
||
1566 | } |
||
1567 | else |
||
1568 | { |
||
1569 | WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]); |
||
1570 | return; |
||
1571 | } |
||
1572 | |||
1573 | if (memex == 0x80 || size == 0x03) |
||
1574 | { |
||
1575 | BAsmCode[0] = 0xFC; |
||
1576 | BAsmCode[1] = OpTabITOF[Index].Opc1 | size; |
||
1577 | BAsmCode[2] = (regs << 4) | regd; |
||
1578 | if (size < 0x03) CodeLen = DispOut(3, size, disp, scale); |
||
1579 | else CodeLen = 3; |
||
1580 | return; |
||
1581 | } |
||
1582 | |||
1583 | BAsmCode[0] = 0x06; |
||
1584 | BAsmCode[1] = 0x20 | (memex << 6) | size; |
||
1585 | BAsmCode[2] = OpTabITOF[Index].Opc2; |
||
1586 | BAsmCode[3] = (regs << 4) | regd; |
||
1587 | CodeLen = DispOut(4, size, disp, scale); |
||
1588 | } |
||
1589 | |||
1590 | static const struct { |
||
1591 | Byte Opc1; |
||
1592 | Byte Opc2; |
||
1593 | } OpTabJMP[] = { |
||
1594 | { 0x7F, 0x00 }, /* JMP */ |
||
1595 | { 0x7F, 0x10 }, /* JSR */ |
||
1596 | { 0x7E, 0xB0 }, /* POP */ |
||
1597 | { 0x7E, 0x50 }, /* ROLC */ |
||
1598 | { 0x7E, 0x40 }, /* RORC */ |
||
1599 | { 0x7E, 0x30 }, /* SAT */ |
||
1600 | }; |
||
1601 | |||
1602 | static void DecodeJMP(Word Index) |
||
1603 | { |
||
1604 | Byte reg; |
||
1605 | |||
1606 | if (!ChkNoAttr()) return; |
||
1607 | if (!ChkArgCnt(1,1)) return; |
||
1608 | |||
1609 | if (DecodeReg(&ArgStr[1], ®, eRn)) |
||
1610 | { |
||
1611 | BAsmCode[0] = OpTabJMP[Index].Opc1; |
||
1612 | BAsmCode[1] = OpTabJMP[Index].Opc2 | reg; |
||
1613 | CodeLen = 2; |
||
1614 | return; |
||
1615 | } |
||
1616 | |||
1617 | WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]); |
||
1618 | } |
||
1619 | |||
1620 | static const struct { |
||
1621 | Byte Opc; |
||
1622 | Byte flags; |
||
1623 | } OpTabMACHI[] = { |
||
1624 | { 0x04, 0x01 }, /* MACHI */ |
||
1625 | { 0x05, 0x01 }, /* MACLO */ |
||
1626 | { 0x00, 0x01 }, /* MULHI */ |
||
1627 | { 0x01, 0x01 }, /* MULLO */ |
||
1628 | { 0x67, 0x00 }, /* REVL */ |
||
1629 | |||
1630 | { 0x65, 0x00 }, /* REVW */ |
||
1631 | { 0x07, 0x11 }, /* EMACA */ |
||
1632 | { 0x47, 0x11 }, /* EMSBA */ |
||
1633 | { 0x03, 0x11 }, /* EMULA */ |
||
1634 | { 0x06, 0x11 }, /* MACLH */ |
||
1635 | |||
1636 | { 0x44, 0x11 }, /* MSBHI */ |
||
1637 | { 0x46, 0x11 }, /* MSBLH */ |
||
1638 | { 0x45, 0x11 }, /* MSBLO */ |
||
1639 | { 0x02, 0x11 }, /* MULLH */ |
||
1640 | }; |
||
1641 | |||
1642 | static void DecodeMACHI(Word Index) |
||
1643 | { |
||
1644 | Byte reg1; |
||
1645 | Byte reg2; |
||
1646 | Byte acc = 0; |
||
1647 | |||
1648 | if ((OpTabMACHI[Index].flags & 0x10) && !CheckV2()) return; |
||
1649 | if (!ChkNoAttr()) return; |
||
1650 | if (pCurrCPUProps->InstSet == eRXv1) |
||
1651 | { |
||
1652 | if (!ChkArgCnt(2,2)) return; |
||
1653 | } |
||
1654 | else |
||
1655 | { |
||
1656 | if (OpTabMACHI[Index].flags & 0x01) |
||
1657 | { |
||
1658 | if (!ChkArgCnt(3,3)) return; |
||
1659 | if (!DecodeAcc(&ArgStr[3], &acc)) |
||
1660 | { |
||
1661 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[3]); |
||
1662 | return; |
||
1663 | } |
||
1664 | } |
||
1665 | else |
||
1666 | { |
||
1667 | if (!ChkArgCnt(2,2)) return; |
||
1668 | } |
||
1669 | } |
||
1670 | |||
1671 | if (!DecodeReg(&ArgStr[1], ®1, eRn)) |
||
1672 | { |
||
1673 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]); |
||
1674 | return; |
||
1675 | } |
||
1676 | |||
1677 | if (!DecodeReg(&ArgStr[2], ®2, eRn)) |
||
1678 | { |
||
1679 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]); |
||
1680 | return; |
||
1681 | } |
||
1682 | |||
1683 | BAsmCode[0] = 0xFD; |
||
1684 | BAsmCode[1] = OpTabMACHI[Index].Opc | (acc << 3); |
||
1685 | BAsmCode[2] = (reg1 << 4) | reg2; |
||
1686 | CodeLen = 3; |
||
1687 | } |
||
1688 | |||
1689 | static void DecodeMOV(Word Index) |
||
1690 | { |
||
1691 | tSymbolSize size; |
||
1692 | Byte regs; |
||
1693 | Byte regd; |
||
1694 | LongInt imm; |
||
1695 | LongInt disp; |
||
1696 | tSymbolFlags flags; |
||
1697 | tSymbolFlags flags2; |
||
1698 | Byte disp2; |
||
1699 | Byte isize; |
||
1700 | Byte dsize; |
||
1701 | Byte scale; |
||
1702 | Byte regi; |
||
1703 | |||
1704 | UNUSED(Index); |
||
1705 | |||
1706 | size = DecodeAttrSize(); |
||
1707 | if (size == eSymbolSizeUnknown) return; |
||
1708 | scale = Size2Scale(size); |
||
1709 | |||
1710 | if (DecodeReg(&ArgStr[1], ®s, eRn) && regs < 8 && |
||
1711 | DecodeRelative(&ArgStr[2], ®d, &disp, &flags)) |
||
1712 | { /* (1) */ |
||
1713 | if (ChkDisp5(size, disp, flags)) |
||
1714 | { |
||
1715 | disp2 = DispSize5(size, disp); |
||
1716 | |||
1717 | BAsmCode[0] = 0x80 | (size << 4) | ((disp2 >> 2) & 0x07); |
||
1718 | BAsmCode[1] = ((disp2 << 6) & 0x80) | (regd << 4) | ((disp2 << 3) & 0x08) | regs; |
||
1719 | CodeLen = 2; |
||
1720 | return; |
||
1721 | } |
||
1722 | } |
||
1723 | |||
1724 | if (DecodeRelative(&ArgStr[1], ®s, &disp, &flags) && |
||
1725 | DecodeReg(&ArgStr[2], ®d, eRn) && regd < 8) |
||
1726 | { /* (2) */ |
||
1727 | if (ChkDisp5(size, disp, flags)) |
||
1728 | { |
||
1729 | disp2 = DispSize5(size, disp); |
||
1730 | |||
1731 | BAsmCode[0] = 0x88 | (size << 4) | ((disp2 >> 2) & 0x07); |
||
1732 | BAsmCode[1] = ((disp2 << 6) & 0x80) | (regs << 4) | ((disp2 << 3) & 0x08) | regd; |
||
1733 | CodeLen = 2; |
||
1734 | return; |
||
1735 | } |
||
1736 | } |
||
1737 | |||
1738 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
1739 | { |
||
1740 | if (size == 0x02 && DecodeReg(&ArgStr[2], ®d, eRn) && |
||
1741 | !mFirstPassUnknown(flags) && imm >= 0 && imm < 16) |
||
1742 | { /* (3) */ |
||
1743 | BAsmCode[0] = 0x66; |
||
1744 | BAsmCode[1] = (imm << 4) | regd; |
||
1745 | CodeLen = 2; |
||
1746 | return; |
||
1747 | } |
||
1748 | |||
1749 | if (DecodeRelative(&ArgStr[2], ®d, &disp, &flags)) |
||
1750 | { /* (4) */ |
||
1751 | if ((size == 0x00 && imm >= -128 && imm < 256) || |
||
1752 | (size != 0x00 && imm >= 0 && imm < 256)) |
||
1753 | { |
||
1754 | disp2 = DispSize5(size, disp); |
||
1755 | |||
1756 | BAsmCode[0] = 0x3C | size; |
||
1757 | BAsmCode[1] = ((disp2 << 3) & 0x80) | (regd << 4) | (disp2 & 0x0F); |
||
1758 | BAsmCode[2] = imm; |
||
1759 | CodeLen = 3; |
||
1760 | return; |
||
1761 | } |
||
1762 | } |
||
1763 | |||
1764 | if (DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1765 | { |
||
1766 | if (size == 0x02 && !mFirstPassUnknown(flags) && |
||
1767 | imm >= 0 && imm < 256) |
||
1768 | { /* (5) */ |
||
1769 | BAsmCode[0] = 0x75; |
||
1770 | BAsmCode[1] = 0x40 | regd; |
||
1771 | BAsmCode[2] = imm; |
||
1772 | CodeLen = 3; |
||
1773 | return; |
||
1774 | } |
||
1775 | |||
1776 | /* (6) */ |
||
1777 | isize = ImmSize32(imm, flags); |
||
1778 | |||
1779 | BAsmCode[0] = 0xFB; |
||
1780 | BAsmCode[1] = (regd << 4) | (isize << 2) | 0x02; |
||
1781 | |||
1782 | CodeLen = ImmOut(2, isize, imm); |
||
1783 | return; |
||
1784 | } |
||
1785 | |||
1786 | if (DecodeIndirectADC(&ArgStr[2], ®d, &disp, &flags2)) |
||
1787 | { /* (8) */ |
||
1788 | switch (size) |
||
1789 | { |
||
1790 | case 0x00: /* B */ |
||
1791 | if (imm < -128 || imm > 255) |
||
1792 | { |
||
1793 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]); |
||
1794 | return; |
||
1795 | } |
||
1796 | isize = 0x01; |
||
1797 | break; |
||
1798 | case 0x01: /* W */ |
||
1799 | if (imm < -32768 || imm > 65535) |
||
1800 | { |
||
1801 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]); |
||
1802 | return; |
||
1803 | } |
||
1804 | isize = ImmSize16(imm, flags); |
||
1805 | break; |
||
1806 | case 0x02: /* L */ |
||
1807 | isize = ImmSize32(imm, flags); |
||
1808 | break; |
||
1809 | default: |
||
1810 | WrError(ErrNum_InternalError); |
||
1811 | return; |
||
1812 | } |
||
1813 | |||
1814 | dsize = DispSize(disp, flags2, scale); |
||
1815 | |||
1816 | BAsmCode[0] = 0xF8 | dsize; |
||
1817 | BAsmCode[1] = (regd << 4) | (isize << 2) | size; |
||
1818 | CodeLen = DispOut(2, dsize, disp, scale); |
||
1819 | CodeLen = ImmOut(CodeLen, isize, imm); |
||
1820 | return; |
||
1821 | } |
||
1822 | |||
1823 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]); |
||
1824 | } |
||
1825 | |||
1826 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
1827 | { |
||
1828 | if (DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1829 | { /* (7) */ |
||
1830 | BAsmCode[0] = 0xCF | (size << 4); |
||
1831 | BAsmCode[1] = (regs << 4) | regd; |
||
1832 | CodeLen = 2; |
||
1833 | return; |
||
1834 | } |
||
1835 | |||
1836 | if (DecodeIndirectADC(&ArgStr[2], ®d, &disp, &flags)) |
||
1837 | { /* (11) */ |
||
1838 | dsize = DispSize(disp, flags, scale); |
||
1839 | |||
1840 | BAsmCode[0] = 0xC3 | (size << 4) | (dsize << 2); |
||
1841 | BAsmCode[1] = (regd << 4) | regs; |
||
1842 | CodeLen = DispOut(2, dsize, disp, scale); |
||
1843 | return; |
||
1844 | } |
||
1845 | |||
1846 | if (DecodeIndexed(&ArgStr[2], ®i, ®d)) |
||
1847 | { /* (12) */ |
||
1848 | BAsmCode[0] = 0xFE; |
||
1849 | BAsmCode[1] = (size << 4) | regi; |
||
1850 | BAsmCode[2] = (regd << 4) | regs; |
||
1851 | CodeLen = 3; |
||
1852 | return; |
||
1853 | } |
||
1854 | |||
1855 | if (DecodeIncDec(&ArgStr[2], ®d, ®i)) |
||
1856 | { /* (14) */ |
||
1857 | BAsmCode[0] = 0xFD; |
||
1858 | BAsmCode[1] = 0x20 | (regi << 2) | size; |
||
1859 | BAsmCode[2] = (regd << 4) | regs; |
||
1860 | CodeLen = 3; |
||
1861 | return; |
||
1862 | } |
||
1863 | } |
||
1864 | |||
1865 | if (DecodeIndirectADC(&ArgStr[1], ®s, &disp, &flags)) |
||
1866 | { |
||
1867 | if (DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1868 | { /* (9) */ |
||
1869 | dsize = DispSize(disp, flags, scale); |
||
1870 | |||
1871 | BAsmCode[0] = 0xCC | (size << 4) | dsize; |
||
1872 | BAsmCode[1] = (regs << 4) | regd; |
||
1873 | CodeLen = DispOut(2, dsize, disp, scale); |
||
1874 | return; |
||
1875 | } |
||
1876 | |||
1877 | if (DecodeIndirectADC(&ArgStr[2], ®d, &imm, &flags2)) |
||
1878 | { /* (13) */ |
||
1879 | dsize = DispSize(disp, flags, scale); /* src */ |
||
1880 | isize = DispSize(imm, flags2, scale); /* dst */ |
||
1881 | |||
1882 | BAsmCode[0] = 0xC0 | (size << 4) | (isize << 2) | dsize; |
||
1883 | BAsmCode[1] = (regs << 4) | regd; |
||
1884 | CodeLen = DispOut(2, dsize, disp, scale); |
||
1885 | CodeLen = DispOut(CodeLen, isize, imm, scale); |
||
1886 | return; |
||
1887 | } |
||
1888 | } |
||
1889 | |||
1890 | if (DecodeIndexed(&ArgStr[1], ®i, ®s) && |
||
1891 | DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1892 | { /* (10) */ |
||
1893 | BAsmCode[0] = 0xFE; |
||
1894 | BAsmCode[1] = 0x40 | (size << 4) | regi; |
||
1895 | BAsmCode[2] = (regs << 4) | regd; |
||
1896 | CodeLen = 3; |
||
1897 | return; |
||
1898 | } |
||
1899 | |||
1900 | if (DecodeIncDec(&ArgStr[1], ®s, ®i) && |
||
1901 | DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1902 | { |
||
1903 | BAsmCode[0] = 0xFD; |
||
1904 | BAsmCode[1] = 0x28 | (regi << 2) | size; |
||
1905 | BAsmCode[2] = (regs << 4) | regd; |
||
1906 | CodeLen = 3; |
||
1907 | return; |
||
1908 | } |
||
1909 | |||
1910 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]); |
||
1911 | } |
||
1912 | |||
1913 | static void DecodeMOVU(Word Index) |
||
1914 | { |
||
1915 | tSymbolSize size; |
||
1916 | Byte regs; |
||
1917 | Byte regd; |
||
1918 | Byte scale; |
||
1919 | LongInt disp; |
||
1920 | tSymbolFlags flags; |
||
1921 | Byte disp2; |
||
1922 | Byte dsize; |
||
1923 | Byte regi; |
||
1924 | |||
1925 | UNUSED(Index); |
||
1926 | |||
1927 | size = DecodeAttrSize(); |
||
1928 | if (size == eSymbolSizeUnknown || size == eSymbolSize32Bit) return; |
||
1929 | scale = Size2Scale(size); |
||
1930 | |||
1931 | if (DecodeReg(&ArgStr[2], ®d, eRn)) |
||
1932 | { |
||
1933 | if (DecodeRelative(&ArgStr[1], ®s, &disp, &flags) && |
||
1934 | ChkDisp5(size, disp, flags) && regd < 8) |
||
1935 | { /* (1) */ |
||
1936 | disp2 = DispSize5(size, disp); |
||
1937 | |||
1938 | BAsmCode[0] = 0xB0 | (size << 3) | ((disp2 >> 2) & 0x07); |
||
1939 | BAsmCode[1] = ((disp2 << 6) & 0x80) | (regs << 4) | ((disp2 << 3) & 0x08) | regd; |
||
1940 | CodeLen = 2; |
||
1941 | return; |
||
1942 | } |
||
1943 | |||
1944 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
1945 | { /* (2)-1 */ |
||
1946 | BAsmCode[0] = 0x5B | (size << 2); |
||
1947 | BAsmCode[1] = (regs << 4) | regd; |
||
1948 | CodeLen = 2; |
||
1949 | return; |
||
1950 | } |
||
1951 | |||
1952 | if (DecodeIndirectADC(&ArgStr[1], ®s, &disp, &flags)) |
||
1953 | { /* (2)-2 */ |
||
1954 | dsize = DispSize(disp, flags, scale); |
||
1955 | |||
1956 | BAsmCode[0] = 0x58 | (size << 2) | dsize; |
||
1957 | BAsmCode[1] = (regs << 4) | regd; |
||
1958 | CodeLen = DispOut(2, dsize, disp, scale); |
||
1959 | return; |
||
1960 | } |
||
1961 | |||
1962 | if (DecodeIndexed(&ArgStr[1], ®i, ®s)) |
||
1963 | { /* (3) */ |
||
1964 | BAsmCode[0] = 0xFE; |
||
1965 | BAsmCode[1] = 0xC0 | (size << 4) | regi; |
||
1966 | BAsmCode[2] = (regs << 4) | regd; |
||
1967 | CodeLen = 3; |
||
1968 | return; |
||
1969 | } |
||
1970 | |||
1971 | if (DecodeIncDec(&ArgStr[1], ®s, ®i)) |
||
1972 | { /* (4) */ |
||
1973 | BAsmCode[0] = 0xFD; |
||
1974 | BAsmCode[1] = 0x38 | (regi << 2) | size; |
||
1975 | BAsmCode[2] = (regs << 4) | regd; |
||
1976 | CodeLen = 3; |
||
1977 | return; |
||
1978 | } |
||
1979 | } |
||
1980 | |||
1981 | WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]); |
||
1982 | } |
||
1983 | |||
1984 | static const struct { |
||
1985 | Byte Opc2; |
||
1986 | Byte Opc3; |
||
1987 | Byte flags; |
||
1988 | } OpTabMVFACHI[] = { |
||
1989 | { 0x1E, 0x00, 0x00 }, /* MVFACHI */ |
||
1990 | { 0x1E, 0x20, 0x00 }, /* MVFACMI */ |
||
1991 | { 0x1E, 0x30, 0x10 }, /* MVFACGU */ |
||
1992 | { 0x1E, 0x10, 0x10 }, /* MVFACLO */ |
||
1993 | }; |
||
1994 | |||
1995 | static void DecodeMVFACHI(Word Index) |
||
1996 | { |
||
1997 | LongInt imm; |
||
1998 | tSymbolFlags flags; |
||
1999 | Byte acc; |
||
2000 | Byte reg; |
||
2001 | |||
2002 | if ((OpTabMVFACHI[Index].flags & 0x10) && !CheckV2()) return; |
||
2003 | if (!ChkNoAttr()) return; |
||
2004 | |||
2005 | if (pCurrCPUProps->InstSet == eRXv1) |
||
2006 | { |
||
2007 | if (!ChkArgCnt(1,1)) return; |
||
2008 | imm = 0x02; |
||
2009 | acc = 0x00; |
||
2010 | } |
||
2011 | else |
||
2012 | { |
||
2013 | if (!ChkArgCnt(3,3)) return; |
||
2014 | if (!DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2015 | { |
||
2016 | WrStrErrorPos(ErrNum_OnlyImmAddr, &ArgStr[1]); |
||
2017 | return; |
||
2018 | } |
||
2019 | switch (imm) |
||
2020 | { |
||
2021 | case 0: |
||
2022 | imm = 0x02; |
||
2023 | break; |
||
2024 | case 1: |
||
2025 | imm = 0x03; |
||
2026 | break; |
||
2027 | case 2: |
||
2028 | imm = 0x00; |
||
2029 | break; |
||
2030 | default: |
||
2031 | if (mSymbolQuestionable(flags)) break; |
||
2032 | WrStrErrorPos(ErrNum_ArgOutOfRange, &ArgStr[1]); |
||
2033 | return; |
||
2034 | } |
||
2035 | |||
2036 | if (!DecodeAcc(&ArgStr[2], &acc)) |
||
2037 | { |
||
2038 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]); |
||
2039 | return; |
||
2040 | } |
||
2041 | } |
||
2042 | |||
2043 | if (!DecodeReg(&ArgStr[ArgCnt], ®, eRn)) |
||
2044 | { |
||
2045 | WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[ArgCnt]); |
||
2046 | return; |
||
2047 | } |
||
2048 | |||
2049 | BAsmCode[0] = 0xFD; |
||
2050 | BAsmCode[1] = OpTabMVFACHI[Index].Opc2 | ((imm >> 1) & 0x01); |
||
2051 | BAsmCode[2] = OpTabMVFACHI[Index].Opc3 | (acc << 7) | ((imm << 6) & 0x40) | reg; |
||
2052 | CodeLen = 3; |
||
2053 | } |
||
2054 | |||
2055 | static const char *SPReg[] = { |
||
2056 | "PSW", "PC", "USP", "FPSW", NULL, NULL, NULL, NULL, |
||
2057 | "BPSW", "BPC", "ISP", "FINTV", "INTB", "EXTB", NULL, NULL, |
||
2058 | }; |
||
2059 | |||
2060 | static void DecodeMVFC(Word Index) |
||
2061 | { |
||
2062 | Byte reg; |
||
2063 | size_t i; |
||
2064 | |||
2065 | UNUSED(Index); |
||
2066 | |||
2067 | if (!ChkNoAttr()) return; |
||
2068 | if (!ChkArgCnt(2,2)) return; |
||
2069 | |||
2070 | if (DecodeReg(&ArgStr[2], ®, eRn)) |
||
2071 | { |
||
2072 | for (i = 0; i < as_array_size(SPReg); i++) |
||
2073 | { |
||
2074 | if (i == 13 && pCurrCPUProps->InstSet == eRXv1) |
||
2075 | { |
||
2076 | WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]); |
||
2077 | } |
||
2078 | |||
2079 | if (SPReg[i] && !as_strcasecmp(SPReg[i], ArgStr[1].str.p_str)) |
||
2080 | { |
||
2081 | BAsmCode[0] = 0xFD; |
||
2082 | BAsmCode[1] = 0x6A; |
||
2083 | BAsmCode[2] = (i << 4) | reg; |
||
2084 | CodeLen = 3; |
||
2085 | return; |
||
2086 | } |
||
2087 | } |
||
2088 | |||
2089 | WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]); |
||
2090 | } |
||
2091 | |||
2092 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]); |
||
2093 | } |
||
2094 | |||
2095 | static const struct { |
||
2096 | Byte Opc2; |
||
2097 | Byte Opc3; |
||
2098 | Byte flags; |
||
2099 | } OpTabMVTACHI[] = { |
||
2100 | { 0x17, 0x00, 0x00 }, /* MVTACHI */ |
||
2101 | { 0x17, 0x10, 0x00 }, /* MVTACLO */ |
||
2102 | { 0x17, 0x30, 0x10 }, /* MVTACGU */ |
||
2103 | }; |
||
2104 | |||
2105 | static void DecodeMVTACHI(Word Index) |
||
2106 | { |
||
2107 | Byte acc; |
||
2108 | Byte reg; |
||
2109 | |||
2110 | if ((OpTabMVTACHI[Index].flags & 0x10) && !CheckV2()) return; |
||
2111 | if (!ChkNoAttr()) return; |
||
2112 | |||
2113 | if (pCurrCPUProps->InstSet == eRXv1) |
||
2114 | { |
||
2115 | if (!ChkArgCnt(1,1)) return; |
||
2116 | acc = 0x00; |
||
2117 | } |
||
2118 | else |
||
2119 | { |
||
2120 | if (!ChkArgCnt(2,2)) return; |
||
2121 | |||
2122 | if (!DecodeAcc(&ArgStr[2], &acc)) |
||
2123 | { |
||
2124 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]); |
||
2125 | return; |
||
2126 | } |
||
2127 | } |
||
2128 | |||
2129 | if (!DecodeReg(&ArgStr[1], ®, eRn)) |
||
2130 | { |
||
2131 | WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]); |
||
2132 | return; |
||
2133 | } |
||
2134 | |||
2135 | BAsmCode[0] = 0xFD; |
||
2136 | BAsmCode[1] = OpTabMVTACHI[Index].Opc2; |
||
2137 | BAsmCode[2] = OpTabMVTACHI[Index].Opc3 | (acc << 7) | reg; |
||
2138 | CodeLen = 3; |
||
2139 | } |
||
2140 | |||
2141 | static void DecodeMVTC(Word Index) |
||
2142 | { |
||
2143 | Byte reg; |
||
2144 | LongInt imm; |
||
2145 | Byte size; |
||
2146 | tSymbolFlags flags; |
||
2147 | size_t i; |
||
2148 | |||
2149 | UNUSED(Index); |
||
2150 | |||
2151 | if (!ChkNoAttr()) return; |
||
2152 | if (!ChkArgCnt(2,2)) return; |
||
2153 | |||
2154 | for (i = 0; i < as_array_size(SPReg); i++) |
||
2155 | { |
||
2156 | if (SPReg[i] && !as_strcasecmp(SPReg[i], ArgStr[2].str.p_str)) |
||
2157 | { |
||
2158 | if (i == 1) |
||
2159 | { |
||
2160 | WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]); |
||
2161 | return; |
||
2162 | } |
||
2163 | |||
2164 | if (i == 13 && pCurrCPUProps->InstSet == eRXv1) |
||
2165 | { |
||
2166 | WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]); |
||
2167 | } |
||
2168 | |||
2169 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2170 | { |
||
2171 | size = ImmSize32(imm, flags); |
||
2172 | |||
2173 | BAsmCode[0] = 0xFD; |
||
2174 | BAsmCode[1] = 0x73 | (size << 2); |
||
2175 | BAsmCode[2] = i; |
||
2176 | CodeLen = ImmOut(3, size, imm); |
||
2177 | return; |
||
2178 | } |
||
2179 | |||
2180 | if (DecodeReg(&ArgStr[1], ®, eRn)) |
||
2181 | { |
||
2182 | BAsmCode[0] = 0xFD; |
||
2183 | BAsmCode[1] = 0x68; |
||
2184 | BAsmCode[2] = (reg << 4) | i; |
||
2185 | CodeLen = 3; |
||
2186 | return; |
||
2187 | } |
||
2188 | |||
2189 | WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]); |
||
2190 | } |
||
2191 | } |
||
2192 | |||
2193 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]); |
||
2194 | } |
||
2195 | |||
2196 | static void DecodeMVTIPL(Word Index) |
||
2197 | { |
||
2198 | LongInt imm; |
||
2199 | tSymbolFlags flags; |
||
2200 | |||
2201 | UNUSED(Index); |
||
2202 | |||
2203 | if (!CheckSup()) return; |
||
2204 | if (!ChkNoAttr()) return; |
||
2205 | if (!ChkArgCnt(1,1)) return; |
||
2206 | |||
2207 | if (!pCurrCPUProps->hasMVTIPL) |
||
2208 | { |
||
2209 | WrError(ErrNum_InstructionNotSupported); |
||
2210 | return; |
||
2211 | } |
||
2212 | |||
2213 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2214 | { |
||
2215 | if (!mFirstPassUnknown(flags) && (imm < 0 || imm > 15)) |
||
2216 | { |
||
2217 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]); |
||
2218 | return; |
||
2219 | } |
||
2220 | |||
2221 | BAsmCode[0] = 0x75; |
||
2222 | BAsmCode[1] = 0x70; |
||
2223 | BAsmCode[2] = imm; |
||
2224 | CodeLen = 3; |
||
2225 | return; |
||
2226 | } |
||
2227 | |||
2228 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]); |
||
2229 | } |
||
2230 | |||
2231 | static const Byte OpTabPOPC[] = { |
||
2232 | 0xE0, /* POPC */ |
||
2233 | 0xC0, /* PUSHC */ |
||
2234 | }; |
||
2235 | |||
2236 | static void DecodePOPC(Word Index) |
||
2237 | { |
||
2238 | size_t i; |
||
2239 | |||
2240 | UNUSED(Index); |
||
2241 | |||
2242 | if (!ChkNoAttr()) return; |
||
2243 | if (!ChkArgCnt(1,1)) return; |
||
2244 | |||
2245 | for (i = 0; i < as_array_size(SPReg); i++) |
||
2246 | { |
||
2247 | if (SPReg[i] && !as_strcasecmp(SPReg[i], ArgStr[1].str.p_str)) |
||
2248 | { |
||
2249 | if (Index == 0 && i == 1) |
||
2250 | { |
||
2251 | WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]); |
||
2252 | return; |
||
2253 | } |
||
2254 | |||
2255 | if (i == 13 && pCurrCPUProps->InstSet == eRXv1) |
||
2256 | { |
||
2257 | WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]); |
||
2258 | } |
||
2259 | |||
2260 | BAsmCode[0] = 0x7E; |
||
2261 | BAsmCode[1] = OpTabPOPC[Index] | i; |
||
2262 | CodeLen = 2; |
||
2263 | return; |
||
2264 | } |
||
2265 | } |
||
2266 | |||
2267 | WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]); |
||
2268 | } |
||
2269 | |||
2270 | static const Byte OpTabPOPM[] = { |
||
2271 | 0x6F, /* POPM */ |
||
2272 | 0x6E, /* PUSHM */ |
||
2273 | }; |
||
2274 | |||
2275 | static void DecodePOPM(Word Index) |
||
2276 | { |
||
2277 | Byte range; |
||
2278 | |||
2279 | if (!ChkNoAttr()) return; |
||
2280 | if (!ChkArgCnt(1,1)) return; |
||
2281 | |||
2282 | if (DecodeRegRange(&ArgStr[1], &range)) |
||
2283 | { |
||
2284 | BAsmCode[0] = OpTabPOPM[Index]; |
||
2285 | BAsmCode[1] = range; |
||
2286 | CodeLen = 2; |
||
2287 | return; |
||
2288 | } |
||
2289 | |||
2290 | WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]); |
||
2291 | } |
||
2292 | |||
2293 | static void DecodePUSH(Word Index) |
||
2294 | { |
||
2295 | tSymbolSize size; |
||
2296 | Byte reg; |
||
2297 | LongInt disp; |
||
2298 | tSymbolFlags flags; |
||
2299 | Byte dsize; |
||
2300 | Byte scale; |
||
2301 | |||
2302 | UNUSED(Index); |
||
2303 | |||
2304 | size = DecodeAttrSize(); |
||
2305 | if (size == eSymbolSizeUnknown) return; |
||
2306 | if (!ChkArgCnt(1,1)) return; |
||
2307 | |||
2308 | scale = Size2Scale(size); |
||
2309 | |||
2310 | if (DecodeReg(&ArgStr[1], ®, eRn)) |
||
2311 | { |
||
2312 | BAsmCode[0] = 0x7E; |
||
2313 | BAsmCode[1] = 0x80 | (size << 4) | reg; |
||
2314 | CodeLen = 2; |
||
2315 | return; |
||
2316 | } |
||
2317 | |||
2318 | if (DecodeIndirectADC(&ArgStr[1], ®, &disp, &flags)) |
||
2319 | { |
||
2320 | dsize = DispSize(disp, flags, scale); |
||
2321 | |||
2322 | BAsmCode[0] = 0xF4 | dsize; |
||
2323 | BAsmCode[1] = 0x08 | (reg << 4) | size; |
||
2324 | CodeLen = DispOut(2, dsize, disp, scale); |
||
2325 | return; |
||
2326 | } |
||
2327 | |||
2328 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]); |
||
2329 | } |
||
2330 | |||
2331 | static const struct { |
||
2332 | Byte Opc2; |
||
2333 | Byte Opc3; |
||
2334 | Byte flags; |
||
2335 | } OpTabRACW[] = { |
||
2336 | { 0x18, 0x00, 0x00 }, /* RACW */ |
||
2337 | { 0x19, 0x00, 0x10 }, /* RACL */ |
||
2338 | { 0x19, 0x40, 0x10 }, /* RDACL */ |
||
2339 | { 0x18, 0x40, 0x10 }, /* RDACW */ |
||
2340 | }; |
||
2341 | |||
2342 | static void DecodeRACW(Word Index) |
||
2343 | { |
||
2344 | LongInt imm; |
||
2345 | tSymbolFlags flags; |
||
2346 | Byte acc = 0; |
||
2347 | |||
2348 | if ((OpTabRACW[Index].flags & 0x10) && !CheckV2()) return; |
||
2349 | if (!ChkNoAttr()) return; |
||
2350 | |||
2351 | if (pCurrCPUProps->InstSet == eRXv1) |
||
2352 | { |
||
2353 | if (!ChkArgCnt(1,1)) return; |
||
2354 | } |
||
2355 | else |
||
2356 | { |
||
2357 | if (!ChkArgCnt(2,2)) return; |
||
2358 | |||
2359 | if (!DecodeAcc(&ArgStr[2], &acc)) |
||
2360 | { |
||
2361 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]); |
||
2362 | return; |
||
2363 | } |
||
2364 | } |
||
2365 | |||
2366 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2367 | { |
||
2368 | if (mFirstPassUnknown(flags) || imm == 1 || imm == 2) |
||
2369 | { |
||
2370 | BAsmCode[0] = 0xFD; |
||
2371 | BAsmCode[1] = OpTabRACW[Index].Opc2; |
||
2372 | BAsmCode[2] = OpTabRACW[Index].Opc3 | (acc << 7) | ((imm - 1) << 4); |
||
2373 | CodeLen = 3; |
||
2374 | return; |
||
2375 | } |
||
2376 | } |
||
2377 | |||
2378 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]); |
||
2379 | } |
||
2380 | |||
2381 | static void DecodeRMPA(Word Index) |
||
2382 | { |
||
2383 | tSymbolSize size; |
||
2384 | |||
2385 | size = DecodeAttrSize(); |
||
2386 | if (size == eSymbolSizeUnknown) return; |
||
2387 | if (!ChkArgCnt(0,0)) return; |
||
2388 | |||
2389 | BAsmCode[0] = 0x7F; |
||
2390 | BAsmCode[1] = Index | size; |
||
2391 | CodeLen = 2; |
||
2392 | } |
||
2393 | |||
2394 | static const struct { |
||
2395 | Byte Opc1; |
||
2396 | Byte Opc2; |
||
2397 | } OpTabROTL[] = { |
||
2398 | { 0x6E, 0x66 }, /* ROTL */ |
||
2399 | { 0x6C, 0x64 }, /* ROTR */ |
||
2400 | }; |
||
2401 | |||
2402 | static void DecodeROTL(Word Index) |
||
2403 | { |
||
2404 | Byte regs; |
||
2405 | Byte regd; |
||
2406 | LongInt imm; |
||
2407 | tSymbolFlags flags; |
||
2408 | |||
2409 | if (!ChkNoAttr()) return; |
||
2410 | if (!ChkArgCnt(2,2)) return; |
||
2411 | |||
2412 | if (!DecodeReg(&ArgStr[2], ®d, eRn)) |
||
2413 | { |
||
2414 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]); |
||
2415 | return; |
||
2416 | } |
||
2417 | |||
2418 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2419 | { |
||
2420 | if (!mFirstPassUnknown(flags) && (imm < 0 || imm > 31)) |
||
2421 | { |
||
2422 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]); |
||
2423 | return; |
||
2424 | } |
||
2425 | |||
2426 | BAsmCode[0] = 0xFD; |
||
2427 | BAsmCode[1] = OpTabROTL[Index].Opc1 | ((imm >> 4) & 0x01); |
||
2428 | BAsmCode[2] = ((imm << 4) & 0xF0) | regd; |
||
2429 | CodeLen = 3; |
||
2430 | return; |
||
2431 | } |
||
2432 | |||
2433 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
2434 | { |
||
2435 | BAsmCode[0] = 0xFD; |
||
2436 | BAsmCode[1] = OpTabROTL[Index].Opc2; |
||
2437 | BAsmCode[2] = (regs << 4) | regd; |
||
2438 | CodeLen = 3; |
||
2439 | return; |
||
2440 | } |
||
2441 | |||
2442 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]); |
||
2443 | } |
||
2444 | |||
2445 | static void DecodeRTE(Word Index) |
||
2446 | { |
||
2447 | if (!ChkNoAttr()) return; |
||
2448 | if (!ChkArgCnt(0,0)) return; |
||
2449 | |||
2450 | switch (Index) |
||
2451 | { |
||
2452 | case 0x7F95: /* RTE */ |
||
2453 | case 0x7F94: /* RTFI */ |
||
2454 | case 0x7F96: /* WAIT */ |
||
2455 | if (!CheckSup()) return; |
||
2456 | } |
||
2457 | |||
2458 | BAsmCode[0] = Index >> 8; |
||
2459 | BAsmCode[1] = Index; |
||
2460 | CodeLen = 2; |
||
2461 | } |
||
2462 | |||
2463 | static void DecodeRTSD(Word Index) |
||
2464 | { |
||
2465 | LongInt imm; |
||
2466 | tSymbolFlags flags; |
||
2467 | Byte range; |
||
2468 | |||
2469 | UNUSED(Index); |
||
2470 | |||
2471 | if (!ChkNoAttr()) return; |
||
2472 | if (!ChkArgCnt(1,2)) return; |
||
2473 | |||
2474 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2475 | { |
||
2476 | if (mSymbolQuestionable(flags) && (imm < 0 || imm > 255)) |
||
2477 | { |
||
2478 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]); |
||
2479 | return; |
||
2480 | } |
||
2481 | |||
2482 | if (ArgCnt == 2 && DecodeRegRange(&ArgStr[2], &range)) |
||
2483 | { |
||
2484 | BAsmCode[0] = 0x3F; |
||
2485 | BAsmCode[1] = range; |
||
2486 | BAsmCode[2] = imm; |
||
2487 | CodeLen = 3; |
||
2488 | return; |
||
2489 | } |
||
2490 | |||
2491 | if (ArgCnt > 1) |
||
2492 | { |
||
2493 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]); |
||
2494 | return; |
||
2495 | } |
||
2496 | |||
2497 | BAsmCode[0] = 0x67; |
||
2498 | BAsmCode[1] = imm; |
||
2499 | CodeLen = 2; |
||
2500 | return; |
||
2501 | } |
||
2502 | |||
2503 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]); |
||
2504 | } |
||
2505 | |||
2506 | static void DecodeSCCnd(Word Index) |
||
2507 | { |
||
2508 | tSymbolSize size; |
||
2509 | Byte reg; |
||
2510 | LongInt disp; |
||
2511 | tSymbolFlags flags; |
||
2512 | Byte dsize; |
||
2513 | Byte scale; |
||
2514 | |||
2515 | size = DecodeAttrSize(); |
||
2516 | if (size == eSymbolSizeUnknown) return; |
||
2517 | if (!ChkArgCnt(1,1)) return; |
||
2518 | |||
2519 | scale = Size2Scale(size); |
||
2520 | |||
2521 | if (DecodeReg(&ArgStr[1], ®, eRn)) |
||
2522 | { |
||
2523 | if (size != 0x02) |
||
2524 | { |
||
2525 | WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]); |
||
2526 | return; |
||
2527 | } |
||
2528 | |||
2529 | BAsmCode[0] = 0xFC; |
||
2530 | BAsmCode[1] = 0xD3 | (size << 2); |
||
2531 | BAsmCode[2] = (reg << 4) | Index; |
||
2532 | CodeLen = 3; |
||
2533 | return; |
||
2534 | } |
||
2535 | |||
2536 | if (DecodeIndirectADC(&ArgStr[1], ®, &disp, &flags)) |
||
2537 | { |
||
2538 | dsize = DispSize(disp, flags, scale); |
||
2539 | |||
2540 | BAsmCode[0] = 0xFC; |
||
2541 | BAsmCode[1] = 0xD0 | (size << 2) | dsize; |
||
2542 | BAsmCode[2] = (reg << 4) | Index; |
||
2543 | CodeLen = DispOut(3, dsize, disp, scale); |
||
2544 | return; |
||
2545 | } |
||
2546 | |||
2547 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]); |
||
2548 | } |
||
2549 | |||
2550 | static const struct { |
||
2551 | Byte Opc1; |
||
2552 | Byte Opc2; |
||
2553 | Byte Opc3; |
||
2554 | } OpTabSHAR[] = { |
||
2555 | { 0x6A, 0x61, 0xA0 }, /* SHAR */ |
||
2556 | { 0x6C, 0x62, 0xC0 }, /* SHLL */ |
||
2557 | { 0x68, 0x60, 0x80 }, /* SHLR */ |
||
2558 | }; |
||
2559 | |||
2560 | static void DecodeSHAR(Word Index) |
||
2561 | { |
||
2562 | Byte regs; |
||
2563 | Byte regd; |
||
2564 | LongInt imm; |
||
2565 | tSymbolFlags flags; |
||
2566 | |||
2567 | if (!ChkNoAttr()) return; |
||
2568 | if (!ChkArgCnt(2,3)) return; |
||
2569 | |||
2570 | if (!DecodeReg(&ArgStr[ArgCnt], ®d, eRn)) |
||
2571 | { |
||
2572 | WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]); |
||
2573 | return; |
||
2574 | } |
||
2575 | |||
2576 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2577 | { |
||
2578 | if (!mFirstPassUnknown(flags) && (imm < 0 || imm > 31)) |
||
2579 | { |
||
2580 | WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]); |
||
2581 | return; |
||
2582 | } |
||
2583 | |||
2584 | if (ArgCnt == 3) |
||
2585 | { |
||
2586 | if (DecodeReg(&ArgStr[2], ®s, eRn)) |
||
2587 | { /* (3) */ |
||
2588 | BAsmCode[0] = 0xFD; |
||
2589 | BAsmCode[1] = OpTabSHAR[Index].Opc3 | imm; |
||
2590 | BAsmCode[2] = (regs << 4) | regd; |
||
2591 | CodeLen = 3; |
||
2592 | return; |
||
2593 | } |
||
2594 | |||
2595 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]); |
||
2596 | return; |
||
2597 | } |
||
2598 | |||
2599 | /* (1) */ |
||
2600 | BAsmCode[0] = OpTabSHAR[Index].Opc1 | (imm >> 4); |
||
2601 | BAsmCode[1] = ((imm << 4) & 0xF0) | regd; |
||
2602 | CodeLen = 2; |
||
2603 | return; |
||
2604 | } |
||
2605 | |||
2606 | if (ArgCnt > 2) |
||
2607 | { |
||
2608 | WrStrErrorPos(ErrNum_TooManyArgs, &ArgStr[2]); |
||
2609 | return; |
||
2610 | } |
||
2611 | |||
2612 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
2613 | { /* (2) */ |
||
2614 | BAsmCode[0] = 0xFD; |
||
2615 | BAsmCode[1] = OpTabSHAR[Index].Opc2; |
||
2616 | BAsmCode[2] = (regs << 4) | regd; |
||
2617 | CodeLen = 3; |
||
2618 | return; |
||
2619 | } |
||
2620 | |||
2621 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]); |
||
2622 | } |
||
2623 | |||
2624 | static const struct { |
||
2625 | Byte OpcIR; |
||
2626 | Byte OpcRR; |
||
2627 | } OpTabSTNZ[] = { |
||
2628 | { 0xF0, 0x4F }, /* STNZ */ |
||
2629 | { 0xE0, 0x4B }, /* STZ */ |
||
2630 | }; |
||
2631 | |||
2632 | static void DecodeSTNZ(Word Index) |
||
2633 | { |
||
2634 | LongInt imm; |
||
2635 | tSymbolFlags flags; |
||
2636 | Byte regd; |
||
2637 | Byte regs; |
||
2638 | Byte size; |
||
2639 | |||
2640 | if (!ChkNoAttr()) return; |
||
2641 | if (!ChkArgCnt(2,2)) return; |
||
2642 | |||
2643 | if (!DecodeReg(&ArgStr[2], ®d, eRn)) |
||
2644 | { |
||
2645 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]); |
||
2646 | return; |
||
2647 | } |
||
2648 | |||
2649 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2650 | { |
||
2651 | size = ImmSize32(imm, flags); |
||
2652 | |||
2653 | BAsmCode[0] = 0xFD; |
||
2654 | BAsmCode[1] = 0x70 | (size << 2); |
||
2655 | BAsmCode[2] = OpTabSTNZ[Index].OpcIR | regd; |
||
2656 | CodeLen = ImmOut(3, size, imm); |
||
2657 | return; |
||
2658 | } |
||
2659 | |||
2660 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
2661 | { |
||
2662 | if (!CheckV2()) return; |
||
2663 | |||
2664 | BAsmCode[0] = 0xFC; |
||
2665 | BAsmCode[1] = OpTabSTNZ[Index].OpcRR; |
||
2666 | BAsmCode[2] = (regs << 4) | regd; |
||
2667 | CodeLen = 3; |
||
2668 | return; |
||
2669 | } |
||
2670 | |||
2671 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]); |
||
2672 | } |
||
2673 | |||
2674 | static const struct { |
||
2675 | Byte Opc1; |
||
2676 | Byte Opc2; |
||
2677 | Byte Opc3; |
||
2678 | Byte flags; |
||
2679 | } OpTabTST[] = { |
||
2680 | { 0xC0, 0x30, 0x0C, 0x01 }, /* TST */ |
||
2681 | { 0, 0x40, 0x10, 0x00 }, /* XCHG */ |
||
2682 | { 0xD0, 0x34, 0x0D, 0x03 }, /* XOR */ |
||
2683 | }; |
||
2684 | |||
2685 | static void DecodeTST(Word Index) |
||
2686 | { |
||
2687 | Byte reg1; |
||
2688 | Byte reg2; |
||
2689 | LongInt imm; |
||
2690 | LongInt disp; |
||
2691 | tSymbolFlags flags; |
||
2692 | Byte size; |
||
2693 | Byte memex; |
||
2694 | Byte scale; |
||
2695 | |||
2696 | if (!ChkNoAttr()) return; |
||
2697 | if ((OpTabTST[Index].flags & 0x02) && ArgCnt == 3) |
||
2698 | { |
||
2699 | Byte reg3; |
||
2700 | |||
2701 | if (!CheckV3()) return; |
||
2702 | |||
2703 | if (!DecodeReg(&ArgStr[1], ®1, eRn)) |
||
2704 | { |
||
2705 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]); |
||
2706 | return; |
||
2707 | } |
||
2708 | |||
2709 | if (!DecodeReg(&ArgStr[2], ®2, eRn)) |
||
2710 | { |
||
2711 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]); |
||
2712 | return; |
||
2713 | } |
||
2714 | |||
2715 | if (!DecodeReg(&ArgStr[3], ®3, eRn)) |
||
2716 | { |
||
2717 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[3]); |
||
2718 | return; |
||
2719 | } |
||
2720 | |||
2721 | BAsmCode[0] = 0xFF; |
||
2722 | BAsmCode[1] = 0x60 | reg3; |
||
2723 | BAsmCode[2] = (reg1 << 4) | reg2; |
||
2724 | CodeLen = 3; |
||
2725 | return; |
||
2726 | } |
||
2727 | |||
2728 | if (!ChkArgCnt(2,2)) return; |
||
2729 | |||
2730 | if (!DecodeReg(&ArgStr[2], ®2, eRn)) |
||
2731 | { |
||
2732 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]); |
||
2733 | return; |
||
2734 | } |
||
2735 | |||
2736 | if ((OpTabTST[Index].flags & 0x01) && |
||
2737 | DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2738 | { |
||
2739 | size = ImmSize32(imm, flags); |
||
2740 | |||
2741 | BAsmCode[0] = 0xFD; |
||
2742 | BAsmCode[1] = 0x70 | (size << 2); |
||
2743 | BAsmCode[2] = OpTabTST[Index].Opc1 | reg2; |
||
2744 | CodeLen = ImmOut(3, size, imm); |
||
2745 | return; |
||
2746 | } |
||
2747 | |||
2748 | if (DecodeReg(&ArgStr[1], ®1, eRn)) |
||
2749 | { |
||
2750 | BAsmCode[0] = 0xFC; |
||
2751 | BAsmCode[1] = OpTabTST[Index].Opc2 | 0x03; |
||
2752 | BAsmCode[2] = (reg1 << 4) | reg2; |
||
2753 | CodeLen = 3; |
||
2754 | return; |
||
2755 | } |
||
2756 | |||
2757 | if (DecodeIndirectADD(&ArgStr[1], ®1, &disp, &flags, &memex, &scale)) |
||
2758 | { |
||
2759 | if (memex == 0x80) |
||
2760 | { |
||
2761 | size = DispSize(disp, flags, 1); |
||
2762 | |||
2763 | BAsmCode[0] = 0xFC; |
||
2764 | BAsmCode[1] = OpTabTST[Index].Opc2 | size; |
||
2765 | BAsmCode[2] = (reg1 << 4) | reg2; |
||
2766 | CodeLen = DispOut(3, size, disp, 1); |
||
2767 | return; |
||
2768 | } |
||
2769 | |||
2770 | size = DispSize(disp, flags, scale); |
||
2771 | |||
2772 | BAsmCode[0] = 0x06; |
||
2773 | BAsmCode[1] = 0x20 | (memex << 6) | size; |
||
2774 | BAsmCode[2] = OpTabTST[Index].Opc3; |
||
2775 | BAsmCode[3] = (reg1 << 4) | reg2; |
||
2776 | CodeLen = DispOut(4, size, disp, scale); |
||
2777 | return; |
||
2778 | } |
||
2779 | |||
2780 | } |
||
2781 | |||
2782 | static void DecodeMOVCO(Word Index) |
||
2783 | { |
||
2784 | Byte regs; |
||
2785 | Byte regd; |
||
2786 | |||
2787 | UNUSED(Index); |
||
2788 | |||
2789 | if (!CheckV2()) return; |
||
2790 | |||
2791 | if (!ChkNoAttr()) return; |
||
2792 | if (!ChkArgCnt(2,2)) return; |
||
2793 | |||
2794 | if (!DecodeReg(&ArgStr[1], ®s, eRn)) |
||
2795 | { |
||
2796 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]); |
||
2797 | return; |
||
2798 | } |
||
2799 | |||
2800 | if (!DecodeIndirect(&ArgStr[2], ®d)) |
||
2801 | { |
||
2802 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]); |
||
2803 | return; |
||
2804 | } |
||
2805 | |||
2806 | BAsmCode[0] = 0xFD; |
||
2807 | BAsmCode[1] = 0x27; |
||
2808 | BAsmCode[2] = (regd << 4) | regs; |
||
2809 | CodeLen = 3; |
||
2810 | } |
||
2811 | |||
2812 | static void DecodeMOVLI(Word Index) |
||
2813 | { |
||
2814 | Byte regs; |
||
2815 | Byte regd; |
||
2816 | |||
2817 | UNUSED(Index); |
||
2818 | |||
2819 | if (!ChkNoAttr()) return; |
||
2820 | if (!ChkArgCnt(2,2)) return; |
||
2821 | |||
2822 | if (!DecodeIndirect(&ArgStr[1], ®s)) |
||
2823 | { |
||
2824 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]); |
||
2825 | return; |
||
2826 | } |
||
2827 | |||
2828 | if (!DecodeReg(&ArgStr[2], ®d, eRn)) |
||
2829 | { |
||
2830 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]); |
||
2831 | return; |
||
2832 | } |
||
2833 | |||
2834 | BAsmCode[0] = 0xFD; |
||
2835 | BAsmCode[1] = 0x2F; |
||
2836 | BAsmCode[2] = (regs << 4) | regd; |
||
2837 | CodeLen = 3; |
||
2838 | } |
||
2839 | |||
2840 | static const Byte OpTabBFMOV[] = { |
||
2841 | 0x5E, /* BFMOV */ |
||
2842 | 0x5A, /* BFMOVZ */ |
||
2843 | }; |
||
2844 | |||
2845 | static void DecodeBFMOV(Word Index) |
||
2846 | { |
||
2847 | LongInt slsb; |
||
2848 | LongInt dlsb; |
||
2849 | LongInt width; |
||
2850 | tSymbolFlags flags; |
||
2851 | Byte regs; |
||
2852 | Byte regd; |
||
2853 | |||
2854 | if (!ChkNoAttr()) return; |
||
2855 | if (!ChkArgCnt(5,5)) return; |
||
2856 | if (!CheckV3()) return; |
||
2857 | |||
2858 | if (!DecodeImm(&ArgStr[1], &slsb, &flags)) |
||
2859 | { |
||
2860 | WrStrErrorPos(ErrNum_ExpectInt, &ArgStr[1]); |
||
2861 | return; |
||
2862 | } |
||
2863 | if (!mFirstPassUnknownOrQuestionable(flags) && !ChkRange(slsb, 0, 31)) return; |
||
2864 | |||
2865 | if (!DecodeImm(&ArgStr[2], &dlsb, &flags)) |
||
2866 | { |
||
2867 | WrStrErrorPos(ErrNum_ExpectInt, &ArgStr[2]); |
||
2868 | return; |
||
2869 | } |
||
2870 | if (!mFirstPassUnknownOrQuestionable(flags) && !ChkRange(dlsb, 0, 31)) return; |
||
2871 | |||
2872 | if (!DecodeImm(&ArgStr[3], &width, &flags)) |
||
2873 | { |
||
2874 | WrStrErrorPos(ErrNum_ExpectInt, &ArgStr[3]); |
||
2875 | return; |
||
2876 | } |
||
2877 | if (!mFirstPassUnknownOrQuestionable(flags) && !ChkRange(width, 1, 31)) return; |
||
2878 | |||
2879 | if (!DecodeReg(&ArgStr[4], ®s, eRn)) |
||
2880 | { |
||
2881 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[4]); |
||
2882 | return; |
||
2883 | } |
||
2884 | |||
2885 | if (!DecodeReg(&ArgStr[5], ®d, eRn)) |
||
2886 | { |
||
2887 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[5]); |
||
2888 | return; |
||
2889 | } |
||
2890 | |||
2891 | if (slsb + width > 32 || dlsb + width > 32) |
||
2892 | { |
||
2893 | WrError(ErrNum_OverRange); |
||
2894 | return; |
||
2895 | } |
||
2896 | |||
2897 | BAsmCode[0] = 0xFC; |
||
2898 | BAsmCode[1] = OpTabBFMOV[Index]; |
||
2899 | BAsmCode[2] = (regs << 4) | regd; |
||
2900 | BAsmCode[3] = ((dlsb - slsb) & 0x1f) | ((dlsb << 5) & 0xE0); |
||
2901 | BAsmCode[4] = ((dlsb >> 3) & 0x03) | (((dlsb + width) << 2) & 0x7C); |
||
2902 | CodeLen = 5; |
||
2903 | } |
||
2904 | |||
2905 | static const struct { |
||
2906 | Byte OpcI; |
||
2907 | Byte OpcR; |
||
2908 | } OpTabRSTR[] = { |
||
2909 | { 0xF0, 0xD0 }, /* RSTR */ |
||
2910 | { 0xE0, 0xC0 }, /* SAVE */ |
||
2911 | }; |
||
2912 | |||
2913 | static void DecodeRSTR(Word Index) |
||
2914 | { |
||
2915 | LongInt imm; |
||
2916 | tSymbolFlags flags; |
||
2917 | Byte reg; |
||
2918 | |||
2919 | if (!ChkNoAttr()) return; |
||
2920 | if (!ChkArgCnt(1,1)) return; |
||
2921 | if (!CheckV3()) return; |
||
2922 | |||
2923 | if (!pCurrCPUProps->RegBank) |
||
2924 | { |
||
2925 | WrError(ErrNum_InstructionNotSupported); |
||
2926 | return; |
||
2927 | } |
||
2928 | |||
2929 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
2930 | { |
||
2931 | if (!ChkRange(imm, 0, pCurrCPUProps->RegBank - 1)) return; |
||
2932 | |||
2933 | BAsmCode[0] = 0xFD; |
||
2934 | BAsmCode[1] = 0x76; |
||
2935 | BAsmCode[2] = OpTabRSTR[Index].OpcI; |
||
2936 | BAsmCode[3] = imm; |
||
2937 | CodeLen = 4; |
||
2938 | return; |
||
2939 | } |
||
2940 | |||
2941 | if (DecodeReg(&ArgStr[1], ®, eRn)) |
||
2942 | { |
||
2943 | BAsmCode[0] = 0xFD; |
||
2944 | BAsmCode[1] = 0x76; |
||
2945 | BAsmCode[2] = OpTabRSTR[Index].OpcR | reg; |
||
2946 | BAsmCode[3] = 0x00; |
||
2947 | CodeLen = 4; |
||
2948 | return; |
||
2949 | } |
||
2950 | |||
2951 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]); |
||
2952 | } |
||
2953 | |||
2954 | static const struct { |
||
2955 | Byte Opc1; |
||
2956 | Byte Opc2; |
||
2957 | } OpTabDABS[] = { |
||
2958 | { 0x0C, 0x01 }, /* DABS */ |
||
2959 | { 0x0C, 0x02 }, /* DNEG */ |
||
2960 | { 0x0D, 0x0D }, /* DROUND */ |
||
2961 | { 0x0D, 0x00 }, /* DSQRT */ |
||
2962 | { 0x0D, 0x0C }, /* DTOF */ |
||
2963 | { 0x0D, 0x08 }, /* DTOI */ |
||
2964 | { 0x0D, 0x09 }, /* DTOU */ |
||
2965 | }; |
||
2966 | |||
2967 | static void DecodeDABS(Word Index) |
||
2968 | { |
||
2969 | Byte regs; |
||
2970 | Byte regd; |
||
2971 | |||
2972 | if (!ChkNoAttr()) return; |
||
2973 | if (!ChkArgCnt(2,2)) return; |
||
2974 | if (!CheckV3()) return; |
||
2975 | if (!CheckDouble()) return; |
||
2976 | |||
2977 | if (!DecodeReg(&ArgStr[1], ®s, eDRn)) |
||
2978 | { |
||
2979 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]); |
||
2980 | return; |
||
2981 | } |
||
2982 | |||
2983 | if (!DecodeReg(&ArgStr[2], ®d, eDRn)) |
||
2984 | { |
||
2985 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]); |
||
2986 | return; |
||
2987 | } |
||
2988 | |||
2989 | BAsmCode[0] = 0x76; |
||
2990 | BAsmCode[1] = 0x90; |
||
2991 | BAsmCode[2] = OpTabDABS[Index].Opc1 | (regs << 4); |
||
2992 | BAsmCode[3] = OpTabDABS[Index].Opc2 | (regd << 4); |
||
2993 | CodeLen = 4; |
||
2994 | } |
||
2995 | |||
2996 | static const struct { |
||
2997 | Byte Opc; |
||
2998 | } OpTabDADD[] = { |
||
2999 | { 0x00 }, /* DADD */ |
||
3000 | { 0x05 }, /* DDIV */ |
||
3001 | { 0x02 }, /* DMUL */ |
||
3002 | { 0x01 }, /* DSUB */ |
||
3003 | }; |
||
3004 | |||
3005 | static void DecodeDADD(Word Index) |
||
3006 | { |
||
3007 | Byte regs1; |
||
3008 | Byte regs2; |
||
3009 | Byte regd; |
||
3010 | |||
3011 | if (!ChkNoAttr()) return; |
||
3012 | if (!ChkArgCnt(3,3)) return; |
||
3013 | if (!CheckV3()) return; |
||
3014 | if (!CheckDouble()) return; |
||
3015 | |||
3016 | if (!DecodeReg(&ArgStr[1], ®s1, eDRn)) |
||
3017 | { |
||
3018 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]); |
||
3019 | return; |
||
3020 | } |
||
3021 | |||
3022 | if (!DecodeReg(&ArgStr[2], ®s2, eDRn)) |
||
3023 | { |
||
3024 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]); |
||
3025 | return; |
||
3026 | } |
||
3027 | |||
3028 | if (!DecodeReg(&ArgStr[3], ®d, eDRn)) |
||
3029 | { |
||
3030 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[3]); |
||
3031 | return; |
||
3032 | } |
||
3033 | |||
3034 | BAsmCode[0] = 0x76; |
||
3035 | BAsmCode[1] = 0x90; |
||
3036 | BAsmCode[2] = OpTabDADD[Index].Opc | (regs2 << 4); |
||
3037 | BAsmCode[3] = (regd << 4) | regs1; |
||
3038 | CodeLen = 4; |
||
3039 | } |
||
3040 | |||
3041 | static void DecodeDCMPcm(Word Index) |
||
3042 | { |
||
3043 | Byte regs1; |
||
3044 | Byte regs2; |
||
3045 | |||
3046 | if (!ChkNoAttr()) return; |
||
3047 | if (!ChkArgCnt(2,2)) return; |
||
3048 | if (!CheckV3()) return; |
||
3049 | if (!CheckDouble()) return; |
||
3050 | |||
3051 | if (!DecodeReg(&ArgStr[1], ®s1, eDRn)) |
||
3052 | { |
||
3053 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]); |
||
3054 | return; |
||
3055 | } |
||
3056 | |||
3057 | if (!DecodeReg(&ArgStr[2], ®s2, eDRn)) |
||
3058 | { |
||
3059 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]); |
||
3060 | return; |
||
3061 | } |
||
3062 | |||
3063 | BAsmCode[0] = 0x76; |
||
3064 | BAsmCode[1] = 0x90; |
||
3065 | BAsmCode[2] = 0x08 | (regs2 << 4); |
||
3066 | BAsmCode[3] = ((Index << 4) & 0xF0) | regs1; |
||
3067 | CodeLen = 4; |
||
3068 | } |
||
3069 | |||
3070 | static void DecodeDMOV(Word Index) |
||
3071 | { |
||
3072 | Byte size; |
||
3073 | Byte regs; |
||
3074 | Byte regd; |
||
3075 | LongInt disp; |
||
3076 | LongInt imm; |
||
3077 | tSymbolFlags flags; |
||
3078 | Byte dsize; |
||
3079 | |||
3080 | UNUSED(Index); |
||
3081 | |||
3082 | if (!ChkArgCnt(2,2)) return; |
||
3083 | if (!CheckV3()) return; |
||
3084 | if (!CheckDouble()) return; |
||
3085 | |||
3086 | if (!DecodeAttrDouble(&size)) return; |
||
3087 | |||
3088 | if (DecodeReg(&ArgStr[1], ®s, eRn)) |
||
3089 | { |
||
3090 | if (DecodeReg(&ArgStr[2], ®d, eDRHn)) |
||
3091 | { /* (1) / (2) */ |
||
3092 | BAsmCode[0] = 0xFD; |
||
3093 | BAsmCode[1] = 0x77; |
||
3094 | BAsmCode[2] = 0x80 | regs; |
||
3095 | BAsmCode[3] = 0x02 | (regd << 4) | size; |
||
3096 | CodeLen = 4; |
||
3097 | return; |
||
3098 | } |
||
3099 | |||
3100 | if (DecodeReg(&ArgStr[2], ®d, eDRLn) && !size) |
||
3101 | { /* (3) */ |
||
3102 | BAsmCode[0] = 0xFD; |
||
3103 | BAsmCode[1] = 0x77; |
||
3104 | BAsmCode[2] = 0x80 | regs; |
||
3105 | BAsmCode[3] = 0x00 | (regd << 4); |
||
3106 | CodeLen = 4; |
||
3107 | return; |
||
3108 | } |
||
3109 | } |
||
3110 | |||
3111 | if (DecodeReg(&ArgStr[2], ®d, eRn)) |
||
3112 | { |
||
3113 | if (DecodeReg(&ArgStr[1], ®s, eDRHn) && !size) |
||
3114 | { /* (4) */ |
||
3115 | BAsmCode[0] = 0xFD; |
||
3116 | BAsmCode[1] = 0x75; |
||
3117 | BAsmCode[2] = 0x80 | regd; |
||
3118 | BAsmCode[3] = 0x02 | (regs << 4); |
||
3119 | CodeLen = 4; |
||
3120 | return; |
||
3121 | } |
||
3122 | |||
3123 | if (DecodeReg(&ArgStr[1], ®s, eDRLn) && !size) |
||
3124 | { /* (5) */ |
||
3125 | BAsmCode[0] = 0xFD; |
||
3126 | BAsmCode[1] = 0x75; |
||
3127 | BAsmCode[2] = 0x80 | regd; |
||
3128 | BAsmCode[3] = 0x00 | (regs << 4); |
||
3129 | CodeLen = 4; |
||
3130 | return; |
||
3131 | } |
||
3132 | } |
||
3133 | |||
3134 | if (DecodeReg(&ArgStr[1], ®s, eDRn) && size) |
||
3135 | { |
||
3136 | if (DecodeReg(&ArgStr[2], ®d, eDRn)) |
||
3137 | { /* (6) */ |
||
3138 | BAsmCode[0] = 0xFD; |
||
3139 | BAsmCode[1] = 0x90; |
||
3140 | BAsmCode[2] = 0x0C | (regs << 4); |
||
3141 | BAsmCode[3] = 0x00 | (regd << 4); |
||
3142 | CodeLen = 4; |
||
3143 | return; |
||
3144 | } |
||
3145 | |||
3146 | if (DecodeIndirectADC(&ArgStr[2], ®d, &disp, &flags) && size) |
||
3147 | { /* (7) */ |
||
3148 | dsize = DispSize(disp, flags, 8); |
||
3149 | |||
3150 | BAsmCode[0] = 0xFC; |
||
3151 | BAsmCode[1] = 0x78 | dsize; |
||
3152 | BAsmCode[2] = 0x08 | (regd << 4); |
||
3153 | CodeLen = DispOut(3, dsize, disp, 8); |
||
3154 | BAsmCode[CodeLen++] = 0x00 | (regs << 4); |
||
3155 | return; |
||
3156 | } |
||
3157 | } |
||
3158 | |||
3159 | if (DecodeIndirectADC(&ArgStr[1], ®s, &disp, &flags) && size) |
||
3160 | { |
||
3161 | if (DecodeReg(&ArgStr[2], ®d, eDRn)) |
||
3162 | { /* (8) */ |
||
3163 | dsize = DispSize(disp, flags, 8); |
||
3164 | |||
3165 | BAsmCode[0] = 0xFC; |
||
3166 | BAsmCode[1] = 0xC8 | dsize; |
||
3167 | BAsmCode[2] = 0x08 | (regs << 4); |
||
3168 | CodeLen = DispOut(3, dsize, disp, 8); |
||
3169 | BAsmCode[CodeLen++] = 0x00 | (regd << 4); |
||
3170 | return; |
||
3171 | } |
||
3172 | } |
||
3173 | |||
3174 | if (DecodeImm(&ArgStr[1], &imm, &flags)) |
||
3175 | { |
||
3176 | if (DecodeReg(&ArgStr[2], ®d, eDRHn)) |
||
3177 | { /* (9) / (10) */ |
||
3178 | BAsmCode[0] = 0xF9; |
||
3179 | BAsmCode[1] = 0x03; |
||
3180 | BAsmCode[2] = 0x02 | (regd << 4) | size; |
||
3181 | CodeLen = ImmOut(3, 0, imm); |
||
3182 | return; |
||
3183 | } |
||
3184 | |||
3185 | if (DecodeReg(&ArgStr[2], ®d, eDRLn) && !size) |
||
3186 | { /* (11) */ |
||
3187 | BAsmCode[0] = 0xF9; |
||
3188 | BAsmCode[1] = 0x03; |
||
3189 | BAsmCode[2] = 0x00 | (regd << 4); |
||
3190 | CodeLen = ImmOut(3, 0, imm); |
||
3191 | return; |
||
3192 | } |
||
3193 | } |
||
3194 | |||
3195 | WrError(ErrNum_InvArg); |
||
3196 | } |
||
3197 | |||
3198 | static const Byte OpTabDPOPM[] = { |
||
3199 | 0xA8, /* DPOPM */ |
||
3200 | 0xA0 /* DPUSHM */ |
||
3201 | }; |
||
3202 | |||
3203 | static void DecodeDPOPM(Word Index) |
||
3204 | { |
||
3205 | const int len = strlen(ArgStr[1].str.p_str); |
||
3206 | Byte size; |
||
3207 | Byte reg1; |
||
3208 | Byte reg2; |
||
3209 | int i; |
||
3210 | |||
3211 | if (!DecodeAttrDouble(&size)) return; |
||
3212 | if (!ChkArgCnt(1,1)) return; |
||
3213 | if (!CheckV3()) return; |
||
3214 | if (!CheckDouble()) return; |
||
3215 | |||
3216 | for (i = 0; i < len; i++) |
||
3217 | { |
||
3218 | if (ArgStr[1].str.p_str[i] == '-') break; |
||
3219 | } |
||
3220 | if (i >= len) |
||
3221 | { |
||
3222 | WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]); |
||
3223 | return; |
||
3224 | } |
||
3225 | |||
3226 | StrCompCopySub(&Temp1, &ArgStr[1], 0, i); |
||
3227 | if (!DecodeReg(&Temp1, ®1, size ? eDRn : eDCRn)) |
||
3228 | { |
||
3229 | WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]); |
||
3230 | return; |
||
3231 | } |
||
3232 | |||
3233 | StrCompCopySub(&Temp1, &ArgStr[1], i + 1, len - i - 1); |
||
3234 | if (!DecodeReg(&Temp1, ®2, size ? eDRn : eDCRn)) |
||
3235 | { |
||
3236 | WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]); |
||
3237 | return; |
||
3238 | } |
||
3239 | |||
3240 | if (reg2 >= reg1) |
||
3241 | { |
||
3242 | BAsmCode[0] = 0x75; |
||
3243 | BAsmCode[1] = OpTabDPOPM[Index] | (size << 4); |
||
3244 | BAsmCode[2] = (reg1 << 4) | (reg2 - reg1); |
||
3245 | CodeLen = 3; |
||
3246 | return; |
||
3247 | } |
||
3248 | |||
3249 | WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]); |
||
3250 | } |
||
3251 | |||
3252 | static const struct { |
||
3253 | Byte Opc1; |
||
3254 | Byte Opc2; |
||
3255 | } OpTabFTOD[] = { |
||
3256 | { 0x80, 0x0A }, /* FTOD */ |
||
3257 | { 0x80, 0x09 }, /* ITOD */ |
||
3258 | { 0x80, 0x0D }, /* UTOD */ |
||
3259 | }; |
||
3260 | |||
3261 | static void DecodeFTOD(Word Index) |
||
3262 | { |
||
3263 | Byte regs; |
||
3264 | Byte regd; |
||
3265 | |||
3266 | UNUSED(Index); |
||
3267 | |||
3268 | if (!ChkNoAttr()) return; |
||
3269 | if (!ChkArgCnt(2,2)) return; |
||
3270 | if (!CheckV3()) return; |
||
3271 | if (!CheckDouble()) return; |
||
3272 | |||
3273 | if (!DecodeReg(&ArgStr[1], ®s, eRn)) |
||
3274 | { |
||
3275 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]); |
||
3276 | return; |
||
3277 | } |
||
3278 | |||
3279 | if (!DecodeReg(&ArgStr[2], ®d, eDRn)) |
||
3280 | { |
||
3281 | WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]); |
||
3282 | return; |
||
3283 | } |
||
3284 | |||
3285 | BAsmCode[0] = 0xFD; |
||
3286 | BAsmCode[1] = 0x77; |
||
3287 | BAsmCode[2] = OpTabFTOD[Index].Opc1 | regs; |
||
3288 | BAsmCode[3] = OpTabFTOD[Index].Opc2 | (regd << 4); |
||
3289 | CodeLen = 4; |
||
3290 | } |
||
3291 | |||
3292 | static void DecodeMVFDC(Word Index) |
||
3293 | { |
||
3294 | Byte regc; |
||
3295 | Byte reg; |
||
3296 | |||
3297 | UNUSED(Index); |
||
3298 | |||
3299 | if (!ChkNoAttr()) return; |
||
3300 | if (!ChkArgCnt(2,2)) return; |
||
3301 | if (!CheckV3()) return; |
||
3302 | if (!CheckDouble()) return; |
||
3303 | |||
3304 | if (!DecodeReg(&ArgStr[Index + 1], ®c, eDCRn)) |
||
3305 | { |
||
3306 | WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[Index + 1]); |
||
3307 | return; |
||
3308 | } |
||
3309 | |||
3310 | if (!DecodeReg(&ArgStr[2 - Index], ®, eRn)) |
||
3311 | { |
||
3312 | WrStrErrorPos(ErrNum_InvReg, &ArgStr[2 - Index]); |
||
3313 | return; |
||
3314 | } |
||
3315 | |||
3316 | BAsmCode[0] = 0xFD; |
||
3317 | BAsmCode[1] = 0x75 | (Index << 1); |
||
3318 | BAsmCode[2] = 0x80 | reg; |
||
3319 | BAsmCode[3] = 0x04 | (regc << 4); |
||
3320 | CodeLen = 4; |
||
3321 | } |
||
3322 | |||
3323 | static void DecodeMVFDR(Word Index) |
||
3324 | { |
||
3325 | UNUSED(Index); |
||
3326 | |||
3327 | if (!ChkNoAttr()) return; |
||
3328 | if (!ChkArgCnt(0,0)) return; |
||
3329 | if (!CheckV3()) return; |
||
3330 | if (!CheckDouble()) return; |
||
3331 | |||
3332 | BAsmCode[0] = 0x75; |
||
3333 | BAsmCode[1] = 0x90; |
||
3334 | BAsmCode[2] = 0x1B; |
||
3335 | CodeLen = 3; |
||
3336 | } |
||
3337 | |||
3338 | #ifdef COMPAT |
||
3339 | |||
3340 | #define BigEndianSymName "BIGENDIAN" /* T.B.D. */ |
||
3341 | static void DecodeENDIAN(Word Index) |
||
3342 | { |
||
3343 | const char *str; |
||
3344 | |||
3345 | UNUSED(Index); |
||
3346 | |||
3347 | if (!ChkNoAttr()) return; |
||
3348 | if (!ChkArgCnt(1,1)) return; |
||
3349 | |||
3350 | str = ArgStr[1].str.p_str; |
||
3351 | if (!as_strcasecmp(str, "BIG")) |
||
3352 | SetFlag(&TargetBigEndian, BigEndianSymName, True); |
||
3353 | else if (!as_strcasecmp(str, "LITTLE")) |
||
3354 | SetFlag(&TargetBigEndian, BigEndianSymName, False); |
||
3355 | else |
||
3356 | WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]); |
||
3357 | } |
||
3358 | |||
3359 | #endif /* COMPAT */ |
||
3360 | |||
3361 | /*---------------------------------------------------------------------------*/ |
||
3362 | |||
3363 | static void AddABS(const char *NName, Word NCode) |
||
3364 | { |
||
3365 | AddInstTable(InstTable, NName, NCode, DecodeABS); |
||
3366 | } |
||
3367 | |||
3368 | static void AddADC(const char *NName, Word NCode) |
||
3369 | { |
||
3370 | AddInstTable(InstTable, NName, NCode, DecodeADC); |
||
3371 | } |
||
3372 | |||
3373 | static void AddADD(const char *NName, Word NCode) |
||
3374 | { |
||
3375 | AddInstTable(InstTable, NName, NCode, DecodeADD); |
||
3376 | } |
||
3377 | |||
3378 | static void AddBCLR(const char *NName, Word NCode) |
||
3379 | { |
||
3380 | AddInstTable(InstTable, NName, NCode, DecodeBCLR); |
||
3381 | } |
||
3382 | |||
3383 | static void AddBCnd(const char *NName, Word NCode) |
||
3384 | { |
||
3385 | AddInstTable(InstTable, NName, NCode, DecodeBCnd); |
||
3386 | } |
||
3387 | |||
3388 | static void AddBMCnd(const char *NName, Word NCode) |
||
3389 | { |
||
3390 | AddInstTable(InstTable, NName, NCode, DecodeBMCnd); |
||
3391 | } |
||
3392 | |||
3393 | static void AddBRK(const char *NName, Word NCode) |
||
3394 | { |
||
3395 | AddInstTable(InstTable, NName, NCode, DecodeBRK); |
||
3396 | } |
||
3397 | |||
3398 | static void AddBSR(const char *NName, Word NCode) |
||
3399 | { |
||
3400 | AddInstTable(InstTable, NName, NCode, DecodeBSR); |
||
3401 | } |
||
3402 | |||
3403 | static void AddCLRPSW(const char *NName, Word NCode) |
||
3404 | { |
||
3405 | AddInstTable(InstTable, NName, NCode, DecodeCLRPSW); |
||
3406 | } |
||
3407 | |||
3408 | static void AddDIV(const char *NName, Word NCode) |
||
3409 | { |
||
3410 | AddInstTable(InstTable, NName, NCode, DecodeDIV); |
||
3411 | } |
||
3412 | |||
3413 | static void AddFADD(const char *NName, Word NCode) |
||
3414 | { |
||
3415 | AddInstTable(InstTable, NName, NCode, DecodeFADD); |
||
3416 | } |
||
3417 | |||
3418 | static void AddINT(const char *NName, Word NCode) |
||
3419 | { |
||
3420 | AddInstTable(InstTable, NName, NCode, DecodeINT); |
||
3421 | } |
||
3422 | |||
3423 | static void AddITOF(const char *NName, Word NCode) |
||
3424 | { |
||
3425 | AddInstTable(InstTable, NName, NCode, DecodeITOF); |
||
3426 | } |
||
3427 | |||
3428 | static void AddJMP(const char *NName, Word NCode) |
||
3429 | { |
||
3430 | AddInstTable(InstTable, NName, NCode, DecodeJMP); |
||
3431 | } |
||
3432 | |||
3433 | static void AddMACHI(const char *NName, Word NCode) |
||
3434 | { |
||
3435 | AddInstTable(InstTable, NName, NCode, DecodeMACHI); |
||
3436 | } |
||
3437 | |||
3438 | static void AddMOV(const char *NName, Word NCode) |
||
3439 | { |
||
3440 | AddInstTable(InstTable, NName, NCode, DecodeMOV); |
||
3441 | } |
||
3442 | |||
3443 | static void AddMOVU(const char *NName, Word NCode) |
||
3444 | { |
||
3445 | AddInstTable(InstTable, NName, NCode, DecodeMOVU); |
||
3446 | } |
||
3447 | |||
3448 | static void AddMVFACHI(const char *NName, Word NCode) |
||
3449 | { |
||
3450 | AddInstTable(InstTable, NName, NCode, DecodeMVFACHI); |
||
3451 | } |
||
3452 | |||
3453 | static void AddMVFC(const char *NName, Word NCode) |
||
3454 | { |
||
3455 | AddInstTable(InstTable, NName, NCode, DecodeMVFC); |
||
3456 | } |
||
3457 | |||
3458 | static void AddMVTACHI(const char *NName, Word NCode) |
||
3459 | { |
||
3460 | AddInstTable(InstTable, NName, NCode, DecodeMVTACHI); |
||
3461 | } |
||
3462 | |||
3463 | static void AddMVTC(const char *NName, Word NCode) |
||
3464 | { |
||
3465 | AddInstTable(InstTable, NName, NCode, DecodeMVTC); |
||
3466 | } |
||
3467 | |||
3468 | static void AddMVTIPL(const char *NName, Word NCode) |
||
3469 | { |
||
3470 | AddInstTable(InstTable, NName, NCode, DecodeMVTIPL); |
||
3471 | } |
||
3472 | |||
3473 | static void AddPOPC(const char *NName, Word NCode) |
||
3474 | { |
||
3475 | AddInstTable(InstTable, NName, NCode, DecodePOPC); |
||
3476 | } |
||
3477 | |||
3478 | static void AddPOPM(const char *NName, Word NCode) |
||
3479 | { |
||
3480 | AddInstTable(InstTable, NName, NCode, DecodePOPM); |
||
3481 | } |
||
3482 | |||
3483 | static void AddPUSH(const char *NName, Word NCode) |
||
3484 | { |
||
3485 | AddInstTable(InstTable, NName, NCode, DecodePUSH); |
||
3486 | } |
||
3487 | |||
3488 | static void AddRACW(const char *NName, Word NCode) |
||
3489 | { |
||
3490 | AddInstTable(InstTable, NName, NCode, DecodeRACW); |
||
3491 | } |
||
3492 | |||
3493 | static void AddRMPA(const char *NName, Word NCode) |
||
3494 | { |
||
3495 | AddInstTable(InstTable, NName, NCode, DecodeRMPA); |
||
3496 | } |
||
3497 | |||
3498 | static void AddROTL(const char *NName, Word NCode) |
||
3499 | { |
||
3500 | AddInstTable(InstTable, NName, NCode, DecodeROTL); |
||
3501 | } |
||
3502 | |||
3503 | static void AddRTE(const char *NName, Word NCode) |
||
3504 | { |
||
3505 | AddInstTable(InstTable, NName, NCode, DecodeRTE); |
||
3506 | } |
||
3507 | |||
3508 | static void AddRTSD(const char *NName, Word NCode) |
||
3509 | { |
||
3510 | AddInstTable(InstTable, NName, NCode, DecodeRTSD); |
||
3511 | } |
||
3512 | |||
3513 | static void AddSCCnd(const char *NName, Word NCode) |
||
3514 | { |
||
3515 | AddInstTable(InstTable, NName, NCode, DecodeSCCnd); |
||
3516 | } |
||
3517 | |||
3518 | static void AddSHAR(const char *NName, Word NCode) |
||
3519 | { |
||
3520 | AddInstTable(InstTable, NName, NCode, DecodeSHAR); |
||
3521 | } |
||
3522 | |||
3523 | static void AddSTNZ(const char *NName, Word NCode) |
||
3524 | { |
||
3525 | AddInstTable(InstTable, NName, NCode, DecodeSTNZ); |
||
3526 | } |
||
3527 | |||
3528 | static void AddTST(const char *NName, Word NCode) |
||
3529 | { |
||
3530 | AddInstTable(InstTable, NName, NCode, DecodeTST); |
||
3531 | } |
||
3532 | |||
3533 | static void AddMOVCO(const char *NName, Word NCode) |
||
3534 | { |
||
3535 | AddInstTable(InstTable, NName, NCode, DecodeMOVCO); |
||
3536 | } |
||
3537 | |||
3538 | static void AddMOVLI(const char *NName, Word NCode) |
||
3539 | { |
||
3540 | AddInstTable(InstTable, NName, NCode, DecodeMOVLI); |
||
3541 | } |
||
3542 | |||
3543 | static void AddBFMOV(const char *NName, Word NCode) |
||
3544 | { |
||
3545 | AddInstTable(InstTable, NName, NCode, DecodeBFMOV); |
||
3546 | } |
||
3547 | |||
3548 | static void AddRSTR(const char *NName, Word NCode) |
||
3549 | { |
||
3550 | AddInstTable(InstTable, NName, NCode, DecodeRSTR); |
||
3551 | } |
||
3552 | |||
3553 | static void AddDABS(const char *NName, Word NCode) |
||
3554 | { |
||
3555 | AddInstTable(InstTable, NName, NCode, DecodeDABS); |
||
3556 | } |
||
3557 | |||
3558 | static void AddDADD(const char *NName, Word NCode) |
||
3559 | { |
||
3560 | AddInstTable(InstTable, NName, NCode, DecodeDADD); |
||
3561 | } |
||
3562 | |||
3563 | static void AddDCMPcm(const char *NName, Word NCode) |
||
3564 | { |
||
3565 | AddInstTable(InstTable, NName, NCode, DecodeDCMPcm); |
||
3566 | } |
||
3567 | |||
3568 | static void AddDMOV(const char *NName, Word NCode) |
||
3569 | { |
||
3570 | AddInstTable(InstTable, NName, NCode, DecodeDMOV); |
||
3571 | } |
||
3572 | |||
3573 | static void AddDPOPM(const char *NName, Word NCode) |
||
3574 | { |
||
3575 | AddInstTable(InstTable, NName, NCode, DecodeDPOPM); |
||
3576 | } |
||
3577 | |||
3578 | static void AddFTOD(const char *NName, Word NCode) |
||
3579 | { |
||
3580 | AddInstTable(InstTable, NName, NCode, DecodeFTOD); |
||
3581 | } |
||
3582 | |||
3583 | static void AddMVFDC(const char *NName, Word NCode) |
||
3584 | { |
||
3585 | AddInstTable(InstTable, NName, NCode, DecodeMVFDC); |
||
3586 | } |
||
3587 | |||
3588 | static void AddMVFDR(const char *NName, Word NCode) |
||
3589 | { |
||
3590 | AddInstTable(InstTable, NName, NCode, DecodeMVFDR); |
||
3591 | } |
||
3592 | |||
3593 | #ifdef COMPAT |
||
3594 | |||
3595 | static void AddBLK(const char *NName, Word NCode) |
||
3596 | { |
||
3597 | AddInstTable(InstTable, NName, NCode, DecodeIntelDS); |
||
3598 | } |
||
3599 | |||
3600 | #endif /* COMPAT */ |
||
3601 | |||
3602 | static Boolean TrueFnc(void) |
||
3603 | { |
||
3604 | return True; |
||
3605 | } |
||
3606 | |||
3607 | static void InitFields(void) |
||
3608 | { |
||
3609 | InstTable = CreateInstTable(201); |
||
3610 | |||
3611 | add_null_pseudo(InstTable); |
||
3612 | |||
3613 | /* RXv1 */ |
||
3614 | AddABS("ABS", 0x200F); |
||
3615 | AddADC("ADC", 0x0802); |
||
3616 | AddADD("ADD", 0); |
||
3617 | AddADD("AND", 1); |
||
3618 | AddBCLR("BCLR", 0); |
||
3619 | AddBCnd("BEQ", 0); |
||
3620 | AddBCnd("BZ", 0); |
||
3621 | AddBCnd("BNE", 1); |
||
3622 | AddBCnd("BNZ", 1); |
||
3623 | AddBCnd("BGEU", 2); |
||
3624 | AddBCnd("BC", 2); |
||
3625 | AddBCnd("BLTU", 3); |
||
3626 | AddBCnd("BNC", 3); |
||
3627 | AddBCnd("BGTU", 4); |
||
3628 | AddBCnd("BLEU", 5); |
||
3629 | AddBCnd("BPZ", 6); |
||
3630 | AddBCnd("BN", 7); |
||
3631 | AddBCnd("BGE", 8); |
||
3632 | AddBCnd("BLT", 9); |
||
3633 | AddBCnd("BGT", 10); |
||
3634 | AddBCnd("BLE", 11); |
||
3635 | AddBCnd("BO", 12); |
||
3636 | AddBCnd("BNO", 13); |
||
3637 | AddBMCnd("BMEQ", 0); |
||
3638 | AddBMCnd("BMZ", 0); |
||
3639 | AddBMCnd("BMNE", 1); |
||
3640 | AddBMCnd("BMNZ", 1); |
||
3641 | AddBMCnd("BMGEU", 2); |
||
3642 | AddBMCnd("BMC", 2); |
||
3643 | AddBMCnd("BMLTU", 3); |
||
3644 | AddBMCnd("BMNC", 3); |
||
3645 | AddBMCnd("BMGTU", 4); |
||
3646 | AddBMCnd("BMLEU", 5); |
||
3647 | AddBMCnd("BMPZ", 6); |
||
3648 | AddBMCnd("BMN", 7); |
||
3649 | AddBMCnd("BMGE", 8); |
||
3650 | AddBMCnd("BMLT", 9); |
||
3651 | AddBMCnd("BMGT", 10); |
||
3652 | AddBMCnd("BMLE", 11); |
||
3653 | AddBMCnd("BMO", 12); |
||
3654 | AddBMCnd("BMNO", 13); |
||
3655 | AddBCLR("BNOT", 1); |
||
3656 | AddBCnd("BRA", 14); |
||
3657 | AddBRK("BRK", 0x0000); |
||
3658 | AddBCLR("BSET", 2); |
||
3659 | AddBSR("BSR", 0); |
||
3660 | AddBCLR("BTST", 3); |
||
3661 | AddCLRPSW("CLRPSW", 0xB0); |
||
3662 | AddADD("CMP", 2); |
||
3663 | AddDIV("DIV", 0); |
||
3664 | AddDIV("DIVU", 1); |
||
3665 | AddDIV("EMUL", 2); |
||
3666 | AddDIV("EMULU", 3); |
||
3667 | AddFADD("FADD", 0); |
||
3668 | AddFADD("FCMP", 1); |
||
3669 | AddFADD("FDIV", 2); |
||
3670 | AddFADD("FMUL", 3); |
||
3671 | AddFADD("FSUB", 4); |
||
3672 | AddFADD("FTOI", 5); |
||
3673 | AddINT("INT", 0); |
||
3674 | AddITOF("ITOF", 0); |
||
3675 | AddJMP("JMP", 0); |
||
3676 | AddJMP("JSR", 1); |
||
3677 | AddMACHI("MACHI", 0); |
||
3678 | AddMACHI("MACLO", 1); |
||
3679 | AddDIV("MAX", 4); |
||
3680 | AddDIV("MIN", 5); |
||
3681 | AddMOV("MOV", 0); |
||
3682 | AddMOVU("MOVU", 0); |
||
3683 | AddADD("MUL", 3); |
||
3684 | AddMACHI("MULHI", 2); |
||
3685 | AddMACHI("MULLO", 3); |
||
3686 | AddMVFACHI("MVFACHI", 0); |
||
3687 | AddMVFACHI("MVFACMI", 1); |
||
3688 | AddMVFC("MVFC", 0); |
||
3689 | AddMVTACHI("MVTACHI", 0); |
||
3690 | AddMVTACHI("MVTACLO", 1); |
||
3691 | AddMVTC("MVTC", 0); |
||
3692 | AddMVTIPL("MVTIPL", 0); |
||
3693 | AddABS("NEG", 0x1007); |
||
3694 | AddBRK("NOP", 0x0003); |
||
3695 | AddABS("NOT", 0x003B); |
||
3696 | AddADD("OR", 4); |
||
3697 | AddJMP("POP", 2); |
||
3698 | AddPOPC("POPC", 0); |
||
3699 | AddPOPM("POPM", 0); |
||
3700 | AddPUSH("PUSH", 0); |
||
3701 | AddPOPC("PUSHC", 1); |
||
3702 | AddPOPM("PUSHM", 1); |
||
3703 | AddRACW("RACW", 0); |
||
3704 | AddMACHI("REVL", 4); |
||
3705 | AddMACHI("REVW", 5); |
||
3706 | AddRMPA("RMPA", 0x8C); |
||
3707 | AddJMP("ROLC", 3); |
||
3708 | AddJMP("RORC", 4); |
||
3709 | AddROTL("ROTL", 0); |
||
3710 | AddROTL("ROTR", 1); |
||
3711 | AddFADD("ROUND", 6); |
||
3712 | AddRTE("RTE", 0x7F95); |
||
3713 | AddRTE("RTFI", 0x7F94); |
||
3714 | AddBRK("RTS", 0x0002); |
||
3715 | AddRTSD("RTSD", 0); |
||
3716 | AddJMP("SAT", 5); |
||
3717 | AddRTE("SATR", 0x7F93); |
||
3718 | AddADC("SBB", 0x0000); |
||
3719 | AddSCCnd("SCEQ", 0); |
||
3720 | AddSCCnd("SCZ", 0); |
||
3721 | AddSCCnd("SCNE", 1); |
||
3722 | AddSCCnd("SCNZ", 1); |
||
3723 | AddSCCnd("SCGEU", 2); |
||
3724 | AddSCCnd("SCC", 2); |
||
3725 | AddSCCnd("SCLTU", 3); |
||
3726 | AddSCCnd("SCNC", 3); |
||
3727 | AddSCCnd("SCGTU", 4); |
||
3728 | AddSCCnd("SCLEU", 5); |
||
3729 | AddSCCnd("SCPZ", 6); |
||
3730 | AddSCCnd("SCN", 7); |
||
3731 | AddSCCnd("SCGE", 8); |
||
3732 | AddSCCnd("SCLT", 9); |
||
3733 | AddSCCnd("SCGT", 10); |
||
3734 | AddSCCnd("SCLE", 11); |
||
3735 | AddSCCnd("SCO", 12); |
||
3736 | AddSCCnd("SCNO", 13); |
||
3737 | AddRTE("SCMPU", 0x7F83); |
||
3738 | AddCLRPSW("SETPSW", 0xA0); |
||
3739 | AddSHAR("SHAR", 0); |
||
3740 | AddSHAR("SHLL", 1); |
||
3741 | AddSHAR("SHLR", 2); |
||
3742 | AddRTE("SMOVB", 0x7F8B); |
||
3743 | AddRTE("SMOVF", 0x7F8F); |
||
3744 | AddRTE("SMOVU", 0x7F87); |
||
3745 | AddRMPA("SSTR", 0x88); |
||
3746 | AddSTNZ("STNZ", 0); |
||
3747 | AddSTNZ("STZ", 1); |
||
3748 | AddADD("SUB", 5); |
||
3749 | AddRMPA("SUNTIL", 0x80); |
||
3750 | AddRMPA("SWHILE", 0x84); |
||
3751 | AddTST("TST", 0); |
||
3752 | AddRTE("WAIT", 0x7F96); |
||
3753 | AddTST("XCHG", 1); |
||
3754 | AddTST("XOR", 2); |
||
3755 | |||
3756 | /* RXv2 */ |
||
3757 | AddFADD("FSQRT", 7); |
||
3758 | AddFADD("FTOU", 8); |
||
3759 | AddITOF("UTOF", 1); |
||
3760 | AddMOVCO("MOVCO", 0); |
||
3761 | AddMOVLI("MOVLI", 0); |
||
3762 | AddMACHI("EMACA", 6); |
||
3763 | AddMACHI("EMSBA", 7); |
||
3764 | AddMACHI("EMULA", 8); |
||
3765 | AddMACHI("MACLH", 9); |
||
3766 | AddMACHI("MSBHI", 10); |
||
3767 | AddMACHI("MSBLH", 11); |
||
3768 | AddMACHI("MSBLO", 12); |
||
3769 | AddMACHI("MULLH", 13); |
||
3770 | AddMVFACHI("MVFACGU", 2); |
||
3771 | AddMVFACHI("MVFACLO", 3); |
||
3772 | AddMVTACHI("MVTACGU", 2); |
||
3773 | AddRACW("RACL", 1); |
||
3774 | AddRACW("RDACL", 2); |
||
3775 | AddRACW("RDACW", 3); |
||
3776 | |||
3777 | /* RXv3 */ |
||
3778 | AddBFMOV("BFMOV", 0); |
||
3779 | AddBFMOV("BFMOVZ", 1); |
||
3780 | AddRSTR("RSTR", 0); |
||
3781 | AddRSTR("SAVE", 1); SaveIsOccupiedFnc = TrueFnc; |
||
3782 | AddDABS("DABS", 0); |
||
3783 | AddDADD("DADD", 0); |
||
3784 | AddDCMPcm("DCMPUN", 0x01); |
||
3785 | AddDCMPcm("DCMPEQ", 0x02); |
||
3786 | AddDCMPcm("DCMPLT", 0x04); |
||
3787 | AddDCMPcm("DCMPLE", 0x06); |
||
3788 | AddDADD("DDIV", 1); |
||
3789 | AddDMOV("DMOV", 0); |
||
3790 | AddDADD("DMUL", 2); |
||
3791 | AddDABS("DNEG", 1); |
||
3792 | AddDPOPM("DPOPM", 0); |
||
3793 | AddDPOPM("DPUSHM", 1); |
||
3794 | AddDABS("DROUND", 2); |
||
3795 | AddDABS("DSQRT", 3); |
||
3796 | AddDADD("DSUB", 3); |
||
3797 | AddDABS("DTOF", 4); |
||
3798 | AddDABS("DTOI", 5); |
||
3799 | AddDABS("DTOU", 6); |
||
3800 | AddFTOD("FTOD", 0); |
||
3801 | AddFTOD("ITOD", 1); |
||
3802 | AddMVFDC("MVFDC", 0); |
||
3803 | AddMVFDR("MVFDR", 0); |
||
3804 | AddMVFDC("MVTDC", 1); |
||
3805 | AddFTOD("UTOD", 2); |
||
3806 | |||
3807 | /* Pseudo Instructions */ |
||
3808 | #ifdef COMPAT |
||
3809 | AddInstTable(InstTable, "ENDIAN", 0, DecodeENDIAN); |
||
3810 | AddBLK("BLKB", 1); |
||
3811 | AddBLK("BLKW", 2); |
||
3812 | AddBLK("BLKL", 4); |
||
3813 | AddBLK("BLKD", 8); |
||
3814 | AddInstTable(InstTable, "BYTE", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString, DecodeIntelDB); |
||
3815 | AddInstTable(InstTable, "WORD", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowInt, DecodeIntelDW); |
||
3816 | AddInstTable(InstTable, "LWORD", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowInt, DecodeIntelDD); |
||
3817 | AddInstTable(InstTable, "FLOAT", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowFloat, DecodeIntelDD); |
||
3818 | AddInstTable(InstTable, "DOUBLE", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowFloat, DecodeIntelDQ); |
||
3819 | #endif |
||
3820 | |||
3821 | StrCompAlloc(&Temp1, STRINGSIZE); |
||
3822 | StrCompAlloc(&Temp2, STRINGSIZE); |
||
3823 | } |
||
3824 | |||
3825 | static void DeinitFields(void) |
||
3826 | { |
||
3827 | StrCompFree(&Temp2); |
||
3828 | StrCompFree(&Temp1); |
||
3829 | |||
3830 | DestroyInstTable(InstTable); |
||
3831 | } |
||
3832 | |||
3833 | /*---------------------------------------------------------------------------*/ |
||
3834 | |||
3835 | static void MakeCode_RX(void) |
||
3836 | { |
||
3837 | if (!LookupInstTable(InstTable, OpPart.str.p_str)) |
||
3838 | WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart); |
||
3839 | } |
||
3840 | |||
3841 | static Boolean IsDef_RX(void) |
||
3842 | { |
||
3843 | return False; |
||
3844 | } |
||
3845 | |||
3846 | static void SwitchFrom_RX(void) |
||
3847 | { |
||
3848 | DeinitFields(); |
||
3849 | } |
||
3850 | |||
3851 | static void SwitchTo_RX(void *pUser) |
||
3852 | { |
||
3853 | const TFamilyDescr *pDescr; |
||
3854 | |||
3855 | TurnWords = False; |
||
3856 | SetIntConstMode(eIntConstModeIntel); |
||
3857 | |||
3858 | pDescr = FindFamilyByName("RX"); |
||
3859 | PCSymbol = "$"; |
||
3860 | HeaderID = pDescr->Id; |
||
3861 | NOPCode = 0x03; |
||
3862 | DivideChars = ","; |
||
3863 | HasAttrs = True; |
||
3864 | AttrChars = "."; |
||
3865 | |||
3866 | ValidSegs = (1 << SegCode); |
||
3867 | Grans[SegCode] = 1; |
||
3868 | ListGrans[SegCode] = 1; |
||
3869 | SegInits[SegCode] = 0x0000; |
||
3870 | SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max; |
||
3871 | |||
3872 | MakeCode = MakeCode_RX; |
||
3873 | IsDef = IsDef_RX; |
||
3874 | SwitchFrom = SwitchFrom_RX; |
||
3875 | InitFields(); |
||
3876 | onoff_supmode_add(); |
||
3877 | onoff_bigendian_add(); |
||
3878 | |||
3879 | pCurrCPUProps = (const tCPUProps *)pUser; |
||
3880 | } |
||
3881 | |||
3882 | static const tCPUProps CPUProps[] = |
||
3883 | { |
||
3884 | /* Group InsSet FLT DBL RegB MVTIPL */ |
||
3885 | { "RXV1", eRXv1, True, False, 0, True }, /* Generic RXv1 (Full option) */ |
||
3886 | { "RX110", eRXv1, False, False, 0, True }, |
||
3887 | { "RX111", eRXv1, False, False, 0, True }, |
||
3888 | { "RX113", eRXv1, False, False, 0, True }, |
||
3889 | { "RX130", eRXv1, False, False, 0, True }, |
||
3890 | { "RX210", eRXv1, False, False, 0, True }, |
||
3891 | { "RX21A", eRXv1, False, False, 0, True }, |
||
3892 | { "RX220", eRXv1, False, False, 0, True }, |
||
3893 | { "RX610", eRXv1, True, False, 0, False }, |
||
3894 | { "RX621", eRXv1, True, False, 0, True }, |
||
3895 | { "RX62N", eRXv1, True, False, 0, True }, |
||
3896 | { "RX630", eRXv1, True, False, 0, True }, |
||
3897 | { "RX631", eRXv1, True, False, 0, True }, |
||
3898 | |||
3899 | { "RXV2", eRXv2, True, False, 0, True }, /* Generic RXv2 */ |
||
3900 | { "RX140", eRXv2, True, False, 0, True }, |
||
3901 | { "RX230", eRXv2, True, False, 0, True }, |
||
3902 | { "RX231", eRXv2, True, False, 0, True }, |
||
3903 | { "RX64M", eRXv2, True, False, 0, True }, |
||
3904 | { "RX651", eRXv2, True, False, 0, True }, |
||
3905 | |||
3906 | { "RXV3", eRXv3, True, True, 256, True }, /* Generic RXv3 (Full option) */ |
||
3907 | { "RX660", eRXv3, True, False, 16, True }, |
||
3908 | { "RX671", eRXv3, True, True, 16, True }, |
||
3909 | { "RX72M", eRXv3, True, True, 16, True }, |
||
3910 | { "RX72N", eRXv3, True, True, 16, True }, |
||
3911 | |||
3912 | { "" , eRXv1, False, False, 0, False } |
||
3913 | }; |
||
3914 | |||
3915 | void coderx_init(void) |
||
3916 | { |
||
3917 | const tCPUProps *pProp; |
||
3918 | |||
3919 | for (pProp = CPUProps; pProp->Name[0]; pProp++) |
||
3920 | (void)AddCPUUser(pProp->Name, SwitchTo_RX, (void *)pProp, NULL); |
||
3921 | |||
3922 | AddCopyright("Renesas RX Generator (C) 2023 Haruo Asano"); |
||
3923 | } |