Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

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