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