1 /* code68k.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator 680x0-Familie */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "nls.h"
16 #include "bpemu.h"
17 #include "endian.h"
18 #include "ieeefloat.h"
19 #include "strutil.h"
20 #include "asmdef.h"
21 #include "asmsub.h"
22 #include "asmpars.h"
23 #include "asmallg.h"
24 #include "asmcode.h"
25 #include "motpseudo.h"
26 #include "asmitree.h"
27 #include "codevars.h"
28 #include "errmsg.h"
29 #include "codepseudo.h"
30
31 #include "code68k.h"
32
33 typedef enum
34 {
35 e68KGen1a, /* 68008/68000 */
36 e68KGen1b, /* 68010/68012 */
37 eColdfire,
38 eCPU32,
39 e68KGen2, /* 68020/68030 */
40 e68KGen3 /* 68040 */
41 } tFamily;
42
43 typedef enum
44 {
45 eCfISA_None,
46 eCfISA_A,
47 eCfISA_APlus,
48 eCfISA_B,
49 eCfISA_C
50 } tCfISA;
51
52 typedef enum
53 {
54 eFlagNone = 0,
55 eFlagLogCCR = 1 << 0,
56 eFlagIdxScaling = 1 << 1,
57 eFlagCALLM_RTM = 1 << 2,
58 eFlagIntFPU = 1 << 3,
59 eFlagExtFPU = 1 << 4,
60 eFlagIntPMMU = 1 << 5,
61 eFlagBranch32 = 1 << 6,
62 eFlagMAC = 1 << 7,
63 eFlagEMAC = 1 << 8
64 } tSuppFlags;
65
66 #define eSymbolSizeShiftCnt ((tSymbolSize)8)
67
68 #ifdef __cplusplus
69 # include "code68k.hpp"
70 #endif
71
72 enum
73 {
74 Std_Variant = 0,
75 I_Variant = 4,
76 A_Variant = 8,
77 VariantMask = 12
78 };
79
80 typedef struct
81 {
82 const char *Name;
83 Word Code;
84 } tCtReg;
85
86 #define MAX_CTREGS_GROUPS 4
87
88 typedef struct
89 {
90 const char *pName;
91 LongWord AddrSpaceMask;
92 tFamily Family;
93 tCfISA CfISA;
94 tSuppFlags SuppFlags;
95 const tCtReg *pCtRegs[MAX_CTREGS_GROUPS];
96 } tCPUProps;
97
98 typedef struct
99 {
100 Word Code;
101 Boolean MustSup;
102 Word FamilyMask;
103 } FixedOrder;
104
105 typedef struct
106 {
107 Byte Code;
108 Boolean Dya;
109 tSuppFlags NeedsSuppFlags;
110 } FPUOp;
111
112 typedef struct
113 {
114 const char *pName;
115 tSymbolSize Size;
116 Word Code;
117 } PMMUReg;
118
119 #define FixedOrderCnt 10
120 #define CtRegCnt 29
121 #define FPUOpCnt 47
122 #define PMMURegCnt 13
123
124 #define EMACAvailName "HASEMAC"
125 #define PMMUAvailName "HASPMMU" /* PMMU-Befehle erlaubt */
126 #define FullPMMUName "FULLPMMU" /* voller PMMU-Befehlssatz */
127
128 #define REG_SP 15
129 #define REG_MARK 16 /* internal mark to differentiate SP<->A7 */
130 #define REG_FPCTRL 8
131 #define REG_FPCR 4
132 #define REG_FPSR 2
133 #define REG_FPIAR 1
134
135 enum
136 {
137 ModNone = 0,
138 ModData = 1,
139 ModAdr = 2,
140 ModAdrI = 3,
141 ModPost = 4,
142 ModPre = 5,
143 ModDAdrI = 6,
144 ModAIX = 7,
145 ModPC = 8,
146 ModPCIdx = 9,
147 ModAbs = 10,
148 ModImm = 11,
149 ModFPn = 12,
150 ModFPCR = 13
151 };
152
153 enum
154 {
155 MModData = 1 << (ModData - 1),
156 MModAdr = 1 << (ModAdr - 1),
157 MModAdrI = 1 << (ModAdrI - 1),
158 MModPost = 1 << (ModPost - 1),
159 MModPre = 1 << (ModPre - 1),
160 MModDAdrI = 1 << (ModDAdrI - 1),
161 MModAIX = 1 << (ModAIX - 1),
162 MModPC = 1 << (ModPC - 1),
163 MModPCIdx = 1 << (ModPCIdx - 1),
164 MModAbs = 1 << (ModAbs - 1),
165 MModImm = 1 << (ModImm - 1),
166 MModFPn = 1 << (ModFPn - 1),
167 MModFPCR = 1 << (ModFPCR - 1)
168 };
169
170 typedef struct
171 {
172 Byte Num;
173 Word Mode;
174 Word Vals[10];
175 tSymbolFlags ImmSymFlags;
176 int Cnt;
177 } tAdrResult;
178
179 static tSymbolSize OpSize;
180 static ShortInt RelPos;
181 static Boolean PMMUAvail; /* PMMU-Befehle erlaubt? */
182 static Boolean FullPMMU; /* voller PMMU-Befehlssatz? */
183
184 static FixedOrder *FixedOrders;
185 static FPUOp *FPUOps;
186 static PMMUReg *PMMURegs;
187
188 static const tCPUProps *pCurrCPUProps;
189 static tSymbolSize NativeFloatSize;
190
191 static const Byte FSizeCodes[10] =
192 {
193 6, 4, 0, 7, 0, 1, 5, 2, 0, 3
194 };
195
196 /*-------------------------------------------------------------------------*/
197 /* Unterroutinen */
198
199 #define CopyAdrVals(Dest, pAdrResult) memcpy(Dest, (pAdrResult)->Vals, (pAdrResult)->Cnt)
200
CheckFamilyCore(unsigned FamilyMask)201 static Boolean CheckFamilyCore(unsigned FamilyMask)
202 {
203 return !!((FamilyMask >> pCurrCPUProps->Family) & 1);
204 }
205
CheckFamily(unsigned FamilyMask)206 static Boolean CheckFamily(unsigned FamilyMask)
207 {
208 if (CheckFamilyCore(FamilyMask))
209 return True;
210 WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
211 CodeLen = 0;
212 return False;
213 }
214
CheckISA(unsigned ISAMask)215 static Boolean CheckISA(unsigned ISAMask)
216 {
217 if ((ISAMask >> pCurrCPUProps->CfISA) & 1)
218 return True;
219 WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
220 CodeLen = 0;
221 return False;
222 }
223
CheckNoFamily(unsigned FamilyMask)224 static Boolean CheckNoFamily(unsigned FamilyMask)
225 {
226 if (!CheckFamilyCore(FamilyMask))
227 return True;
228 WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
229 CodeLen = 0;
230 return False;
231 }
232
CheckSup(void)233 static void CheckSup(void)
234 {
235 if (!SupAllowed)
236 WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
237 }
238
CheckColdSize(void)239 static Boolean CheckColdSize(void)
240 {
241 if ((OpSize > eSymbolSize32Bit) || ((pCurrCPUProps->Family == eColdfire) && (OpSize < eSymbolSize32Bit)))
242 {
243 WrError(ErrNum_InvOpSize);
244 return False;
245 }
246 else
247 return True;
248 }
249
CheckFloatSize(void)250 static Boolean CheckFloatSize(void)
251 {
252 if (!*AttrPart.Str)
253 OpSize = NativeFloatSize;
254
255 switch (OpSize)
256 {
257 case eSymbolSize8Bit:
258 case eSymbolSize16Bit:
259 case eSymbolSize32Bit:
260 case eSymbolSizeFloat32Bit:
261 case eSymbolSizeFloat64Bit:
262 return True;
263 case eSymbolSizeFloat96Bit:
264 case eSymbolSizeFloatDec96Bit:
265 if (pCurrCPUProps->Family != eColdfire)
266 return True;
267 /* else fall-through */
268 default:
269 WrError(ErrNum_InvOpSize);
270 return False;
271 }
272 }
273
FloatOpSizeFitsDataReg(tSymbolSize OpSize)274 static Boolean FloatOpSizeFitsDataReg(tSymbolSize OpSize)
275 {
276 return (OpSize <= eSymbolSize32Bit) || (OpSize == eSymbolSizeFloat32Bit);
277 }
278
ValReg(char Ch)279 static Boolean ValReg(char Ch)
280 {
281 return ((Ch >= '0') && (Ch <= '7'));
282 }
283
284 /*-------------------------------------------------------------------------*/
285 /* Register Symbols */
286
287 /*!------------------------------------------------------------------------
288 * \fn DecodeRegCore(const char *pArg, Word *pResult)
289 * \brief check whether argument is a CPU register
290 * \param pArg argument to check
291 * \param pResult numeric register value if yes
292 * \return True if yes
293 * ------------------------------------------------------------------------ */
294
DecodeRegCore(const char * pArg,Word * pResult)295 static Boolean DecodeRegCore(const char *pArg, Word *pResult)
296 {
297 if (!as_strcasecmp(pArg, "SP"))
298 {
299 *pResult = REG_SP | REG_MARK;
300 return True;
301 }
302
303 if (strlen(pArg) != 2)
304 return False;
305 if ((*pResult = pArg[1] - '0') > 7)
306 return False;
307
308 switch (as_toupper(*pArg))
309 {
310 case 'D':
311 return True;
312 case 'A':
313 *pResult |= 8;
314 return True;
315 default:
316 return False;
317 }
318 }
319
320 /*!------------------------------------------------------------------------
321 * \fn DecodeFPRegCore(const char *pArg, Word *pResult)
322 * \brief check whether argument is an FPU register
323 * \param pArg argument to check
324 * \param pResult numeric register value if yes
325 * \return True if yes
326 * ------------------------------------------------------------------------ */
327
DecodeFPRegCore(const char * pArg,Word * pResult)328 static Boolean DecodeFPRegCore(const char *pArg, Word *pResult)
329 {
330 if (!as_strcasecmp(pArg, "FPCR"))
331 {
332 *pResult = REG_FPCTRL | REG_FPCR;
333 return True;
334 }
335 if (!as_strcasecmp(pArg, "FPSR"))
336 {
337 *pResult = REG_FPCTRL | REG_FPSR;
338 return True;
339 }
340 if (!as_strcasecmp(pArg, "FPIAR"))
341 {
342 *pResult = REG_FPCTRL | REG_FPIAR;
343 return True;
344 }
345
346 if (strlen(pArg) != 3)
347 return False;
348 if (as_strncasecmp(pArg, "FP", 2))
349 return False;
350 if ((*pResult = pArg[2] - '0') > 7)
351 return False;
352 return True;
353 }
354
355 /*!------------------------------------------------------------------------
356 * \fn DissectReg_68K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
357 * \brief dissect register symbols - 68K variant
358 * \param pDest destination buffer
359 * \param DestSize destination buffer size
360 * \param Value numeric register value
361 * \param InpSize register size
362 * ------------------------------------------------------------------------ */
363
DissectReg_68K(char * pDest,size_t DestSize,tRegInt Value,tSymbolSize InpSize)364 static void DissectReg_68K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
365 {
366 if (InpSize == NativeFloatSize)
367 {
368 switch (Value)
369 {
370 case REG_FPCTRL | REG_FPCR:
371 as_snprintf(pDest, DestSize, "FPCR");
372 break;
373 case REG_FPCTRL | REG_FPSR:
374 as_snprintf(pDest, DestSize, "FPSR");
375 break;
376 case REG_FPCTRL | REG_FPIAR:
377 as_snprintf(pDest, DestSize, "FPIAR");
378 break;
379 default:
380 as_snprintf(pDest, DestSize, "FP%u", (unsigned)Value);
381 }
382 }
383 else if (InpSize == eSymbolSize32Bit)
384 {
385 switch (Value)
386 {
387 case REG_MARK | REG_SP:
388 as_snprintf(pDest, DestSize, "SP");
389 break;
390 default:
391 as_snprintf(pDest, DestSize, "%c%u", Value & 8 ? 'A' : 'D', (unsigned)(Value & 7));
392 }
393 }
394 else
395 as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
396 }
397
398 /*-------------------------------------------------------------------------*/
399 /* Adressparser */
400
401 typedef enum
402 {
403 PC, AReg, Index, indir, Disp, None
404 } CompType;
405
406 /* static const char *CompNames[] = { "PC", "AReg", "Index", "indir", "Disp", "None" }; */
407
408 typedef struct
409 {
410 tStrComp Comp;
411 CompType Art;
412 Word ANummer, INummer;
413 Boolean Long;
414 Word Scale;
415 ShortInt Size;
416 LongInt Wert;
417 } AdrComp;
418
ClrAdrVals(tAdrResult * pResult)419 static void ClrAdrVals(tAdrResult *pResult)
420 {
421 pResult->Num = ModNone;
422 pResult->Cnt = 0;
423 }
424
ACheckFamily(unsigned FamilyMask,const tStrComp * pAdrComp,tAdrResult * pResult)425 static Boolean ACheckFamily(unsigned FamilyMask, const tStrComp *pAdrComp, tAdrResult *pResult)
426 {
427 if (CheckFamilyCore(FamilyMask))
428 return True;
429 WrStrErrorPos(ErrNum_AddrModeNotSupported, pAdrComp);
430 ClrAdrVals(pResult);
431 return False;
432 }
433
434 /*!------------------------------------------------------------------------
435 * \fn DecodeReg(const tStrComp *pArg, Word *pErg, Boolean MustBeReg)
436 * \brief check whether argument is a CPU register or register alias
437 * \param pArg argument to check
438 * \param pResult numeric register value if yes
439 * \param MustBeReg argument is expected to be a register
440 * \return RegEvalResult
441 * ------------------------------------------------------------------------ */
442
DecodeReg(const tStrComp * pArg,Word * pResult,Boolean MustBeReg)443 static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
444 {
445 tRegDescr RegDescr;
446 tEvalResult EvalResult;
447 tRegEvalResult RegEvalResult;
448
449 if (DecodeRegCore(pArg->Str, pResult))
450 {
451 *pResult &= ~REG_MARK;
452 return eIsReg;
453 }
454
455 RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize32Bit, MustBeReg);
456 *pResult = RegDescr.Reg & ~REG_MARK;
457 return RegEvalResult;
458 }
459
460 /*!------------------------------------------------------------------------
461 * \fn DecodeFPReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
462 * \brief check whether argument is a FPU register or register alias
463 * \param pArg argument to check
464 * \param pResult numeric register value if yes
465 * \param MustBeReg argument is expected to be a register
466 * \return RegEvalResult
467 * ------------------------------------------------------------------------ */
468
DecodeFPReg(const tStrComp * pArg,Word * pResult,Boolean MustBeReg)469 static tRegEvalResult DecodeFPReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
470 {
471 tRegDescr RegDescr;
472 tEvalResult EvalResult;
473 tRegEvalResult RegEvalResult;
474
475 if (DecodeFPRegCore(pArg->Str, pResult))
476 {
477 *pResult &= ~REG_MARK;
478 return eIsReg;
479 }
480
481 RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, NativeFloatSize, MustBeReg);
482 *pResult = RegDescr.Reg;
483 return RegEvalResult;
484 }
485
486 /*!------------------------------------------------------------------------
487 * \fn DecodeRegOrFPReg(const tStrComp *pArg, Word *pErg, tSymbolSize *pSize, Boolean MustBeReg)
488 * \brief check whether argument is an CPU/FPU register or register alias
489 * \param pArg argument to check
490 * \param pResult numeric register value if yes
491 * \param pSize size of register if yes
492 * \param MustBeReg argument is expected to be a register
493 * \return RegEvalResult
494 * ------------------------------------------------------------------------ */
495
DecodeRegOrFPReg(const tStrComp * pArg,Word * pResult,tSymbolSize * pSize,Boolean MustBeReg)496 static tRegEvalResult DecodeRegOrFPReg(const tStrComp *pArg, Word *pResult, tSymbolSize *pSize, Boolean MustBeReg)
497 {
498 tRegDescr RegDescr;
499 tEvalResult EvalResult;
500 tRegEvalResult RegEvalResult;
501
502 if (DecodeRegCore(pArg->Str, pResult))
503 {
504 *pResult &= ~REG_MARK;
505 *pSize = eSymbolSize32Bit;
506 return eIsReg;
507 }
508 if (DecodeFPRegCore(pArg->Str, pResult))
509 {
510 *pSize = NativeFloatSize;
511 return eIsReg;
512 }
513
514 RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
515 *pResult = RegDescr.Reg & ~REG_MARK;
516 *pSize = EvalResult.DataSize;
517 return RegEvalResult;
518 }
519
DecodeRegPair(tStrComp * pArg,Word * Erg1,Word * Erg2)520 static Boolean DecodeRegPair(tStrComp *pArg, Word *Erg1, Word *Erg2)
521 {
522 char *pSep = strchr(pArg->Str, ':');
523 tStrComp Left, Right;
524
525 if (!pSep)
526 return False;
527 StrCompSplitRef(&Left, &Right, pArg, pSep);
528 return (DecodeReg(&Left, Erg1, False) == eIsReg)
529 && (*Erg1 <= 7)
530 && (DecodeReg(&Right, Erg2, False) == eIsReg)
531 && (*Erg2 <= 7);
532 }
533
CodeIndRegPair(tStrComp * pArg,Word * Erg1,Word * Erg2)534 static Boolean CodeIndRegPair(tStrComp *pArg, Word *Erg1, Word *Erg2)
535 {
536 char *pSep = strchr(pArg->Str, ':');
537 tStrComp Left, Right;
538
539 if (!pSep)
540 return False;
541 StrCompSplitRef(&Left, &Right, pArg, pSep);
542
543 if (!IsIndirect(Left.Str) || !IsIndirect(Right.Str))
544 return False;
545 StrCompShorten(&Left, 1);
546 StrCompIncRefLeft(&Left, 1);
547 StrCompShorten(&Right, 1);
548 StrCompIncRefLeft(&Right, 1);
549
550 return (DecodeReg(&Left, Erg1, False) == eIsReg)
551 && (DecodeReg(&Right, Erg2, False) == eIsReg);
552 }
553
CodeCache(char * Asc,Word * Erg)554 static Boolean CodeCache(char *Asc, Word *Erg)
555 {
556 if (!as_strcasecmp(Asc, "IC"))
557 *Erg = 2;
558 else if (!as_strcasecmp(Asc, "DC"))
559 *Erg = 1;
560 else if (!as_strcasecmp(Asc, "IC/DC"))
561 *Erg = 3;
562 else if (!as_strcasecmp(Asc, "DC/IC"))
563 *Erg = 3;
564 else
565 return False;
566 return True;
567 }
568
DecodeCtrlReg(char * Asc,Word * Erg)569 static Boolean DecodeCtrlReg(char *Asc, Word *Erg)
570 {
571 int Grp;
572 String Asc_N;
573 const tCtReg *pReg;
574
575 strmaxcpy(Asc_N, Asc, STRINGSIZE);
576 NLS_UpString(Asc_N);
577 Asc = Asc_N;
578
579 for (Grp = 0; Grp < MAX_CTREGS_GROUPS; Grp++)
580 {
581 pReg = pCurrCPUProps->pCtRegs[Grp];
582 if (!pReg)
583 return False;
584 for (; pReg->Name; pReg++)
585 if (!strcmp(pReg->Name, Asc))
586 {
587 *Erg = pReg->Code;
588 return True;
589 }
590 }
591 return False;
592 }
593
OneField(const tStrComp * pArg,Word * Erg,Boolean Ab1)594 static Boolean OneField(const tStrComp *pArg, Word *Erg, Boolean Ab1)
595 {
596 switch (DecodeReg(pArg, Erg, False))
597 {
598 case eIsReg:
599 if (*Erg > 7)
600 return False;
601 *Erg |= 0x20;
602 return True;
603 case eIsNoReg:
604 {
605 Boolean ValOK;
606
607 *Erg = EvalStrIntExpression(pArg, Int8, &ValOK);
608 if (Ab1 && (*Erg == 32))
609 *Erg = 0;
610 return (ValOK && (*Erg < 32));
611 }
612 default:
613 return False;
614 }
615 }
616
SplitBitField(tStrComp * pArg,Word * Erg)617 static Boolean SplitBitField(tStrComp *pArg, Word *Erg)
618 {
619 char *p;
620 Word OfsVal;
621 tStrComp FieldArg, OffsArg, WidthArg;
622
623 p = strchr(pArg->Str, '{');
624 if (!p)
625 return False;
626 StrCompSplitRef(pArg, &FieldArg, pArg, p);
627 if ((!*FieldArg.Str) || (FieldArg.Str[strlen(FieldArg.Str) - 1] != '}'))
628 return False;
629 StrCompShorten(&FieldArg, 1);
630
631 p = strchr(FieldArg.Str, ':');
632 if (!p)
633 return False;
634 StrCompSplitRef(&OffsArg, &WidthArg, &FieldArg, p);
635 if (!OneField(&OffsArg, &OfsVal, False))
636 return False;
637 if (!OneField(&WidthArg, Erg, True))
638 return False;
639 *Erg += OfsVal << 6;
640 return True;
641 }
642
SplitSize(tStrComp * pArg,ShortInt * DispLen,unsigned OpSizeMask)643 static Boolean SplitSize(tStrComp *pArg, ShortInt *DispLen, unsigned OpSizeMask)
644 {
645 ShortInt NewLen = -1;
646 int ArgLen = strlen(pArg->Str);
647
648 if ((ArgLen > 2) && (pArg->Str[ArgLen - 2] == '.'))
649 {
650 switch (as_toupper(pArg->Str[ArgLen - 1]))
651 {
652 case 'B':
653 if (OpSizeMask & 1)
654 NewLen = 0;
655 else
656 goto wrong;
657 break;
658 case 'W':
659 if (OpSizeMask & 2)
660 NewLen = 1;
661 else
662 goto wrong;
663 break;
664 case 'L':
665 if (OpSizeMask & 2)
666 NewLen = 2;
667 else
668 goto wrong;
669 break;
670 default:
671 wrong:
672 WrError(ErrNum_InvOpSize);
673 return False;
674 }
675 if ((*DispLen != -1) && (*DispLen != NewLen))
676 {
677 WrError(ErrNum_ConfOpSizes);
678 return False;
679 }
680 *DispLen = NewLen;
681 StrCompShorten(pArg, 2);
682 }
683
684 return True;
685 }
686
ClassComp(AdrComp * C)687 static Boolean ClassComp(AdrComp *C)
688 {
689 int CompLen = strlen(C->Comp.Str);
690 Boolean IsReg;
691 char *pEnd, Save;
692
693 C->Art = None;
694 C->ANummer = C->INummer = 0;
695 C->Long = False;
696 C->Scale = 0;
697 C->Size = -1;
698 C->Wert = 0;
699
700 if ((*C->Comp.Str == '[') && (C->Comp.Str[CompLen - 1] == ']'))
701 {
702 C->Art = indir;
703 return True;
704 }
705
706 if (!as_strcasecmp(C->Comp.Str, "PC"))
707 {
708 C->Art = PC;
709 return True;
710 }
711
712 /* use ChkMacSymbName so . is not taken as valid character: TODO: what about _ ? */
713
714 pEnd = ChkMacSymbNameUpTo(C->Comp.Str, C->Comp.Str + CompLen);
715 IsReg = (pEnd > C->Comp.Str);
716 if (IsReg)
717 {
718 tRegEvalResult RegEvalResult;
719
720 Save = *pEnd;
721 *pEnd = '\0';
722 RegEvalResult = DecodeReg(&C->Comp, &C->ANummer, False);
723 *pEnd = Save;
724 if (eRegAbort == RegEvalResult)
725 return False;
726 IsReg = (RegEvalResult == eIsReg);
727 }
728 if (IsReg)
729 {
730 int ScaleOffs = pEnd - C->Comp.Str;
731
732 if ((C->ANummer > 7) && (ScaleOffs == CompLen))
733 {
734 C->Art = AReg;
735 C->ANummer -= 8;
736 return True;
737 }
738 else
739 {
740 if ((CompLen >= ScaleOffs + 2) && (C->Comp.Str[ScaleOffs] == '.'))
741 {
742 switch (as_toupper(C->Comp.Str[ScaleOffs + 1]))
743 {
744 case 'L':
745 C->Long = True;
746 break;
747 case 'W':
748 C->Long = False;
749 break;
750 default:
751 return False;
752 }
753 ScaleOffs += 2;
754 }
755 else
756 C->Long = (pCurrCPUProps->Family == eColdfire);
757 if ((CompLen > ScaleOffs + 1) && (C->Comp.Str[ScaleOffs] == '*'))
758 {
759 switch (C->Comp.Str[ScaleOffs + 1])
760 {
761 case '1':
762 C->Scale = 0;
763 break;
764 case '2':
765 C->Scale = 1;
766 break;
767 case '4':
768 C->Scale = 2;
769 break;
770 case '8':
771 if (pCurrCPUProps->Family == eColdfire)
772 return False;
773 C->Scale = 3;
774 break;
775 default:
776 return False;
777 }
778 ScaleOffs += 2;
779 }
780 else
781 C->Scale = 0;
782 C->INummer = C->ANummer;
783 C->Art = Index;
784 return True;
785 }
786 }
787
788 C->Art = Disp;
789 if ((CompLen >= 2) && (C->Comp.Str[CompLen - 2] == '.'))
790 {
791 switch (as_toupper(C->Comp.Str[CompLen - 1]))
792 {
793 case 'L':
794 C->Size = 2;
795 break;
796 case 'W':
797 C->Size = 1;
798 break;
799 default:
800 return False;
801 }
802 StrCompShorten(&C->Comp, 2);
803 }
804 else
805 C->Size = -1;
806 C->Art = Disp;
807 return True;
808 }
809
SwapAdrComps(AdrComp * pComp1,AdrComp * pComp2)810 static void SwapAdrComps(AdrComp *pComp1, AdrComp *pComp2)
811 {
812 AdrComp Tmp;
813
814 Tmp = *pComp1;
815 *pComp1 = *pComp2;
816 *pComp2 = Tmp;
817 }
818
AdrCompToIndex(AdrComp * pComp)819 static void AdrCompToIndex(AdrComp *pComp)
820 {
821 pComp->Art = Index;
822 pComp->INummer = pComp->ANummer + 8;
823 pComp->Long = False;
824 pComp->Scale = 0;
825 }
826
IsShortAdr(LongInt Addr)827 static Boolean IsShortAdr(LongInt Addr)
828 {
829 LongWord OrigAddr = (LongWord)Addr, ExtAddr;
830
831 /* Assuming we would code this address as short address... */
832
833 ExtAddr = OrigAddr & 0xffff;
834 if (ExtAddr & 0x8000)
835 ExtAddr |= 0xffff0000ul;
836
837 /* ...would this result in the same address on the bus? */
838
839 return (ExtAddr & pCurrCPUProps->AddrSpaceMask) == (OrigAddr & pCurrCPUProps->AddrSpaceMask);
840 }
841
IsDisp8(LongInt Disp)842 static Boolean IsDisp8(LongInt Disp)
843 {
844 return ((Disp >= -128) && (Disp <= 127));
845 }
846
IsDisp16(LongInt Disp)847 static Boolean IsDisp16(LongInt Disp)
848 {
849 return ((Disp >= -32768) && (Disp <= 32767));
850 }
851
GetDispLen(LongInt Disp)852 ShortInt GetDispLen(LongInt Disp)
853 {
854 if (IsDisp8(Disp))
855 return 0;
856 else if (IsDisp16(Disp))
857 return 1;
858 else
859 return 2;
860 }
861
ChkEven(LongInt Adr)862 static void ChkEven(LongInt Adr)
863 {
864 switch (pCurrCPUProps->Family)
865 {
866 case e68KGen1a:
867 case e68KGen1b:
868 case eColdfire:
869 if (Odd(Adr))
870 WrError(ErrNum_AddrNotAligned);
871 break;
872 default:
873 break;
874 }
875 }
876
DecodeAbs(const tStrComp * pArg,ShortInt Size,tAdrResult * pResult)877 static void DecodeAbs(const tStrComp *pArg, ShortInt Size, tAdrResult *pResult)
878 {
879 Boolean ValOK;
880 tSymbolFlags Flags;
881 LongInt HVal;
882 Integer HVal16;
883
884 pResult->Cnt = 0;
885
886 HVal = EvalStrIntExpressionWithFlags(pArg, Int32, &ValOK, &Flags);
887
888 if (ValOK)
889 {
890 if (!mFirstPassUnknown(Flags) && (OpSize > eSymbolSize8Bit))
891 ChkEven(HVal);
892 HVal16 = HVal;
893
894 if (Size == -1)
895 Size = (IsShortAdr(HVal)) ? 1 : 2;
896 pResult->Num = ModAbs;
897
898 if (Size == 1)
899 {
900 if (!IsShortAdr(HVal))
901 {
902 WrError(ErrNum_NoShortAddr);
903 pResult->Num = ModNone;
904 }
905 else
906 {
907 pResult->Mode = 0x38;
908 pResult->Vals[0] = HVal16;
909 pResult->Cnt = 2;
910 }
911 }
912 else
913 {
914 pResult->Mode = 0x39;
915 pResult->Vals[0] = HVal >> 16;
916 pResult->Vals[1] = HVal & 0xffff;
917 pResult->Cnt = 4;
918 }
919 }
920 }
921
DecodeAdr(const tStrComp * pArg,Word Erl,tAdrResult * pResult)922 static Byte DecodeAdr(const tStrComp *pArg, Word Erl, tAdrResult *pResult)
923 {
924 Byte i;
925 int ArgLen;
926 char *p;
927 Word rerg;
928 Byte lklamm, rklamm, lastrklamm;
929 Boolean doklamm;
930
931 AdrComp AdrComps[3], OneComp;
932 Byte CompCnt;
933 ShortInt OutDispLen = -1;
934 Boolean PreInd;
935
936 #ifdef HAS64
937 QuadInt QVal;
938 #endif
939 LongInt HVal;
940 Integer HVal16;
941 ShortInt HVal8;
942 Double DVal;
943 Boolean ValOK;
944 tSymbolFlags Flags;
945 Word SwapField[6];
946 String ArgStr;
947 tStrComp Arg;
948 String CReg;
949 tStrComp CRegArg;
950 const unsigned ExtAddrFamilyMask = (1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32);
951 IntType DispIntType;
952 tSymbolSize RegSize;
953
954 /* some insns decode the same arg twice, so we must keep the original string intact. */
955
956 StrCompMkTemp(&Arg, ArgStr);
957 StrCompCopy(&Arg, pArg);
958 KillPrefBlanksStrComp(&Arg);
959 KillPostBlanksStrComp(&Arg);
960 ArgLen = strlen(Arg.Str);
961 ClrAdrVals(pResult);
962
963 StrCompMkTemp(&CRegArg, CReg);
964
965 /* immediate : */
966
967 if (*Arg.Str == '#')
968 {
969 tStrComp ImmArg;
970
971 StrCompRefRight(&ImmArg, &Arg, 1);
972 KillPrefBlanksStrComp(&ImmArg);
973
974 pResult->Num = ModImm;
975 pResult->Mode = 0x3c;
976 switch (OpSize)
977 {
978 case eSymbolSize8Bit:
979 pResult->Cnt = 2;
980 HVal8 = EvalStrIntExpressionWithFlags(&ImmArg, Int8, &ValOK, &pResult->ImmSymFlags);
981 if (ValOK)
982 pResult->Vals[0] = (Word)((Byte) HVal8);
983 break;
984 case eSymbolSize16Bit:
985 pResult->Cnt = 2;
986 HVal16 = EvalStrIntExpressionWithFlags(&ImmArg, Int16, &ValOK, &pResult->ImmSymFlags);
987 if (ValOK)
988 pResult->Vals[0] = (Word) HVal16;
989 break;
990 case eSymbolSize32Bit:
991 pResult->Cnt = 4;
992 HVal = EvalStrIntExpressionWithFlags(&ImmArg, Int32, &ValOK, &pResult->ImmSymFlags);
993 if (ValOK)
994 {
995 pResult->Vals[0] = HVal >> 16;
996 pResult->Vals[1] = HVal & 0xffff;
997 }
998 break;
999 #ifdef HAS64
1000 case eSymbolSize64Bit:
1001 pResult->Cnt = 8;
1002 QVal = EvalStrIntExpressionWithFlags(&ImmArg, Int64, &ValOK, &pResult->ImmSymFlags);
1003 if (ValOK)
1004 {
1005 pResult->Vals[0] = (QVal >> 48) & 0xffff;
1006 pResult->Vals[1] = (QVal >> 32) & 0xffff;
1007 pResult->Vals[2] = (QVal >> 16) & 0xffff;
1008 pResult->Vals[3] = (QVal ) & 0xffff;
1009 }
1010 break;
1011 #endif
1012 case eSymbolSizeFloat32Bit:
1013 pResult->Cnt = 4;
1014 DVal = EvalStrFloatExpression(&ImmArg, Float32, &ValOK);
1015 if (ValOK)
1016 {
1017 Double_2_ieee4(DVal, (Byte *) SwapField, BigEndian);
1018 if (BigEndian)
1019 DWSwap((Byte *) SwapField, 4);
1020 pResult->Vals[0] = SwapField[1];
1021 pResult->Vals[1] = SwapField[0];
1022 }
1023 break;
1024 case eSymbolSizeFloat64Bit:
1025 pResult->Cnt = 8;
1026 DVal = EvalStrFloatExpression(&ImmArg, Float64, &ValOK);
1027 if (ValOK)
1028 {
1029 Double_2_ieee8(DVal, (Byte *) SwapField, BigEndian);
1030 if (BigEndian)
1031 QWSwap((Byte *) SwapField, 8);
1032 pResult->Vals[0] = SwapField[3];
1033 pResult->Vals[1] = SwapField[2];
1034 pResult->Vals[2] = SwapField[1];
1035 pResult->Vals[3] = SwapField[0];
1036 }
1037 break;
1038 case eSymbolSizeFloat96Bit:
1039 pResult->Cnt = 12;
1040 DVal = EvalStrFloatExpression(&ImmArg, Float64, &ValOK);
1041 if (ValOK)
1042 {
1043 Double_2_ieee10(DVal, (Byte *) SwapField, False);
1044 if (BigEndian)
1045 WSwap((Byte *) SwapField, 10);
1046 pResult->Vals[0] = SwapField[4];
1047 pResult->Vals[1] = 0;
1048 pResult->Vals[2] = SwapField[3];
1049 pResult->Vals[3] = SwapField[2];
1050 pResult->Vals[4] = SwapField[1];
1051 pResult->Vals[5] = SwapField[0];
1052 }
1053 break;
1054 case eSymbolSizeFloatDec96Bit:
1055 pResult->Cnt = 12;
1056 DVal = EvalStrFloatExpression(&ImmArg, Float64, &ValOK);
1057 if (ValOK)
1058 {
1059 ConvertMotoFloatDec(DVal, (Byte *) SwapField, False);
1060 pResult->Vals[0] = SwapField[5];
1061 pResult->Vals[1] = SwapField[4];
1062 pResult->Vals[2] = SwapField[3];
1063 pResult->Vals[3] = SwapField[2];
1064 pResult->Vals[4] = SwapField[1];
1065 pResult->Vals[5] = SwapField[0];
1066 }
1067 break;
1068 case eSymbolSizeShiftCnt: /* special arg 1..8 */
1069 pResult->Cnt = 2;
1070 HVal8 = EvalStrIntExpressionWithFlags(&ImmArg, UInt4, &ValOK, &pResult->ImmSymFlags);
1071 if (ValOK)
1072 {
1073 if (mFirstPassUnknown(pResult->ImmSymFlags))
1074 HVal8 = 1;
1075 ValOK = ChkRange(HVal8, 1, 8);
1076 }
1077 if (ValOK)
1078 pResult->Vals[0] = (Word)((Byte) HVal8);
1079 break;
1080 default:
1081 break;
1082 }
1083 goto chk;
1084 }
1085
1086 /* CPU/FPU-Register direkt: */
1087
1088 switch (DecodeRegOrFPReg(&Arg, &pResult->Mode, &RegSize, False))
1089 {
1090 case eIsReg:
1091 pResult->Cnt = 0;
1092 if (RegSize == NativeFloatSize)
1093 {
1094 pResult->Num = (pResult->Mode > 7) ? ModFPCR : ModFPn;
1095 pResult->Mode &= 7;
1096 }
1097 else
1098 pResult->Num = (pResult->Mode >> 3) + ModData;
1099 /* fall-through */
1100 case eRegAbort:
1101 goto chk;
1102 default:
1103 break;
1104 }
1105
1106 /* Adressregister indirekt mit Predekrement: */
1107
1108 if ((ArgLen >= 4) && (*Arg.Str == '-') && (Arg.Str[1] == '(') && (Arg.Str[ArgLen - 1] == ')'))
1109 {
1110 StrCompCopySub(&CRegArg, &Arg, 2, ArgLen - 3);
1111 if ((DecodeReg(&CRegArg, &rerg, False) == eIsReg) && (rerg > 7))
1112 {
1113 pResult->Mode = rerg + 24;
1114 pResult->Cnt = 0;
1115 pResult->Num = ModPre;
1116 goto chk;
1117 }
1118 }
1119
1120 /* Adressregister indirekt mit Postinkrement */
1121
1122 if ((ArgLen >= 4) && (*Arg.Str == '(') && (Arg.Str[ArgLen - 2] == ')') && (Arg.Str[ArgLen - 1] == '+'))
1123 {
1124 StrCompCopySub(&CRegArg, &Arg, 1, ArgLen - 3);
1125 if ((DecodeReg(&CRegArg, &rerg, False) == eIsReg) && (rerg > 7))
1126 {
1127 pResult->Mode = rerg + 16;
1128 pResult->Cnt = 0;
1129 pResult->Num = ModPost;
1130 goto chk;
1131 }
1132 }
1133
1134 /* Unterscheidung direkt<->indirekt: */
1135
1136 lklamm = 0;
1137 rklamm = 0;
1138 lastrklamm = 0;
1139 doklamm = True;
1140 for (p = Arg.Str; *p; p++)
1141 {
1142 if (*p == '[')
1143 doklamm = False;
1144 if (*p == ']')
1145 doklamm = True;
1146 if (doklamm)
1147 {
1148 if (*p == '(')
1149 lklamm++;
1150 else if (*p == ')')
1151 {
1152 rklamm++;
1153 lastrklamm = p - Arg.Str;
1154 }
1155 }
1156 }
1157
1158 if ((lklamm == 1) && (rklamm == 1) && (lastrklamm == ArgLen - 1))
1159 {
1160 tStrComp OutDisp, IndirComps, Remainder;
1161 char *pCompSplit;
1162
1163 /* aeusseres Displacement abspalten, Klammern loeschen: */
1164
1165 p = strchr(Arg.Str, '(');
1166 *p = '\0';
1167 StrCompSplitRef(&OutDisp, &IndirComps, &Arg, p);
1168 OutDispLen = -1;
1169 if (!SplitSize(&OutDisp, &OutDispLen, 7))
1170 return ModNone;
1171 StrCompShorten(&IndirComps, 1);
1172
1173 /* in Komponenten zerteilen: */
1174
1175 CompCnt = 0;
1176 do
1177 {
1178 doklamm = True;
1179 pCompSplit = IndirComps.Str;
1180 do
1181 {
1182 if (*pCompSplit == '[')
1183 doklamm = False;
1184 else if (*pCompSplit == ']')
1185 doklamm = True;
1186 pCompSplit++;
1187 }
1188 while (((!doklamm) || (*pCompSplit != ',')) && (*pCompSplit != '\0'));
1189
1190 if (*pCompSplit == '\0')
1191 {
1192 AdrComps[CompCnt].Comp = IndirComps;
1193 pCompSplit = NULL;
1194 }
1195 else
1196 {
1197 StrCompSplitRef(&AdrComps[CompCnt].Comp, &Remainder, &IndirComps, pCompSplit);
1198 IndirComps = Remainder;
1199 }
1200
1201 /* ignore empty component */
1202
1203 if (!AdrComps[CompCnt].Comp.Str[0])
1204 continue;
1205 if (!ClassComp(&AdrComps[CompCnt]))
1206 {
1207 WrStrErrorPos(ErrNum_InvAddrMode, &AdrComps[CompCnt].Comp);
1208 return ModNone;
1209 }
1210
1211 /* Base register position is already occupied and we get another one: */
1212
1213 if ((CompCnt == 1) && ((AdrComps[CompCnt].Art == AReg) || (AdrComps[CompCnt].Art == PC)))
1214 {
1215 /* Index register at "base position": just swap comp 0 & 1, so we get (An,Xi) or (PC,Xi): */
1216
1217 if (AdrComps[0].Art == Index)
1218 SwapAdrComps(&AdrComps[CompCnt], &AdrComps[0]);
1219
1220 /* Address register at "base position" and we add PC: also swap and convert it to index so we get again (PC,Xi): */
1221
1222 else if ((AdrComps[0].Art == AReg) && (AdrComps[CompCnt].Art == PC))
1223 {
1224 SwapAdrComps(&AdrComps[CompCnt], &AdrComps[0]);
1225 AdrCompToIndex(&AdrComps[CompCnt]);
1226 }
1227
1228 /* Otherwise, convert address to general index register. Result may require 68020++ modes: */
1229
1230 else
1231 AdrCompToIndex(&AdrComps[CompCnt]);
1232
1233 CompCnt++;
1234 }
1235
1236 /* a displacement found inside (...), but outside [...]. Explicit
1237 sizes must be consistent, implicitly checked by SplitSize(). */
1238
1239 else if (AdrComps[CompCnt].Art == Disp)
1240 {
1241 if (*OutDisp.Str)
1242 {
1243 WrError(ErrNum_InvAddrMode);
1244 return ModNone;
1245 }
1246 OutDisp = AdrComps[CompCnt].Comp;
1247 OutDispLen = AdrComps[CompCnt].Size;
1248 }
1249
1250 /* no second index */
1251
1252 else if ((AdrComps[CompCnt].Art != Index) && (CompCnt != 0))
1253 {
1254 WrError(ErrNum_InvAddrMode);
1255 return ModNone;
1256 }
1257
1258 else
1259 CompCnt++;
1260 }
1261 while (pCompSplit);
1262
1263 if ((CompCnt > 2) || ((CompCnt > 1) && (AdrComps[0].Art == Index)))
1264 {
1265 WrError(ErrNum_InvAddrMode);
1266 return ModNone;
1267 }
1268
1269 /* 0. Absolut in Klammern (d) */
1270
1271 if (CompCnt == 0)
1272 {
1273 DecodeAbs(&OutDisp, OutDispLen, pResult);
1274 }
1275
1276 /* 1. Variante (An....), d(An....) */
1277
1278 else if (AdrComps[0].Art == AReg)
1279 {
1280
1281 /* 1.1. Variante (An), d(An) */
1282
1283 if (CompCnt == 1)
1284 {
1285 /* 1.1.1. Variante (An) */
1286
1287 if ((*OutDisp.Str == '\0') && ((MModAdrI & Erl) != 0))
1288 {
1289 pResult->Mode = 0x10 + AdrComps[0].ANummer;
1290 pResult->Num = ModAdrI;
1291 pResult->Cnt = 0;
1292 goto chk;
1293 }
1294
1295 /* 1.1.2. Variante d(An) */
1296
1297 else
1298 {
1299 /* only try 32-bit displacement if explicitly requested, or 68020++ and no size given */
1300
1301 if (OutDispLen < 0)
1302 DispIntType = CheckFamilyCore(ExtAddrFamilyMask) ? SInt32 : SInt16;
1303 else
1304 DispIntType = (OutDispLen >= 2) ? SInt32 : SInt16;
1305 HVal = EvalStrIntExpression(&OutDisp, DispIntType, &ValOK);
1306 if (!ValOK)
1307 return ModNone;
1308 if (ValOK && (HVal == 0) && ((MModAdrI & Erl) != 0) && (OutDispLen == -1))
1309 {
1310 pResult->Mode = 0x10 + AdrComps[0].ANummer;
1311 pResult->Num = ModAdrI;
1312 pResult->Cnt = 0;
1313 goto chk;
1314 }
1315 if (OutDispLen == -1)
1316 OutDispLen = (IsDisp16(HVal)) ? 1 : 2;
1317 switch (OutDispLen)
1318 {
1319 case 1: /* d16(An) */
1320 pResult->Mode = 0x28 + AdrComps[0].ANummer;
1321 pResult->Num = ModDAdrI;
1322 pResult->Cnt = 2;
1323 pResult->Vals[0] = HVal & 0xffff;
1324 goto chk;
1325 case 2: /* d32(An) */
1326 pResult->Mode = 0x30 + AdrComps[0].ANummer;
1327 pResult->Num = ModAIX;
1328 pResult->Cnt = 6;
1329 pResult->Vals[0] = 0x0170;
1330 pResult->Vals[1] = (HVal >> 16) & 0xffff;
1331 pResult->Vals[2] = HVal & 0xffff;
1332 ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
1333 goto chk;
1334 }
1335 }
1336 }
1337
1338 /* 1.2. Variante d(An,Xi) */
1339
1340 else
1341 {
1342 pResult->Vals[0] = (AdrComps[1].INummer << 12) + (Ord(AdrComps[1].Long) << 11) + (AdrComps[1].Scale << 9);
1343 pResult->Mode = 0x30 + AdrComps[0].ANummer;
1344
1345 /* only try 32-bit displacement if explicitly requested, or 68020++ and no size given */
1346
1347 if (OutDispLen < 0)
1348 DispIntType = CheckFamilyCore(ExtAddrFamilyMask) ? SInt32 : SInt8;
1349 else
1350 DispIntType = (OutDispLen >= 2) ? SInt32 : (OutDispLen >= 1 ? SInt16 : SInt8);
1351 HVal = EvalStrIntExpression(&OutDisp, DispIntType, &ValOK);
1352 if (ValOK)
1353 switch (OutDispLen)
1354 {
1355 case 0:
1356 if (!IsDisp8(HVal))
1357 {
1358 WrError(ErrNum_OverRange);
1359 ValOK = FALSE;
1360 }
1361 break;
1362 case 1:
1363 if (!IsDisp16(HVal))
1364 {
1365 WrError(ErrNum_OverRange);
1366 ValOK = FALSE;
1367 }
1368 break;
1369 }
1370 if (ValOK)
1371 {
1372 if (OutDispLen == -1)
1373 OutDispLen = GetDispLen(HVal);
1374 switch (OutDispLen)
1375 {
1376 case 0:
1377 pResult->Num = ModAIX;
1378 pResult->Cnt = 2;
1379 pResult->Vals[0] += (HVal & 0xff);
1380 if ((AdrComps[1].Scale != 0) && (!(pCurrCPUProps->SuppFlags & eFlagIdxScaling)))
1381 {
1382 WrStrErrorPos(ErrNum_AddrModeNotSupported, &AdrComps[1].Comp);
1383 ClrAdrVals(pResult);
1384 }
1385 goto chk;
1386 case 1:
1387 pResult->Num = ModAIX;
1388 pResult->Cnt = 4;
1389 pResult->Vals[0] += 0x120;
1390 pResult->Vals[1] = HVal & 0xffff;
1391 ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
1392 goto chk;
1393 case 2:
1394 pResult->Num = ModAIX;
1395 pResult->Cnt = 6;
1396 pResult->Vals[0] += 0x130;
1397 pResult->Vals[1] = HVal >> 16;
1398 pResult->Vals[2] = HVal & 0xffff;
1399 ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
1400 goto chk;
1401 }
1402 }
1403 }
1404 }
1405
1406 /* 2. Variante d(PC....) */
1407
1408 else if (AdrComps[0].Art == PC)
1409 {
1410 /* 2.1. Variante d(PC) */
1411
1412 if (CompCnt == 1)
1413 {
1414 HVal = EvalStrIntExpressionWithFlags(&OutDisp, Int32, &ValOK, &Flags) - (EProgCounter() + RelPos);
1415 if (!ValOK)
1416 return ModNone;
1417 if (OutDispLen < 0)
1418 {
1419 if (mSymbolQuestionable(Flags) && !CheckFamilyCore(ExtAddrFamilyMask))
1420 HVal &= 0x7fff;
1421 OutDispLen = (IsDisp16(HVal)) ? 1 : 2;
1422 }
1423 switch (OutDispLen)
1424 {
1425 case 1:
1426 pResult->Mode = 0x3a;
1427 if (!mSymbolQuestionable(Flags) && !IsDisp16(HVal))
1428 {
1429 WrError(ErrNum_DistTooBig);
1430 return ModNone;
1431 }
1432 pResult->Num = ModPC;
1433 pResult->Cnt = 2;
1434 pResult->Vals[0] = HVal & 0xffff;
1435 goto chk;
1436 case 2:
1437 pResult->Mode = 0x3b;
1438 pResult->Num = ModPCIdx;
1439 pResult->Cnt = 6;
1440 pResult->Vals[0] = 0x170;
1441 pResult->Vals[1] = HVal >> 16;
1442 pResult->Vals[2] = HVal & 0xffff;
1443 ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
1444 goto chk;
1445 }
1446 }
1447
1448 /* 2.2. Variante d(PC,Xi) */
1449
1450 else
1451 {
1452 pResult->Vals[0] = (AdrComps[1].INummer << 12) + (Ord(AdrComps[1].Long) << 11) + (AdrComps[1].Scale << 9);
1453 HVal = EvalStrIntExpressionWithFlags(&OutDisp, Int32, &ValOK, &Flags) - (EProgCounter() + RelPos);
1454 if (!ValOK)
1455 return ModNone;
1456 if (OutDispLen < 0)
1457 {
1458 if (mSymbolQuestionable(Flags) && !CheckFamilyCore(ExtAddrFamilyMask))
1459 HVal &= 0x7f;
1460 OutDispLen = GetDispLen(HVal);
1461 }
1462 pResult->Mode = 0x3b;
1463 switch (OutDispLen)
1464 {
1465 case 0:
1466 if (!mSymbolQuestionable(Flags) && !IsDisp8(HVal))
1467 {
1468 WrError(ErrNum_DistTooBig);
1469 return ModNone;
1470 }
1471 pResult->Vals[0] += (HVal & 0xff);
1472 pResult->Cnt = 2;
1473 pResult->Num = ModPCIdx;
1474 if ((AdrComps[1].Scale != 0) && (!(pCurrCPUProps->SuppFlags & eFlagIdxScaling)))
1475 {
1476 WrStrErrorPos(ErrNum_AddrModeNotSupported, &AdrComps[1].Comp);
1477 ClrAdrVals(pResult);
1478 }
1479 goto chk;
1480 case 1:
1481 if (!mSymbolQuestionable(Flags) && !IsDisp16(HVal))
1482 {
1483 WrError(ErrNum_DistTooBig);
1484 return ModNone;
1485 }
1486 pResult->Vals[0] += 0x120;
1487 pResult->Cnt = 4;
1488 pResult->Num = ModPCIdx;
1489 pResult->Vals[1] = HVal & 0xffff;
1490 ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
1491 goto chk;
1492 case 2:
1493 pResult->Vals[0] += 0x130;
1494 pResult->Cnt = 6;
1495 pResult->Num = ModPCIdx;
1496 pResult->Vals[1] = HVal >> 16;
1497 pResult->Vals[2] = HVal & 0xffff;
1498 ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
1499 goto chk;
1500 }
1501 }
1502 }
1503
1504 /* 3. Variante (Xi), d(Xi) */
1505
1506 else if (AdrComps[0].Art == Index)
1507 {
1508 pResult->Vals[0] = (AdrComps[0].INummer << 12) + (Ord(AdrComps[0].Long) << 11) + (AdrComps[0].Scale << 9) + 0x180;
1509 pResult->Mode = 0x30;
1510 if (*OutDisp.Str == '\0')
1511 {
1512 pResult->Vals[0] = pResult->Vals[0] + 0x0010;
1513 pResult->Cnt = 2;
1514 pResult->Num = ModAIX;
1515 ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
1516 goto chk;
1517 }
1518 else
1519 {
1520 HVal = EvalStrIntExpression(&OutDisp, (OutDispLen != 1) ? SInt32 : SInt16, &ValOK);
1521 if (ValOK)
1522 {
1523 if (OutDispLen == -1)
1524 OutDispLen = IsDisp16(HVal) ? 1 : 2;
1525 switch (OutDispLen)
1526 {
1527 case 0:
1528 case 1:
1529 pResult->Vals[0] = pResult->Vals[0] + 0x0020;
1530 pResult->Vals[1] = HVal & 0xffff;
1531 pResult->Num = ModAIX;
1532 pResult->Cnt = 4;
1533 ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
1534 goto chk;
1535 case 2:
1536 pResult->Vals[0] = pResult->Vals[0] + 0x0030;
1537 pResult->Num = ModAIX;
1538 pResult->Cnt = 6;
1539 pResult->Vals[1] = HVal >> 16;
1540 pResult->Vals[2] = HVal & 0xffff;
1541 ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
1542 goto chk;
1543 }
1544 }
1545 }
1546 }
1547
1548 /* 4. Variante indirekt: */
1549
1550 else if (AdrComps[0].Art == indir)
1551 {
1552 /* erst ab 68020 erlaubt */
1553
1554 if (!ACheckFamily((1 << e68KGen3) | (1 << e68KGen2), pArg, pResult))
1555 return ModNone;
1556
1557 /* Unterscheidung Vor- <---> Nachindizierung: */
1558
1559 if (CompCnt == 2)
1560 {
1561 PreInd = False;
1562 AdrComps[2] = AdrComps[1];
1563 }
1564 else
1565 {
1566 PreInd = True;
1567 AdrComps[2].Art = None;
1568 }
1569
1570 /* indirektes Argument herauskopieren: */
1571
1572 StrCompRefRight(&IndirComps, &AdrComps[0].Comp, 1);
1573 StrCompShorten(&IndirComps, 1);
1574
1575 /* Felder loeschen: */
1576
1577 for (i = 0; i < 2; AdrComps[i++].Art = None);
1578
1579 /* indirekten Ausdruck auseinanderfieseln: */
1580
1581 do
1582 {
1583 /* abschneiden & klassifizieren: */
1584
1585 pCompSplit = strchr(IndirComps.Str, ',');
1586 if (!pCompSplit)
1587 OneComp.Comp = IndirComps;
1588 else
1589 {
1590 StrCompSplitRef(&OneComp.Comp, &Remainder, &IndirComps, pCompSplit);
1591 IndirComps = Remainder;
1592 }
1593 if (!ClassComp(&OneComp))
1594 {
1595 WrError(ErrNum_InvAddrMode);
1596 return ModNone;
1597 }
1598
1599 /* passend einsortieren: */
1600
1601 if ((AdrComps[1].Art != None) && (OneComp.Art == AReg))
1602 {
1603 OneComp.Art = Index;
1604 OneComp.INummer = OneComp.ANummer + 8;
1605 OneComp.Long = False;
1606 OneComp.Scale = 0;
1607 }
1608 switch (OneComp.Art)
1609 {
1610 case Disp:
1611 i = 0;
1612 break;
1613 case AReg:
1614 case PC:
1615 i = 1;
1616 break;
1617 case Index:
1618 i = 2;
1619 break;
1620 default:
1621 i = -1;
1622 }
1623 if (AdrComps[i].Art != None)
1624 {
1625 WrError(ErrNum_InvAddrMode);
1626 return ModNone;
1627 }
1628 else
1629 AdrComps[i] = OneComp;
1630 }
1631 while (pCompSplit);
1632
1633 /* extension word: 68020 format */
1634
1635 pResult->Vals[0] = 0x100;
1636
1637 /* bit 2 = post-indexed. */
1638
1639 if (!PreInd)
1640 pResult->Vals[0] |= 0x0004;
1641
1642 /* Set post-indexed also for no index register for compatibility with older versions. */
1643
1644 if (AdrComps[2].Art == None)
1645 pResult->Vals[0] |= 0x0040 | 0x0004;
1646 else
1647 pResult->Vals[0] |= (AdrComps[2].INummer << 12) + (Ord(AdrComps[2].Long) << 11) + (AdrComps[2].Scale << 9);
1648
1649 /* 4.1 Variante d([...PC...]...) */
1650
1651 if (AdrComps[1].Art == PC)
1652 {
1653 if (AdrComps[0].Art == None)
1654 {
1655 pResult->Mode = 0x3b;
1656 pResult->Vals[0] |= 0x10;
1657 pResult->Num = ModAIX;
1658 pResult->Cnt = 2;
1659 }
1660 else
1661 {
1662 HVal = EvalStrIntExpression(&AdrComps[0].Comp, Int32, &ValOK);
1663 HVal -= EProgCounter() + RelPos;
1664 if (!ValOK)
1665 return ModNone;
1666 switch (AdrComps[0].Size)
1667 {
1668 case -1:
1669 if (IsDisp16(HVal))
1670 goto PCIs16;
1671 else
1672 goto PCIs32;
1673 case 1:
1674 if (!IsDisp16(HVal))
1675 {
1676 WrError(ErrNum_DistTooBig);
1677 return ModNone;
1678 }
1679 PCIs16:
1680 pResult->Vals[1] = HVal & 0xffff;
1681 pResult->Mode = 0x3b;
1682 pResult->Vals[0] += 0x20;
1683 pResult->Num = ModAIX;
1684 pResult->Cnt = 4;
1685 break;
1686 case 2:
1687 PCIs32:
1688 pResult->Vals[1] = HVal >> 16;
1689 pResult->Vals[2] = HVal & 0xffff;
1690 pResult->Mode = 0x3b;
1691 pResult->Vals[0] += 0x30;
1692 pResult->Num = ModAIX;
1693 pResult->Cnt = 6;
1694 break;
1695 }
1696 }
1697 }
1698
1699 /* 4.2 Variante d([...An...]...) */
1700
1701 else
1702 {
1703 if (AdrComps[1].Art == None)
1704 {
1705 pResult->Mode = 0x30;
1706 pResult->Vals[0] += 0x80;
1707 }
1708 else
1709 pResult->Mode = 0x30 + AdrComps[1].ANummer;
1710
1711 if (AdrComps[0].Art == None)
1712 {
1713 pResult->Num = ModAIX;
1714 pResult->Cnt = 2;
1715 pResult->Vals[0] += 0x10;
1716 }
1717 else
1718 {
1719 HVal = EvalStrIntExpression(&AdrComps[0].Comp, Int32, &ValOK);
1720 if (!ValOK)
1721 return ModNone;
1722 switch (AdrComps[0].Size)
1723 {
1724 case -1:
1725 if (IsDisp16(HVal))
1726 goto AnIs16;
1727 else
1728 goto AnIs32;
1729 case 1:
1730 if (!IsDisp16(HVal))
1731 {
1732 WrError(ErrNum_DistTooBig);
1733 return ModNone;
1734 }
1735 AnIs16:
1736 pResult->Vals[0] += 0x20;
1737 pResult->Vals[1] = HVal & 0xffff;
1738 pResult->Num = ModAIX;
1739 pResult->Cnt = 4;
1740 break;
1741 case 2:
1742 AnIs32:
1743 pResult->Vals[0] += 0x30;
1744 pResult->Vals[1] = HVal >> 16;
1745 pResult->Vals[2] = HVal & 0xffff;
1746 pResult->Num = ModAIX;
1747 pResult->Cnt = 6;
1748 break;
1749 }
1750 }
1751 }
1752
1753 /* aeusseres Displacement: */
1754
1755 HVal = EvalStrIntExpression(&OutDisp, (OutDispLen == 1) ? SInt16 : SInt32, &ValOK);
1756 if (!ValOK)
1757 {
1758 pResult->Num = ModNone;
1759 pResult->Cnt = 0;
1760 return ModNone;
1761 }
1762 if (OutDispLen == -1)
1763 OutDispLen = IsDisp16(HVal) ? 1 : 2;
1764 if (*OutDisp.Str == '\0')
1765 {
1766 pResult->Vals[0]++;
1767 goto chk;
1768 }
1769 else
1770 switch (OutDispLen)
1771 {
1772 case 0:
1773 case 1:
1774 pResult->Vals[pResult->Cnt >> 1] = HVal & 0xffff;
1775 pResult->Cnt += 2;
1776 pResult->Vals[0] += 2;
1777 break;
1778 case 2:
1779 pResult->Vals[(pResult->Cnt >> 1) ] = HVal >> 16;
1780 pResult->Vals[(pResult->Cnt >> 1) + 1] = HVal & 0xffff;
1781 pResult->Cnt += 4;
1782 pResult->Vals[0] += 3;
1783 break;
1784 }
1785
1786 goto chk;
1787 }
1788
1789 }
1790
1791 /* absolut: */
1792
1793 else
1794 {
1795 if (!SplitSize(&Arg, &OutDispLen, 6))
1796 return ModNone;
1797 DecodeAbs(&Arg, OutDispLen, pResult);
1798 }
1799
1800 chk:
1801 if ((pResult->Num > 0) && (!(Erl & (1 << (pResult->Num - 1)))))
1802 {
1803 WrStrErrorPos(ErrNum_InvAddrMode, pArg);
1804 ClrAdrVals(pResult);
1805 }
1806 return pResult->Num;
1807 }
1808
DecodeMACACC(const char * pArg,Word * pResult)1809 static Boolean DecodeMACACC(const char *pArg, Word *pResult)
1810 {
1811 /* interprete ACC like ACC0, independent of MAC or EMAC: */
1812
1813 if (!as_strcasecmp(pArg, "ACC"))
1814 *pResult = 0;
1815 else if (!as_strncasecmp(pArg, "ACC", 3) && (strlen(pArg) == 4) && (pArg[3] >= '0') && (pArg[3] <= '3'))
1816 *pResult = pArg[3] - '0';
1817 else
1818 return False;
1819
1820 /* allow ACC1..3 only on EMAC: */
1821
1822 if ((!(pCurrCPUProps->SuppFlags & eFlagEMAC)) && *pResult)
1823 return False;
1824 return True;
1825 }
1826
DecodeMACReg(const char * pArg,Word * pResult)1827 static Boolean DecodeMACReg(const char *pArg, Word *pResult)
1828 {
1829 if (!as_strcasecmp(pArg, "MACSR"))
1830 {
1831 *pResult = 4;
1832 return True;
1833 }
1834 if (!as_strcasecmp(pArg, "MASK"))
1835 {
1836 *pResult = 6;
1837 return True;
1838 }
1839
1840 /* ACCEXT01/23 only on EMAC: */
1841
1842 if (pCurrCPUProps->SuppFlags & eFlagEMAC)
1843 {
1844 if (!as_strcasecmp(pArg, "ACCEXT01"))
1845 {
1846 *pResult = 5;
1847 return True;
1848 }
1849 if (!as_strcasecmp(pArg, "ACCEXT23"))
1850 {
1851 *pResult = 7;
1852 return True;
1853 }
1854 }
1855 return DecodeMACACC(pArg, pResult);
1856 }
1857
DecodeRegList(const tStrComp * pArg,Word * Erg)1858 static Boolean DecodeRegList(const tStrComp *pArg, Word *Erg)
1859 {
1860 Word h, h2;
1861 Byte z;
1862 char *p, *p2;
1863 String ArgStr;
1864 tStrComp Arg, Remainder, From, To;
1865
1866 StrCompMkTemp(&Arg, ArgStr);
1867 StrCompCopy(&Arg, pArg);
1868
1869 *Erg = 0;
1870 do
1871 {
1872 p = strchr(Arg.Str, '/');
1873 if (p)
1874 StrCompSplitRef(&Arg, &Remainder, &Arg, p);
1875 p2 = strchr(Arg.Str, '-');
1876 if (!p2)
1877 {
1878 if (DecodeReg(&Arg, &h, False) != eIsReg)
1879 return False;
1880 *Erg |= 1 << h;
1881 }
1882 else
1883 {
1884 StrCompSplitRef(&From, &To, &Arg, p2);
1885 if (!*From.Str || !*To.Str)
1886 return False;
1887 if ((DecodeReg(&From, &h, False) != eIsReg)
1888 || (DecodeReg(&To, &h2, False) != eIsReg))
1889 return False;
1890 if (h <= h2)
1891 {
1892 for (z = h; z <= h2; z++)
1893 *Erg |= 1 << z;
1894 }
1895 else
1896 {
1897 for (z = h; z <= 15; z++)
1898 *Erg |= 1 << z;
1899 for (z = 0; z <= h2; z++)
1900 *Erg |= 1 << z;
1901 }
1902 }
1903 if (p)
1904 Arg = Remainder;
1905 }
1906 while (p);
1907 return True;
1908 }
1909
DecodeMACScale(const tStrComp * pArg,Word * pResult)1910 static Boolean DecodeMACScale(const tStrComp *pArg, Word *pResult)
1911 {
1912 int l = strlen(pArg->Str);
1913 tStrComp ShiftArg;
1914 Boolean Left = False, OK;
1915 Word ShiftCnt;
1916
1917 /* allow empty argument */
1918
1919 if (!l)
1920 {
1921 *pResult = 0;
1922 return True;
1923 }
1924 /* left or right? */
1925
1926 if (l < 2)
1927 return False;
1928 if (!strncmp(pArg->Str, "<<", 2))
1929 Left = True;
1930 else if (!strncmp(pArg->Str, ">>", 2))
1931 Left = False;
1932 else
1933 return False;
1934
1935 /* evaluate shift cnt - empty count counts as one */
1936
1937 StrCompRefRight(&ShiftArg, pArg, 2);
1938 KillPrefBlanksStrCompRef(&ShiftArg);
1939 if (!*ShiftArg.Str)
1940 {
1941 ShiftCnt = 1;
1942 OK = True;
1943 }
1944 else
1945 ShiftCnt = EvalStrIntExpression(&ShiftArg, UInt1, &OK);
1946 if (!OK)
1947 return False;
1948
1949 /* codify */
1950
1951 if (ShiftCnt)
1952 *pResult = Left ? 1 : 3;
1953 else
1954 *pResult = 0;
1955 return True;
1956 }
1957
SplitMACUpperLower(Word * pResult,tStrComp * pArg)1958 static Boolean SplitMACUpperLower(Word *pResult, tStrComp *pArg)
1959 {
1960 char *pSplit;
1961 tStrComp HalfComp;
1962
1963 *pResult = 0;
1964 pSplit = strrchr(pArg->Str, '.');
1965 if (!pSplit)
1966 {
1967 WrStrErrorPos(ErrNum_InvReg, pArg);
1968 return False;
1969 }
1970
1971 StrCompSplitRef(pArg, &HalfComp, pArg, pSplit);
1972 KillPostBlanksStrComp(pArg);
1973 if (!as_strcasecmp(HalfComp.Str, "L"))
1974 *pResult = 0;
1975 else if (!as_strcasecmp(HalfComp.Str, "U"))
1976 *pResult = 1;
1977 else
1978 {
1979 WrStrErrorPos(ErrNum_InvReg, &HalfComp);
1980 return False;
1981 }
1982 return True;
1983 }
1984
SplitMACANDMASK(Word * pResult,tStrComp * pArg)1985 static Boolean SplitMACANDMASK(Word *pResult, tStrComp *pArg)
1986 {
1987 char *pSplit, Save;
1988 tStrComp MaskComp, AddrComp;
1989
1990 *pResult = 0;
1991 pSplit = strrchr(pArg->Str, '&');
1992 if (!pSplit)
1993 return True;
1994
1995 Save = StrCompSplitRef(&AddrComp, &MaskComp, pArg, pSplit);
1996 KillPrefBlanksStrCompRef(&MaskComp);
1997
1998 /* if no MASK argument, be sure to revert pArg to original state: */
1999
2000 if (!strcmp(MaskComp.Str, "") || !as_strcasecmp(MaskComp.Str, "MASK"))
2001 {
2002 KillPostBlanksStrComp(&AddrComp);
2003 *pArg = AddrComp;
2004 *pResult = 1;
2005 }
2006 else
2007 *pSplit = Save;
2008 return True;
2009 }
2010
2011 /*-------------------------------------------------------------------------*/
2012 /* Dekodierroutinen: Integer-Einheit */
2013
2014 /* 0=MOVE 1=MOVEA */
2015
DecodeMOVE(Word Index)2016 static void DecodeMOVE(Word Index)
2017 {
2018 Word MACReg;
2019 unsigned Variant = Index & VariantMask;
2020
2021 if (!ChkArgCnt(2, 2));
2022 else if (!as_strcasecmp(ArgStr[1].Str, "USP"))
2023 {
2024 if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
2025 else if ((pCurrCPUProps->Family != eColdfire) || CheckISA((1 << eCfISA_APlus) | (1 << eCfISA_B) | (1 << eCfISA_C)))
2026 {
2027 tAdrResult AdrResult;
2028
2029 if (DecodeAdr(&ArgStr[2], MModAdr, &AdrResult))
2030 {
2031 CodeLen = 2;
2032 WAsmCode[0] = 0x4e68 | (AdrResult.Mode & 7);
2033 CheckSup();
2034 }
2035 }
2036 }
2037 else if (!as_strcasecmp(ArgStr[2].Str, "USP"))
2038 {
2039 if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
2040 else if ((pCurrCPUProps->Family != eColdfire) || CheckISA((1 << eCfISA_APlus) | (1 << eCfISA_B) | (1 << eCfISA_C)))
2041 {
2042 tAdrResult AdrResult;
2043
2044 if (DecodeAdr(&ArgStr[1], MModAdr, &AdrResult))
2045 {
2046 CodeLen = 2;
2047 WAsmCode[0] = 0x4e60 | (AdrResult.Mode & 7);
2048 CheckSup();
2049 }
2050 }
2051 }
2052 else if (!as_strcasecmp(ArgStr[1].Str, "SR"))
2053 {
2054 if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
2055 else
2056 {
2057 tAdrResult AdrResult;
2058
2059 if (DecodeAdr(&ArgStr[2], MModData | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
2060 {
2061 CodeLen = 2 + AdrResult.Cnt;
2062 WAsmCode[0] = 0x40c0 | AdrResult.Mode;
2063 CopyAdrVals(WAsmCode + 1, &AdrResult);
2064 if (pCurrCPUProps->Family != e68KGen1a)
2065 CheckSup();
2066 }
2067 }
2068 }
2069 else if (!as_strcasecmp(ArgStr[1].Str, "CCR"))
2070 {
2071 if (*AttrPart.Str && (OpSize > eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
2072 else if (!CheckNoFamily(1 << e68KGen1a));
2073 else
2074 {
2075 tAdrResult AdrResult;
2076
2077 OpSize = eSymbolSize8Bit;
2078 if (DecodeAdr(&ArgStr[2], MModData | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
2079 {
2080 CodeLen = 2 + AdrResult.Cnt;
2081 WAsmCode[0] = 0x42c0 | AdrResult.Mode;
2082 CopyAdrVals(WAsmCode + 1, &AdrResult);
2083 }
2084 }
2085 }
2086 else if ((pCurrCPUProps->SuppFlags & eFlagMAC) && (DecodeMACReg(ArgStr[1].Str, &MACReg)))
2087 {
2088 Word DestMACReg;
2089
2090 if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
2091 else if ((MACReg == 4) && (!as_strcasecmp(ArgStr[2].Str, "CCR")))
2092 {
2093 WAsmCode[0] = 0xa9c0;
2094 CodeLen = 2;
2095 }
2096 else if ((MACReg < 4) && DecodeMACReg(ArgStr[2].Str, &DestMACReg) && (DestMACReg < 4) && (pCurrCPUProps->SuppFlags & eFlagEMAC))
2097 {
2098 WAsmCode[0] = 0xa110 | (DestMACReg << 9) | (MACReg << 0);
2099 CodeLen = 2;
2100 }
2101 else
2102 {
2103 tAdrResult AdrResult;
2104
2105 if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
2106 {
2107 CodeLen = 2;
2108 WAsmCode[0] = 0xa180 | (AdrResult.Mode & 15) | (MACReg << 9);
2109 }
2110 }
2111 }
2112 else if ((pCurrCPUProps->SuppFlags & eFlagMAC) && (DecodeMACReg(ArgStr[2].Str, &MACReg)))
2113 {
2114 if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
2115 else
2116 {
2117 tAdrResult AdrResult;
2118
2119 if (DecodeAdr(&ArgStr[1], MModData | MModAdr | MModImm, &AdrResult))
2120 {
2121 CodeLen = 2 + AdrResult.Cnt;
2122 WAsmCode[0] = 0xa100 | (AdrResult.Mode) | (MACReg << 9);
2123 CopyAdrVals(WAsmCode + 1, &AdrResult);
2124 }
2125 }
2126 }
2127 else if (!as_strcasecmp(ArgStr[2].Str, "SR"))
2128 {
2129 if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
2130 else
2131 {
2132 tAdrResult AdrResult;
2133
2134 if (DecodeAdr(&ArgStr[1], MModData | MModImm | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs), &AdrResult))
2135 {
2136 CodeLen = 2 + AdrResult.Cnt;
2137 WAsmCode[0] = 0x46c0 | AdrResult.Mode;
2138 CopyAdrVals(WAsmCode + 1, &AdrResult);
2139 CheckSup();
2140 }
2141 }
2142 }
2143 else if (!as_strcasecmp(ArgStr[2].Str, "CCR"))
2144 {
2145 if (*AttrPart.Str && (OpSize > eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
2146 else
2147 {
2148 tAdrResult AdrResult;
2149
2150 if (DecodeAdr(&ArgStr[1], MModData | MModImm | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs), &AdrResult))
2151 {
2152 CodeLen = 2 + AdrResult.Cnt;
2153 WAsmCode[0] = 0x44c0 | AdrResult.Mode;
2154 CopyAdrVals(WAsmCode + 1, &AdrResult);
2155 }
2156 }
2157 }
2158 else
2159 {
2160 if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
2161 else
2162 {
2163 tAdrResult AdrResult;
2164
2165 DecodeAdr(&ArgStr[1], ((Variant == I_Variant) ? 0 : MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs) | MModImm, &AdrResult);
2166
2167 /* Is An as source in byte mode allowed for ColdFire? No corresponding footnote in CFPRM... */
2168
2169 if ((AdrResult.Num == ModAdr) && (OpSize == eSymbolSize8Bit) && (pCurrCPUProps->Family != eColdfire)) WrError(ErrNum_InvOpSize);
2170 else if (AdrResult.Num != ModNone)
2171 {
2172 unsigned SrcAdrNum = AdrResult.Num;
2173
2174 CodeLen = 2 + AdrResult.Cnt;
2175 CopyAdrVals(WAsmCode + 1, &AdrResult);
2176 if (OpSize == eSymbolSize8Bit)
2177 WAsmCode[0] = 0x1000;
2178 else if (OpSize == eSymbolSize16Bit)
2179 WAsmCode[0] = 0x3000;
2180 else
2181 WAsmCode[0] = 0x2000;
2182 WAsmCode[0] |= AdrResult.Mode;
2183 DecodeAdr(&ArgStr[2], ((Variant == A_Variant) ? 0 : MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs) | MModAdr, &AdrResult);
2184 if ((AdrResult.Num == ModAdr) && (OpSize == eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
2185 else if (AdrResult.Mode != 0)
2186 {
2187 Boolean CombinationOK;
2188
2189 /* ColdFire does not allow all combinations of src+dest: */
2190
2191 if (pCurrCPUProps->Family == eColdfire)
2192 switch (SrcAdrNum)
2193 {
2194 case ModData: /* Dn */
2195 case ModAdr: /* An */
2196 case ModAdrI: /* (An) */
2197 case ModPost: /* (An)+ */
2198 case ModPre: /* -(An) */
2199 CombinationOK = True;
2200 break;
2201 case ModDAdrI: /* (d16,An) */
2202 case ModPC: /* (d16,PC) */
2203 CombinationOK = (AdrResult.Num != ModAIX) /* no (d8,An,Xi) */
2204 && (AdrResult.Num != ModAbs); /* no (xxx).W/L */
2205 break;
2206 case ModAIX: /* (d8,An,Xi) */
2207 case ModPCIdx: /* (d8,PC,Xi) */
2208 case ModAbs: /* (xxx).W/L */
2209 CombinationOK = (AdrResult.Num != ModDAdrI) /* no (d16,An) */
2210 && (AdrResult.Num != ModAIX) /* no (d8,An,Xi) */
2211 && (AdrResult.Num != ModAbs); /* no (xxx).W/L */
2212 break;
2213 case ModImm: /* #xxx */
2214 if (AdrResult.Num == ModDAdrI) /* (d16,An) OK for 8/16 bit starting with ISA B */
2215 CombinationOK = (pCurrCPUProps->CfISA >= eCfISA_B) && (OpSize <= eSymbolSize16Bit);
2216 else
2217 CombinationOK = (AdrResult.Num != ModAIX) /* no (d8,An,Xi) */
2218 && (AdrResult.Num != ModAbs); /* no (xxx).W/L */
2219 break;
2220 default: /* should not occur */
2221 CombinationOK = False;
2222 }
2223 else
2224 CombinationOK = True;
2225 if (!CombinationOK)
2226 {
2227 WrError(ErrNum_InvAddrMode);
2228 CodeLen = 0;
2229 }
2230 else
2231 {
2232 AdrResult.Mode = ((AdrResult.Mode & 7) << 3) | (AdrResult.Mode >> 3);
2233 WAsmCode[0] |= AdrResult.Mode << 6;
2234 CopyAdrVals(WAsmCode + (CodeLen >> 1), &AdrResult);
2235 CodeLen += AdrResult.Cnt;
2236 }
2237 }
2238 }
2239 }
2240 }
2241 }
2242
DecodeLEA(Word Index)2243 static void DecodeLEA(Word Index)
2244 {
2245 UNUSED(Index);
2246
2247 if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
2248 else if (!ChkArgCnt(2, 2));
2249 else
2250 {
2251 tAdrResult AdrResult;
2252
2253 if (DecodeAdr(&ArgStr[2], MModAdr, &AdrResult))
2254 {
2255 OpSize = eSymbolSize8Bit;
2256 WAsmCode[0] = 0x41c0 | ((AdrResult.Mode & 7) << 9);
2257 if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
2258 {
2259 WAsmCode[0] |= AdrResult.Mode;
2260 CodeLen = 2 + AdrResult.Cnt;
2261 CopyAdrVals(WAsmCode + 1, &AdrResult);
2262 }
2263 }
2264 }
2265 }
2266
2267 /* 0=ASR 1=ASL 2=LSR 3=LSL 4=ROXR 5=ROXL 6=ROR 7=ROL */
2268
DecodeShift(Word Index)2269 static void DecodeShift(Word Index)
2270 {
2271 Boolean ValOK;
2272 Byte HVal8;
2273 Word LFlag = (Index >> 2), Op = Index & 3;
2274
2275 if (!ChkArgCnt(1, 2));
2276 else if ((*OpPart.Str == 'R') && (!CheckNoFamily(1 << eColdfire)));
2277 else
2278 {
2279 tAdrResult AdrResult;
2280
2281 if (DecodeAdr(&ArgStr[ArgCnt], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult) == ModData)
2282 {
2283 if (CheckColdSize())
2284 {
2285 WAsmCode[0] = 0xe000 | AdrResult.Mode | (Op << 3) | (OpSize << 6) | (LFlag << 8);
2286 OpSize = eSymbolSizeShiftCnt;
2287 if (ArgCnt == 2)
2288 DecodeAdr(&ArgStr[1], MModData | MModImm, &AdrResult);
2289 else
2290 {
2291 AdrResult.Num = ModImm;
2292 AdrResult.Vals[0] = 1;
2293 }
2294 if ((AdrResult.Num == ModData) || ((AdrResult.Num == ModImm) && (Lo(AdrResult.Vals[0]) >= 1) && (Lo(AdrResult.Vals[0]) <= 8)))
2295 {
2296 CodeLen = 2;
2297 WAsmCode[0] |= (AdrResult.Num == ModData) ? 0x20 | (AdrResult.Mode << 9) : ((AdrResult.Vals[0] & 7) << 9);
2298 }
2299 else
2300 WrStrErrorPos(ErrNum_InvShiftArg, &ArgStr[1]);
2301 }
2302 }
2303 else if (AdrResult.Num != ModNone)
2304 {
2305 if (pCurrCPUProps->Family == eColdfire) WrError(ErrNum_InvAddrMode);
2306 else
2307 {
2308 if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
2309 else
2310 {
2311 WAsmCode[0] = 0xe0c0 | AdrResult.Mode | (Op << 9) | (LFlag << 8);
2312 CopyAdrVals(WAsmCode + 1, &AdrResult);
2313 if (2 == ArgCnt)
2314 {
2315 HVal8 = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].Str == '#'), Int8, &ValOK);
2316 }
2317 else
2318 {
2319 HVal8 = 1;
2320 ValOK = True;
2321 }
2322 if ((ValOK) && (HVal8 == 1))
2323 CodeLen = 2 + AdrResult.Cnt;
2324 else
2325 WrStrErrorPos(ErrNum_Only1, &ArgStr[1]);
2326 }
2327 }
2328 }
2329 }
2330 }
2331
2332 /* ADDQ=0 SUBQ=1 */
2333
DecodeADDQSUBQ(Word Index)2334 static void DecodeADDQSUBQ(Word Index)
2335 {
2336 Byte HVal8;
2337 Boolean ValOK;
2338 tSymbolFlags Flags;
2339 tAdrResult AdrResult;
2340
2341 if (!CheckColdSize())
2342 return;
2343
2344 if (!ChkArgCnt(2, 2))
2345 return;
2346
2347 if (!DecodeAdr(&ArgStr[2], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
2348 return;
2349
2350 if ((ModAdr == AdrResult.Num) && (eSymbolSize8Bit == OpSize))
2351 {
2352 WrError(ErrNum_InvOpSize);
2353 return;
2354 }
2355
2356 WAsmCode[0] = 0x5000 | AdrResult.Mode | (OpSize << 6) | (Index << 8);
2357 CopyAdrVals(WAsmCode + 1, &AdrResult);
2358 HVal8 = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], !!(*ArgStr[1].Str == '#'), UInt4, &ValOK, &Flags);
2359 if (mFirstPassUnknown(Flags)) HVal8 = 1;
2360 if (!ValOK && ((HVal8 < 1) | (HVal8 > 8)))
2361 {
2362 WrError(ErrNum_Range18);
2363 return;
2364 }
2365
2366 CodeLen = 2 + AdrResult.Cnt;
2367 WAsmCode[0] |= (((Word) HVal8 & 7) << 9);
2368 }
2369
2370 /* 0=SUBX 1=ADDX */
2371
DecodeADDXSUBX(Word Index)2372 static void DecodeADDXSUBX(Word Index)
2373 {
2374 if (CheckColdSize())
2375 {
2376 if (ChkArgCnt(2, 2))
2377 {
2378 tAdrResult AdrResult;
2379
2380 if (DecodeAdr(&ArgStr[1], MModData | MModPre, &AdrResult))
2381 {
2382 WAsmCode[0] = 0x9100 | (OpSize << 6) | (AdrResult.Mode & 7) | (Index << 14);
2383 if (AdrResult.Num == ModPre)
2384 WAsmCode[0] |= 8;
2385 if (DecodeAdr(&ArgStr[2], 1 << (AdrResult.Num - 1), &AdrResult))
2386 {
2387 CodeLen = 2;
2388 WAsmCode[0] |= (AdrResult.Mode & 7) << 9;
2389 }
2390 }
2391 }
2392 }
2393 }
2394
DecodeCMPM(Word Index)2395 static void DecodeCMPM(Word Index)
2396 {
2397 UNUSED(Index);
2398
2399 if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
2400 else if (ChkArgCnt(2, 2)
2401 && CheckNoFamily(1 << eColdfire))
2402 {
2403 tAdrResult AdrResult;
2404
2405 if (DecodeAdr(&ArgStr[1], MModPost, &AdrResult) == ModPost)
2406 {
2407 WAsmCode[0] = 0xb108 | (OpSize << 6) | (AdrResult.Mode & 7);
2408 if (DecodeAdr(&ArgStr[2], MModPost, &AdrResult) == ModPost)
2409 {
2410 WAsmCode[0] |= (AdrResult.Mode & 7) << 9;
2411 CodeLen = 2;
2412 }
2413 }
2414 }
2415 }
2416
2417 /* 0=SUB 1=CMP 2=ADD +4=..I +8=..A */
2418
DecodeADDSUBCMP(Word Index)2419 static void DecodeADDSUBCMP(Word Index)
2420 {
2421 Word Op = Index & 3, Reg;
2422 unsigned Variant = Index & VariantMask;
2423 Word DestMask, SrcMask;
2424 Boolean OpSizeOK;
2425
2426 if (I_Variant == Variant)
2427 SrcMask = MModImm;
2428 else
2429 SrcMask = MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm;
2430
2431 if (A_Variant == Variant)
2432 DestMask = MModAdr;
2433 else
2434 {
2435 DestMask = MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs;
2436
2437 /* Since CMP only reads operands, PC-relative addressing is also
2438 allowed for the second operand on 68020++ */
2439
2440 if ((as_toupper(*OpPart.Str) == 'C')
2441 && (pCurrCPUProps->Family > e68KGen1b))
2442 DestMask |= MModPC | MModPCIdx;
2443 }
2444
2445 /* ColdFire ISA B ff. allows 8/16 bit operand size of CMP: */
2446
2447 if (OpSize > eSymbolSize32Bit)
2448 OpSizeOK = False;
2449 else if (OpSize == eSymbolSize32Bit)
2450 OpSizeOK = True;
2451 else
2452 OpSizeOK = (pCurrCPUProps->Family != eColdfire)
2453 || ((pCurrCPUProps->CfISA >= eCfISA_B) && (Op == 1));
2454
2455 if (!OpSizeOK) WrError(ErrNum_InvOpSize);
2456 else
2457 {
2458 if (ChkArgCnt(2, 2))
2459 {
2460 tAdrResult AdrResult;
2461
2462 switch (DecodeAdr(&ArgStr[2], DestMask, &AdrResult))
2463 {
2464 case ModAdr: /* ADDA/SUBA/CMPA ? */
2465 if (OpSize == eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
2466 else
2467 {
2468 WAsmCode[0] = 0x90c0 | ((AdrResult.Mode & 7) << 9) | (Op << 13);
2469 if (OpSize == eSymbolSize32Bit) WAsmCode[0] |= 0x100;
2470 if (DecodeAdr(&ArgStr[1], SrcMask, &AdrResult))
2471 {
2472 WAsmCode[0] |= AdrResult.Mode;
2473 CodeLen = 2 + AdrResult.Cnt;
2474 CopyAdrVals(WAsmCode + 1, &AdrResult);
2475 }
2476 }
2477 break;
2478
2479 case ModData: /* ADD/SUB/CMP <ea>,Dn ? */
2480 WAsmCode[0] = 0x9000 | (OpSize << 6) | ((Reg = AdrResult.Mode) << 9) | (Op << 13);
2481 DecodeAdr(&ArgStr[1], SrcMask, &AdrResult);
2482
2483 /* CMP.B An,Dn allowed for Coldfire? */
2484
2485 if ((AdrResult.Num == ModAdr) && (OpSize == eSymbolSize8Bit) && (pCurrCPUProps->Family != eColdfire)) WrError(ErrNum_InvOpSize);
2486 if (AdrResult.Num != ModNone)
2487 {
2488 if ((AdrResult.Num == ModImm) && (Variant == I_Variant))
2489 {
2490 if (Op == 1) Op = 8;
2491 WAsmCode[0] = 0x400 | (OpSize << 6) | (Op << 8) | Reg;
2492 }
2493 else
2494 WAsmCode[0] |= AdrResult.Mode;
2495 CopyAdrVals(WAsmCode + 1, &AdrResult);
2496 CodeLen = 2 + AdrResult.Cnt;
2497 }
2498 break;
2499
2500 case ModNone:
2501 break;
2502
2503 default: /* CMP/ADD/SUB <ea>, Dn */
2504 if (DecodeAdr(&ArgStr[1], MModData | MModImm, &AdrResult) == ModImm) /* ADDI/SUBI/CMPI ? */
2505 {
2506 /* we have to set the PC offset before we decode the destination operand. Luckily,
2507 this is only needed afterwards for an immediate source operand, so we know the
2508 # of words ahead: */
2509
2510 if (*ArgStr[1].Str == '#')
2511 RelPos += (OpSize == eSymbolSize32Bit) ? 4 : 2;
2512
2513 if (Op == 1) Op = 8;
2514 WAsmCode[0] = 0x400 | (OpSize << 6) | (Op << 8);
2515 CodeLen = 2 + AdrResult.Cnt;
2516 CopyAdrVals(WAsmCode + 1, &AdrResult);
2517 if (DecodeAdr(&ArgStr[2], (pCurrCPUProps->Family == eColdfire) ? (Word)MModData : DestMask, &AdrResult))
2518 {
2519 WAsmCode[0] |= AdrResult.Mode;
2520 CopyAdrVals(WAsmCode + (CodeLen >> 1), &AdrResult);
2521 CodeLen += AdrResult.Cnt;
2522 }
2523 else
2524 CodeLen = 0;
2525 }
2526 else if (AdrResult.Num != ModNone) /* ADD Dn,<EA> ? */
2527 {
2528 if (Op == 1) WrError(ErrNum_InvCmpMode);
2529 else
2530 {
2531 WAsmCode[0] = 0x9100 | (OpSize << 6) | (AdrResult.Mode << 9) | (Op << 13);
2532 if (DecodeAdr(&ArgStr[2], DestMask, &AdrResult))
2533 {
2534 CodeLen = 2 + AdrResult.Cnt; CopyAdrVals(WAsmCode + 1, &AdrResult);
2535 WAsmCode[0] |= AdrResult.Mode;
2536 }
2537 }
2538 }
2539 }
2540 }
2541 }
2542 }
2543
2544 /* 0=OR 1=AND +4=..I */
2545
DecodeANDOR(Word Index)2546 static void DecodeANDOR(Word Index)
2547 {
2548 Word Op = Index & 3, Reg;
2549 char Variant = Index & VariantMask;
2550 tAdrResult AdrResult;
2551
2552 if (!ChkArgCnt(2, 2));
2553 else if (CheckColdSize())
2554 {
2555 if ((as_strcasecmp(ArgStr[2].Str, "CCR")) && (as_strcasecmp(ArgStr[2].Str, "SR")))
2556 DecodeAdr(&ArgStr[2], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult);
2557 if (!as_strcasecmp(ArgStr[2].Str, "CCR")) /* AND #...,CCR */
2558 {
2559 if (*AttrPart.Str && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
2560 else if (!(pCurrCPUProps->SuppFlags & eFlagLogCCR)) WrError(ErrNum_InstructionNotSupported);
2561 {
2562 WAsmCode[0] = 0x003c | (Op << 9);
2563 OpSize = eSymbolSize8Bit;
2564 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
2565 {
2566 CodeLen = 4;
2567 WAsmCode[1] = AdrResult.Vals[0];
2568 }
2569 }
2570 }
2571 else if (!as_strcasecmp(ArgStr[2].Str, "SR")) /* AND #...,SR */
2572 {
2573 if (*AttrPart.Str && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
2574 else if (CheckNoFamily(1 << eColdfire))
2575 {
2576 WAsmCode[0] = 0x007c | (Op << 9);
2577 OpSize = eSymbolSize16Bit;
2578 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
2579 {
2580 CodeLen = 4;
2581 WAsmCode[1] = AdrResult.Vals[0];
2582 CheckSup();
2583 }
2584 }
2585 }
2586 else if (AdrResult.Num == ModData) /* AND <EA>,Dn */
2587 {
2588 WAsmCode[0] = 0x8000 | (OpSize << 6) | ((Reg = AdrResult.Mode) << 9) | (Op << 14);
2589 if (DecodeAdr(&ArgStr[1], ((Variant == I_Variant) ? 0 : MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs) | MModImm, &AdrResult))
2590 {
2591 if ((AdrResult.Num == ModImm) && (Variant == I_Variant))
2592 WAsmCode[0] = (OpSize << 6) | (Op << 9) | Reg;
2593 else
2594 WAsmCode[0] |= AdrResult.Mode;
2595 CodeLen = 2 + AdrResult.Cnt;
2596 CopyAdrVals(WAsmCode + 1, &AdrResult);
2597 }
2598 }
2599 else if (AdrResult.Num != ModNone) /* AND ...,<EA> */
2600 {
2601 if (DecodeAdr(&ArgStr[1], MModData | MModImm, &AdrResult) == ModImm) /* AND #..,<EA> */
2602 {
2603 WAsmCode[0] = (OpSize << 6) | (Op << 9);
2604 CodeLen = 2 + AdrResult.Cnt;
2605 CopyAdrVals(WAsmCode + 1, &AdrResult);
2606 if (DecodeAdr(&ArgStr[2], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
2607 {
2608 WAsmCode[0] |= AdrResult.Mode;
2609 CopyAdrVals(WAsmCode + (CodeLen >> 1), &AdrResult);
2610 CodeLen += AdrResult.Cnt;
2611 }
2612 else
2613 CodeLen = 0;
2614 }
2615 else if (AdrResult.Num != ModNone) /* AND Dn,<EA> ? */
2616 {
2617 WAsmCode[0] = 0x8100 | (OpSize << 6) | (AdrResult.Mode << 9) | (Op << 14);
2618 if (DecodeAdr(&ArgStr[2], MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
2619 {
2620 CodeLen = 2 + AdrResult.Cnt;
2621 CopyAdrVals(WAsmCode + 1, &AdrResult);
2622 WAsmCode[0] |= AdrResult.Mode;
2623 }
2624 }
2625 }
2626 }
2627 }
2628
2629 /* 0=EOR 4=EORI */
2630
DecodeEOR(Word Index)2631 static void DecodeEOR(Word Index)
2632 {
2633 unsigned Variant = Index | VariantMask;
2634 tAdrResult AdrResult;
2635
2636 if (!ChkArgCnt(2, 2));
2637 else if (!as_strcasecmp(ArgStr[2].Str, "CCR"))
2638 {
2639 if (*AttrPart.Str && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
2640 else if (CheckNoFamily(1 << eColdfire))
2641 {
2642 WAsmCode[0] = 0xa3c;
2643 OpSize = eSymbolSize8Bit;
2644 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
2645 {
2646 CodeLen = 4;
2647 WAsmCode[1] = AdrResult.Vals[0];
2648 }
2649 }
2650 }
2651 else if (!as_strcasecmp(ArgStr[2].Str, "SR"))
2652 {
2653 if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
2654 else if (CheckNoFamily(1 << eColdfire))
2655 {
2656 WAsmCode[0] = 0xa7c;
2657 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
2658 {
2659 CodeLen = 4;
2660 WAsmCode[1] = AdrResult.Vals[0];
2661 CheckSup();
2662 }
2663 }
2664 }
2665 else if (CheckColdSize())
2666 {
2667 if (DecodeAdr(&ArgStr[1], ((Variant == I_Variant) ? 0 : MModData) | MModImm, &AdrResult) == ModData)
2668 {
2669 WAsmCode[0] = 0xb100 | (AdrResult.Mode << 9) | (OpSize << 6);
2670 if (DecodeAdr(&ArgStr[2], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
2671 {
2672 CodeLen = 2 + AdrResult.Cnt;
2673 CopyAdrVals(WAsmCode + 1, &AdrResult);
2674 WAsmCode[0] |= AdrResult.Mode;
2675 }
2676 }
2677 else if (AdrResult.Num == ModImm)
2678 {
2679 WAsmCode[0] = 0x0a00 | (OpSize << 6);
2680 CopyAdrVals(WAsmCode + 1, &AdrResult);
2681 CodeLen = 2 + AdrResult.Cnt;
2682 if (DecodeAdr(&ArgStr[2], MModData | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
2683 {
2684 CopyAdrVals(WAsmCode + (CodeLen >> 1), &AdrResult);
2685 CodeLen += AdrResult.Cnt;
2686 WAsmCode[0] |= AdrResult.Mode;
2687 }
2688 else CodeLen = 0;
2689 }
2690 }
2691 }
2692
DecodePEA(Word Index)2693 static void DecodePEA(Word Index)
2694 {
2695 UNUSED(Index);
2696
2697 if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_UseLessAttr);
2698 else if (ChkArgCnt(1, 1))
2699 {
2700 tAdrResult AdrResult;
2701
2702 OpSize = eSymbolSize8Bit;
2703 if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
2704 {
2705 CodeLen = 2 + AdrResult.Cnt;
2706 WAsmCode[0] = 0x4840 | AdrResult.Mode;
2707 CopyAdrVals(WAsmCode + 1, &AdrResult);
2708 }
2709 }
2710 }
2711
2712 /* 0=CLR 1=TST */
2713
DecodeCLRTST(Word Index)2714 static void DecodeCLRTST(Word Index)
2715 {
2716 if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
2717 else if (ChkArgCnt(1, 1))
2718 {
2719 Word w1 = MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs;
2720 tAdrResult AdrResult;
2721
2722 switch (pCurrCPUProps->Family)
2723 {
2724 case eCPU32:
2725 case e68KGen2:
2726 case e68KGen3:
2727 w1 |= MModPC | MModPCIdx | MModImm;
2728 if (OpSize != eSymbolSize8Bit)
2729 w1 |= MModAdr;
2730 default:
2731 break;
2732 }
2733 if (DecodeAdr(&ArgStr[1], w1, &AdrResult))
2734 {
2735 CodeLen = 2 + AdrResult.Cnt;
2736 WAsmCode[0] = 0x4200 | (Index << 11) | (OpSize << 6) | AdrResult.Mode;
2737 CopyAdrVals(WAsmCode + 1, &AdrResult);
2738 }
2739 }
2740 }
2741
2742 /* 0=JSR 1=JMP */
2743
DecodeJSRJMP(Word Index)2744 static void DecodeJSRJMP(Word Index)
2745 {
2746 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
2747 else if (ChkArgCnt(1, 1))
2748 {
2749 tAdrResult AdrResult;
2750
2751 if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
2752 {
2753 CodeLen = 2 + AdrResult.Cnt;
2754 WAsmCode[0] = 0x4e80 | (Index << 6) | AdrResult.Mode;
2755 CopyAdrVals(WAsmCode + 1, &AdrResult);
2756 }
2757 }
2758 }
2759
2760 /* 0=TAS 1=NBCD */
2761
DecodeNBCDTAS(Word Index)2762 static void DecodeNBCDTAS(Word Index)
2763 {
2764 Boolean Allowed;
2765
2766 /* TAS is allowed on ColdFire ISA B ff. ... */
2767
2768 if (pCurrCPUProps->Family != eColdfire)
2769 Allowed = True;
2770 else
2771 Allowed = Index ? False : (pCurrCPUProps->CfISA >= eCfISA_B);
2772
2773 if (*AttrPart.Str && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
2774 else if (!Allowed) WrError(ErrNum_InstructionNotSupported);
2775 else if (ChkArgCnt(1, 1))
2776 {
2777 tAdrResult AdrResult;
2778
2779 OpSize = eSymbolSize8Bit;
2780
2781 /* ...but not on data register: */
2782
2783 if (DecodeAdr(&ArgStr[1], ((pCurrCPUProps->Family == eColdfire) ? 0 : MModData) | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
2784 {
2785 CodeLen = 2 + AdrResult.Cnt;
2786 WAsmCode[0] = (Index == 1) ? 0x4800 : 0x4ac0;
2787 WAsmCode[0] |= AdrResult.Mode;
2788 CopyAdrVals(WAsmCode + 1, &AdrResult);
2789 }
2790 }
2791 }
2792
2793 /* 0=NEGX 2=NEG 3=NOT */
2794
DecodeNEGNOT(Word Index)2795 static void DecodeNEGNOT(Word Index)
2796 {
2797 if (ChkArgCnt(1, 1)
2798 && CheckColdSize())
2799 {
2800 tAdrResult AdrResult;
2801
2802 if (DecodeAdr(&ArgStr[1], (pCurrCPUProps->Family == eColdfire) ? MModData : (MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
2803 {
2804 CodeLen = 2 + AdrResult.Cnt;
2805 WAsmCode[0] = 0x4000 | (Index << 9) | (OpSize << 6) | AdrResult.Mode;
2806 CopyAdrVals(WAsmCode + 1, &AdrResult);
2807 }
2808 }
2809 }
2810
DecodeSWAP(Word Index)2811 static void DecodeSWAP(Word Index)
2812 {
2813 UNUSED(Index);
2814
2815 if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
2816 else if (ChkArgCnt(1, 1))
2817 {
2818 tAdrResult AdrResult;
2819
2820 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
2821 {
2822 CodeLen = 2;
2823 WAsmCode[0] = 0x4840 | AdrResult.Mode;
2824 }
2825 }
2826 }
2827
DecodeUNLK(Word Index)2828 static void DecodeUNLK(Word Index)
2829 {
2830 UNUSED(Index);
2831
2832 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
2833 else if (ChkArgCnt(1, 1))
2834 {
2835 tAdrResult AdrResult;
2836
2837 if (DecodeAdr(&ArgStr[1], MModAdr, &AdrResult))
2838 {
2839 CodeLen = 2;
2840 WAsmCode[0] = 0x4e58 | AdrResult.Mode;
2841 }
2842 }
2843 }
2844
DecodeEXT(Word Index)2845 static void DecodeEXT(Word Index)
2846 {
2847 UNUSED(Index);
2848
2849 if (!ChkArgCnt(1, 1));
2850 else if ((OpSize == eSymbolSize8Bit) || (OpSize > eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
2851 else
2852 {
2853 tAdrResult AdrResult;
2854
2855 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult) == ModData)
2856 {
2857 WAsmCode[0] = 0x4880 | AdrResult.Mode | (((Word)OpSize - 1) << 6);
2858 CodeLen = 2;
2859 }
2860 }
2861 }
2862
DecodeWDDATA(Word Index)2863 static void DecodeWDDATA(Word Index)
2864 {
2865 UNUSED(Index);
2866
2867 if (!ChkArgCnt(1, 1));
2868 else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
2869 else if (CheckFamily(1 << eColdfire))
2870 {
2871 tAdrResult AdrResult;
2872
2873 if (DecodeAdr(&ArgStr[1], MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
2874 {
2875 WAsmCode[0] = 0xf400 + (OpSize << 6) + AdrResult.Mode;
2876 CopyAdrVals(WAsmCode + 1, &AdrResult);
2877 CodeLen = 2 + AdrResult.Cnt;
2878 CheckSup();
2879 }
2880 }
2881 }
2882
DecodeWDEBUG(Word Index)2883 static void DecodeWDEBUG(Word Index)
2884 {
2885 UNUSED(Index);
2886
2887 if (ChkArgCnt(1, 1)
2888 && CheckFamily(1 << eColdfire)
2889 && CheckColdSize())
2890 {
2891 tAdrResult AdrResult;
2892
2893 if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI, &AdrResult))
2894 {
2895 WAsmCode[0] = 0xfbc0 + AdrResult.Mode;
2896 WAsmCode[1] = 0x0003;
2897 CopyAdrVals(WAsmCode + 2, &AdrResult);
2898 CodeLen = 4 + AdrResult.Cnt;
2899 CheckSup();
2900 }
2901 }
2902 }
2903
DecodeFixed(Word Index)2904 static void DecodeFixed(Word Index)
2905 {
2906 FixedOrder *FixedZ = FixedOrders + Index;
2907
2908 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2909 else if (ChkArgCnt(0, 0)
2910 && CheckFamily(FixedZ->FamilyMask))
2911 {
2912 CodeLen = 2;
2913 WAsmCode[0] = FixedZ->Code;
2914 if (FixedZ->MustSup)
2915 CheckSup();
2916 }
2917 }
2918
DecodeMOVEM(Word Index)2919 static void DecodeMOVEM(Word Index)
2920 {
2921 int z;
2922 UNUSED(Index);
2923
2924 if (!ChkArgCnt(2, 2));
2925 else if ((OpSize < eSymbolSize16Bit) || (OpSize > eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
2926 else if ((pCurrCPUProps->Family == eColdfire) && (OpSize == 1)) WrError(ErrNum_InvOpSize);
2927 else
2928 {
2929 tAdrResult AdrResult;
2930
2931 RelPos = 4;
2932 if (DecodeRegList(&ArgStr[2], WAsmCode + 1))
2933 {
2934 if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModPost | MModAIX | MModPC | MModPCIdx | MModAbs), &AdrResult))
2935 {
2936 WAsmCode[0] = 0x4c80 | AdrResult.Mode | ((OpSize - 1) << 6);
2937 CodeLen = 4 + AdrResult.Cnt; CopyAdrVals(WAsmCode + 2, &AdrResult);
2938 }
2939 }
2940 else if (DecodeRegList(&ArgStr[1], WAsmCode + 1))
2941 {
2942 if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModPre | MModAIX | MModAbs), &AdrResult))
2943 {
2944 WAsmCode[0] = 0x4880 | AdrResult.Mode | ((OpSize - 1) << 6);
2945 CodeLen = 4 + AdrResult.Cnt; CopyAdrVals(WAsmCode + 2, &AdrResult);
2946 if (AdrResult.Num == ModPre)
2947 {
2948 Word Tmp = WAsmCode[1];
2949
2950 WAsmCode[1] = 0;
2951 for (z = 0; z < 16; z++)
2952 {
2953 WAsmCode[1] = (WAsmCode[1] << 1) + (Tmp & 1);
2954 Tmp >>= 1;
2955 }
2956 }
2957 }
2958 }
2959 else WrError(ErrNum_InvRegList);
2960 }
2961 }
2962
DecodeMOVEQ(Word Index)2963 static void DecodeMOVEQ(Word Index)
2964 {
2965 UNUSED(Index);
2966
2967 if (!ChkArgCnt(2, 2));
2968 else if ((*AttrPart.Str) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
2969 else if (*ArgStr[1].Str != '#') WrStrErrorPos(ErrNum_OnlyImmAddr, &ArgStr[1]);
2970 else
2971 {
2972 tAdrResult AdrResult;
2973
2974 if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
2975 {
2976 Boolean OK;
2977 tSymbolFlags Flags;
2978 LongWord Value;
2979
2980 WAsmCode[0] = 0x7000 | (AdrResult.Mode << 9);
2981 Value = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], 1, Int32, &OK, &Flags);
2982 if (mFirstPassUnknown(Flags))
2983 Value &= 0x7f;
2984 if ((Value > 0x7f) && (Value < 0xffffff80ul))
2985 WrStrErrorPos((Value & 0x80000000ul) ? ErrNum_UnderRange : ErrNum_OverRange, &ArgStr[1]);
2986 else
2987 {
2988 CodeLen = 2;
2989 WAsmCode[0] |= Value & 0xff;
2990 }
2991 }
2992 }
2993 }
2994
DecodeSTOP(Word Index)2995 static void DecodeSTOP(Word Index)
2996 {
2997 Word HVal;
2998 Boolean ValOK;
2999 UNUSED(Index);
3000
3001 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
3002 else if (!ChkArgCnt(1, 1));
3003 else if (*ArgStr[1].Str != '#') WrError(ErrNum_OnlyImmAddr);
3004 else
3005 {
3006 HVal = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int16, &ValOK);
3007 if (ValOK)
3008 {
3009 CodeLen = 4;
3010 WAsmCode[0] = 0x4e72;
3011 WAsmCode[1] = HVal;
3012 CheckSup();
3013 }
3014 }
3015 }
3016
DecodeLPSTOP(Word Index)3017 static void DecodeLPSTOP(Word Index)
3018 {
3019 Word HVal;
3020 Boolean ValOK;
3021 UNUSED(Index);
3022
3023 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
3024 else if (!ChkArgCnt(1, 1));
3025 else if (!CheckFamily(1 << eCPU32));
3026 else if (*ArgStr[1].Str != '#') WrError(ErrNum_OnlyImmAddr);
3027 else
3028 {
3029 HVal = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int16, &ValOK);
3030 if (ValOK)
3031 {
3032 CodeLen = 6;
3033 WAsmCode[0] = 0xf800;
3034 WAsmCode[1] = 0x01c0;
3035 WAsmCode[2] = HVal;
3036 CheckSup();
3037 }
3038 }
3039 }
3040
DecodeTRAP(Word Index)3041 static void DecodeTRAP(Word Index)
3042 {
3043 Byte HVal8;
3044 Boolean ValOK;
3045 UNUSED(Index);
3046
3047 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
3048 else if (!ChkArgCnt(1, 1));
3049 else if (*ArgStr[1].Str != '#') WrError(ErrNum_OnlyImmAddr);
3050 else
3051 {
3052 HVal8 = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int4, &ValOK);
3053 if (ValOK)
3054 {
3055 CodeLen = 2;
3056 WAsmCode[0] = 0x4e40 + (HVal8 & 15);
3057 }
3058 }
3059 }
3060
DecodeBKPT(Word Index)3061 static void DecodeBKPT(Word Index)
3062 {
3063 Byte HVal8;
3064 Boolean ValOK;
3065 UNUSED(Index);
3066
3067 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
3068 else if (!ChkArgCnt(1, 1));
3069 else if (!CheckNoFamily((1 << e68KGen1a) | (1 << eColdfire)));
3070 else if (*ArgStr[1].Str != '#') WrError(ErrNum_OnlyImmAddr);
3071 else
3072 {
3073 HVal8 = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt3, &ValOK);
3074 if (ValOK)
3075 {
3076 CodeLen = 2;
3077 WAsmCode[0] = 0x4848 + (HVal8 & 7);
3078 }
3079 }
3080 UNUSED(Index);
3081 }
3082
DecodeRTD(Word Index)3083 static void DecodeRTD(Word Index)
3084 {
3085 Word HVal;
3086 Boolean ValOK;
3087 UNUSED(Index);
3088
3089 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
3090 else if (!ChkArgCnt(1, 1));
3091 else if (!CheckNoFamily((1 << e68KGen1a) | (1 << eColdfire)));
3092 else if (*ArgStr[1].Str != '#') WrError(ErrNum_OnlyImmAddr);
3093 else
3094 {
3095 HVal = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int16, &ValOK);
3096 if (ValOK)
3097 {
3098 CodeLen = 4;
3099 WAsmCode[0] = 0x4e74;
3100 WAsmCode[1] = HVal;
3101 }
3102 }
3103 }
3104
DecodeEXG(Word Index)3105 static void DecodeEXG(Word Index)
3106 {
3107 Word HReg;
3108 UNUSED(Index);
3109
3110 if ((*AttrPart.Str) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
3111 else if (ChkArgCnt(2, 2)
3112 && CheckNoFamily(1 << eColdfire))
3113 {
3114 tAdrResult AdrResult;
3115
3116 if (DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult) == ModData)
3117 {
3118 WAsmCode[0] = 0xc100 | (AdrResult.Mode << 9);
3119 if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult) == ModData)
3120 {
3121 WAsmCode[0] |= 0x40 | AdrResult.Mode;
3122 CodeLen = 2;
3123 }
3124 else if (AdrResult.Num == ModAdr)
3125 {
3126 WAsmCode[0] |= 0x88 | (AdrResult.Mode & 7);
3127 CodeLen = 2;
3128 }
3129 }
3130 else if (AdrResult.Num == ModAdr)
3131 {
3132 WAsmCode[0] = 0xc100;
3133 HReg = AdrResult.Mode & 7;
3134 if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult) == ModData)
3135 {
3136 WAsmCode[0] |= 0x88 | (AdrResult.Mode << 9) | HReg;
3137 CodeLen = 2;
3138 }
3139 else
3140 {
3141 WAsmCode[0] |= 0x48 | (HReg << 9) | (AdrResult.Mode & 7);
3142 CodeLen = 2;
3143 }
3144 }
3145 }
3146 }
3147
DecodeMOVE16(Word Index)3148 static void DecodeMOVE16(Word Index)
3149 {
3150 Word z, z2, w1, w2;
3151 UNUSED(Index);
3152
3153 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
3154 else if (ChkArgCnt(2, 2)
3155 && CheckFamily(1 << e68KGen3))
3156 {
3157 tAdrResult AdrResult;
3158
3159 if (DecodeAdr(&ArgStr[1], MModPost | MModAdrI | MModAbs, &AdrResult))
3160 {
3161 w1 = AdrResult.Num;
3162 z = AdrResult.Mode & 7;
3163 if ((w1 == ModAbs) && (AdrResult.Cnt == 2))
3164 {
3165 AdrResult.Vals[1] = AdrResult.Vals[0];
3166 AdrResult.Vals[0] = 0 - (AdrResult.Vals[1] >> 15);
3167 }
3168 if (DecodeAdr(&ArgStr[2], MModPost | MModAdrI | MModAbs, &AdrResult))
3169 {
3170 w2 = AdrResult.Num;
3171 z2 = AdrResult.Mode & 7;
3172 if ((w2 == ModAbs) && (AdrResult.Cnt == 2))
3173 {
3174 AdrResult.Vals[1] = AdrResult.Vals[0];
3175 AdrResult.Vals[0] = 0 - (AdrResult.Vals[1] >> 15);
3176 }
3177 if ((w1 == ModPost) && (w2 == ModPost))
3178 {
3179 WAsmCode[0] = 0xf620 + z;
3180 WAsmCode[1] = 0x8000 + (z2 << 12);
3181 CodeLen = 4;
3182 }
3183 else
3184 {
3185 WAsmCode[1] = AdrResult.Vals[0];
3186 WAsmCode[2] = AdrResult.Vals[1];
3187 CodeLen = 6;
3188 if ((w1 == ModPost) && (w2 == ModAbs))
3189 WAsmCode[0] = 0xf600 + z;
3190 else if ((w1 == ModAbs) && (w2 == ModPost))
3191 WAsmCode[0] = 0xf608 + z2;
3192 else if ((w1 == ModAdrI) && (w2 == ModAbs))
3193 WAsmCode[0] = 0xf610 + z;
3194 else if ((w1 == ModAbs) && (w2 == ModAdrI))
3195 WAsmCode[0] = 0xf618 + z2;
3196 else
3197 {
3198 WrError(ErrNum_InvAddrMode);
3199 CodeLen = 0;
3200 }
3201 }
3202 }
3203 }
3204 }
3205 }
3206
DecodeCacheAll(Word Index)3207 static void DecodeCacheAll(Word Index)
3208 {
3209 Word w1;
3210
3211 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
3212 else if (!ChkArgCnt(1, 1));
3213 else if (!CheckFamily(1 << e68KGen3));
3214 else if (!CodeCache(ArgStr[1].Str, &w1)) WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
3215 else
3216 {
3217 WAsmCode[0] = 0xf418 + (w1 << 6) + (Index << 5);
3218 CodeLen = 2;
3219 CheckSup();
3220 }
3221 }
3222
DecodeCache(Word Index)3223 static void DecodeCache(Word Index)
3224 {
3225 Word w1;
3226
3227 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
3228 else if (!ChkArgCnt(2, 2));
3229 else if (!CheckFamily(1 << e68KGen3));
3230 else if (!CodeCache(ArgStr[1].Str, &w1)) WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
3231 else
3232 {
3233 tAdrResult AdrResult;
3234
3235 if (DecodeAdr(&ArgStr[2], MModAdrI, &AdrResult))
3236 {
3237 WAsmCode[0] = 0xf400 + (w1 << 6) + (Index << 3) + (AdrResult.Mode & 7);
3238 CodeLen = 2;
3239 CheckSup();
3240 }
3241 }
3242 }
3243
DecodeMUL_DIV(Word Code)3244 static void DecodeMUL_DIV(Word Code)
3245 {
3246 tAdrResult AdrResult;
3247
3248 if (!ChkArgCnt(2, 2));
3249 else if ((*OpPart.Str == 'D') && !CheckNoFamily(1 << eColdfire));
3250 else if (OpSize == eSymbolSize16Bit)
3251 {
3252 if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
3253 {
3254 WAsmCode[0] = 0x80c0 | (AdrResult.Mode << 9) | (Code & 0x0100);
3255 if (!(Code & 1))
3256 WAsmCode[0] |= 0x4000;
3257 if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
3258 {
3259 WAsmCode[0] |= AdrResult.Mode;
3260 CodeLen = 2 + AdrResult.Cnt; CopyAdrVals(WAsmCode + 1, &AdrResult);
3261 }
3262 }
3263 }
3264 else if (OpSize == eSymbolSize32Bit)
3265 {
3266 Word w1, w2;
3267 Boolean OK;
3268
3269 if (strchr(ArgStr[2].Str, ':'))
3270 OK = DecodeRegPair(&ArgStr[2], &w1, &w2);
3271 else
3272 {
3273 OK = DecodeReg(&ArgStr[2], &w1, True) && (w1 < 8);
3274 w2 = w1;
3275 }
3276 if (!OK) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[2]);
3277 else
3278 {
3279 WAsmCode[1] = w1 | (w2 << 12) | ((Code & 0x0100) << 3);
3280 RelPos = 4;
3281 if (w1 != w2)
3282 WAsmCode[1] |= 0x400;
3283 if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
3284 {
3285 WAsmCode[0] = 0x4c00 + AdrResult.Mode + (Lo(Code) << 6);
3286 CopyAdrVals(WAsmCode + 2, &AdrResult);
3287 CodeLen = 4 + AdrResult.Cnt;
3288 CheckFamily((1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32) | ((w1 == w2) ? (1 << eColdfire) : 0));
3289 }
3290 }
3291 }
3292 else
3293 WrError(ErrNum_InvOpSize);
3294 }
3295
DecodeDIVL(Word Index)3296 static void DecodeDIVL(Word Index)
3297 {
3298 Word w1, w2;
3299
3300 if (!*AttrPart.Str)
3301 OpSize = eSymbolSize32Bit;
3302 if (!ChkArgCnt(2, 2));
3303 else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32)));
3304 else if (OpSize != eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
3305 else if (!DecodeRegPair(&ArgStr[2], &w1, &w2)) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[2]);
3306 else
3307 {
3308 tAdrResult AdrResult;
3309
3310 RelPos = 4;
3311 WAsmCode[1] = w1 | (w2 << 12) | (Index << 11);
3312 if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
3313 {
3314 WAsmCode[0] = 0x4c40 + AdrResult.Mode;
3315 CopyAdrVals(WAsmCode + 2, &AdrResult);
3316 CodeLen = 4 + AdrResult.Cnt;
3317 }
3318 }
3319 }
3320
DecodeASBCD(Word Index)3321 static void DecodeASBCD(Word Index)
3322 {
3323 if ((OpSize != eSymbolSize8Bit) && *AttrPart.Str) WrError(ErrNum_InvOpSize);
3324 else if (ChkArgCnt(2, 2)
3325 && CheckNoFamily(1 << eColdfire))
3326 {
3327 tAdrResult AdrResult;
3328
3329 OpSize = eSymbolSize8Bit;
3330 if (DecodeAdr(&ArgStr[1], MModData | MModPre, &AdrResult))
3331 {
3332 WAsmCode[0] = 0x8100 | (AdrResult.Mode & 7) | (Index << 14) | ((AdrResult.Num == ModPre) ? 8 : 0);
3333 if (DecodeAdr(&ArgStr[2], 1 << (AdrResult.Num - 1), &AdrResult))
3334 {
3335 CodeLen = 2;
3336 WAsmCode[0] |= (AdrResult.Mode & 7) << 9;
3337 }
3338 }
3339 }
3340 }
3341
DecodeCHK(Word Index)3342 static void DecodeCHK(Word Index)
3343 {
3344 UNUSED(Index);
3345
3346 if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
3347 else if (ChkArgCnt(2, 2)
3348 && CheckNoFamily(1 << eColdfire))
3349 {
3350 tAdrResult AdrResult;
3351
3352 if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
3353 {
3354 WAsmCode[0] = 0x4000 | AdrResult.Mode | ((4 - OpSize) << 7);
3355 CodeLen = 2 + AdrResult.Cnt;
3356 CopyAdrVals(WAsmCode + 1, &AdrResult);
3357 if (DecodeAdr(&ArgStr[2], MModData, &AdrResult) == ModData)
3358 WAsmCode[0] |= WAsmCode[0] | (AdrResult.Mode << 9);
3359 else
3360 CodeLen = 0;
3361 }
3362 }
3363 }
3364
DecodeLINK(Word Index)3365 static void DecodeLINK(Word Index)
3366 {
3367 UNUSED(Index);
3368
3369 if (!*AttrPart.Str && (pCurrCPUProps->Family == eColdfire)) OpSize = eSymbolSize16Bit;
3370 if ((OpSize < 1) || (OpSize > 2)) WrError(ErrNum_InvOpSize);
3371 else if ((OpSize == eSymbolSize32Bit) && !CheckFamily((1 << eCPU32) | (1 << e68KGen2) | (1 << e68KGen3)));
3372 else if (ChkArgCnt(2, 2))
3373 {
3374 tAdrResult AdrResult;
3375
3376 if (DecodeAdr(&ArgStr[1], MModAdr, &AdrResult))
3377 {
3378 WAsmCode[0] = (OpSize == eSymbolSize16Bit) ? 0x4e50 : 0x4808;
3379 WAsmCode[0] += AdrResult.Mode & 7;
3380 if (DecodeAdr(&ArgStr[2], MModImm, &AdrResult) == ModImm)
3381 {
3382 CodeLen = 2 + AdrResult.Cnt;
3383 memcpy(WAsmCode + 1, AdrResult.Vals, AdrResult.Cnt);
3384 }
3385 }
3386 }
3387 }
3388
DecodeMOVEP(Word Index)3389 static void DecodeMOVEP(Word Index)
3390 {
3391 UNUSED(Index);
3392
3393 if ((OpSize == eSymbolSize8Bit) || (OpSize > eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
3394 else if (ChkArgCnt(2, 2)
3395 && CheckNoFamily(1 << eColdfire))
3396 {
3397 tAdrResult AdrResult;
3398
3399 if (DecodeAdr(&ArgStr[1], MModData | MModDAdrI, &AdrResult) == ModData)
3400 {
3401 WAsmCode[0] = 0x188 | ((OpSize - 1) << 6) | (AdrResult.Mode << 9);
3402 if (DecodeAdr(&ArgStr[2], MModDAdrI, &AdrResult) == ModDAdrI)
3403 {
3404 WAsmCode[0] |= AdrResult.Mode & 7;
3405 CodeLen = 4;
3406 WAsmCode[1] = AdrResult.Vals[0];
3407 }
3408 }
3409 else if (AdrResult.Num == ModDAdrI)
3410 {
3411 WAsmCode[0] = 0x108 | ((OpSize - 1) << 6) | (AdrResult.Mode & 7);
3412 WAsmCode[1] = AdrResult.Vals[0];
3413 if (DecodeAdr(&ArgStr[2], MModData, &AdrResult) == ModData)
3414 {
3415 WAsmCode[0] |= (AdrResult.Mode & 7) << 9;
3416 CodeLen = 4;
3417 }
3418 }
3419 }
3420 }
3421
DecodeMOVEC(Word Index)3422 static void DecodeMOVEC(Word Index)
3423 {
3424 UNUSED(Index);
3425
3426 if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
3427 else if (ChkArgCnt(2, 2))
3428 {
3429 tAdrResult AdrResult;
3430
3431 if (DecodeCtrlReg(ArgStr[1].Str, WAsmCode + 1))
3432 {
3433 if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
3434 {
3435 CodeLen = 4;
3436 WAsmCode[0] = 0x4e7a;
3437 WAsmCode[1] |= AdrResult.Mode << 12;
3438 CheckSup();
3439 }
3440 }
3441 else if (DecodeCtrlReg(ArgStr[2].Str, WAsmCode + 1))
3442 {
3443 if (DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult))
3444 {
3445 CodeLen = 4;
3446 WAsmCode[0] = 0x4e7b;
3447 WAsmCode[1] |= AdrResult.Mode << 12; CheckSup();
3448 }
3449 }
3450 else
3451 WrError(ErrNum_InvCtrlReg);
3452 }
3453 }
3454
DecodeMOVES(Word Index)3455 static void DecodeMOVES(Word Index)
3456 {
3457 UNUSED(Index);
3458
3459 if (!ChkArgCnt(2, 2));
3460 else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
3461 else if (CheckNoFamily((1 << e68KGen1a) | (1 << eColdfire)))
3462 {
3463 tAdrResult AdrResult;
3464
3465 switch (DecodeAdr(&ArgStr[1], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
3466 {
3467 case ModData:
3468 case ModAdr:
3469 {
3470 WAsmCode[1] = 0x800 | (AdrResult.Mode << 12);
3471 if (DecodeAdr(&ArgStr[2], MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
3472 {
3473 WAsmCode[0] = 0xe00 | AdrResult.Mode | (OpSize << 6);
3474 CodeLen = 4 + AdrResult.Cnt;
3475 CopyAdrVals(WAsmCode + 2, &AdrResult);
3476 CheckSup();
3477 }
3478 break;
3479 }
3480 case ModNone:
3481 break;
3482 default:
3483 {
3484 WAsmCode[0] = 0xe00 | AdrResult.Mode | (OpSize << 6);
3485 CodeLen = 4 + AdrResult.Cnt;
3486 CopyAdrVals(WAsmCode + 2, &AdrResult);
3487 if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
3488 {
3489 WAsmCode[1] = AdrResult.Mode << 12;
3490 CheckSup();
3491 }
3492 else
3493 CodeLen = 0;
3494 }
3495 }
3496 }
3497 }
3498
DecodeCALLM(Word Index)3499 static void DecodeCALLM(Word Index)
3500 {
3501 UNUSED(Index);
3502
3503 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
3504 else if (!(pCurrCPUProps->SuppFlags & eFlagCALLM_RTM)) WrError(ErrNum_InstructionNotSupported);
3505 else if (ChkArgCnt(2, 2))
3506 {
3507 tAdrResult AdrResult;
3508
3509 OpSize = eSymbolSize8Bit;
3510 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
3511 {
3512 WAsmCode[1] = AdrResult.Vals[0];
3513 RelPos = 4;
3514 if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
3515 {
3516 WAsmCode[0] = 0x06c0 + AdrResult.Mode;
3517 CopyAdrVals(WAsmCode + 2, &AdrResult);
3518 CodeLen = 4 + AdrResult.Cnt;
3519 }
3520 }
3521 }
3522 }
3523
DecodeCAS(Word Index)3524 static void DecodeCAS(Word Index)
3525 {
3526 UNUSED(Index);
3527
3528 if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
3529 else if (ChkArgCnt(3, 3)
3530 && CheckFamily((1 << e68KGen3) | (1 << e68KGen2)))
3531 {
3532 tAdrResult AdrResult;
3533
3534 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
3535 {
3536 WAsmCode[1] = AdrResult.Mode;
3537 if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
3538 {
3539 RelPos = 4;
3540 WAsmCode[1] += (((Word)AdrResult.Mode) << 6);
3541 if (DecodeAdr(&ArgStr[3], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
3542 {
3543 WAsmCode[0] = 0x08c0 + AdrResult.Mode + (((Word)OpSize + 1) << 9);
3544 CopyAdrVals(WAsmCode + 2, &AdrResult);
3545 CodeLen = 4 + AdrResult.Cnt;
3546 }
3547 }
3548 }
3549 }
3550 }
3551
DecodeCAS2(Word Index)3552 static void DecodeCAS2(Word Index)
3553 {
3554 Word w1, w2;
3555 UNUSED(Index);
3556
3557 if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
3558 else if (!ChkArgCnt(3, 3));
3559 else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
3560 else if (!DecodeRegPair(&ArgStr[1], WAsmCode + 1, WAsmCode + 2)) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[1]);
3561 else if (!DecodeRegPair(&ArgStr[2], &w1, &w2)) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[2]);
3562 else
3563 {
3564 WAsmCode[1] += (w1 << 6);
3565 WAsmCode[2] += (w2 << 6);
3566 if (!CodeIndRegPair(&ArgStr[3], &w1, &w2)) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[3]);
3567 else
3568 {
3569 WAsmCode[1] += (w1 << 12);
3570 WAsmCode[2] += (w2 << 12);
3571 WAsmCode[0] = 0x0cfc + (((Word)OpSize - 1) << 9);
3572 CodeLen = 6;
3573 }
3574 }
3575 }
3576
DecodeCMPCHK2(Word Index)3577 static void DecodeCMPCHK2(Word Index)
3578 {
3579 if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
3580 else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32)));
3581 else if (ChkArgCnt(2, 2))
3582 {
3583 tAdrResult AdrResult;
3584
3585 if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
3586 {
3587 RelPos = 4;
3588 WAsmCode[1] = (((Word)AdrResult.Mode) << 12) | (Index << 11);
3589 if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
3590 {
3591 WAsmCode[0] = 0x00c0 + (((Word)OpSize) << 9) + AdrResult.Mode;
3592 CopyAdrVals(WAsmCode + 2, &AdrResult);
3593 CodeLen = 4 + AdrResult.Cnt;
3594 }
3595 }
3596 }
3597 }
3598
DecodeEXTB(Word Index)3599 static void DecodeEXTB(Word Index)
3600 {
3601 UNUSED(Index);
3602
3603 if ((OpSize != eSymbolSize32Bit) && *AttrPart.Str) WrError(ErrNum_InvOpSize);
3604 else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32)));
3605 else if (ChkArgCnt(1, 1))
3606 {
3607 tAdrResult AdrResult;
3608
3609 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
3610 {
3611 WAsmCode[0] = 0x49c0 + AdrResult.Mode;
3612 CodeLen = 2;
3613 }
3614 }
3615 }
3616
DecodePACK(Word Index)3617 static void DecodePACK(Word Index)
3618 {
3619 if (!ChkArgCnt(3, 3));
3620 else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
3621 else if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
3622 else
3623 {
3624 tAdrResult AdrResult;
3625
3626 if (DecodeAdr(&ArgStr[1], MModData | MModPre, &AdrResult))
3627 {
3628 WAsmCode[0] = (0x8140 + (Index << 6)) | (AdrResult.Mode & 7);
3629 if (AdrResult.Num == ModPre)
3630 WAsmCode[0] += 8;
3631 if (DecodeAdr(&ArgStr[2], 1 << (AdrResult.Num - 1), &AdrResult))
3632 {
3633 WAsmCode[0] |= ((AdrResult.Mode & 7) << 9);
3634 if (DecodeAdr(&ArgStr[3], MModImm, &AdrResult))
3635 {
3636 WAsmCode[1] = AdrResult.Vals[0];
3637 CodeLen = 4;
3638 }
3639 }
3640 }
3641 }
3642 }
3643
DecodeRTM(Word Index)3644 static void DecodeRTM(Word Index)
3645 {
3646 UNUSED(Index);
3647
3648 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
3649 else if (!(pCurrCPUProps->SuppFlags & eFlagCALLM_RTM)) WrError(ErrNum_InstructionNotSupported);
3650 else if (ChkArgCnt(1, 1))
3651 {
3652 tAdrResult AdrResult;
3653
3654 if (DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult))
3655 {
3656 WAsmCode[0] = 0x06c0 + AdrResult.Mode;
3657 CodeLen = 2;
3658 }
3659 }
3660 }
3661
DecodeTBL(Word Index)3662 static void DecodeTBL(Word Index)
3663 {
3664 char *p;
3665 Word w2, Mode;
3666
3667 if (!ChkArgCnt(2, 2));
3668 else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
3669 else if (CheckFamily(1 << eCPU32))
3670 {
3671 tAdrResult AdrResult;
3672
3673 if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
3674 {
3675 Mode = AdrResult.Mode;
3676 p = strchr(ArgStr[1].Str, ':');
3677 if (!p)
3678 {
3679 RelPos = 4;
3680 if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX| MModAbs | MModPC | MModPCIdx, &AdrResult))
3681 {
3682 WAsmCode[0] = 0xf800 | AdrResult.Mode;
3683 WAsmCode[1] = 0x0100 | (OpSize << 6) | (Mode << 12) | (Index << 10);
3684 memcpy(WAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
3685 CodeLen = 4 + AdrResult.Cnt;
3686 }
3687 }
3688 else
3689 {
3690 strcpy(ArgStr[3].Str, p + 1);
3691 *p = '\0';
3692 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
3693 {
3694 w2 = AdrResult.Mode;
3695 if (DecodeAdr(&ArgStr[3], MModData, &AdrResult))
3696 {
3697 WAsmCode[0] = 0xf800 | w2;
3698 WAsmCode[1] = 0x0000 | (OpSize << 6) | (Mode << 12) | AdrResult.Mode;
3699 if (OpPart.Str[3] == 'S')
3700 WAsmCode[1] |= 0x0800;
3701 if (OpPart.Str[strlen(OpPart.Str) - 1] == 'N')
3702 WAsmCode[1] |= 0x0400;
3703 CodeLen = 4;
3704 }
3705 }
3706 }
3707 }
3708 }
3709 }
3710
3711 /* 0=BTST 1=BCHG 2=BCLR 3=BSET */
3712
DecodeBits(Word Index)3713 static void DecodeBits(Word Index)
3714 {
3715 Word Mask, BitNum, BitMax;
3716 tSymbolSize SaveOpSize;
3717 unsigned ResCodeLen;
3718 Boolean BitNumUnknown = False;
3719 tAdrResult AdrResult;
3720
3721 if (!ChkArgCnt(2, 2))
3722 return;
3723
3724 WAsmCode[0] = (Index << 6);
3725 ResCodeLen = 1;
3726
3727 SaveOpSize = OpSize;
3728 OpSize = eSymbolSize8Bit;
3729 switch (DecodeAdr(&ArgStr[1], MModData | MModImm, &AdrResult))
3730 {
3731 case ModData:
3732 WAsmCode[0] |= 0x100 | (AdrResult.Mode << 9);
3733 BitNum = 0; /* implicitly suppresses bit pos check */
3734 break;
3735 case ModImm:
3736 WAsmCode[0] |= 0x800;
3737 WAsmCode[ResCodeLen++] = BitNum = AdrResult.Vals[0];
3738 BitNumUnknown = mFirstPassUnknown(AdrResult.ImmSymFlags);
3739 break;
3740 default:
3741 return;
3742 }
3743
3744 OpSize = SaveOpSize;
3745 if (!*AttrPart.Str)
3746 OpSize = eSymbolSize8Bit;
3747
3748 Mask = MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs;
3749 if (!Index)
3750 Mask |= MModPC | MModPCIdx | MModImm;
3751 RelPos = ResCodeLen << 1;
3752 DecodeAdr(&ArgStr[2], Mask, &AdrResult);
3753
3754 if (!*AttrPart.Str)
3755 OpSize = (AdrResult.Num == ModData) ? eSymbolSize32Bit : eSymbolSize8Bit;
3756 if (!AdrResult.Num)
3757 return;
3758 if (((AdrResult.Num == ModData) && (OpSize != eSymbolSize32Bit)) || ((AdrResult.Num != ModData) && (OpSize != eSymbolSize8Bit)))
3759 {
3760 WrError(ErrNum_InvOpSize);
3761 return;
3762 }
3763
3764 BitMax = (AdrResult.Num == ModData) ? 31 : 7;
3765 WAsmCode[0] |= AdrResult.Mode;
3766 CopyAdrVals(WAsmCode + ResCodeLen, &AdrResult);
3767 CodeLen = (ResCodeLen << 1) + AdrResult.Cnt;
3768 if (!BitNumUnknown && (BitNum > BitMax))
3769 WrError(ErrNum_BitNumberTruncated);
3770 }
3771
3772 /* 0=BFTST 1=BFCHG 2=BFCLR 3=BFSET */
3773
DecodeFBits(Word Index)3774 static void DecodeFBits(Word Index)
3775 {
3776 if (!ChkArgCnt(1, 1));
3777 else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
3778 else if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
3779 else if (!SplitBitField(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvBitMask);
3780 else
3781 {
3782 tAdrResult AdrResult;
3783
3784 RelPos = 4;
3785 OpSize = eSymbolSize8Bit;
3786 if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModDAdrI | MModAIX | MModAbs | (Memo("BFTST") ? (MModPC | MModPCIdx) : 0), &AdrResult))
3787 {
3788 WAsmCode[0] = 0xe8c0 | AdrResult.Mode | (Index << 10);
3789 CopyAdrVals(WAsmCode + 2, &AdrResult);
3790 CodeLen = 4 + AdrResult.Cnt;
3791 }
3792 }
3793 }
3794
3795 /* 0=BFEXTU 1=BFEXTS 2=BFFFO */
3796
DecodeEBits(Word Index)3797 static void DecodeEBits(Word Index)
3798 {
3799 if (!ChkArgCnt(2, 2));
3800 else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
3801 else if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
3802 else if (!SplitBitField(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvBitMask);
3803 else
3804 {
3805 tAdrResult AdrResult;
3806
3807 RelPos = 4;
3808 OpSize = eSymbolSize8Bit;
3809 if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
3810 {
3811 LongInt ThisCodeLen = 4 + AdrResult.Cnt;
3812
3813 WAsmCode[0] = 0xe9c0 + AdrResult.Mode + (Index << 9); CopyAdrVals(WAsmCode + 2, &AdrResult);
3814 if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
3815 {
3816 WAsmCode[1] |= AdrResult.Mode << 12;
3817 CodeLen = ThisCodeLen;
3818 }
3819 }
3820 }
3821 }
3822
DecodeBFINS(Word Index)3823 static void DecodeBFINS(Word Index)
3824 {
3825 UNUSED(Index);
3826
3827 if (!ChkArgCnt(2, 2));
3828 else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
3829 else if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
3830 else if (!SplitBitField(&ArgStr[2], WAsmCode + 1)) WrError(ErrNum_InvBitMask);
3831 else
3832 {
3833 tAdrResult AdrResult;
3834
3835 OpSize = eSymbolSize8Bit;
3836 if (DecodeAdr(&ArgStr[2], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
3837 {
3838 LongInt ThisCodeLen = 4 + AdrResult.Cnt;
3839
3840 WAsmCode[0] = 0xefc0 + AdrResult.Mode;
3841 CopyAdrVals(WAsmCode + 2, &AdrResult);
3842 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
3843 {
3844 WAsmCode[1] |= AdrResult.Mode << 12;
3845 CodeLen = ThisCodeLen;
3846 }
3847 }
3848 }
3849 }
3850
3851 /* bedingte Befehle */
3852
DecodeBcc(Word CondCode)3853 static void DecodeBcc(Word CondCode)
3854 {
3855 /* .W, .S, .L, .X erlaubt */
3856
3857 if ((OpSize > eSymbolSize32Bit) && (OpSize != eSymbolSizeFloat32Bit) && (OpSize != eSymbolSizeFloat96Bit)) WrError(ErrNum_InvOpSize);
3858
3859 /* nur ein Operand erlaubt */
3860
3861 else if (ChkArgCnt(1, 1))
3862 {
3863 LongInt HVal;
3864 Integer HVal16;
3865 ShortInt HVal8;
3866 Boolean ValOK, IsBSR = (1 == CondCode);
3867 tSymbolFlags Flags;
3868
3869 /* Zieladresse ermitteln, zum Programmzaehler relativieren */
3870
3871 HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &Flags);
3872 HVal = HVal - (EProgCounter() + 2);
3873
3874 /* Bei Automatik Groesse festlegen */
3875
3876 if (!*AttrPart.Str)
3877 {
3878 if (IsDisp8(HVal))
3879 {
3880 /* BSR with zero displacement cannot be converted to NOP. Generate a
3881 16 bit displacement instead. */
3882
3883 if (!HVal && IsBSR)
3884 OpSize = eSymbolSize32Bit;
3885
3886 /* if the jump target is the address right behind the BSR, keep
3887 16 bit displacement to avoid oscillating back and forth between
3888 8 and 16 bits: */
3889
3890 else if ((Flags & eSymbolFlag_NextLabelAfterBSR) && (HVal == 2) && IsBSR)
3891 OpSize = eSymbolSize32Bit;
3892 else
3893 OpSize = eSymbolSizeFloat32Bit;
3894 }
3895 else if (IsDisp16(HVal))
3896 OpSize = eSymbolSize32Bit;
3897 else
3898 OpSize = eSymbolSizeFloat96Bit;
3899 }
3900
3901 if (ValOK)
3902 {
3903 /* 16 Bit ? */
3904
3905 if ((OpSize == eSymbolSize32Bit) || (OpSize == eSymbolSize16Bit))
3906 {
3907 /* zu weit ? */
3908
3909 HVal16 = HVal;
3910 if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
3911 else
3912 {
3913 /* Code erzeugen */
3914
3915 CodeLen = 4;
3916 WAsmCode[0] = 0x6000 | (CondCode << 8);
3917 WAsmCode[1] = HVal16;
3918 }
3919 }
3920
3921 /* 8 Bit ? */
3922
3923 else if ((OpSize == eSymbolSizeFloat32Bit) || (OpSize == eSymbolSize8Bit))
3924 {
3925 /* zu weit ? */
3926
3927 HVal8 = HVal;
3928 if (!IsDisp8(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
3929
3930 /* cannot generate short BSR with zero displacement, and BSR cannot
3931 be replaced with NOP -> error */
3932
3933 else if ((HVal == 0) && IsBSR && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
3934
3935 /* Code erzeugen */
3936
3937 else
3938 {
3939 CodeLen = 2;
3940 if ((HVal8 != 0) || IsBSR)
3941 {
3942 WAsmCode[0] = 0x6000 | (CondCode << 8) | ((Byte)HVal8);
3943 }
3944 else
3945 {
3946 WAsmCode[0] = NOPCode;
3947 if ((!Repass) && *AttrPart.Str)
3948 WrError(ErrNum_DistNull);
3949 }
3950 }
3951 }
3952
3953 /* 32 Bit ? */
3954
3955 else if (!(pCurrCPUProps->SuppFlags & eFlagBranch32)) WrError(ErrNum_InstructionNotSupported);
3956 else
3957 {
3958 CodeLen = 6;
3959 WAsmCode[0] = 0x60ff | (CondCode << 8);
3960 WAsmCode[1] = HVal >> 16;
3961 WAsmCode[2] = HVal & 0xffff;
3962 }
3963 }
3964
3965 if ((CodeLen > 0) && IsBSR)
3966 AfterBSRAddr = EProgCounter() + CodeLen;
3967 }
3968 }
3969
DecodeScc(Word CondCode)3970 static void DecodeScc(Word CondCode)
3971 {
3972 if (*AttrPart.Str && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
3973 else if (ArgCnt != 1) WrError(ErrNum_InvOpSize);
3974 else
3975 {
3976 tAdrResult AdrResult;
3977
3978 OpSize = eSymbolSize8Bit;
3979 if (DecodeAdr(&ArgStr[1], MModData | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
3980 {
3981 WAsmCode[0] = 0x50c0 | (CondCode << 8) | AdrResult.Mode;
3982 CodeLen = 2 + AdrResult.Cnt;
3983 CopyAdrVals(WAsmCode + 1, &AdrResult);
3984 }
3985 }
3986 }
3987
DecodeDBcc(Word CondCode)3988 static void DecodeDBcc(Word CondCode)
3989 {
3990 if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
3991 else if (ChkArgCnt(2, 2)
3992 && CheckNoFamily(1 << eColdfire))
3993 {
3994 Boolean ValOK;
3995 tSymbolFlags Flags;
3996 LongInt HVal = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &ValOK, &Flags);
3997 Integer HVal16;
3998
3999 if (ValOK)
4000 {
4001 HVal -= (EProgCounter() + 2);
4002 HVal16 = HVal;
4003 if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
4004 else
4005 {
4006 tAdrResult AdrResult;
4007
4008 CodeLen = 4;
4009 WAsmCode[0] = 0x50c8 | (CondCode << 8);
4010 WAsmCode[1] = HVal16;
4011 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult) == ModData)
4012 WAsmCode[0] |= AdrResult.Mode;
4013 else
4014 CodeLen = 0;
4015 }
4016 }
4017 }
4018 }
4019
DecodeTRAPcc(Word CondCode)4020 static void DecodeTRAPcc(Word CondCode)
4021 {
4022 int ExpectArgCnt;
4023
4024 if (!*AttrPart.Str)
4025 OpSize = eSymbolSize8Bit;
4026 ExpectArgCnt = (OpSize == eSymbolSize8Bit) ? 0 : 1;
4027 if (OpSize > 2) WrError(ErrNum_InvOpSize);
4028 else if (!ChkArgCnt(ExpectArgCnt, ExpectArgCnt));
4029 else if ((CondCode != 1) && !CheckNoFamily(1 << eColdfire));
4030 else
4031 {
4032 WAsmCode[0] = 0x50f8 + (CondCode << 8);
4033 if (OpSize == eSymbolSize8Bit)
4034 {
4035 WAsmCode[0] += 4;
4036 CodeLen = 2;
4037 }
4038 else
4039 {
4040 tAdrResult AdrResult;
4041
4042 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
4043 {
4044 WAsmCode[0] += OpSize + 1;
4045 CopyAdrVals(WAsmCode + 1, &AdrResult);
4046 CodeLen = 2 + AdrResult.Cnt;
4047 }
4048 }
4049 CheckFamily((1 << eColdfire) | (1 << eCPU32) | (1 << e68KGen2) | (1 << e68KGen3));
4050 }
4051 }
4052
4053 /*-------------------------------------------------------------------------*/
4054 /* Dekodierroutinen Gleitkommaeinheit */
4055
4056 enum { eFMovemTypNone = 0, eFMovemTypDyn = 1, eFMovemTypStatic = 2, eFMovemTypCtrl = 3 };
4057
DecodeFRegList(const tStrComp * pArg,Byte * pTyp,Byte * pList)4058 static void DecodeFRegList(const tStrComp *pArg, Byte *pTyp, Byte *pList)
4059 {
4060 Word hw, Reg, RegFrom, RegTo;
4061 Byte z;
4062 char *p, *p2;
4063 String ArgStr;
4064 tStrComp Arg, Remainder, From, To;
4065
4066 StrCompMkTemp(&Arg, ArgStr);
4067 StrCompCopy(&Arg, pArg);
4068
4069 *pTyp = eFMovemTypNone;
4070 if (*Arg.Str == '\0')
4071 return;
4072
4073 switch (DecodeReg(&Arg, &Reg, False))
4074 {
4075 case eIsReg:
4076 if (Reg & 8)
4077 return;
4078 *pTyp = eFMovemTypDyn;
4079 *pList = Reg << 4;
4080 return;
4081 case eRegAbort:
4082 return;
4083 default:
4084 break;
4085 }
4086
4087 hw = 0;
4088 do
4089 {
4090 p = strchr(Arg.Str, '/');
4091 if (p)
4092 StrCompSplitRef(&Arg, &Remainder, &Arg, p);
4093 p2 = strchr(Arg.Str, '-');
4094 if (p2)
4095 {
4096 StrCompSplitRef(&From, &To, &Arg, p2);
4097 if ((DecodeFPReg(&From, &RegFrom, False) != eIsReg)
4098 || (RegFrom & REG_FPCTRL)
4099 || (DecodeFPReg(&To, &RegTo, False) != eIsReg)
4100 || (RegTo & REG_FPCTRL))
4101 return;
4102 if (RegFrom <= RegTo)
4103 for (z = RegFrom; z <= RegTo; z++) hw |= (1 << (7 - z));
4104 else
4105 {
4106 for (z = RegFrom; z <= 7; z++) hw |= (1 << (7 - z));
4107 for (z = 0; z <= RegTo; z++) hw |= (1 << (7 - z));
4108 }
4109 }
4110 else
4111 {
4112 if (DecodeFPReg(&Arg, &Reg, False) != eIsReg)
4113 return;
4114 if (Reg & REG_FPCTRL)
4115 hw |= (Reg & 7) << 8;
4116 else
4117 hw |= (1 << (7 - Reg));
4118 }
4119 if (p)
4120 Arg = Remainder;
4121 }
4122 while (p);
4123 if (Hi(hw) == 0)
4124 {
4125 *pTyp = eFMovemTypStatic;
4126 *pList = Lo(hw);
4127 }
4128 else if (Lo(hw) == 0)
4129 {
4130 *pTyp = eFMovemTypCtrl;
4131 *pList = Hi(hw);
4132 }
4133 }
4134
Mirror8(Byte List)4135 static Byte Mirror8(Byte List)
4136 {
4137 Byte hList;
4138 int z;
4139
4140 hList = List; List = 0;
4141 for (z = 0; z < 8; z++)
4142 {
4143 List = List << 1;
4144 if (hList & 1)
4145 List |= 1;
4146 hList = hList >> 1;
4147 }
4148 return List;
4149 }
4150
GenerateMovem(Byte Typ,Byte List,tAdrResult * pResult)4151 static void GenerateMovem(Byte Typ, Byte List, tAdrResult *pResult)
4152 {
4153 if (pResult->Num == ModNone)
4154 return;
4155 CodeLen = 4 + pResult->Cnt;
4156 CopyAdrVals(WAsmCode + 2, pResult);
4157 WAsmCode[0] = 0xf200 | pResult->Mode;
4158 switch (Typ)
4159 {
4160 case eFMovemTypDyn:
4161 case eFMovemTypStatic:
4162 WAsmCode[1] |= 0xc000;
4163 if (Typ == eFMovemTypDyn)
4164 WAsmCode[1] |= 0x800;
4165 if (pResult->Num != ModPre)
4166 WAsmCode[1] |= 0x1000;
4167 if ((pResult->Num == ModPre) && (Typ == eFMovemTypStatic))
4168 List = Mirror8(List);
4169 WAsmCode[1] |= List;
4170 break;
4171 case eFMovemTypCtrl:
4172 WAsmCode[1] |= 0x8000 | (((Word)List) << 10);
4173 break;
4174 }
4175 }
4176
4177 /*-------------------------------------------------------------------------*/
4178
DecodeFPUOp(Word Index)4179 static void DecodeFPUOp(Word Index)
4180 {
4181 FPUOp *Op = FPUOps + Index;
4182 tStrComp *pArg2 = &ArgStr[2];
4183
4184 if ((ArgCnt == 1) && (!Op->Dya))
4185 {
4186 pArg2 = &ArgStr[1];
4187 ArgCnt = 2;
4188 }
4189
4190 if (!CheckFloatSize());
4191 else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4192 else if ((pCurrCPUProps->SuppFlags & Op->NeedsSuppFlags) != Op->NeedsSuppFlags) WrError(ErrNum_InstructionNotSupported);
4193 else if (ChkArgCnt(2, 2))
4194 {
4195 tAdrResult AdrResult;
4196
4197 if (DecodeAdr(pArg2, MModFPn, &AdrResult) == ModFPn)
4198 {
4199 Word SrcMask;
4200
4201 WAsmCode[0] = 0xf200;
4202 WAsmCode[1] = Op->Code | (AdrResult.Mode << 7);
4203 RelPos = 4;
4204
4205 SrcMask = MModAdrI | MModDAdrI | MModPost | MModPre | MModPC | MModFPn;
4206 if (FloatOpSizeFitsDataReg(OpSize))
4207 SrcMask |= MModData;
4208 if (pCurrCPUProps->Family != eColdfire)
4209 SrcMask |= MModAIX | MModAbs | MModPCIdx | MModImm;
4210 if (DecodeAdr(&ArgStr[1], SrcMask, &AdrResult) == ModFPn)
4211 {
4212 WAsmCode[1] |= AdrResult.Mode << 10;
4213 if (OpSize == NativeFloatSize)
4214 CodeLen = 4;
4215 else
4216 WrError(ErrNum_InvOpSize);
4217 }
4218 else if (AdrResult.Num != ModNone)
4219 {
4220 CodeLen = 4 + AdrResult.Cnt;
4221 CopyAdrVals(WAsmCode + 2, &AdrResult);
4222 WAsmCode[0] |= AdrResult.Mode;
4223 WAsmCode[1] |= 0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
4224 }
4225 }
4226 }
4227 }
4228
DecodeFSAVE(Word Code)4229 static void DecodeFSAVE(Word Code)
4230 {
4231 UNUSED(Code);
4232
4233 if (!ChkArgCnt(1, 1));
4234 else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4235 else if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
4236 else
4237 {
4238 tAdrResult AdrResult;
4239
4240 if (DecodeAdr(&ArgStr[1], MModAdrI | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
4241 {
4242 CodeLen = 2 + AdrResult.Cnt;
4243 WAsmCode[0] = 0xf300 | AdrResult.Mode;
4244 CopyAdrVals(WAsmCode + 1, &AdrResult);
4245 CheckSup();
4246 }
4247 }
4248 }
4249
DecodeFRESTORE(Word Code)4250 static void DecodeFRESTORE(Word Code)
4251 {
4252 UNUSED(Code);
4253
4254 if (!ChkArgCnt(1, 1));
4255 else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4256 else if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
4257 else
4258 {
4259 tAdrResult AdrResult;
4260
4261 if (DecodeAdr(&ArgStr[1], MModAdrI | MModPost | MModDAdrI | MModAIX | MModAbs, &AdrResult))
4262 {
4263 CodeLen = 2 + AdrResult.Cnt;
4264 WAsmCode[0] = 0xf340 | AdrResult.Mode;
4265 CopyAdrVals(WAsmCode + 1, &AdrResult);
4266 CheckSup();
4267 }
4268 }
4269 }
4270
DecodeFNOP(Word Code)4271 static void DecodeFNOP(Word Code)
4272 {
4273 UNUSED(Code);
4274
4275 if (!ChkArgCnt(0, 0));
4276 else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4277 else if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
4278 else
4279 {
4280 CodeLen = 4;
4281 WAsmCode[0] = 0xf280;
4282 WAsmCode[1] = 0;
4283 }
4284 }
4285
DecodeFMOVE(Word Code)4286 static void DecodeFMOVE(Word Code)
4287 {
4288 char *pKSep;
4289 tStrComp KArg;
4290
4291 UNUSED(Code);
4292
4293 if (!ChkArgCnt(2, 2));
4294 else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4295 else if (!CheckFloatSize());
4296 else
4297 {
4298 Word DestMask, SrcMask;
4299 tAdrResult AdrResult;
4300
4301 /* k-Faktor abspalten */
4302
4303 pKSep = strchr(AttrPart.Str, '{');
4304 if (pKSep)
4305 {
4306 StrCompSplitRef(&AttrPart, &KArg, &AttrPart, pKSep);
4307 StrCompShorten(&KArg, 1);
4308 }
4309
4310 DestMask = MModAdrI | MModPost | MModPre | MModDAdrI | MModFPCR | MModFPn;
4311 if (pCurrCPUProps->Family != eColdfire)
4312 DestMask |= MModAIX | MModAbs | MModImm;
4313 if (FloatOpSizeFitsDataReg(OpSize))
4314 DestMask |= MModData;
4315 if (DecodeAdr(&ArgStr[2], DestMask, &AdrResult) == ModFPn) /* FMOVE.x <ea>/FPm,FPn ? */
4316 {
4317 WAsmCode[0] = 0xf200;
4318 WAsmCode[1] = AdrResult.Mode << 7;
4319 RelPos = 4;
4320 SrcMask = MModAdrI | MModPost | MModPre | MModDAdrI | MModPC | MModFPn;
4321 if (pCurrCPUProps->Family != eColdfire)
4322 SrcMask |= MModAIX | MModAbs | MModImm | MModPCIdx;
4323 if (FloatOpSizeFitsDataReg(OpSize))
4324 SrcMask |= MModData;
4325 if (DecodeAdr(&ArgStr[1], SrcMask, &AdrResult) == ModFPn) /* FMOVE.X FPm,FPn ? */
4326 {
4327 WAsmCode[1] |= AdrResult.Mode << 10;
4328 if (OpSize == NativeFloatSize)
4329 CodeLen = 4;
4330 else
4331 WrError(ErrNum_InvOpSize);
4332 }
4333 else if (AdrResult.Num != ModNone) /* FMOVE.x <ea>,FPn ? */
4334 {
4335 CodeLen = 4 + AdrResult.Cnt;
4336 CopyAdrVals(WAsmCode + 2, &AdrResult);
4337 WAsmCode[0] |= AdrResult.Mode;
4338 WAsmCode[1] |= 0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
4339 }
4340 }
4341 else if (AdrResult.Num == ModFPCR) /* FMOVE.L <ea>,FPcr ? */
4342 {
4343 if ((OpSize != eSymbolSize32Bit) && *AttrPart.Str) WrError(ErrNum_InvOpSize);
4344 else
4345 {
4346 RelPos = 4;
4347 WAsmCode[0] = 0xf200;
4348 WAsmCode[1] = 0x8000 | (AdrResult.Mode << 10);
4349 SrcMask = MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModPC;
4350 if (pCurrCPUProps->Family != eColdfire)
4351 SrcMask |= MModAIX | MModAbs | MModImm | MModPCIdx;
4352 if (AdrResult.Num != ModData) /* only for FPIAR */
4353 SrcMask |= MModAdr;
4354 if (DecodeAdr(&ArgStr[1], SrcMask, &AdrResult))
4355 {
4356 WAsmCode[0] |= AdrResult.Mode;
4357 CodeLen = 4 + AdrResult.Cnt;
4358 CopyAdrVals(WAsmCode + 2, &AdrResult);
4359 }
4360 }
4361 }
4362 else if (AdrResult.Num != ModNone) /* FMOVE.x ????,<ea> ? */
4363 {
4364 WAsmCode[0] = 0xf200 | AdrResult.Mode;
4365 CodeLen = 4 + AdrResult.Cnt;
4366 CopyAdrVals(WAsmCode + 2, &AdrResult);
4367 switch (DecodeAdr(&ArgStr[1], (AdrResult.Num == ModAdr) ? MModFPCR : MModFPn | MModFPCR, &AdrResult))
4368 {
4369 case ModFPn: /* FMOVE.x FPn,<ea> ? */
4370 {
4371 WAsmCode[1] = 0x6000 | (((Word)FSizeCodes[OpSize]) << 10) | (AdrResult.Mode << 7);
4372 if (OpSize == eSymbolSizeFloatDec96Bit)
4373 {
4374 if (pKSep && (strlen(KArg.Str) > 0))
4375 {
4376 OpSize = eSymbolSize8Bit;
4377 switch (DecodeAdr(&KArg, MModData | MModImm, &AdrResult))
4378 {
4379 case ModData:
4380 WAsmCode[1] |= (AdrResult.Mode << 4) | 0x1000;
4381 break;
4382 case ModImm:
4383 WAsmCode[1] |= (AdrResult.Vals[0] & 127);
4384 break;
4385 default:
4386 CodeLen = 0;
4387 }
4388 }
4389 else
4390 WAsmCode[1] |= 17;
4391 }
4392 break;
4393 }
4394 case ModFPCR: /* FMOVE.L FPcr,<ea> ? */
4395 {
4396 if (*AttrPart.Str && (OpSize != eSymbolSize32Bit))
4397 {
4398 WrError(ErrNum_InvOpSize);
4399 CodeLen = 0;
4400 }
4401 else
4402 {
4403 WAsmCode[1] = 0xa000 | (AdrResult.Mode << 10);
4404 if ((AdrResult.Mode != 1) && ((WAsmCode[0] & 0x38) == 8))
4405 {
4406 WrError(ErrNum_InvAddrMode);
4407 CodeLen = 0;
4408 }
4409 }
4410 break;
4411 }
4412 default:
4413 CodeLen = 0;
4414 }
4415 }
4416 }
4417 }
4418
DecodeFMOVECR(Word Code)4419 static void DecodeFMOVECR(Word Code)
4420 {
4421 UNUSED(Code);
4422
4423 if (!ChkArgCnt(2, 2));
4424 else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4425 else if (!CheckNoFamily(1 << eColdfire));
4426 else if (*AttrPart.Str && (OpSize != eSymbolSizeFloat96Bit)) WrError(ErrNum_InvOpSize);
4427 else
4428 {
4429 tAdrResult AdrResult;
4430
4431 if (DecodeAdr(&ArgStr[2], MModFPn, &AdrResult) == ModFPn)
4432 {
4433 WAsmCode[0] = 0xf200;
4434 WAsmCode[1] = 0x5c00 | (AdrResult.Mode << 7);
4435 OpSize = eSymbolSize8Bit;
4436 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult) == ModImm)
4437 {
4438 if (AdrResult.Vals[0] > 63) WrError(ErrNum_RomOffs063);
4439 else
4440 {
4441 CodeLen = 4;
4442 WAsmCode[1] |= AdrResult.Vals[0];
4443 }
4444 }
4445 }
4446 }
4447 }
4448
DecodeFTST(Word Code)4449 static void DecodeFTST(Word Code)
4450 {
4451 UNUSED(Code);
4452
4453 if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4454 else if (!CheckFloatSize());
4455 else if (ChkArgCnt(1, 1))
4456 {
4457 Word Mask;
4458 tAdrResult AdrResult;
4459
4460 RelPos = 4;
4461 Mask = MModAdrI | MModPost | MModPre | MModDAdrI | MModPC | MModFPn;
4462 if (pCurrCPUProps->Family != eColdfire)
4463 Mask |= MModAIX | MModPCIdx | MModAbs | MModImm;
4464 if (FloatOpSizeFitsDataReg(OpSize))
4465 Mask |= MModData;
4466 if (DecodeAdr(&ArgStr[1], Mask, &AdrResult) == ModFPn)
4467 {
4468 WAsmCode[0] = 0xf200;
4469 WAsmCode[1] = 0x3a | (AdrResult.Mode << 10);
4470 CodeLen = 4;
4471 }
4472 else if (AdrResult.Num != ModNone)
4473 {
4474 WAsmCode[0] = 0xf200 | AdrResult.Mode;
4475 WAsmCode[1] = 0x403a | (((Word)FSizeCodes[OpSize]) << 10);
4476 CodeLen = 4 + AdrResult.Cnt;
4477 CopyAdrVals(WAsmCode + 2, &AdrResult);
4478 }
4479 }
4480 }
4481
DecodeFSINCOS(Word Code)4482 static void DecodeFSINCOS(Word Code)
4483 {
4484 UNUSED(Code);
4485
4486 if (!*AttrPart.Str)
4487 OpSize = NativeFloatSize;
4488 if (OpSize == 3) WrError(ErrNum_InvOpSize);
4489 else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4490 else if (!CheckNoFamily(1 << eColdfire));
4491 else if (ChkArgCnt(2, 3))
4492 {
4493 tStrComp *pArg2, *pArg3, Arg2, Arg3;
4494 tAdrResult AdrResult;
4495
4496 if (3 == ArgCnt)
4497 {
4498 pArg2 = &ArgStr[2];
4499 pArg3 = &ArgStr[3];
4500 }
4501 else
4502 {
4503 char *pKSep = strrchr(ArgStr[2].Str, ':');
4504
4505 if (!pKSep)
4506 {
4507 WrError(ErrNum_WrongArgCnt);
4508 return;
4509 }
4510 StrCompSplitRef(&Arg2, &Arg3, &ArgStr[2], pKSep);
4511 pArg2 = &Arg2;
4512 pArg3 = &Arg3;
4513 }
4514 if (DecodeAdr(pArg2, MModFPn, &AdrResult) == ModFPn)
4515 {
4516 WAsmCode[1] = AdrResult.Mode | 0x30;
4517 if (DecodeAdr(pArg3, MModFPn, &AdrResult) == ModFPn)
4518 {
4519 WAsmCode[1] |= (AdrResult.Mode << 7);
4520 RelPos = 4;
4521 switch (DecodeAdr(&ArgStr[1], ((OpSize <= eSymbolSize32Bit) || (OpSize == eSymbolSizeFloat32Bit))
4522 ? MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm | MModFPn
4523 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm | MModFPn, &AdrResult))
4524 {
4525 case ModFPn:
4526 WAsmCode[0] = 0xf200;
4527 WAsmCode[1] |= (AdrResult.Mode << 10);
4528 CodeLen = 4;
4529 break;
4530 case ModNone:
4531 break;
4532 default:
4533 WAsmCode[0] = 0xf200 | AdrResult.Mode;
4534 WAsmCode[1] |= 0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
4535 CodeLen = 4 + AdrResult.Cnt;
4536 CopyAdrVals(WAsmCode + 2, &AdrResult);
4537 }
4538 }
4539 }
4540 }
4541 }
4542
DecodeFDMOVE_FSMOVE(Word Code)4543 static void DecodeFDMOVE_FSMOVE(Word Code)
4544 {
4545 if (!ChkArgCnt(2, 2));
4546 else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4547 else if (CheckFamily((1 << e68KGen3) | (1 << eColdfire)))
4548 {
4549 tAdrResult AdrResult;
4550
4551 if (DecodeAdr(&ArgStr[2], MModFPn, &AdrResult) == ModFPn)
4552 {
4553 unsigned Mask;
4554
4555 WAsmCode[0] = 0xf200;
4556 WAsmCode[1] = Code | AdrResult.Mode << 7;
4557 RelPos = 4;
4558 if (!*AttrPart.Str)
4559 OpSize = NativeFloatSize;
4560 Mask = MModFPn | MModAdrI | MModPost | MModPre | MModDAdrI | MModPC;
4561 if (pCurrCPUProps->Family != eColdfire)
4562 Mask |= MModAIX | MModAbs | MModPCIdx | MModImm;
4563 if (FloatOpSizeFitsDataReg(OpSize))
4564 Mask |= MModData;
4565 if (DecodeAdr(&ArgStr[1], Mask, &AdrResult) == ModFPn)
4566 {
4567 CodeLen = 4;
4568 WAsmCode[1] |= (AdrResult.Mode << 10);
4569 }
4570 else if (AdrResult.Num != ModNone)
4571 {
4572 CodeLen = 4 + AdrResult.Cnt;
4573 CopyAdrVals(WAsmCode + 2, &AdrResult);
4574 WAsmCode[0] |= AdrResult.Mode;
4575 WAsmCode[1] |= 0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
4576 }
4577 }
4578 }
4579 }
4580
DecodeFMOVEM(Word Code)4581 static void DecodeFMOVEM(Word Code)
4582 {
4583 Byte Typ, List;
4584 Word Mask;
4585
4586 UNUSED(Code);
4587
4588 if (!ChkArgCnt(2, 2));
4589 else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4590 else
4591 {
4592 tAdrResult AdrResult;
4593
4594 DecodeFRegList(&ArgStr[2], &Typ, &List);
4595 if (Typ != eFMovemTypNone)
4596 {
4597 if (*AttrPart.Str
4598 && (((Typ < eFMovemTypCtrl) && (OpSize != NativeFloatSize))
4599 || ((Typ == eFMovemTypCtrl) && (OpSize != eSymbolSize32Bit))))
4600 WrError(ErrNum_InvOpSize);
4601 else if ((Typ != eFMovemTypStatic) && (pCurrCPUProps->Family == eColdfire))
4602 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
4603 else
4604 {
4605 RelPos = 4;
4606 Mask = MModAdrI | MModDAdrI | MModPC;
4607 if (pCurrCPUProps->Family != eColdfire)
4608 Mask |= MModPost | MModAIX | MModPCIdx | MModAbs;
4609 if (Typ == eFMovemTypCtrl) /* Steuerregister auch Predekrement */
4610 {
4611 Mask |= MModPre;
4612 if ((List == REG_FPCR) | (List == REG_FPSR) | (List == REG_FPIAR)) /* nur ein Register */
4613 Mask |= MModData | MModImm;
4614 if (List == REG_FPIAR) /* nur FPIAR */
4615 Mask |= MModAdr;
4616 }
4617 if (DecodeAdr(&ArgStr[1], Mask, &AdrResult))
4618 {
4619 WAsmCode[1] = 0x0000;
4620 GenerateMovem(Typ, List, &AdrResult);
4621 }
4622 }
4623 }
4624 else
4625 {
4626 DecodeFRegList(&ArgStr[1], &Typ, &List);
4627 if (Typ != eFMovemTypNone)
4628 {
4629 if (*AttrPart.Str && (((Typ < eFMovemTypCtrl) && (OpSize != NativeFloatSize)) || ((Typ == eFMovemTypCtrl) && (OpSize != eSymbolSize32Bit)))) WrError(ErrNum_InvOpSize);
4630 else if ((Typ != eFMovemTypStatic) && (pCurrCPUProps->Family == eColdfire)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
4631 else
4632 {
4633 Mask = MModAdrI | MModDAdrI;
4634 if (pCurrCPUProps->Family != eColdfire)
4635 Mask |= MModPre | MModAIX | MModAbs;
4636 if (Typ == eFMovemTypCtrl) /* Steuerregister auch Postinkrement */
4637 {
4638 Mask |= MModPre;
4639 if ((List == REG_FPCR) | (List == REG_FPSR) | (List == REG_FPIAR)) /* nur ein Register */
4640 Mask |= MModData;
4641 if (List == REG_FPIAR) /* nur FPIAR */
4642 Mask |= MModAdr;
4643 }
4644 if (DecodeAdr(&ArgStr[2], Mask, &AdrResult))
4645 {
4646 WAsmCode[1] = 0x2000;
4647 GenerateMovem(Typ, List, &AdrResult);
4648 }
4649 }
4650 }
4651 else
4652 WrError(ErrNum_InvRegList);
4653 }
4654 }
4655 }
4656
DecodeFBcc(Word CondCode)4657 static void DecodeFBcc(Word CondCode)
4658 {
4659 if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4660 else
4661 {
4662 if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit) && (OpSize != eSymbolSizeFloat96Bit)) WrError(ErrNum_InvOpSize);
4663 else if (ChkArgCnt(1, 1))
4664 {
4665 LongInt HVal;
4666 Integer HVal16;
4667 Boolean ValOK;
4668 tSymbolFlags Flags;
4669
4670 HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &Flags) - (EProgCounter() + 2);
4671 HVal16 = HVal;
4672
4673 if (!*AttrPart.Str)
4674 {
4675 OpSize = (IsDisp16(HVal)) ? eSymbolSize32Bit : eSymbolSizeFloat96Bit;
4676 }
4677
4678 if ((OpSize == eSymbolSize32Bit) || (OpSize == eSymbolSize16Bit))
4679 {
4680 if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
4681 else
4682 {
4683 CodeLen = 4;
4684 WAsmCode[0] = 0xf280 | CondCode;
4685 WAsmCode[1] = HVal16;
4686 }
4687 }
4688 else
4689 {
4690 CodeLen = 6;
4691 WAsmCode[0] = 0xf2c0 | CondCode;
4692 WAsmCode[2] = HVal & 0xffff;
4693 WAsmCode[1] = HVal >> 16;
4694 if (IsDisp16(HVal) && (PassNo > 1) && !*AttrPart.Str)
4695 {
4696 WrError(ErrNum_ShortJumpPossible);
4697 WAsmCode[0] ^= 0x40;
4698 CodeLen -= 2;
4699 WAsmCode[1] = WAsmCode[2];
4700 StopfZahl++;
4701 }
4702 }
4703 }
4704 }
4705 }
4706
DecodeFDBcc(Word CondCode)4707 static void DecodeFDBcc(Word CondCode)
4708 {
4709 if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4710 else if (CheckNoFamily(1 << eColdfire))
4711 {
4712 if ((OpSize != eSymbolSize16Bit) && *AttrPart.Str) WrError(ErrNum_InvOpSize);
4713 else if (ChkArgCnt(2, 2))
4714 {
4715 tAdrResult AdrResult;
4716
4717 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
4718 {
4719 LongInt HVal;
4720 Integer HVal16;
4721 Boolean ValOK;
4722 tSymbolFlags Flags;
4723
4724 WAsmCode[0] = 0xf248 | AdrResult.Mode;
4725 WAsmCode[1] = CondCode;
4726 HVal = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &ValOK, &Flags) - (EProgCounter() + 4);
4727 if (ValOK)
4728 {
4729 HVal16 = HVal;
4730 WAsmCode[2] = HVal16;
4731 if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
4732 else CodeLen = 6;
4733 }
4734 }
4735 }
4736 }
4737 }
4738
DecodeFScc(Word CondCode)4739 static void DecodeFScc(Word CondCode)
4740 {
4741 if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4742 else if (!CheckNoFamily(1 << eColdfire));
4743 else if ((OpSize != eSymbolSize8Bit) && *AttrPart.Str) WrError(ErrNum_InvOpSize);
4744 else if (ChkArgCnt(1, 1))
4745 {
4746 tAdrResult AdrResult;
4747
4748 if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
4749 {
4750 CodeLen = 4 + AdrResult.Cnt;
4751 WAsmCode[0] = 0xf240 | AdrResult.Mode;
4752 WAsmCode[1] = CondCode;
4753 CopyAdrVals(WAsmCode + 2, &AdrResult);
4754 }
4755 }
4756 }
4757
DecodeFTRAPcc(Word CondCode)4758 static void DecodeFTRAPcc(Word CondCode)
4759 {
4760 if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
4761 else if (!CheckNoFamily(1 << eColdfire));
4762 else
4763 {
4764 if (!*AttrPart.Str)
4765 OpSize = eSymbolSize8Bit;
4766 if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
4767 else if (ChkArgCnt(OpSize ? 1 : 0, OpSize ? 1 : 0))
4768 {
4769 WAsmCode[0] = 0xf278;
4770 WAsmCode[1] = CondCode;
4771 if (OpSize == eSymbolSize8Bit)
4772 {
4773 WAsmCode[0] |= 4;
4774 CodeLen = 4;
4775 }
4776 else
4777 {
4778 tAdrResult AdrResult;
4779
4780 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
4781 {
4782 WAsmCode[0] |= (OpSize + 1);
4783 CopyAdrVals(WAsmCode + 2, &AdrResult);
4784 CodeLen = 4 + AdrResult.Cnt;
4785 }
4786 }
4787 }
4788 }
4789 }
4790
4791 /*-------------------------------------------------------------------------*/
4792 /* Hilfsroutinen MMU: */
4793
DecodeFC(const tStrComp * pArg,Word * erg)4794 static Boolean DecodeFC(const tStrComp *pArg, Word *erg)
4795 {
4796 Boolean OK;
4797 Word Val;
4798
4799 if (!as_strcasecmp(pArg->Str, "SFC"))
4800 {
4801 *erg = 0;
4802 return True;
4803 }
4804
4805 if (!as_strcasecmp(pArg->Str, "DFC"))
4806 {
4807 *erg = 1;
4808 return True;
4809 }
4810
4811 switch (DecodeReg(pArg, erg, False))
4812 {
4813 case eIsReg:
4814 if (*erg < 8)
4815 {
4816 *erg += 8;
4817 return True;
4818 }
4819 break;
4820 case eIsNoReg:
4821 break;
4822 default:
4823 return False;
4824 }
4825
4826 if (*pArg->Str == '#')
4827 {
4828 Val = EvalStrIntExpressionOffs(pArg, 1, Int4, &OK);
4829 if (OK)
4830 *erg = Val + 16;
4831 return OK;
4832 }
4833
4834 return False;
4835 }
4836
DecodePMMUReg(char * Asc,Word * erg,tSymbolSize * pSize)4837 static Boolean DecodePMMUReg(char *Asc, Word *erg, tSymbolSize *pSize)
4838 {
4839 Byte z;
4840
4841 if ((strlen(Asc) == 4) && (!as_strncasecmp(Asc, "BAD", 3)) && ValReg(Asc[3]))
4842 {
4843 *pSize = eSymbolSize16Bit;
4844 *erg = 0x7000 + ((Asc[3] - '0') << 2);
4845 return True;
4846 }
4847 if ((strlen(Asc) == 4) && (!as_strncasecmp(Asc, "BAC", 3)) && ValReg(Asc[3]))
4848 {
4849 *pSize = eSymbolSize16Bit;
4850 *erg = 0x7400 + ((Asc[3] - '0') << 2);
4851 return True;
4852 }
4853
4854 for (z = 0; z < PMMURegCnt; z++)
4855 if (!as_strcasecmp(Asc, PMMURegs[z].pName))
4856 break;
4857 if (z < PMMURegCnt)
4858 {
4859 *pSize = PMMURegs[z].Size;
4860 *erg = PMMURegs[z].Code << 10;
4861 }
4862 return (z < PMMURegCnt);
4863 }
4864
4865 /*-------------------------------------------------------------------------*/
4866
DecodePSAVE(Word Code)4867 static void DecodePSAVE(Word Code)
4868 {
4869 UNUSED(Code);
4870
4871 if (!ChkArgCnt(1, 1));
4872 else if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
4873 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
4874 else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
4875 else
4876 {
4877 tAdrResult AdrResult;
4878
4879 if (DecodeAdr(&ArgStr[1], MModAdrI | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
4880 {
4881 CodeLen = 2 + AdrResult.Cnt;
4882 WAsmCode[0] = 0xf100 | AdrResult.Mode;
4883 CopyAdrVals(WAsmCode + 1, &AdrResult);
4884 CheckSup();
4885 }
4886 }
4887 }
4888
DecodePRESTORE(Word Code)4889 static void DecodePRESTORE(Word Code)
4890 {
4891 UNUSED(Code);
4892
4893 if (!ChkArgCnt(1, 1));
4894 else if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
4895 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
4896 else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
4897 else
4898 {
4899 tAdrResult AdrResult;
4900
4901 if (DecodeAdr(&ArgStr[1], MModAdrI | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
4902 {
4903 CodeLen = 2 + AdrResult.Cnt;
4904 WAsmCode[0] = 0xf140 | AdrResult.Mode;
4905 CopyAdrVals(WAsmCode + 1, &AdrResult);
4906 CheckSup();
4907 }
4908 }
4909 }
4910
DecodePFLUSHA(Word Code)4911 static void DecodePFLUSHA(Word Code)
4912 {
4913 UNUSED(Code);
4914
4915 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
4916 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
4917 else if (ChkArgCnt(0, 0))
4918 {
4919 switch (pCurrCPUProps->Family)
4920 {
4921 case e68KGen3:
4922 CodeLen = 2;
4923 WAsmCode[0] = 0xf518;
4924 break;
4925 default:
4926 CodeLen = 4;
4927 WAsmCode[0] = 0xf000;
4928 WAsmCode[1] = 0x2400;
4929 break;
4930 }
4931 CheckSup();
4932 }
4933 }
4934
DecodePFLUSHAN(Word Code)4935 static void DecodePFLUSHAN(Word Code)
4936 {
4937 UNUSED(Code);
4938
4939 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
4940 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
4941 else if (ChkArgCnt(0, 0)
4942 && CheckFamily(1 << e68KGen3))
4943 {
4944 CodeLen = 2;
4945 WAsmCode[0] = 0xf510;
4946 CheckSup();
4947 }
4948 }
4949
DecodePFLUSH_PFLUSHS(Word Code)4950 static void DecodePFLUSH_PFLUSHS(Word Code)
4951 {
4952 tAdrResult AdrResult;
4953
4954 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
4955 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
4956 else if (pCurrCPUProps->Family == e68KGen3)
4957 {
4958 if (Code) WrError(ErrNum_FullPMMUNotEnabled);
4959 else if (ChkArgCnt(1, 1))
4960 {
4961 if (DecodeAdr(&ArgStr[1], MModAdrI, &AdrResult))
4962 {
4963 WAsmCode[0] = 0xf508 + (AdrResult.Mode & 7);
4964 CodeLen = 2;
4965 CheckSup();
4966 }
4967 }
4968 }
4969 else if (!ChkArgCnt(2, 3));
4970 else if ((Code) && (!FullPMMU)) WrError(ErrNum_FullPMMUNotEnabled);
4971 else if (!DecodeFC(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvFCode);
4972 else
4973 {
4974 OpSize = eSymbolSize8Bit;
4975 if (DecodeAdr(&ArgStr[2], MModImm, &AdrResult))
4976 {
4977 if (AdrResult.Vals[0] > 15) WrError(ErrNum_InvFMask);
4978 else
4979 {
4980 WAsmCode[1] |= (AdrResult.Vals[0] << 5) | 0x3000 | Code;
4981 WAsmCode[0] = 0xf000;
4982 CodeLen = 4;
4983 CheckSup();
4984 if (ArgCnt == 3)
4985 {
4986 WAsmCode[1] |= 0x800;
4987 if (!DecodeAdr(&ArgStr[3], MModAdrI | MModDAdrI | MModAIX | MModAbs, &AdrResult))
4988 CodeLen = 0;
4989 else
4990 {
4991 WAsmCode[0] |= AdrResult.Mode;
4992 CodeLen += AdrResult.Cnt;
4993 CopyAdrVals(WAsmCode + 2, &AdrResult);
4994 }
4995 }
4996 }
4997 }
4998 }
4999 }
5000
DecodePFLUSHN(Word Code)5001 static void DecodePFLUSHN(Word Code)
5002 {
5003 UNUSED(Code);
5004
5005 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
5006 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5007 else if (ChkArgCnt(1, 1)
5008 && CheckFamily(1 << e68KGen3))
5009 {
5010 tAdrResult AdrResult;
5011
5012 if (DecodeAdr(&ArgStr[1], MModAdrI, &AdrResult))
5013 {
5014 WAsmCode[0] = 0xf500 + (AdrResult.Mode & 7);
5015 CodeLen = 2;
5016 CheckSup();
5017 }
5018 }
5019 }
5020
DecodePFLUSHR(Word Code)5021 static void DecodePFLUSHR(Word Code)
5022 {
5023 UNUSED(Code);
5024
5025 if (*AttrPart.Str)
5026 OpSize = eSymbolSize64Bit;
5027 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5028 if (OpSize != eSymbolSize64Bit) WrError(ErrNum_InvOpSize);
5029 else if (!ChkArgCnt(1, 1));
5030 else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
5031 else
5032 {
5033 tAdrResult AdrResult;
5034
5035 RelPos = 4;
5036 if (DecodeAdr(&ArgStr[1], MModAdrI | MModPre | MModPost | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
5037 {
5038 WAsmCode[0] = 0xf000 | AdrResult.Mode;
5039 WAsmCode[1] = 0xa000;
5040 CopyAdrVals(WAsmCode + 2, &AdrResult);
5041 CodeLen = 4 + AdrResult.Cnt; CheckSup();
5042 }
5043 }
5044 }
5045
DecodePLOADR_PLOADW(Word Code)5046 static void DecodePLOADR_PLOADW(Word Code)
5047 {
5048 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
5049 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5050 else if (!ChkArgCnt(2, 2));
5051 else if (!DecodeFC(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvFCode);
5052 else
5053 {
5054 tAdrResult AdrResult;
5055
5056 if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI | MModAIX | MModAbs, &AdrResult))
5057 {
5058 WAsmCode[0] = 0xf000 | AdrResult.Mode;
5059 WAsmCode[1] |= Code;
5060 CodeLen = 4 + AdrResult.Cnt;
5061 CopyAdrVals(WAsmCode + 2, &AdrResult);
5062 CheckSup();
5063 }
5064 }
5065 }
5066
DecodePMOVE_PMOVEFD(Word Code)5067 static void DecodePMOVE_PMOVEFD(Word Code)
5068 {
5069 tSymbolSize RegSize;
5070 unsigned Mask;
5071 tAdrResult AdrResult;
5072
5073 if (!ChkArgCnt(2, 2));
5074 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5075 else
5076 {
5077 if (DecodePMMUReg(ArgStr[1].Str, WAsmCode + 1, &RegSize))
5078 {
5079 WAsmCode[1] |= 0x200;
5080 if (!*AttrPart.Str)
5081 OpSize = RegSize;
5082 if (OpSize != RegSize) WrError(ErrNum_InvOpSize);
5083 else
5084 {
5085 Mask = MModAdrI | MModDAdrI | MModAIX | MModAbs;
5086 if (FullPMMU)
5087 {
5088 Mask *= MModPost | MModPre;
5089 if (RegSize != eSymbolSize64Bit)
5090 Mask += MModData | MModAdr;
5091 }
5092 if (DecodeAdr(&ArgStr[2], Mask, &AdrResult))
5093 {
5094 WAsmCode[0] = 0xf000 | AdrResult.Mode;
5095 CodeLen = 4 + AdrResult.Cnt;
5096 CopyAdrVals(WAsmCode + 2, &AdrResult);
5097 CheckSup();
5098 }
5099 }
5100 }
5101 else if (DecodePMMUReg(ArgStr[2].Str, WAsmCode + 1, &RegSize))
5102 {
5103 if (!*AttrPart.Str)
5104 OpSize = RegSize;
5105 if (OpSize != RegSize) WrError(ErrNum_InvOpSize);
5106 else
5107 {
5108 RelPos = 4;
5109 Mask = MModAdrI | MModDAdrI | MModAIX | MModAbs;
5110 if (FullPMMU)
5111 {
5112 Mask += MModPost | MModPre | MModPC | MModPCIdx | MModImm;
5113 if (RegSize != eSymbolSize64Bit)
5114 Mask += MModData | MModAdr;
5115 }
5116 if (DecodeAdr(&ArgStr[1], Mask, &AdrResult))
5117 {
5118 WAsmCode[0] = 0xf000 | AdrResult.Mode;
5119 CodeLen = 4 + AdrResult.Cnt;
5120 CopyAdrVals(WAsmCode + 2, &AdrResult);
5121 WAsmCode[1] += Code;
5122 CheckSup();
5123 }
5124 }
5125 }
5126 else
5127 WrError(ErrNum_InvMMUReg);
5128 }
5129 }
5130
DecodePTESTR_PTESTW(Word Code)5131 static void DecodePTESTR_PTESTW(Word Code)
5132 {
5133 tAdrResult AdrResult;
5134
5135 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
5136 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5137 else if (pCurrCPUProps->Family == e68KGen3)
5138 {
5139 if (ChkArgCnt(1, 1))
5140 {
5141 if (DecodeAdr(&ArgStr[1], MModAdrI, &AdrResult))
5142 {
5143 WAsmCode[0] = 0xf548 + (AdrResult.Mode & 7) + (Code << 5);
5144 CodeLen = 2;
5145 CheckSup();
5146 }
5147 }
5148 }
5149 else if (ChkArgCnt(3, 4))
5150 {
5151 if (!DecodeFC(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvFCode);
5152 else
5153 {
5154 if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI | MModAIX | MModAbs, &AdrResult))
5155 {
5156 WAsmCode[0] = 0xf000 | AdrResult.Mode;
5157 CodeLen = 4 + AdrResult.Cnt;
5158 WAsmCode[1] |= 0x8000 | (Code << 9);
5159 CopyAdrVals(WAsmCode + 2, &AdrResult);
5160 if (DecodeAdr(&ArgStr[3], MModImm, &AdrResult))
5161 {
5162 if (AdrResult.Vals[0] > 7)
5163 {
5164 WrError(ErrNum_Level07);
5165 CodeLen = 0;
5166 }
5167 else
5168 {
5169 WAsmCode[1] |= AdrResult.Vals[0] << 10;
5170 if (ArgCnt == 4)
5171 {
5172 if (!DecodeAdr(&ArgStr[4], MModAdr, &AdrResult))
5173 CodeLen = 0;
5174 else
5175 WAsmCode[1] |= AdrResult.Mode << 5;
5176 CheckSup();
5177 }
5178 }
5179 }
5180 else
5181 CodeLen = 0;
5182 }
5183 }
5184 }
5185 }
5186
DecodePVALID(Word Code)5187 static void DecodePVALID(Word Code)
5188 {
5189 UNUSED(Code);
5190
5191 if (!ChkArgCnt(2, 2));
5192 else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5193 else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
5194 else if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
5195 else
5196 {
5197 tAdrResult AdrResult;
5198
5199 if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI | MModAIX | MModAbs, &AdrResult))
5200 {
5201 WAsmCode[0] = 0xf000 | AdrResult.Mode;
5202 WAsmCode[1] = 0x2800;
5203 CodeLen = 4 + AdrResult.Cnt;
5204 CopyAdrVals(WAsmCode + 1, &AdrResult);
5205 if (!as_strcasecmp(ArgStr[1].Str, "VAL"));
5206 else
5207 {
5208 if (DecodeAdr(&ArgStr[1], MModAdr, &AdrResult))
5209 WAsmCode[1] |= 0x400 | (AdrResult.Mode & 7);
5210 else
5211 CodeLen = 0;
5212 }
5213 }
5214 }
5215 }
5216
DecodePBcc(Word CondCode)5217 static void DecodePBcc(Word CondCode)
5218 {
5219 if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5220 else
5221 {
5222 if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit) && (OpSize != eSymbolSizeFloat96Bit)) WrError(ErrNum_InvOpSize);
5223 else if (!ChkArgCnt(1, 1));
5224 else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
5225 else
5226 {
5227 LongInt HVal;
5228 Integer HVal16;
5229 Boolean ValOK;
5230 tSymbolFlags Flags;
5231
5232 HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &Flags) - (EProgCounter() + 2);
5233 HVal16 = HVal;
5234
5235 if (!*AttrPart.Str)
5236 OpSize = (IsDisp16(HVal)) ? eSymbolSize32Bit : eSymbolSizeFloat96Bit;
5237
5238 if ((OpSize == eSymbolSize32Bit) || (OpSize == eSymbolSize16Bit))
5239 {
5240 if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
5241 else
5242 {
5243 CodeLen = 4;
5244 WAsmCode[0] = 0xf080 | CondCode;
5245 WAsmCode[1] = HVal16;
5246 CheckSup();
5247 }
5248 }
5249 else
5250 {
5251 CodeLen = 6;
5252 WAsmCode[0] = 0xf0c0 | CondCode;
5253 WAsmCode[2] = HVal & 0xffff;
5254 WAsmCode[1] = HVal >> 16;
5255 CheckSup();
5256 }
5257 }
5258 }
5259 }
5260
DecodePDBcc(Word CondCode)5261 static void DecodePDBcc(Word CondCode)
5262 {
5263 if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5264 else
5265 {
5266 if ((OpSize != eSymbolSize16Bit) && *AttrPart.Str) WrError(ErrNum_InvOpSize);
5267 else if (!ChkArgCnt(2, 2));
5268 else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
5269 else
5270 {
5271 tAdrResult AdrResult;
5272
5273 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
5274 {
5275 LongInt HVal;
5276 Integer HVal16;
5277 Boolean ValOK;
5278 tSymbolFlags Flags;
5279
5280 WAsmCode[0] = 0xf048 | AdrResult.Mode;
5281 WAsmCode[1] = CondCode;
5282 HVal = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &ValOK, &Flags) - (EProgCounter() + 4);
5283 if (ValOK)
5284 {
5285 HVal16 = HVal;
5286 WAsmCode[2] = HVal16;
5287 if ((!IsDisp16(HVal)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
5288 else
5289 CodeLen = 6;
5290 CheckSup();
5291 }
5292 }
5293 }
5294 }
5295 }
5296
DecodePScc(Word CondCode)5297 static void DecodePScc(Word CondCode)
5298 {
5299 if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5300 else
5301 {
5302 if ((OpSize != eSymbolSize8Bit) && *AttrPart.Str) WrError(ErrNum_InvOpSize);
5303 else if (!ChkArgCnt(1, 1));
5304 else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
5305 else
5306 {
5307 tAdrResult AdrResult;
5308
5309 if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
5310 {
5311 CodeLen = 4 + AdrResult.Cnt;
5312 WAsmCode[0] = 0xf040 | AdrResult.Mode;
5313 WAsmCode[1] = CondCode;
5314 CopyAdrVals(WAsmCode + 2, &AdrResult);
5315 CheckSup();
5316 }
5317 }
5318 }
5319 }
5320
DecodePTRAPcc(Word CondCode)5321 static void DecodePTRAPcc(Word CondCode)
5322 {
5323 if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
5324 else
5325 {
5326 if (!*AttrPart.Str)
5327 OpSize = eSymbolSize8Bit;
5328 if (OpSize > 2) WrError(ErrNum_InvOpSize);
5329 else if (!ChkArgCnt(OpSize ? 1 : 0, OpSize ? 1 : 0));
5330 else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
5331 else
5332 {
5333 WAsmCode[0] = 0xf078;
5334 WAsmCode[1] = CondCode;
5335 if (OpSize == eSymbolSize8Bit)
5336 {
5337 WAsmCode[0] |= 4;
5338 CodeLen = 4;
5339 CheckSup();
5340 }
5341 else
5342 {
5343 tAdrResult AdrResult;
5344
5345 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
5346 {
5347 WAsmCode[0] |= (OpSize + 1);
5348 CopyAdrVals(WAsmCode + 2, &AdrResult);
5349 CodeLen = 4 + AdrResult.Cnt;
5350 CheckSup();
5351 }
5352 }
5353 }
5354 }
5355 }
5356
DecodeColdBit(Word Code)5357 static void DecodeColdBit(Word Code)
5358 {
5359 if (!*AttrPart.Str)
5360 OpSize = eSymbolSize32Bit;
5361 if (ChkArgCnt(1, 1)
5362 && CheckColdSize()
5363 && CheckFamily(1 << eColdfire)
5364 && CheckISA((1 << eCfISA_APlus) | (1 << eCfISA_C)))
5365 {
5366 tAdrResult AdrResult;
5367
5368 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
5369 {
5370 CodeLen = 2;
5371 WAsmCode[0] = Code | (AdrResult.Mode & 7);
5372 }
5373 }
5374 }
5375
DecodeSTLDSR(Word Code)5376 static void DecodeSTLDSR(Word Code)
5377 {
5378 UNUSED(Code);
5379
5380 if (!*AttrPart.Str)
5381 OpSize = eSymbolSize16Bit;
5382 if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
5383 else if (ChkArgCnt(1, 1)
5384 && CheckFamily(1 << eColdfire)
5385 && CheckISA((1 << eCfISA_APlus) | (1 << eCfISA_C)))
5386 {
5387 tAdrResult AdrResult;
5388
5389 if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
5390 {
5391 CodeLen = 6;
5392 WAsmCode[0] = 0x40e7;
5393 WAsmCode[1] = 0x46fc;
5394 WAsmCode[2] = AdrResult.Vals[0];
5395 }
5396 }
5397 }
5398
DecodeINTOUCH(Word Code)5399 static void DecodeINTOUCH(Word Code)
5400 {
5401 UNUSED(Code);
5402
5403 if (*AttrPart.Str) WrError(ErrNum_InvOpSize);
5404 else if (ChkArgCnt(1, 1)
5405 && CheckFamily(1 << eColdfire)
5406 && (pCurrCPUProps->CfISA >= eCfISA_B))
5407 {
5408 tAdrResult AdrResult;
5409
5410 if (DecodeAdr(&ArgStr[1], MModAdrI, &AdrResult))
5411 {
5412 CodeLen = 2;
5413 WAsmCode[0] = 0xf428 | (AdrResult.Mode & 7);
5414 CheckSup();
5415 }
5416 }
5417 }
5418
DecodeMOV3Q(Word Code)5419 static void DecodeMOV3Q(Word Code)
5420 {
5421 Boolean OK;
5422 tSymbolFlags Flags;
5423 ShortInt Val;
5424 tAdrResult AdrResult;
5425
5426 UNUSED(Code);
5427
5428 if (!ChkArgCnt(2, 2)
5429 || !CheckFamily(1 << eColdfire)
5430 || (pCurrCPUProps->CfISA < eCfISA_B)
5431 || !CheckColdSize())
5432 return;
5433
5434 if (!DecodeAdr(&ArgStr[2], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
5435 return;
5436
5437 if (*ArgStr[1].Str != '#')
5438 {
5439 WrStrErrorPos(ErrNum_OnlyImmAddr, &ArgStr[1]);
5440 return;
5441 }
5442
5443 Val = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], 1, SInt4, &OK, &Flags);
5444 if (!OK)
5445 return;
5446 if (mFirstPassUnknown(Flags))
5447 Val = 1;
5448
5449 if (Val == -1)
5450 Val = 0;
5451 else if (!ChkRange(Val, 1, 7))
5452 return;
5453
5454 WAsmCode[0] = 0xa140 | ((Val & 7) << 9) | AdrResult.Mode;
5455 CopyAdrVals(WAsmCode + 1, &AdrResult);
5456 CodeLen = 2 + AdrResult.Cnt;
5457 }
5458
DecodeMVS_MVZ(Word Code)5459 static void DecodeMVS_MVZ(Word Code)
5460 {
5461 Word DestReg;
5462 tAdrResult AdrResult;
5463
5464 if (!ChkArgCnt(2, 2)
5465 || !CheckFamily(1 << eColdfire)
5466 || (pCurrCPUProps->CfISA < eCfISA_B))
5467 return;
5468
5469 if (!*AttrPart.Str)
5470 OpSize = eSymbolSize16Bit;
5471 if (OpSize > eSymbolSize16Bit)
5472 {
5473 WrError(ErrNum_InvOpSize);
5474 return;
5475 }
5476
5477 if (!DecodeAdr(&ArgStr[2], MModData, &AdrResult))
5478 return;
5479 DestReg = AdrResult.Mode & 7;
5480
5481 if (DecodeAdr(&ArgStr[1], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs | MModImm | MModPC | MModPCIdx, &AdrResult))
5482 {
5483 WAsmCode[0] = Code | (DestReg << 9) | (OpSize << 6) | AdrResult.Mode;
5484 CopyAdrVals(WAsmCode + 1, &AdrResult);
5485 CodeLen = 2 + AdrResult.Cnt;
5486 }
5487 }
5488
DecodeSATS(Word Code)5489 static void DecodeSATS(Word Code)
5490 {
5491 tAdrResult AdrResult;
5492
5493 UNUSED(Code);
5494
5495 if (!ChkArgCnt(1, 1)
5496 || !CheckFamily(1 << eColdfire)
5497 || (pCurrCPUProps->CfISA < eCfISA_B)
5498 || !CheckColdSize())
5499 return;
5500
5501 if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
5502 {
5503 WAsmCode[0] = 0x4c80 | (AdrResult.Mode & 7);
5504 CodeLen = 2;
5505 }
5506 }
5507
DecodeMAC_MSAC(Word Code)5508 static void DecodeMAC_MSAC(Word Code)
5509 {
5510 Word Rx, Ry, Rw, Ux = 0, Uy = 0, Scale = 0, Mask, AccNum = 0;
5511 int CurrArg, RemArgCnt;
5512 Boolean ExplicitLoad = !!(Code & 0x8000);
5513 tAdrResult AdrResult;
5514
5515 Code &= 0x7fff;
5516
5517 if (!(pCurrCPUProps->SuppFlags & eFlagMAC))
5518 {
5519 WrError(ErrNum_InstructionNotSupported);
5520 return;
5521 }
5522
5523 if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit))
5524 {
5525 WrError(ErrNum_InvOpSize);
5526 return;
5527 }
5528
5529 /* 2 args is the absolute minimum. 6 is the maximum (Ry, Rx, scale, <ea>, Rw, ACC) */
5530
5531 if (!ChkArgCnt(2, 6))
5532 return;
5533
5534 /* Ry and Rx are always present, and are always the first arguments: */
5535
5536 if (OpSize == eSymbolSize16Bit)
5537 {
5538 if (!SplitMACUpperLower(&Uy, &ArgStr[1])
5539 || !SplitMACUpperLower(&Ux, &ArgStr[2]))
5540 return;
5541 }
5542
5543 if (!DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult))
5544 return;
5545 Ry = AdrResult.Mode & 15;
5546 if (!DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
5547 return;
5548 Rx = AdrResult.Mode & 15;
5549 CurrArg = 3;
5550
5551 /* Is a scale given as next argument? */
5552
5553 if ((ArgCnt >= CurrArg) && DecodeMACScale(&ArgStr[CurrArg], &Scale))
5554 CurrArg++;
5555
5556 /* We now have between 0 and 3 args left:
5557 0 -> no load, ACC0
5558 1 -> ACCn
5559 2 -> load, ACC0
5560 3 -> load, ACCn
5561 If the 'L' variant (MACL, MSACL) was given, a parallel
5562 load was specified explicitly and there MUST be the <ea> and Rw arguments: */
5563
5564 RemArgCnt = ArgCnt - CurrArg + 1;
5565 if ((RemArgCnt > 3)
5566 || (ExplicitLoad && (RemArgCnt < 2)))
5567 {
5568 WrError(ErrNum_WrongArgCnt);
5569 return;
5570 }
5571
5572 /* assumed ACC(0) if no accumulator given */
5573
5574 if (Odd(RemArgCnt))
5575 {
5576 if (!DecodeMACACC(ArgStr[ArgCnt].Str, &AccNum))
5577 {
5578 WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgCnt]);
5579 return;
5580 }
5581 }
5582
5583 /* If parallel load, bit 7 of first word is set for MAC. This bit is
5584 used on EMAC to store accumulator # LSB. To keep things upward-compatible,
5585 accumulator # LSB is stored inverted on EMAC if a parallel load is present.
5586 Since MAC only uses accumulator #0, this works for either target: */
5587
5588 if (RemArgCnt >= 2)
5589 AccNum ^= 1;
5590
5591 /* Common things for variant with and without parallel load: */
5592
5593 WAsmCode[0] = 0xa000 | ((AccNum & 1) << 7);
5594 WAsmCode[1] = ((OpSize - 1) << 11) | (Scale << 9) | Code | (Ux << 7) | (Uy << 6) | ((AccNum & 2) << 3);
5595
5596 /* With parallel load? */
5597
5598 if (RemArgCnt >= 2)
5599 {
5600 if (!DecodeAdr(&ArgStr[CurrArg + 1], MModData | MModAdr, &AdrResult))
5601 return;
5602 Rw = AdrResult.Mode & 15;
5603
5604 if (!SplitMACANDMASK(&Mask, &ArgStr[CurrArg]))
5605 return;
5606 if (!DecodeAdr(&ArgStr[CurrArg], MModAdrI | MModPre | MModPost | MModDAdrI, &AdrResult))
5607 return;
5608
5609 WAsmCode[0] |= ((Rw & 7) << 9) | ((Rw & 8) << 3) | AdrResult.Mode;
5610 WAsmCode[1] |= (Mask << 5) | (Rx << 12) | (Ry << 0);
5611 CodeLen = 4 + AdrResult.Cnt;
5612 CopyAdrVals(WAsmCode + 2, &AdrResult);
5613 }
5614
5615 /* multiply/accumulate only */
5616
5617 else
5618 {
5619 WAsmCode[0] |= Ry | ((Rx & 7) << 9) | ((Rx & 8) << 3);
5620 CodeLen = 4;
5621 }
5622 }
5623
DecodeMOVCLR(Word Code)5624 static void DecodeMOVCLR(Word Code)
5625 {
5626 Word ACCReg;
5627
5628 UNUSED(Code);
5629
5630 if (!ChkArgCnt(2,2));
5631 else if (*AttrPart.Str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
5632 else if (!(pCurrCPUProps->SuppFlags & eFlagEMAC)) WrError(ErrNum_InstructionNotSupported);
5633 else if (!DecodeMACACC(ArgStr[1].Str, &ACCReg)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
5634 else
5635 {
5636 tAdrResult AdrResult;
5637
5638 if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
5639 {
5640 WAsmCode[0] = 0xa1c0 | AdrResult.Mode | (ACCReg << 9);
5641 CodeLen = 2;
5642 }
5643 }
5644 }
5645
DecodeMxxAC(Word Code)5646 static void DecodeMxxAC(Word Code)
5647 {
5648 Word Rx, Ry, Ux, Uy, Scale = 0, ACCx, ACCw;
5649 tAdrResult AdrResult;
5650
5651 if (!(pCurrCPUProps->SuppFlags & eFlagEMAC)
5652 || (pCurrCPUProps->CfISA < eCfISA_B))
5653 {
5654 WrError(ErrNum_InstructionNotSupported);
5655 return;
5656 }
5657
5658 if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit))
5659 {
5660 WrError(ErrNum_InvOpSize);
5661 return;
5662 }
5663
5664 if (!ChkArgCnt(4, 5))
5665 return;
5666
5667 if (!DecodeMACACC(ArgStr[ArgCnt - 1].Str, &ACCx))
5668 {
5669 WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgCnt - 1]);
5670 return;
5671 }
5672 if (!DecodeMACACC(ArgStr[ArgCnt].Str, &ACCw))
5673 {
5674 WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgCnt]);
5675 return;
5676 }
5677
5678 if (5 == ArgCnt)
5679 {
5680 if (!DecodeMACScale(&ArgStr[3], &Scale))
5681 {
5682 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[3]);
5683 return;
5684 }
5685 }
5686
5687 if (OpSize == eSymbolSize16Bit)
5688 {
5689 if (!SplitMACUpperLower(&Uy, &ArgStr[1])
5690 || !SplitMACUpperLower(&Ux, &ArgStr[2]))
5691 return;
5692 }
5693 else
5694 Ux = Uy = 0;
5695
5696 if (!DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult))
5697 return;
5698 Ry = AdrResult.Mode & 15;
5699 if (!DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
5700 return;
5701 Rx = AdrResult.Mode & 15;
5702
5703 WAsmCode[0] = 0xa000 | ((Rx & 7) << 9) | ((Rx & 8) << 3) | Ry | ((ACCx & 1) << 7);
5704 WAsmCode[1] = Code | ((OpSize - 1) << 11) | (Scale << 9) | (Ux << 7) | (Uy << 6) | ((ACCx & 2) << 3) | (ACCw << 2);
5705 CodeLen = 4;
5706 }
5707
DecodeCPBCBUSY(Word Code)5708 static void DecodeCPBCBUSY(Word Code)
5709 {
5710 if (pCurrCPUProps->CfISA == eCfISA_None) WrError(ErrNum_InstructionNotSupported);
5711 else if (*AttrPart.Str && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
5712 else if (ChkArgCnt(1, 1))
5713 {
5714 Boolean OK;
5715 tSymbolFlags Flags;
5716 LongInt Dist;
5717
5718 Dist = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt32, &OK, &Flags) - (EProgCounter() + 2);
5719 if (OK)
5720 {
5721 if (!mSymbolQuestionable(Flags) && !IsDisp16(Dist)) WrError(ErrNum_JmpDistTooBig);
5722 else
5723 {
5724 WAsmCode[0] = Code;
5725 WAsmCode[1] = Dist & 0xffff;
5726 CodeLen = 4;
5727 }
5728 }
5729 }
5730 }
5731
DecodeCPLDST(Word Code)5732 static void DecodeCPLDST(Word Code)
5733 {
5734 if (pCurrCPUProps->CfISA == eCfISA_None) WrError(ErrNum_InstructionNotSupported);
5735 else if (ChkArgCnt(1, 4))
5736 {
5737 Boolean OK;
5738 Word Reg;
5739 const tStrComp *pEAArg = NULL, *pRnArg = NULL, *pETArg = NULL;
5740
5741 WAsmCode[0] = Code | (OpSize << 6);
5742
5743 /* CMD is always present and i bits 0..8 - immediate marker is optional
5744 since it is always a constant. */
5745
5746 WAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[ArgCnt], !!(*ArgStr[ArgCnt].Str == '#'), UInt16, &OK);
5747 if (!OK)
5748 return;
5749
5750 if (ArgCnt >= 2)
5751 pEAArg = &ArgStr[1];
5752 switch (ArgCnt)
5753 {
5754 case 4:
5755 pRnArg = &ArgStr[2];
5756 pETArg = &ArgStr[3];
5757 break;
5758 case 3:
5759 if (DecodeReg(&ArgStr[2], &Reg, False) == eIsReg)
5760 pRnArg = &ArgStr[2];
5761 else
5762 pETArg = &ArgStr[2];
5763 break;
5764 }
5765
5766 if (pRnArg)
5767 {
5768 if (DecodeReg(pRnArg, &Reg, True) != eIsReg)
5769 return;
5770 WAsmCode[1] |= Reg << 12;
5771 }
5772 if (pETArg)
5773 {
5774 Word ET;
5775
5776 ET = EvalStrIntExpression(pETArg, UInt3, &OK);
5777 if (!OK)
5778 return;
5779 WAsmCode[1] |= ET << 9;
5780 }
5781
5782 if (pEAArg)
5783 {
5784 tAdrResult AdrResult;
5785
5786 if (!DecodeAdr(pEAArg, MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI, &AdrResult))
5787 return;
5788 WAsmCode[0] |= AdrResult.Mode;
5789 CopyAdrVals(WAsmCode + 2, &AdrResult);
5790 CodeLen = 4 + AdrResult.Cnt;
5791 }
5792 else
5793 CodeLen = 4;
5794 }
5795 }
5796
DecodeCPNOP(Word Code)5797 static void DecodeCPNOP(Word Code)
5798 {
5799 if (pCurrCPUProps->CfISA == eCfISA_None) WrError(ErrNum_InstructionNotSupported);
5800 else if (ChkArgCnt(0, 1))
5801 {
5802 WAsmCode[0] = Code | (OpSize << 6);
5803
5804 /* CMD is always present and i bits 0..8 - immediate marker is optional
5805 since it is always a constant. */
5806
5807 if (ArgCnt > 0)
5808 {
5809 Word ET;
5810 Boolean OK;
5811
5812 ET = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
5813 if (!OK)
5814 return;
5815 WAsmCode[1] |= ET << 9;
5816 }
5817
5818 CodeLen = 4;
5819 }
5820 }
5821
5822 /*-------------------------------------------------------------------------*/
5823 /* Dekodierroutinen Pseudoinstruktionen: */
5824
PutByte(Byte b)5825 static void PutByte(Byte b)
5826 {
5827 if ((CodeLen & 1) && (!BigEndian))
5828 {
5829 BAsmCode[CodeLen] = BAsmCode[CodeLen - 1];
5830 BAsmCode[CodeLen - 1] = b;
5831 }
5832 else
5833 {
5834 BAsmCode[CodeLen] = b;
5835 }
5836 CodeLen++;
5837 }
5838
DecodeSTR(Word Index)5839 static void DecodeSTR(Word Index)
5840 {
5841 int l, z;
5842 UNUSED(Index);
5843
5844 if (!ChkArgCnt(1, 1));
5845 else if (((l = strlen(ArgStr[1].Str)) < 2)
5846 || (*ArgStr[1].Str != '\'')
5847 || (ArgStr[1].Str[l - 1] != '\'')) WrStrErrorPos(ErrNum_ExpectString, &ArgStr[1]);
5848 else
5849 {
5850 PutByte(l - 2);
5851 for (z = 1; z < l - 1; z++)
5852 PutByte(CharTransTable[((usint) ArgStr[1].Str[z]) & 0xff]);
5853 }
5854 }
5855
5856 /*-------------------------------------------------------------------------*/
5857 /* Codetabellenverwaltung */
5858
AddFixed(const char * NName,Word NCode,Boolean NSup,unsigned NMask)5859 static void AddFixed(const char *NName, Word NCode, Boolean NSup, unsigned NMask)
5860 {
5861 if (InstrZ >= FixedOrderCnt) exit(255);
5862 FixedOrders[InstrZ].Code = NCode;
5863 FixedOrders[InstrZ].MustSup = NSup;
5864 FixedOrders[InstrZ].FamilyMask = NMask;
5865 AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
5866 }
5867
AddCond(const char * NName,Byte NCode)5868 static void AddCond(const char *NName, Byte NCode)
5869 {
5870 char TmpName[30];
5871
5872 if (NCode >= 2) /* BT is BRA and BF is BSR */
5873 {
5874 as_snprintf(TmpName, sizeof(TmpName), "B%s", NName);
5875 AddInstTable(InstTable, TmpName, NCode, DecodeBcc);
5876 }
5877 as_snprintf(TmpName, sizeof(TmpName), "S%s", NName);
5878 AddInstTable(InstTable, TmpName, NCode, DecodeScc);
5879 as_snprintf(TmpName, sizeof(TmpName), "DB%s", NName);
5880 AddInstTable(InstTable, TmpName, NCode, DecodeDBcc);
5881 as_snprintf(TmpName, sizeof(TmpName), "TRAP%s", NName);
5882 AddInstTable(InstTable, TmpName, NCode, DecodeTRAPcc);
5883 }
5884
AddFPUOp(const char * NName,Byte NCode,Boolean NDya,tSuppFlags NeedFlags)5885 static void AddFPUOp(const char *NName, Byte NCode, Boolean NDya, tSuppFlags NeedFlags)
5886 {
5887 if (InstrZ >= FPUOpCnt) exit(255);
5888 FPUOps[InstrZ].Code = NCode;
5889 FPUOps[InstrZ].Dya = NDya;
5890 FPUOps[InstrZ].NeedsSuppFlags = NeedFlags;
5891 AddInstTable(InstTable, NName, InstrZ++, DecodeFPUOp);
5892 }
5893
AddFPUCond(const char * NName,Byte NCode)5894 static void AddFPUCond(const char *NName, Byte NCode)
5895 {
5896 char TmpName[30];
5897
5898 as_snprintf(TmpName, sizeof(TmpName), "FB%s", NName);
5899 AddInstTable(InstTable, TmpName, NCode, DecodeFBcc);
5900 as_snprintf(TmpName, sizeof(TmpName), "FDB%s", NName);
5901 AddInstTable(InstTable, TmpName, NCode, DecodeFDBcc);
5902 as_snprintf(TmpName, sizeof(TmpName), "FS%s", NName);
5903 AddInstTable(InstTable, TmpName, NCode, DecodeFScc);
5904 as_snprintf(TmpName, sizeof(TmpName), "FTRAP%s", NName);
5905 AddInstTable(InstTable, TmpName, NCode, DecodeFTRAPcc);
5906 }
5907
AddPMMUCond(const char * NName)5908 static void AddPMMUCond(const char *NName)
5909 {
5910 char TmpName[30];
5911
5912 as_snprintf(TmpName, sizeof(TmpName), "PB%s", NName);
5913 AddInstTable(InstTable, TmpName, InstrZ, DecodePBcc);
5914 as_snprintf(TmpName, sizeof(TmpName), "PDB%s", NName);
5915 AddInstTable(InstTable, TmpName, InstrZ, DecodePDBcc);
5916 as_snprintf(TmpName, sizeof(TmpName), "PS%s", NName);
5917 AddInstTable(InstTable, TmpName, InstrZ, DecodePScc);
5918 as_snprintf(TmpName, sizeof(TmpName), "PTRAP%s", NName);
5919 AddInstTable(InstTable, TmpName, InstrZ, DecodePTRAPcc);
5920 InstrZ++;
5921 }
5922
AddPMMUReg(const char * Name,tSymbolSize Size,Word Code)5923 static void AddPMMUReg(const char *Name, tSymbolSize Size, Word Code)
5924 {
5925 if (InstrZ >= PMMURegCnt) exit(255);
5926 PMMURegs[InstrZ].pName = Name;
5927 PMMURegs[InstrZ].Size = Size;
5928 PMMURegs[InstrZ++].Code = Code;
5929 }
5930
InitFields(void)5931 static void InitFields(void)
5932 {
5933 InstTable = CreateInstTable(607);
5934 SetDynamicInstTable(InstTable);
5935
5936 AddInstTable(InstTable, "MOVE" , Std_Variant, DecodeMOVE);
5937 AddInstTable(InstTable, "MOVEA" , A_Variant, DecodeMOVE);
5938 AddInstTable(InstTable, "MOVEI" , I_Variant, DecodeMOVE);
5939 AddInstTable(InstTable, "LEA" , 0, DecodeLEA);
5940 AddInstTable(InstTable, "ASR" , 0, DecodeShift);
5941 AddInstTable(InstTable, "ASL" , 4, DecodeShift);
5942 AddInstTable(InstTable, "LSR" , 1, DecodeShift);
5943 AddInstTable(InstTable, "LSL" , 5, DecodeShift);
5944 AddInstTable(InstTable, "ROXR" , 2, DecodeShift);
5945 AddInstTable(InstTable, "ROXL" , 6, DecodeShift);
5946 AddInstTable(InstTable, "ROR" , 3, DecodeShift);
5947 AddInstTable(InstTable, "ROL" , 7, DecodeShift);
5948 AddInstTable(InstTable, "ADDQ" , 0, DecodeADDQSUBQ);
5949 AddInstTable(InstTable, "SUBQ" , 1, DecodeADDQSUBQ);
5950 AddInstTable(InstTable, "ADDX" , 1, DecodeADDXSUBX);
5951 AddInstTable(InstTable, "SUBX" , 0, DecodeADDXSUBX);
5952 AddInstTable(InstTable, "CMPM" , 0, DecodeCMPM);
5953 AddInstTable(InstTable, "SUB" , Std_Variant + 0, DecodeADDSUBCMP);
5954 AddInstTable(InstTable, "CMP" , Std_Variant + 1, DecodeADDSUBCMP);
5955 AddInstTable(InstTable, "ADD" , Std_Variant + 2, DecodeADDSUBCMP);
5956 AddInstTable(InstTable, "SUBI" , I_Variant + 0, DecodeADDSUBCMP);
5957 AddInstTable(InstTable, "CMPI" , I_Variant + 1, DecodeADDSUBCMP);
5958 AddInstTable(InstTable, "ADDI" , I_Variant + 2, DecodeADDSUBCMP);
5959 AddInstTable(InstTable, "SUBA" , A_Variant + 0, DecodeADDSUBCMP);
5960 AddInstTable(InstTable, "CMPA" , A_Variant + 1, DecodeADDSUBCMP);
5961 AddInstTable(InstTable, "ADDA" , A_Variant + 2, DecodeADDSUBCMP);
5962 AddInstTable(InstTable, "AND" , Std_Variant + 1, DecodeANDOR);
5963 AddInstTable(InstTable, "OR" , Std_Variant + 0, DecodeANDOR);
5964 AddInstTable(InstTable, "ANDI" , I_Variant + 1, DecodeANDOR);
5965 AddInstTable(InstTable, "ORI" , I_Variant + 0, DecodeANDOR);
5966 AddInstTable(InstTable, "EOR" , Std_Variant, DecodeEOR);
5967 AddInstTable(InstTable, "EORI" , I_Variant, DecodeEOR);
5968 AddInstTable(InstTable, "PEA" , 0, DecodePEA);
5969 AddInstTable(InstTable, "CLR" , 0, DecodeCLRTST);
5970 AddInstTable(InstTable, "TST" , 1, DecodeCLRTST);
5971 AddInstTable(InstTable, "JSR" , 0, DecodeJSRJMP);
5972 AddInstTable(InstTable, "JMP" , 1, DecodeJSRJMP);
5973 AddInstTable(InstTable, "TAS" , 0, DecodeNBCDTAS);
5974 AddInstTable(InstTable, "NBCD" , 1, DecodeNBCDTAS);
5975 AddInstTable(InstTable, "NEGX" , 0, DecodeNEGNOT);
5976 AddInstTable(InstTable, "NEG" , 2, DecodeNEGNOT);
5977 AddInstTable(InstTable, "NOT" , 3, DecodeNEGNOT);
5978 AddInstTable(InstTable, "SWAP" , 0, DecodeSWAP);
5979 AddInstTable(InstTable, "UNLK" , 0, DecodeUNLK);
5980 AddInstTable(InstTable, "EXT" , 0, DecodeEXT);
5981 AddInstTable(InstTable, "WDDATA" , 0, DecodeWDDATA);
5982 AddInstTable(InstTable, "WDEBUG" , 0, DecodeWDEBUG);
5983 AddInstTable(InstTable, "MOVEM" , 0, DecodeMOVEM);
5984 AddInstTable(InstTable, "MOVEQ" , 0, DecodeMOVEQ);
5985 AddInstTable(InstTable, "STOP" , 0, DecodeSTOP);
5986 AddInstTable(InstTable, "LPSTOP" , 0, DecodeLPSTOP);
5987 AddInstTable(InstTable, "TRAP" , 0, DecodeTRAP);
5988 AddInstTable(InstTable, "BKPT" , 0, DecodeBKPT);
5989 AddInstTable(InstTable, "RTD" , 0, DecodeRTD);
5990 AddInstTable(InstTable, "EXG" , 0, DecodeEXG);
5991 AddInstTable(InstTable, "MOVE16" , 0, DecodeMOVE16);
5992 AddInstTable(InstTable, "MULU" , 0x0000, DecodeMUL_DIV);
5993 AddInstTable(InstTable, "MULS" , 0x0100, DecodeMUL_DIV);
5994 AddInstTable(InstTable, "DIVU" , 0x0001, DecodeMUL_DIV);
5995 AddInstTable(InstTable, "DIVS" , 0x0101, DecodeMUL_DIV);
5996 AddInstTable(InstTable, "DIVUL" , 0, DecodeDIVL);
5997 AddInstTable(InstTable, "DIVSL" , 1, DecodeDIVL);
5998 AddInstTable(InstTable, "ABCD" , 1, DecodeASBCD);
5999 AddInstTable(InstTable, "SBCD" , 0, DecodeASBCD);
6000 AddInstTable(InstTable, "CHK" , 0, DecodeCHK);
6001 AddInstTable(InstTable, "LINK" , 0, DecodeLINK);
6002 AddInstTable(InstTable, "MOVEP" , 0, DecodeMOVEP);
6003 AddInstTable(InstTable, "MOVEC" , 0, DecodeMOVEC);
6004 AddInstTable(InstTable, "MOVES" , 0, DecodeMOVES);
6005 AddInstTable(InstTable, "CALLM" , 0, DecodeCALLM);
6006 AddInstTable(InstTable, "CAS" , 0, DecodeCAS);
6007 AddInstTable(InstTable, "CAS2" , 0, DecodeCAS2);
6008 AddInstTable(InstTable, "CMP2" , 0, DecodeCMPCHK2);
6009 AddInstTable(InstTable, "CHK2" , 1, DecodeCMPCHK2);
6010 AddInstTable(InstTable, "EXTB" , 0, DecodeEXTB);
6011 AddInstTable(InstTable, "PACK" , 0, DecodePACK);
6012 AddInstTable(InstTable, "UNPK" , 1, DecodePACK);
6013 AddInstTable(InstTable, "RTM" , 0, DecodeRTM);
6014 AddInstTable(InstTable, "TBLU" , 0, DecodeTBL);
6015 AddInstTable(InstTable, "TBLUN" , 1, DecodeTBL);
6016 AddInstTable(InstTable, "TBLS" , 2, DecodeTBL);
6017 AddInstTable(InstTable, "TBLSN" , 3, DecodeTBL);
6018 AddInstTable(InstTable, "BTST" , 0, DecodeBits);
6019 AddInstTable(InstTable, "BSET" , 3, DecodeBits);
6020 AddInstTable(InstTable, "BCLR" , 2, DecodeBits);
6021 AddInstTable(InstTable, "BCHG" , 1, DecodeBits);
6022 AddInstTable(InstTable, "BFTST" , 0, DecodeFBits);
6023 AddInstTable(InstTable, "BFSET" , 3, DecodeFBits);
6024 AddInstTable(InstTable, "BFCLR" , 2, DecodeFBits);
6025 AddInstTable(InstTable, "BFCHG" , 1, DecodeFBits);
6026 AddInstTable(InstTable, "BFEXTU" , 0, DecodeEBits);
6027 AddInstTable(InstTable, "BFEXTS" , 1, DecodeEBits);
6028 AddInstTable(InstTable, "BFFFO" , 2, DecodeEBits);
6029 AddInstTable(InstTable, "BFINS" , 0, DecodeBFINS);
6030 AddInstTable(InstTable, "CINVA" , 0, DecodeCacheAll);
6031 AddInstTable(InstTable, "CPUSHA" , 1, DecodeCacheAll);
6032 AddInstTable(InstTable, "CINVL" , 1, DecodeCache);
6033 AddInstTable(InstTable, "CPUSHL" , 5, DecodeCache);
6034 AddInstTable(InstTable, "CINVP" , 2, DecodeCache);
6035 AddInstTable(InstTable, "CPUSHP" , 6, DecodeCache);
6036 AddInstTable(InstTable, "STR" , 0, DecodeSTR);
6037
6038 FixedOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * FixedOrderCnt); InstrZ = 0;
6039 AddFixed("NOP" , 0x4e71, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32) | (1 << eColdfire));
6040 AddFixed("RESET" , 0x4e70, True, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32));
6041 AddFixed("ILLEGAL", 0x4afc, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32) | (1 << eColdfire));
6042 AddFixed("TRAPV" , 0x4e76, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32));
6043 AddFixed("RTE" , 0x4e73, True , (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32) | (1 << eColdfire));
6044 AddFixed("RTR" , 0x4e77, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32));
6045 AddFixed("RTS" , 0x4e75, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32) | (1 << eColdfire));
6046 AddFixed("BGND" , 0x4afa, False, (1 << eCPU32));
6047 AddFixed("HALT" , 0x4ac8, True , (1 << eColdfire));
6048 AddFixed("PULSE" , 0x4acc, True , (1 << eColdfire));
6049
6050 AddCond("T" , 0); AddCond("F" , 1); AddCond("HI", 2); AddCond("LS", 3);
6051 AddCond("CC", 4); AddCond("CS", 5); AddCond("NE", 6); AddCond("EQ", 7);
6052 AddCond("VC", 8); AddCond("VS", 9); AddCond("PL",10); AddCond("MI",11);
6053 AddCond("GE",12); AddCond("LT",13); AddCond("GT",14); AddCond("LE",15);
6054 AddCond("HS", 4); AddCond("LO", 5);
6055 AddInstTable(InstTable, "BRA", 0, DecodeBcc);
6056 AddInstTable(InstTable, "BSR", 1, DecodeBcc);
6057 AddInstTable(InstTable, "DBRA", 1, DecodeDBcc);
6058
6059 FPUOps = (FPUOp *) malloc(sizeof(FPUOp) * FPUOpCnt); InstrZ = 0;
6060 AddFPUOp("FINT" , 0x01, False, eFlagNone ); AddFPUOp("FSINH" , 0x02, False, eFlagExtFPU);
6061 AddFPUOp("FINTRZ" , 0x03, False, eFlagNone ); AddFPUOp("FSQRT" , 0x04, False, eFlagNone );
6062 AddFPUOp("FSSQRT" , 0x41, False, eFlagIntFPU); AddFPUOp("FDSQRT" , 0x45, False, eFlagIntFPU);
6063 AddFPUOp("FLOGNP1", 0x06, False, eFlagExtFPU); AddFPUOp("FETOXM1", 0x08, False, eFlagExtFPU);
6064 AddFPUOp("FTANH" , 0x09, False, eFlagExtFPU); AddFPUOp("FATAN" , 0x0a, False, eFlagExtFPU);
6065 AddFPUOp("FASIN" , 0x0c, False, eFlagExtFPU); AddFPUOp("FATANH" , 0x0d, False, eFlagExtFPU);
6066 AddFPUOp("FSIN" , 0x0e, False, eFlagExtFPU); AddFPUOp("FTAN" , 0x0f, False, eFlagExtFPU);
6067 AddFPUOp("FETOX" , 0x10, False, eFlagExtFPU); AddFPUOp("FTWOTOX", 0x11, False, eFlagExtFPU);
6068 AddFPUOp("FTENTOX", 0x12, False, eFlagExtFPU); AddFPUOp("FLOGN" , 0x14, False, eFlagExtFPU);
6069 AddFPUOp("FLOG10" , 0x15, False, eFlagExtFPU); AddFPUOp("FLOG2" , 0x16, False, eFlagExtFPU);
6070 AddFPUOp("FABS" , 0x18, False, eFlagNone ); AddFPUOp("FSABS" , 0x58, False, eFlagIntFPU);
6071 AddFPUOp("FDABS" , 0x5c, False, eFlagIntFPU); AddFPUOp("FCOSH" , 0x19, False, eFlagExtFPU);
6072 AddFPUOp("FNEG" , 0x1a, False, eFlagNone ); AddFPUOp("FACOS" , 0x1c, False, eFlagExtFPU);
6073 AddFPUOp("FCOS" , 0x1d, False, eFlagExtFPU); AddFPUOp("FGETEXP", 0x1e, False, eFlagExtFPU);
6074 AddFPUOp("FGETMAN", 0x1f, False, eFlagExtFPU); AddFPUOp("FDIV" , 0x20, True , eFlagNone );
6075 AddFPUOp("FSDIV" , 0x60, False, eFlagIntFPU); AddFPUOp("FDDIV" , 0x64, True , eFlagIntFPU);
6076 AddFPUOp("FMOD" , 0x21, True , eFlagExtFPU); AddFPUOp("FADD" , 0x22, True , eFlagNone );
6077 AddFPUOp("FSADD" , 0x62, True , eFlagIntFPU); AddFPUOp("FDADD" , 0x66, True , eFlagIntFPU);
6078 AddFPUOp("FMUL" , 0x23, True , eFlagNone ); AddFPUOp("FSMUL" , 0x63, True , eFlagIntFPU);
6079 AddFPUOp("FDMUL" , 0x67, True , eFlagIntFPU); AddFPUOp("FSGLDIV", 0x24, True , eFlagExtFPU);
6080 AddFPUOp("FREM" , 0x25, True , eFlagExtFPU); AddFPUOp("FSCALE" , 0x26, True , eFlagExtFPU);
6081 AddFPUOp("FSGLMUL", 0x27, True , eFlagExtFPU); AddFPUOp("FSUB" , 0x28, True , eFlagNone );
6082 AddFPUOp("FSSUB" , 0x68, True , eFlagIntFPU); AddFPUOp("FDSUB" , 0x6c, True , eFlagIntFPU);
6083 AddFPUOp("FCMP" , 0x38, True , eFlagNone );
6084
6085 AddInstTable(InstTable, "FSAVE", 0, DecodeFSAVE);
6086 AddInstTable(InstTable, "FRESTORE", 0, DecodeFRESTORE);
6087 AddInstTable(InstTable, "FNOP", 0, DecodeFNOP);
6088 AddInstTable(InstTable, "FMOVE", 0, DecodeFMOVE);
6089 AddInstTable(InstTable, "FMOVECR", 0, DecodeFMOVECR);
6090 AddInstTable(InstTable, "FTST", 0, DecodeFTST);
6091 AddInstTable(InstTable, "FSINCOS", 0, DecodeFSINCOS);
6092 AddInstTable(InstTable, "FDMOVE", 0x0044, DecodeFDMOVE_FSMOVE);
6093 AddInstTable(InstTable, "FSMOVE", 0x0040, DecodeFDMOVE_FSMOVE);
6094 AddInstTable(InstTable, "FMOVEM", 0, DecodeFMOVEM);
6095
6096 AddFPUCond("EQ" , 0x01); AddFPUCond("NE" , 0x0e);
6097 AddFPUCond("GT" , 0x12); AddFPUCond("NGT" , 0x1d);
6098 AddFPUCond("GE" , 0x13); AddFPUCond("NGE" , 0x1c);
6099 AddFPUCond("LT" , 0x14); AddFPUCond("NLT" , 0x1b);
6100 AddFPUCond("LE" , 0x15); AddFPUCond("NLE" , 0x1a);
6101 AddFPUCond("GL" , 0x16); AddFPUCond("NGL" , 0x19);
6102 AddFPUCond("GLE" , 0x17); AddFPUCond("NGLE", 0x18);
6103 AddFPUCond("OGT" , 0x02); AddFPUCond("ULE" , 0x0d);
6104 AddFPUCond("OGE" , 0x03); AddFPUCond("ULT" , 0x0c);
6105 AddFPUCond("OLT" , 0x04); AddFPUCond("UGE" , 0x0b);
6106 AddFPUCond("OLE" , 0x05); AddFPUCond("UGT" , 0x0a);
6107 AddFPUCond("OGL" , 0x06); AddFPUCond("UEQ" , 0x09);
6108 AddFPUCond("OR" , 0x07); AddFPUCond("UN" , 0x08);
6109 AddFPUCond("F" , 0x00); AddFPUCond("T" , 0x0f);
6110 AddFPUCond("SF" , 0x10); AddFPUCond("ST" , 0x1f);
6111 AddFPUCond("SEQ" , 0x11); AddFPUCond("SNE" , 0x1e);
6112
6113 AddPMMUCond("BS"); AddPMMUCond("BC"); AddPMMUCond("LS"); AddPMMUCond("LC");
6114 AddPMMUCond("SS"); AddPMMUCond("SC"); AddPMMUCond("AS"); AddPMMUCond("AC");
6115 AddPMMUCond("WS"); AddPMMUCond("WC"); AddPMMUCond("IS"); AddPMMUCond("IC");
6116 AddPMMUCond("GS"); AddPMMUCond("GC"); AddPMMUCond("CS"); AddPMMUCond("CC");
6117
6118 AddInstTable(InstTable, "PSAVE", 0, DecodePSAVE);
6119 AddInstTable(InstTable, "PRESTORE", 0, DecodePRESTORE);
6120 AddInstTable(InstTable, "PFLUSHA", 0, DecodePFLUSHA);
6121 AddInstTable(InstTable, "PFLUSHAN", 0, DecodePFLUSHAN);
6122 AddInstTable(InstTable, "PFLUSH", 0x0000, DecodePFLUSH_PFLUSHS);
6123 AddInstTable(InstTable, "PFLUSHS", 0x0400, DecodePFLUSH_PFLUSHS);
6124 AddInstTable(InstTable, "PFLUSHN", 0, DecodePFLUSHN);
6125 AddInstTable(InstTable, "PFLUSHR", 0, DecodePFLUSHR);
6126 AddInstTable(InstTable, "PLOADR", 0x2200, DecodePLOADR_PLOADW);
6127 AddInstTable(InstTable, "PLOADW", 0x2000, DecodePLOADR_PLOADW);
6128 AddInstTable(InstTable, "PMOVE", 0x0000, DecodePMOVE_PMOVEFD);
6129 AddInstTable(InstTable, "PMOVEFD", 0x0100, DecodePMOVE_PMOVEFD);
6130 AddInstTable(InstTable, "PTESTR", 1, DecodePTESTR_PTESTW);
6131 AddInstTable(InstTable, "PTESTW", 0, DecodePTESTR_PTESTW);
6132 AddInstTable(InstTable, "PVALID", 0, DecodePVALID);
6133
6134 AddInstTable(InstTable, "BITREV", 0x00c0, DecodeColdBit);
6135 AddInstTable(InstTable, "BYTEREV", 0x02c0, DecodeColdBit);
6136 AddInstTable(InstTable, "FF1", 0x04c0, DecodeColdBit);
6137 AddInstTable(InstTable, "STLDSR", 0x0000, DecodeSTLDSR);
6138 AddInstTable(InstTable, "INTOUCH", 0x0000, DecodeINTOUCH);
6139 AddInstTable(InstTable, "MOV3Q", 0x0000, DecodeMOV3Q);
6140 /* MOVEI? */
6141 AddInstTable(InstTable, "MVS", 0x7100, DecodeMVS_MVZ);
6142 AddInstTable(InstTable, "MVZ", 0x7180, DecodeMVS_MVZ);
6143 AddInstTable(InstTable, "SATS", 0x0000, DecodeSATS);
6144 AddInstTable(InstTable, "MAC" , 0x0000, DecodeMAC_MSAC);
6145 AddInstTable(InstTable, "MSAC", 0x0100, DecodeMAC_MSAC);
6146 AddInstTable(InstTable, "MACL" , 0x8000, DecodeMAC_MSAC);
6147 AddInstTable(InstTable, "MSACL", 0x8100, DecodeMAC_MSAC);
6148 AddInstTable(InstTable, "MOVCLR" , 0x0000, DecodeMOVCLR);
6149 AddInstTable(InstTable, "MAAAC" , 0x0001, DecodeMxxAC);
6150 AddInstTable(InstTable, "MASAC" , 0x0003, DecodeMxxAC);
6151 AddInstTable(InstTable, "MSAAC" , 0x0101, DecodeMxxAC);
6152 AddInstTable(InstTable, "MSSAC" , 0x0103, DecodeMxxAC);
6153
6154 AddInstTable(InstTable, "CP0BCBUSY", 0xfcc0, DecodeCPBCBUSY);
6155 AddInstTable(InstTable, "CP1BCBUSY", 0xfec0, DecodeCPBCBUSY);
6156 AddInstTable(InstTable, "CP0LD", 0xfc00, DecodeCPLDST);
6157 AddInstTable(InstTable, "CP1LD", 0xfe00, DecodeCPLDST);
6158 AddInstTable(InstTable, "CP0ST", 0xfd00, DecodeCPLDST);
6159 AddInstTable(InstTable, "CP1ST", 0xff00, DecodeCPLDST);
6160 AddInstTable(InstTable, "CP0NOP", 0xfc00, DecodeCPNOP);
6161 AddInstTable(InstTable, "CP1NOP", 0xfe00, DecodeCPNOP);
6162
6163 PMMURegs = (PMMUReg*) malloc(sizeof(PMMUReg) * PMMURegCnt);
6164 InstrZ = 0;
6165 AddPMMUReg("TC" , eSymbolSize32Bit, 16); AddPMMUReg("DRP" , eSymbolSize64Bit, 17);
6166 AddPMMUReg("SRP" , eSymbolSize64Bit, 18); AddPMMUReg("CRP" , eSymbolSize64Bit, 19);
6167 AddPMMUReg("CAL" , eSymbolSize8Bit, 20); AddPMMUReg("VAL" , eSymbolSize8Bit, 21);
6168 AddPMMUReg("SCC" , eSymbolSize8Bit, 22); AddPMMUReg("AC" , eSymbolSize16Bit, 23);
6169 AddPMMUReg("PSR" , eSymbolSize16Bit, 24); AddPMMUReg("PCSR" , eSymbolSize16Bit, 25);
6170 AddPMMUReg("TT0" , eSymbolSize32Bit, 2); AddPMMUReg("TT1" , eSymbolSize32Bit, 3);
6171 AddPMMUReg("MMUSR", eSymbolSize16Bit, 24);
6172
6173 AddInstTable(InstTable, "REG", 0, CodeREG);
6174 }
6175
DeinitFields(void)6176 static void DeinitFields(void)
6177 {
6178 DestroyInstTable(InstTable);
6179 free(FixedOrders);
6180 free(FPUOps);
6181 free(PMMURegs);
6182 }
6183
6184 /*-------------------------------------------------------------------------*/
6185
6186 /*!------------------------------------------------------------------------
6187 * \fn InternSymbol_68K(char *pArg, TempResult *pResult)
6188 * \brief handle built-in (register) symbols for 68K
6189 * \param pArg source argument
6190 * \param pResult result buffer
6191 * ------------------------------------------------------------------------ */
6192
InternSymbol_68K(char * pArg,TempResult * pResult)6193 static void InternSymbol_68K(char *pArg, TempResult *pResult)
6194 {
6195 Word RegNum;
6196
6197 if (DecodeRegCore(pArg, &RegNum))
6198 {
6199 pResult->Typ = TempReg;
6200 pResult->DataSize = eSymbolSize32Bit;
6201 pResult->Contents.RegDescr.Reg = RegNum;
6202 pResult->Contents.RegDescr.Dissect = DissectReg_68K;
6203 }
6204 else if (DecodeFPRegCore(pArg, &RegNum))
6205 {
6206 pResult->Typ = TempReg;
6207 pResult->DataSize = NativeFloatSize;
6208 pResult->Contents.RegDescr.Reg = RegNum;
6209 pResult->Contents.RegDescr.Dissect = DissectReg_68K;
6210 }
6211 }
6212
DecodeAttrPart_68K(void)6213 static Boolean DecodeAttrPart_68K(void)
6214 {
6215 return DecodeMoto16AttrSize(*AttrPart.Str, &AttrPartOpSize, False);
6216 }
6217
MakeCode_68K(void)6218 static void MakeCode_68K(void)
6219 {
6220 CodeLen = 0;
6221 OpSize = (AttrPartOpSize != eSymbolSizeUnknown)
6222 ? AttrPartOpSize
6223 : ((pCurrCPUProps->Family == eColdfire) ? eSymbolSize32Bit : eSymbolSize16Bit);
6224 DontPrint = False; RelPos = 2;
6225
6226 /* Nullanweisung */
6227
6228 if ((*OpPart.Str == '\0') && !*AttrPart.Str && (ArgCnt == 0))
6229 return;
6230
6231 /* Pseudoanweisungen */
6232
6233 if (DecodeMoto16Pseudo(OpSize, True))
6234 return;
6235
6236 /* Befehlszaehler ungerade ? */
6237
6238 if (Odd(EProgCounter()))
6239 {
6240 if (DoPadding)
6241 InsertPadding(1, False);
6242 else
6243 WrError(ErrNum_AddrNotAligned);
6244 }
6245
6246 if (!LookupInstTable(InstTable, OpPart.Str))
6247 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
6248 }
6249
InitCode_68K(void)6250 static void InitCode_68K(void)
6251 {
6252 SetFlag(&PMMUAvail, PMMUAvailName, False);
6253 SetFlag(&FullPMMU, FullPMMUName, True);
6254 }
6255
IsDef_68K(void)6256 static Boolean IsDef_68K(void)
6257 {
6258 return Memo("REG");
6259 }
6260
SwitchFrom_68K(void)6261 static void SwitchFrom_68K(void)
6262 {
6263 DeinitFields();
6264 ClearONOFF();
6265 }
6266
SwitchTo_68K(void * pUser)6267 static void SwitchTo_68K(void *pUser)
6268 {
6269 TurnWords = True;
6270 ConstMode = ConstModeMoto;
6271
6272 PCSymbol = "*";
6273 HeaderID = 0x01;
6274 NOPCode = 0x4e71;
6275 DivideChars = ",";
6276 HasAttrs = True;
6277 AttrChars = ".";
6278
6279 ValidSegs = (1 << SegCode);
6280 Grans[SegCode] = 1;
6281 ListGrans[SegCode] = 2;
6282 SegInits[SegCode] = 0;
6283 SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
6284
6285 pCurrCPUProps = (const tCPUProps*)pUser;
6286
6287 DecodeAttrPart = DecodeAttrPart_68K;
6288 MakeCode = MakeCode_68K;
6289 IsDef = IsDef_68K;
6290 DissectReg = DissectReg_68K;
6291 InternSymbol = InternSymbol_68K;
6292
6293 SwitchFrom = SwitchFrom_68K;
6294 InitFields();
6295 AddONOFF("PMMU" , &PMMUAvail , PMMUAvailName , False);
6296 AddONOFF("FULLPMMU", &FullPMMU , FullPMMUName , False);
6297 AddONOFF("FPU" , &FPUAvail , FPUAvailName , False);
6298 AddONOFF("SUPMODE" , &SupAllowed, SupAllowedName, False);
6299 AddMoto16PseudoONOFF();
6300
6301 SetFlag(&FullPMMU, FullPMMUName, !(pCurrCPUProps->SuppFlags & eFlagIntPMMU));
6302 SetFlag(&DoPadding, DoPaddingName, True);
6303 NativeFloatSize = (pCurrCPUProps->Family == eColdfire) ? eSymbolSizeFloat64Bit : eSymbolSizeFloat96Bit;
6304 }
6305
6306 static const tCtReg CtRegs_40[] =
6307 {
6308 { "TC" , 0x003 },
6309 { "ITT0" , 0x004 },
6310 { "ITT1" , 0x005 },
6311 { "DTT0" , 0x006 },
6312 { "DTT1" , 0x007 },
6313 { "MMUSR", 0x805 },
6314 { "URP" , 0x806 },
6315 { "SRP" , 0x807 },
6316 { "IACR0", 0x004 },
6317 { "IACR1", 0x005 },
6318 { "DACR0", 0x006 },
6319 { "DACR1", 0x007 },
6320 { NULL , 0x000 },
6321 },
6322 CtRegs_2030[] =
6323 {
6324 { "CAAR" , 0x802 },
6325 { NULL , 0x000 },
6326 },
6327 CtRegs_2040[] =
6328 {
6329 { "CACR" , 0x002 },
6330 { "MSP" , 0x803 },
6331 { "ISP" , 0x804 },
6332 { NULL , 0x000 },
6333 },
6334 CtRegs_1040[] =
6335 {
6336 { "SFC" , 0x000 },
6337 { "DFC" , 0x001 },
6338 { "USP" , 0x800 },
6339 { "VBR" , 0x801 },
6340 { NULL , 0x000 },
6341 };
6342
6343 static const tCtReg CtRegs_5202[] =
6344 {
6345 { "CACR" , 0x002 },
6346 { "ACR0" , 0x004 },
6347 { "ACR1" , 0x005 },
6348 { "VBR" , 0x801 },
6349 { "SR" , 0x80e },
6350 { "PC" , 0x80f },
6351 { NULL , 0x000 },
6352 };
6353
6354 static const tCtReg CtRegs_5202_5204[] =
6355 {
6356 { "RAMBAR" , 0xc04 },
6357 { "MBAR" , 0xc0f },
6358 { NULL , 0x000 },
6359 };
6360
6361 static const tCtReg CtRegs_5202_5208[] =
6362 {
6363 { "RGPIOBAR", 0x009},
6364 { "RAMBAR" , 0xc05 },
6365 { NULL , 0x000 },
6366 };
6367
6368 static const tCtReg CtRegs_5202_5307[] =
6369 {
6370 { "ACR2" , 0x006 },
6371 { "ACR3" , 0x007 },
6372 { "RAMBAR0", 0xc04 },
6373 { "RAMBAR1", 0xc05 },
6374 { NULL , 0x000 },
6375 };
6376
6377 static const tCtReg CtRegs_5202_5329[] =
6378 {
6379 { "RAMBAR" , 0xc05 },
6380 { NULL , 0x000 },
6381 };
6382
6383 static const tCtReg CtRegs_5202_5407[] =
6384 {
6385 { "ACR2" , 0x006 },
6386 { "ACR3" , 0x007 },
6387 { "RAMBAR0", 0xc04 },
6388 { "RAMBAR1", 0xc05 },
6389 { "MBAR" , 0xc0f },
6390 { NULL , 0x000 },
6391 };
6392
6393 static const tCtReg CtRegs_Cf_CPU[] =
6394 {
6395 { "D0_LOAD" , 0x080 },
6396 { "D1_LOAD" , 0x081 },
6397 { "D2_LOAD" , 0x082 },
6398 { "D3_LOAD" , 0x083 },
6399 { "D4_LOAD" , 0x084 },
6400 { "D5_LOAD" , 0x085 },
6401 { "D6_LOAD" , 0x086 },
6402 { "D7_LOAD" , 0x087 },
6403 { "A0_LOAD" , 0x088 },
6404 { "A1_LOAD" , 0x089 },
6405 { "A2_LOAD" , 0x08a },
6406 { "A3_LOAD" , 0x08b },
6407 { "A4_LOAD" , 0x08c },
6408 { "A5_LOAD" , 0x08d },
6409 { "A6_LOAD" , 0x08e },
6410 { "A7_LOAD" , 0x08f },
6411 { "D0_STORE" , 0x180 },
6412 { "D1_STORE" , 0x181 },
6413 { "D2_STORE" , 0x182 },
6414 { "D3_STORE" , 0x183 },
6415 { "D4_STORE" , 0x184 },
6416 { "D5_STORE" , 0x185 },
6417 { "D6_STORE" , 0x186 },
6418 { "D7_STORE" , 0x187 },
6419 { "A0_STORE" , 0x188 },
6420 { "A1_STORE" , 0x189 },
6421 { "A2_STORE" , 0x18a },
6422 { "A3_STORE" , 0x18b },
6423 { "A4_STORE" , 0x18c },
6424 { "A5_STORE" , 0x18d },
6425 { "A6_STORE" , 0x18e },
6426 { "A7_STORE" , 0x18f },
6427 { "OTHER_A7" , 0x800 },
6428 { NULL , 0x000 },
6429 };
6430
6431 static const tCtReg CtRegs_Cf_EMAC[] =
6432 {
6433 { "MACSR" , 0x804 },
6434 { "MASK" , 0x805 },
6435 { "ACC0" , 0x806 },
6436 { "ACCEXT01" , 0x807 },
6437 { "ACCEXT23" , 0x808 },
6438 { "ACC1" , 0x809 },
6439 { "ACC2" , 0x80a },
6440 { "ACC3" , 0x80b },
6441 { NULL , 0x000 },
6442 };
6443
6444 static const tCtReg CtRegs_MCF51[] =
6445 {
6446 { "VBR" , 0x801 },
6447 { "CPUCR" , 0x802 },
6448 { NULL , 0x000 },
6449 };
6450
6451 static const tCPUProps CPUProps[] =
6452 {
6453 /* 68881/68882 may be attached memory-mapped and emulated on pre-68020 devices */
6454 { "68008", 0x000ffffful, e68KGen1a, eCfISA_None , eFlagExtFPU | eFlagLogCCR, { NULL } },
6455 { "68000", 0x00fffffful, e68KGen1a, eCfISA_None , eFlagExtFPU | eFlagLogCCR, { NULL } },
6456 { "68010", 0x00fffffful, e68KGen1b, eCfISA_None , eFlagExtFPU | eFlagLogCCR, { CtRegs_1040 } },
6457 { "68012", 0x7ffffffful, e68KGen1b, eCfISA_None , eFlagExtFPU | eFlagLogCCR, { CtRegs_1040 } },
6458 { "MCF5202", 0xfffffffful, eColdfire, eCfISA_A , eFlagIntFPU | eFlagIdxScaling, { CtRegs_5202 } },
6459 { "MCF5204", 0xfffffffful, eColdfire, eCfISA_A , eFlagIntFPU | eFlagIdxScaling, { CtRegs_5202, CtRegs_5202_5204 } },
6460 { "MCF5206", 0xfffffffful, eColdfire, eCfISA_A , eFlagIntFPU | eFlagIdxScaling, { CtRegs_5202, CtRegs_5202_5204 } },
6461 { "MCF5208", 0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5208, CtRegs_Cf_CPU, CtRegs_Cf_EMAC } }, /* V2 */
6462 { "MCF52274", 0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5208, CtRegs_Cf_CPU, CtRegs_Cf_EMAC } }, /* V2 */
6463 { "MCF52277", 0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5208, CtRegs_Cf_CPU, CtRegs_Cf_EMAC } }, /* V2 */
6464 { "MCF5307", 0xfffffffful, eColdfire, eCfISA_A , eFlagIntFPU | eFlagIdxScaling | eFlagMAC, { CtRegs_5202, CtRegs_5202_5307 } }, /* V3 */
6465 { "MCF5329", 0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5329 } }, /* V3 */
6466 { "MCF5373", 0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5329 } }, /* V3 */
6467 { "MCF5407", 0xfffffffful, eColdfire, eCfISA_B , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4 */
6468 { "MCF5470", 0xfffffffful, eColdfire, eCfISA_B , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
6469 { "MCF5471", 0xfffffffful, eColdfire, eCfISA_B , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
6470 { "MCF5472", 0xfffffffful, eColdfire, eCfISA_B , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
6471 { "MCF5473", 0xfffffffful, eColdfire, eCfISA_B , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
6472 { "MCF5474", 0xfffffffful, eColdfire, eCfISA_B , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
6473 { "MCF5475", 0xfffffffful, eColdfire, eCfISA_B , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
6474 { "MCF51QM", 0xfffffffful, eColdfire, eCfISA_C , eFlagBranch32 | eFlagMAC | eFlagIdxScaling | eFlagEMAC, { CtRegs_MCF51 } }, /* V1 */
6475 { "68332", 0xfffffffful, eCPU32 , eCfISA_None , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling, { CtRegs_1040 } },
6476 { "68340", 0xfffffffful, eCPU32 , eCfISA_None , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling, { CtRegs_1040 } },
6477 { "68360", 0xfffffffful, eCPU32 , eCfISA_None , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling, { CtRegs_1040 } },
6478 { "68020", 0xfffffffful, e68KGen2 , eCfISA_None , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling | eFlagExtFPU | eFlagCALLM_RTM, { CtRegs_1040, CtRegs_2040, CtRegs_2030 } },
6479 { "68030", 0xfffffffful, e68KGen2 , eCfISA_None , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling | eFlagExtFPU | eFlagIntPMMU, { CtRegs_1040, CtRegs_2040, CtRegs_2030 } },
6480 /* setting eFlagExtFPU assumes instructions of external FPU are emulated/provided by M68040FPSP! */
6481 { "68040", 0xfffffffful, e68KGen3 , eCfISA_None , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling | eFlagIntPMMU | eFlagExtFPU | eFlagIntFPU, { CtRegs_1040, CtRegs_2040, CtRegs_40 } },
6482 { NULL , 0 , e68KGen1a, eCfISA_None , eFlagNone, { NULL } },
6483 };
6484
code68k_init(void)6485 void code68k_init(void)
6486 {
6487 const tCPUProps *pProp;
6488 for (pProp = CPUProps; pProp->pName; pProp++)
6489 (void)AddCPUUser(pProp->pName, SwitchTo_68K, (void*)pProp, NULL);
6490
6491 AddInitPassProc(InitCode_68K);
6492 }
6493