Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* codens32k.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Code Generator National Semiconductor NS32000                             */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
#include "bpemu.h"
14
#include "strutil.h"
15
#include "ieeefloat.h"
16
 
17
#include "headids.h"
18
#include "asmdef.h"
19
#include "asmsub.h"
20
#include "asmpars.h"
21
#include "asmallg.h"
22
#include "onoff_common.h"
23
#include "asmitree.h"
24
#include "codevars.h"
25
#include "codepseudo.h"
26
#include "intpseudo.h"
27
 
28
#include "codepseudo.h"
29
#include "intpseudo.h"
30
#include "codens32k.h"
31
 
32
typedef enum
33
{
34
  eCoreNone,
35
  eCoreGen1,
36
  eCoreGen1Ext,
37
  eCoreGenE,
38
  eCoreGen2,
39
  eCoreCount
40
} tCore;
41
 
42
typedef enum
43
{
44
  eFPUNone,
45
  eFPU16081,
46
  eFPU32081,
47
  eFPU32181,
48
  eFPU32381,
49
  eFPU32580,
50
  eFPUCount
51
} tFPU;
52
 
53
typedef enum
54
{
55
  ePMMUNone,
56
  ePMMU16082,
57
  ePMMU32082,
58
  ePMMU32382,
59
  ePMMU32532,
60
  ePMMUCount
61
} tPMMU;
62
 
63
typedef struct
64
{
65
  const char *pName;
66
  Byte CPUType, DefFPU, DefPMMU;
67
  IntType MemIntType;
68
} tCPUProps;
69
 
70
static char FPUNames[eFPUCount][8] = { "OFF", "NS16081", "NS32081", "NS32181", "NS32381", "NS32580" };
71
 
72
static char PMMUNames[ePMMUCount][8] = { "OFF", "NS16082", "NS32082", "NS32382", "NS32532" };
73
 
74
typedef struct
75
{
76
  const char *pName;
77
  Word Code, Mask;
78
  Boolean Privileged;
79
} tCtlReg;
80
 
81
#ifdef __cplusplus
82
#include "codens32k.hpp"
83
#endif
84
 
85
#define MAllowImm (1 << 0)
86
#define MAllowReg (1 << 1)
87
#define MAllowRegPair (1 << 2)
88
 
89
static tCtlReg *CtlRegs, *MMURegs;
90
 
91
static tSymbolSize OpSize;
92
static const tCPUProps *pCurrCPUProps;
93
static tFPU MomFPU;
94
static tPMMU MomPMMU;
95
static Boolean CustomAvail;
96
 
97
/*!------------------------------------------------------------------------
98
 * \fn     SetOpSize(tSymbolSize Size, const tStrComp *pArg)
99
 * \brief  set (new) operand size of instruction
100
 * \param  Size size to set
101
 * \param  pArg source argument size was deduced from
102
 * \return True if no conflict
103
 * ------------------------------------------------------------------------ */
104
 
105
static Boolean SetOpSize(tSymbolSize Size, const tStrComp *pArg)
106
{
107
  if (OpSize == eSymbolSizeUnknown)
108
    OpSize = Size;
109
  else if ((Size != eSymbolSizeUnknown) && (Size != OpSize))
110
  {
111
    WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
112
    return False;
113
  }
114
  return True;
115
}
116
 
117
/*!------------------------------------------------------------------------
118
 * \fn     ResetOpSize(void)
119
 * \brief  back to undefined op size
120
 * \return constat True
121
 * ------------------------------------------------------------------------ */
122
 
123
static Boolean ResetOpSize(void)
124
{
125
  OpSize = eSymbolSizeUnknown;
126
  return True;
127
}
128
 
129
/*!------------------------------------------------------------------------
130
 * \fn     CheckCore(unsigned CoreMask)
131
 * \brief  check for CPU/Core requirement
132
 * \param  CoreMask bit mask of core type supported
133
 * \return True if fulfilled
134
 * ------------------------------------------------------------------------ */
135
 
136
static Boolean CheckCore(unsigned CoreMask)
137
{
138
  if ((CoreMask >> pCurrCPUProps->CPUType) & 1)
139
    return True;
140
  WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
141
  return False;
142
}
143
 
144
/*!------------------------------------------------------------------------
145
 * \fn     CheckSup(Boolean Required, const tStrComp *pArg)
146
 * \brief  check whether supervisor mode requirement is violated
147
 * \param  Required is supervisor mode required?
148
 * \param  pArg source argument
149
 * \return False if violated
150
 * ------------------------------------------------------------------------ */
151
 
152
static Boolean CheckSup(Boolean Required, const tStrComp *pArg)
153
{
154
  if (!SupAllowed && Required)
155
  {
156
    WrStrErrorPos(ErrNum_PrivOrder, pArg);
157
    return False;
158
  }
159
  return True;
160
}
161
 
162
/*!------------------------------------------------------------------------
163
 * \fn     SetMomFPU(tFPU NewFPU)
164
 * \brief  set new FPU type in use
165
 * \param  NewFPU new type
166
 * ------------------------------------------------------------------------ */
167
 
168
static void SetMomFPU(tFPU NewFPU)
169
{
170
  switch ((MomFPU = NewFPU))
171
  {
172
    case eFPU16081:
173
    case eFPU32081:
174
    case eFPU32181:
175
    case eFPU32381:
176
    case eFPU32580:
177
    {
178
      tStrComp TmpComp;
179
      String TmpCompStr;
180
 
181
      StrCompMkTemp(&TmpComp, TmpCompStr, sizeof(TmpCompStr));
182
      strmaxcpy(TmpCompStr, MomFPUIdentName, sizeof(TmpCompStr));
183
      strmaxcpy(MomFPUIdent, FPUNames[MomFPU], sizeof(MomFPUIdent));
184
      EnterStringSymbol(&TmpComp, FPUNames[MomFPU], True);
185
      break;
186
    }
187
    default:
188
      break;
189
  }
190
}
191
 
192
/*!------------------------------------------------------------------------
193
 * \fn     SetMomPMMU(tFPU NewPMMU)
194
 * \brief  set new PMMU type in use
195
 * \param  NewPMMU new type
196
 * ------------------------------------------------------------------------ */
197
 
198
static void SetMomPMMU(tPMMU NewPMMU)
199
{
200
  switch ((MomPMMU = NewPMMU))
201
  {
202
    case ePMMU16082:
203
    case ePMMU32082:
204
    case ePMMU32382:
205
    case ePMMU32532:
206
    {
207
      tStrComp TmpComp;
208
      String TmpCompStr;
209
 
210
      StrCompMkTemp(&TmpComp, TmpCompStr, sizeof(TmpCompStr));
211
      strmaxcpy(TmpCompStr, MomPMMUIdentName, sizeof(TmpCompStr));
212
      strmaxcpy(MomPMMUIdent, PMMUNames[MomPMMU], sizeof(MomPMMUIdent));
213
      EnterStringSymbol(&TmpComp, PMMUNames[MomPMMU], True);
214
      break;
215
    }
216
    default:
217
      break;
218
  }
219
}
220
 
221
/*!------------------------------------------------------------------------
222
 * \fn     CheckFPUAvail(void)
223
 * \brief  check whether FPU instructions are enabled
224
 * \return False if not
225
 * ------------------------------------------------------------------------ */
226
 
227
static Boolean CheckFPUAvail(tFPU MinFPU)
228
{
229
  if (!FPUAvail)
230
  {
231
    WrStrErrorPos(ErrNum_FPUNotEnabled, &OpPart);
232
    return False;
233
  }
234
  else if (MomFPU < MinFPU)
235
  {
236
    WrStrErrorPos(ErrNum_FPUInstructionNotSupported, &OpPart);
237
    return False;
238
  }
239
 
240
  return True;
241
}
242
 
243
/*!------------------------------------------------------------------------
244
 * \fn     CheckPMMUAvail(void)
245
 * \brief  check whether PMMU instructions are enabled
246
 * \return False if not
247
 * ------------------------------------------------------------------------ */
248
 
249
static Boolean CheckPMMUAvail(void)
250
{
251
  if (!PMMUAvail)
252
  {
253
    WrStrErrorPos(ErrNum_PMMUNotEnabled, &OpPart);
254
    return False;
255
  }
256
  return True;
257
}
258
 
259
/*!------------------------------------------------------------------------
260
 * \fn     CheckCustomAvail(void)
261
 * \brief  check whether Custom instructions are enabled
262
 * \return False if not
263
 * ------------------------------------------------------------------------ */
264
 
265
static Boolean CheckCustomAvail(void)
266
{
267
  if (!CustomAvail)
268
  {
269
    WrStrErrorPos(ErrNum_CustomNotEnabled, &OpPart);
270
    return False;
271
  }
272
  return True;
273
}
274
 
275
/*--------------------------------------------------------------------------*/
276
/* Register Handling */
277
 
278
static const char MemRegNames[][3] = { "FP", "SP", "SB" };
279
#define MemRegCount (sizeof(MemRegNames) / sizeof(*MemRegNames))
280
 
281
/*!------------------------------------------------------------------------
282
 * \fn     DecodeRegCore(const char *pArg, Word *pValue, tSymbolSize *pSize)
283
 * \brief  check whether argument describes a register
284
 * \param  pArg source argument
285
 * \param  pValue register number if yes
286
 * \param  pSize register size if yes
287
 * \return True if it is
288
 * ------------------------------------------------------------------------ */
289
 
290
static Boolean DecodeRegCore(const char *pArg, Word *pRegNum, tSymbolSize *pRegSize)
291
{
292
  unsigned z;
293
 
294
  for (z = 0; z < MemRegCount; z++)
295
    if (!as_strcasecmp(pArg, MemRegNames[z]))
296
    {
297
      *pRegNum = z + 8;
298
      *pRegSize = eSymbolSize32Bit;
299
      return True;
300
    }
301
 
302
  if ((strlen(pArg) != 2) || (pArg[1] < '0') || (pArg[1] > '7'))
303
    return False;
304
  *pRegNum = pArg[1] - '0';
305
 
306
  switch (as_toupper(*pArg))
307
  {
308
    case 'F': *pRegSize = eSymbolSizeFloat32Bit; return True;
309
    case 'R': *pRegSize = eSymbolSize32Bit; return True;
310
    case 'L': *pRegSize = eSymbolSizeFloat64Bit; return True;
311
    default:
312
      return False;
313
  }
314
}
315
 
316
/*!------------------------------------------------------------------------
317
 * \fn     DissectReg_NS32K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
318
 * \brief  dissect register symbols - NS32000 variant
319
 * \param  pDest destination buffer
320
 * \param  DestSize destination buffer size
321
 * \param  Value numeric register value
322
 * \param  InpSize register size
323
 * ------------------------------------------------------------------------ */
324
 
325
static void DissectReg_NS32K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
326
{
327
  switch (InpSize)
328
  {
329
    case eSymbolSize32Bit:
330
      if (Value < 8)
331
        as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
332
      else if (Value < 8 + MemRegCount)
333
        as_snprintf(pDest, DestSize, "%s", MemRegNames[Value - 8]);
334
      else
335
        goto unknown;
336
      break;
337
    case eSymbolSizeFloat32Bit:
338
      as_snprintf(pDest, DestSize, "F%u", (unsigned)Value);
339
      break;
340
    case eSymbolSizeFloat64Bit:
341
      as_snprintf(pDest, DestSize, "L%u", (unsigned)Value);
342
      break;
343
    default:
344
    unknown:
345
      as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
346
  }
347
}
348
 
349
/*!------------------------------------------------------------------------
350
 * \fn     DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tSymbolSize ChkRegSize, Boolean MustBeReg)
351
 * \brief  check whether argument is a CPU register or user-defined register alias
352
 * \param  pArg argument
353
 * \param  pValue resulting register # if yes
354
 * \param  pSize resulting register size if yes
355
 * \param  ChkReqSize explicitly request certain register size
356
 * \param  MustBeReg expecting register or maybe not?
357
 * \return reg eval result
358
 * ------------------------------------------------------------------------ */
359
 
360
static Boolean MatchRegSize(tSymbolSize IsSize, tSymbolSize ReqSize)
361
{
362
  return (ReqSize == eSymbolSizeUnknown)
363
      || (IsSize == ReqSize)
364
      || ((ReqSize == eSymbolSizeFloat64Bit) && (IsSize == eSymbolSizeFloat32Bit));
365
}
366
 
367
static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tSymbolSize ChkRegSize, Boolean MustBeReg)
368
{
369
  tEvalResult EvalResult;
370
  tRegEvalResult RegEvalResult;
371
 
372
  if (DecodeRegCore(pArg->str.p_str, pValue, &EvalResult.DataSize))
373
    RegEvalResult = eIsReg;
374
  else
375
  {
376
    tRegDescr RegDescr;
377
 
378
    RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
379
    if (eIsReg == RegEvalResult)
380
      *pValue = RegDescr.Reg;
381
  }
382
 
383
  if ((RegEvalResult == eIsReg) && !MatchRegSize(EvalResult.DataSize, ChkRegSize))
384
  {
385
    WrStrErrorPos(ErrNum_InvOpSize, pArg);
386
    RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
387
  }
388
 
389
  if (pSize) *pSize = EvalResult.DataSize;
390
  return RegEvalResult;
391
}
392
 
393
/*!------------------------------------------------------------------------
394
 * \fn     DecodeCtlReg(const tStrComp *pArg, Word *pResult)
395
 * \brief  decode control processor register
396
 * \param  pArg source argument
397
 * \param  pResult result buffer
398
 * \return True if src expr is a register
399
 * ------------------------------------------------------------------------ */
400
 
401
static Boolean DecodeCtlReg(const tStrComp *pArg, Word *pResult)
402
{
403
  unsigned z;
404
 
405
  for (z = 0; CtlRegs[z].pName; z++)
406
    if (!as_strcasecmp(pArg->str.p_str, CtlRegs[z].pName))
407
    {
408
      *pResult = CtlRegs[z].Code;
409
      return CheckSup(CtlRegs[z].Privileged, pArg);
410
    }
411
  WrStrErrorPos(ErrNum_InvReg, pArg);
412
  return False;
413
}
414
 
415
/*!------------------------------------------------------------------------
416
 * \fn     DecodeMMUReg(const tStrComp *pArg, Word *pResult)
417
 * \brief  decode MMU register
418
 * \param  pArg source argument
419
 * \param  pResult result buffer
420
 * \return True if src expr is a register
421
 * ------------------------------------------------------------------------ */
422
 
423
static Boolean DecodeMMUReg(const tStrComp *pArg, Word *pResult)
424
{
425
  unsigned z;
426
 
427
  for (z = 0; MMURegs[z].pName; z++)
428
    if (!as_strcasecmp(pArg->str.p_str, MMURegs[z].pName))
429
    {
430
      if (!((MMURegs[z].Mask >> MomPMMU) & 1))
431
      {
432
        WrStrErrorPos(ErrNum_InvPMMUReg, pArg);
433
        return False;
434
      }
435
      *pResult = MMURegs[z].Code;
436
      return CheckSup(MMURegs[z].Privileged, pArg);
437
    }
438
  WrStrErrorPos(ErrNum_InvPMMUReg, pArg);
439
  return False;
440
}
441
 
442
/*!------------------------------------------------------------------------
443
 * \fn     DecodeRegList(const tStrComp *pArg, Boolean BitRev, Byte *pResult)
444
 * \brief  Decode Register List
445
 * \param  pArg Source Argument
446
 * \param  BitRev Reverse Bit Order, i.e. R0->Bit 7 ?
447
 * \param  pResult Result Buffer
448
 * \return True if successfully parsed
449
 * ------------------------------------------------------------------------ */
450
 
451
static Boolean DecodeRegList(const tStrComp *pArg, Boolean BitRev, Byte *pResult)
452
{
453
  tStrComp Part, Remainder;
454
  int l = strlen(pArg->str.p_str);
455
  Word Reg;
456
  char *pSep;
457
 
458
  if ((l < 2)
459
   || (pArg->str.p_str[0] != '[')
460
   || (pArg->str.p_str[l - 1] != ']'))
461
  {
462
    WrStrErrorPos(ErrNum_InvRegList, pArg);
463
    return False;
464
  }
465
 
466
  *pResult = 0;
467
  StrCompRefRight(&Part, pArg, 1);
468
  StrCompShorten(&Part, 1);
469
  while (True)
470
  {
471
    KillPrefBlanksStrCompRef(&Part);
472
    pSep = strchr(Part.str.p_str, ',');
473
    if (pSep)
474
      StrCompSplitRef(&Part, &Remainder, &Part, pSep);
475
    KillPostBlanksStrComp(&Part);
476
    if (DecodeReg(&Part, &Reg, NULL, eSymbolSize32Bit, True) != eIsReg)
477
      return False;
478
    if (Reg >= 8)
479
    {
480
      WrStrErrorPos(ErrNum_InvReg, &Part);
481
      return False;
482
    }
483
    *pResult |= 1 << (BitRev ? 7 - Reg : Reg);
484
    if (pSep)
485
      Part = Remainder;
486
    else
487
      break;
488
  }
489
  return True;
490
}
491
 
492
/*!------------------------------------------------------------------------
493
 * \fn     DecodeCfgList(const tStrComp *pArg, Byte *pResult)
494
 * \brief  Decode Config Option List
495
 * \param  pArg Source Argument
496
 * \param  pResult Result Buffer
497
 * \return True if successfully parsed
498
 * ------------------------------------------------------------------------ */
499
 
500
static Boolean DecodeCfgList(const tStrComp *pArg, Byte *pResult)
501
{
502
  tStrComp Part, Remainder;
503
  int l = strlen(pArg->str.p_str);
504
  char *pSep;
505
  const char Opts[] = "IFMC", *pOpt;
506
 
507
  if ((l < 2)
508
   || (pArg->str.p_str[0] != '[')
509
   || (pArg->str.p_str[l - 1] != ']'))
510
  {
511
    WrStrErrorPos(ErrNum_InvCfgList, pArg);
512
    return False;
513
  }
514
 
515
  *pResult = 0;
516
  StrCompRefRight(&Part, pArg, 1);
517
  StrCompShorten(&Part, 1);
518
  while (True)
519
  {
520
    KillPrefBlanksStrCompRef(&Part);
521
    pSep = strchr(Part.str.p_str, ',');
522
    if (pSep)
523
      StrCompSplitRef(&Part, &Remainder, &Part, pSep);
524
    KillPostBlanksStrComp(&Part);
525
    switch (strlen(Part.str.p_str))
526
    {
527
      case 0:
528
        break;
529
      case 1:
530
        pOpt = strchr(Opts, as_toupper(*Part.str.p_str));
531
        if (pOpt)
532
        {
533
          *pResult |= 1 << (pOpt - Opts);
534
          break;
535
        }
536
        /* else fall-through */
537
      default:
538
        WrStrErrorPos(ErrNum_InvCfgList, &Part);
539
        return False;
540
    }
541
    if (pSep)
542
      Part = Remainder;
543
    else
544
      break;
545
  }
546
  return True;
547
}
548
 
549
/*--------------------------------------------------------------------------*/
550
/* Address Decoder */
551
 
552
enum
553
{
554
  AddrCode_Reg = 0x00,
555
  AddrCode_Relative = 0x08,
556
  AddrCode_MemRelative = 0x10,
557
  AddrCode_Reserved = 0x13,
558
  AddrCode_Immediate = 0x14,
559
  AddrCode_Absolute = 0x15,
560
  AddrCode_External = 0x16,
561
  AddrCode_TOS = 0x17,
562
  AddrCode_MemSpace = 0x18,
563
  AddrCode_ScaledIndex = 0x1c
564
};
565
 
566
typedef struct
567
{
568
  Byte Code;
569
  Byte Index[1], Disp[8];
570
  unsigned IndexCnt, DispCnt;
571
} tAdrVals;
572
 
573
static void ClearAdrVals(tAdrVals *pVals)
574
{
575
  pVals->Code = AddrCode_Reserved;
576
  pVals->IndexCnt = pVals->DispCnt = 0;
577
}
578
 
579
/*!------------------------------------------------------------------------
580
 * \fn     EncodeDisplacement(LongInt Disp, tAdrVals *pDest, tErrorNum ErrorNum, const tStrComp *pArg)
581
 * \brief  encode signed displacement
582
 * \param  Disp displacement to encode
583
 * \param  pDest destination buffer
584
 * \param  ErrorNum error msg to print if out of range
585
 * \param  pArg source argument for error messages
586
 * \return True if successfully encoded
587
 * ------------------------------------------------------------------------ */
588
 
589
static Boolean EncodeDisplacement(LongInt Disp, tAdrVals *pDest, tErrorNum ErrorNum, const tStrComp *pArg)
590
{
591
  if ((Disp >= -64) && (Disp <= 63))
592
  {
593
    pDest->Disp[pDest->DispCnt++] = Disp & 0x7f;
594
    return True;
595
  }
596
  else if ((Disp >= -8192) && (Disp <= 8191))
597
  {
598
    pDest->Disp[pDest->DispCnt++] = 0x80 | ((Disp >> 8) & 0x3f);
599
    pDest->Disp[pDest->DispCnt++] = Disp & 0xff;
600
    return True;
601
  }
602
  else if ((Disp >= -520093696) && (Disp <= 536870911))
603
  {
604
    Byte HiByte = 0xc0 | ((Disp >> 24) & 0x3f);
605
 
606
    if (HiByte == 0xe0)
607
      goto error;
608
 
609
    pDest->Disp[pDest->DispCnt++] = HiByte;
610
    pDest->Disp[pDest->DispCnt++] = (Disp >> 16) & 0xff;
611
    pDest->Disp[pDest->DispCnt++] = (Disp >> 8) & 0xff;
612
    pDest->Disp[pDest->DispCnt++] = Disp & 0xff;
613
    return True;
614
  }
615
  else
616
  {
617
error:
618
    WrStrErrorPos(ErrorNum, pArg);
619
    return False;
620
  }
621
}
622
 
623
/*!------------------------------------------------------------------------
624
 * \fn     EncodePCRel(const tStrComp *pArg, tAdrVals *pDest)
625
 * \brief  PC-relative encoding of address
626
 * \param  pArg address in source
627
 * \param  pDest dest buffer
628
 * \return True if success
629
 * ------------------------------------------------------------------------ */
630
 
631
static Boolean EncodePCRel(const tStrComp *pArg, tAdrVals *pDest)
632
{
633
  tEvalResult EvalResult;
634
  LongInt Dist = EvalStrIntExpressionWithResult(pArg, pCurrCPUProps->MemIntType, &EvalResult) - EProgCounter();
635
 
636
  ClearAdrVals(pDest);
637
  if (!EvalResult.OK
638
   || !EncodeDisplacement(Dist, pDest, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_JmpDistTooBig, pArg))
639
    return False;
640
 
641
  pDest->Code = AddrCode_MemSpace + 3;
642
  return True;
643
}
644
 
645
/*!------------------------------------------------------------------------
646
 * \fn     DecodeAdr(tStrComp *pArg, tAdrVals *pDest, unsigned AddrModeMask)
647
 * \brief  decode address expression
648
 * \param  pArg source argument
649
 * \param  pDest dest buffer
650
 * \param  AddrModeMask allow immediate/register addressing?
651
 * \return True if success
652
 * ------------------------------------------------------------------------ */
653
 
654
static Boolean DecodeAdr(const tStrComp *pArg, tAdrVals *pDest, Boolean AddrModeMask)
655
{
656
  Byte IndexCode = 0;
657
  Boolean OK, NeedEvenReg;
658
  const Boolean IsFloat = (OpSize == eSymbolSizeFloat32Bit) || (OpSize == eSymbolSizeFloat64Bit);
659
  Word RegValue, IndexReg = 0;
660
  int ArgLen, SplitPos;
661
  tStrComp BaseArg;
662
  const char IndexChars[] = "BWDQ";
663
  char *pSplit, *pSplit2, Scale;
664
 
665
  ClearAdrVals(pDest);
666
 
667
  /* split off scaled indexing, which is orthogonal to (almost) all other modes */
668
 
669
  pSplit = MatchCharsRev(pArg->str.p_str, " : ? ] ", IndexChars, &Scale);
670
  pSplit2 = (pSplit && (pSplit > pArg->str.p_str))
671
          ? FindOpeningParenthese(pArg->str.p_str, pSplit - 1, "[]")
672
          : NULL;
673
  if (pSplit && pSplit2)
674
  {
675
    tStrComp Mid, Right;
676
    const char *pScaleIndex;
677
 
678
    StrCompSplitRef(&BaseArg, &Right, pArg, pSplit);
679
    StrCompSplitRef(&BaseArg, &Mid, &BaseArg, pSplit2);
680
    KillPrefBlanksStrCompRef(&Mid);
681
    KillPostBlanksStrComp(&BaseArg);
682
    pArg = &BaseArg;
683
 
684
    pScaleIndex = strchr(IndexChars, as_toupper(Scale));
685
    if (!pScaleIndex)
686
    {
687
      WrStrErrorPos(ErrNum_InvScale, &Right);
688
      return False;
689
    }
690
    IndexCode = AddrCode_ScaledIndex + (pScaleIndex - IndexChars);
691
    if ((DecodeReg(&Mid, &IndexReg, NULL, eSymbolSize32Bit, True) == eIsReg)
692
     && (IndexReg >= 8))
693
    {
694
      WrStrErrorPos(ErrNum_InvReg, &Mid);
695
      return False;
696
    }
697
 
698
    /* Immediate cannot be combined with scaling, so disallow regardless of caller's
699
       preference: */
700
 
701
    AddrModeMask &= ~MAllowImm;
702
  }
703
 
704
  /* absolute: */
705
 
706
  if (*pArg->str.p_str == '@')
707
  {
708
    tStrComp Arg;
709
    LongWord Addr;
710
 
711
    StrCompRefRight(&Arg, pArg, 1);
712
    Addr = EvalStrIntExpression(&Arg, pCurrCPUProps->MemIntType, &OK);
713
    if (!OK)
714
      return False;
715
 
716
    /* On a CPU with non-32-bit address bus, addresses @ the upper end may be encoded
717
       as negative 'displacements': */
718
 
719
    if ((pCurrCPUProps->MemIntType == UInt24)
720
     && (Addr & 0x800000ul))
721
      Addr |= 0xff000000ul;
722
    if (EncodeDisplacement((LongInt)Addr, pDest, ErrNum_OverRange, &Arg))
723
    {
724
      pDest->Code = AddrCode_Absolute;
725
      goto chk;
726
    }
727
    else
728
      return False;
729
  }
730
 
731
  /* TOS? */
732
 
733
  if (!as_strcasecmp(pArg->str.p_str, "TOS"))
734
  {
735
    pDest->Code = AddrCode_TOS;
736
    goto chk;
737
  }
738
 
739
  /* register? */
740
 
741
  if (IsFloat)
742
    NeedEvenReg = (OpSize == eSymbolSizeFloat64Bit) && (MomFPU < eFPU32181);
743
  else
744
    NeedEvenReg = !!(AddrModeMask & MAllowRegPair);
745
  switch (DecodeReg(pArg, &RegValue, NULL, IsFloat ? OpSize : eSymbolSize32Bit, False))
746
  {
747
    case eIsReg:
748
      if (NeedEvenReg && (RegValue & 1))
749
      {
750
        WrStrErrorPos(ErrNum_InvRegPair, pArg);
751
        return False;
752
      }
753
      else if (!(AddrModeMask & (MAllowReg | MAllowRegPair)))
754
      {
755
        WrStrErrorPos(ErrNum_InvAddrMode, pArg);
756
        return False;
757
      }
758
      else
759
      {
760
        pDest->Code = AddrCode_Reg + RegValue;
761
        goto chk;
762
      }
763
    case eIsNoReg:
764
      break;
765
    default:
766
      return False;
767
  }
768
 
769
  /* EXT mode */
770
 
771
  pSplit = MatchChars(pArg->str.p_str, " EXT (");
772
  if (pSplit)
773
  {
774
    tStrComp Left, Mid, Right;
775
    LongInt Disp1, Disp2 = 0;
776
    Boolean OK;
777
 
778
    StrCompSplitRef(&Left, &Mid, pArg, pSplit - 1);
779
    pSplit = FindClosingParenthese(Mid.str.p_str);
780
    if (!pSplit)
781
    {
782
      WrStrErrorPos(ErrNum_BrackErr, pArg);
783
      return False;
784
    }
785
    StrCompSplitRef(&Mid, &Right, &Mid, pSplit);
786
    Disp1 = EvalStrIntExpression(&Mid, Int30, &OK);
787
    if (!OK)
788
      return False;
789
    *(--Right.str.p_str) = '0'; Right.Pos.Len++; Right.Pos.StartCol--;
790
    if (*Right.str.p_str)
791
      Disp2 = EvalStrIntExpression(&Right, Int30, &OK);
792
    if (!OK)
793
      return False;
794
 
795
    pDest->Code = AddrCode_External;
796
    if (!EncodeDisplacement(Disp1, pDest, ErrNum_OverRange, &Mid)
797
     || !EncodeDisplacement(Disp2, pDest, ErrNum_OverRange, &Right))
798
      return False;
799
    goto chk;
800
  }
801
 
802
  /* PC-relative */
803
 
804
  if (!strcmp(pArg->str.p_str, "*")
805
   || MatchChars(pArg->str.p_str, "* ?", "+-", NULL))
806
  {
807
    LongInt Disp;
808
    Boolean OK;
809
 
810
    *pArg->str.p_str = '0';
811
    Disp = EvalStrIntExpression(pArg, Int30, &OK);
812
    *pArg->str.p_str = '*';
813
    if (!OK
814
     || !EncodeDisplacement(Disp, pDest, ErrNum_OverRange, pArg))
815
      return False;
816
    pDest->Code = AddrCode_MemSpace + 3;
817
    goto chk;
818
  }
819
 
820
  /* disp(...)? */
821
 
822
  SplitPos = FindDispBaseSplit(pArg->str.p_str, &ArgLen);
823
  if (SplitPos >= 0)
824
  {
825
    tStrComp OutDisp, InnerArg;
826
    LongInt OutDispVal;
827
    tEvalResult OutEvalResult;
828
 
829
    memset(&OutEvalResult, 0, sizeof(OutEvalResult));
830
    StrCompSplitRef(&OutDisp, &InnerArg, pArg, &pArg->str.p_str[SplitPos]);
831
    if (OutDisp.Pos.Len)
832
    {
833
      OutDispVal = EvalStrIntExpressionWithResult(&OutDisp, Int30, &OutEvalResult);
834
      if (!OutEvalResult.OK)
835
        return False;
836
    }
837
    else
838
    {
839
      OutEvalResult.OK = True;
840
      OutDispVal = 0;
841
    }
842
 
843
    StrCompShorten(&InnerArg, 1);
844
    KillPrefBlanksStrCompRef(&InnerArg);
845
    KillPostBlanksStrComp(&InnerArg);
846
    switch (DecodeReg(&InnerArg, &RegValue, NULL, eSymbolSize32Bit, False))
847
    {
848
      case eIsReg: /* disp(Rn/FP/SP/SB) */
849
        pDest->Code = (RegValue < 8) ? AddrCode_Relative + RegValue : AddrCode_MemSpace + (RegValue - 8);
850
        if (!EncodeDisplacement(OutDispVal, pDest, ErrNum_OverRange, &OutDisp))
851
          return False;
852
        goto chk;
853
      IsPCRel:
854
        if (EncodeDisplacement(OutDispVal - EProgCounter(), pDest, mFirstPassUnknownOrQuestionable(OutEvalResult.Flags) ? ErrNum_None : ErrNum_JmpDistTooBig, &OutDisp))
855
          pDest->Code = AddrCode_MemSpace + 3;
856
        goto chk;
857
      case eIsNoReg:
858
      {
859
        tStrComp InDisp;
860
        LongInt InDispVal = 0;
861
 
862
        if (!as_strcasecmp(InnerArg.str.p_str, "PC"))
863
          goto IsPCRel;
864
 
865
        SplitPos = FindDispBaseSplit(InnerArg.str.p_str, &ArgLen);
866
        if (SplitPos < 0)
867
        {
868
          WrStrErrorPos(ErrNum_InvAddrMode, &InnerArg);
869
          return False;
870
        }
871
        StrCompSplitRef(&InDisp, &InnerArg, &InnerArg, &InnerArg.str.p_str[SplitPos]);
872
        if (InDisp.Pos.Len)
873
        {
874
          InDispVal = EvalStrIntExpression(&InDisp, Int30, &OK);
875
          if (!OK)
876
            return False;
877
        }
878
 
879
        StrCompShorten(&InnerArg, 1);
880
        KillPrefBlanksStrCompRef(&InnerArg);
881
        KillPostBlanksStrComp(&InnerArg);
882
 
883
        /* disp2(disp1(ext)) is an alias for EXT(disp1)+disp2 */
884
 
885
        if (!as_strcasecmp(InnerArg.str.p_str, "EXT"))
886
        {
887
          pDest->Code = AddrCode_External;
888
        }
889
 
890
        /* disp2(disp1(FP/SP/SB)) */
891
 
892
        else
893
        {
894
          if (DecodeReg(&InnerArg, &RegValue, NULL, eSymbolSize32Bit, True) != eIsReg)
895
            return False;
896
          if (RegValue < 8)
897
          {
898
            WrStrErrorPos(ErrNum_InvReg, &InnerArg);
899
            return False;
900
          }
901
          pDest->Code = AddrCode_MemRelative + (RegValue - 8);
902
        }
903
        if (!EncodeDisplacement(InDispVal, pDest, ErrNum_OverRange, &InDisp)
904
         || !EncodeDisplacement(OutDispVal, pDest, ErrNum_OverRange, &OutDisp))
905
          return False;
906
        goto chk;
907
      }
908
      default:
909
        return False;
910
    }
911
  }
912
 
913
  /* -> immediate or PC-relative */
914
 
915
  if (AddrModeMask & MAllowImm)
916
  {
917
    switch (OpSize)
918
    {
919
      case eSymbolSize8Bit:
920
        pDest->Disp[0] = EvalStrIntExpression(pArg, Int8, &OK);
921
        if (OK)
922
          pDest->DispCnt = 1;
923
        break;
924
      case eSymbolSize16Bit:
925
      {
926
        Word Val = EvalStrIntExpression(pArg, Int16, &OK);
927
        if (OK)
928
        {
929
          pDest->Disp[pDest->DispCnt++] = Hi(Val);
930
          pDest->Disp[pDest->DispCnt++] = Lo(Val);
931
        }
932
        break;
933
      }
934
      case eSymbolSize32Bit:
935
      {
936
        LongWord Val = EvalStrIntExpression(pArg, Int32, &OK);
937
        if (OK)
938
        {
939
          pDest->Disp[pDest->DispCnt++] = (Val >> 24) & 0xff;
940
          pDest->Disp[pDest->DispCnt++] = (Val >> 16) & 0xff;
941
          pDest->Disp[pDest->DispCnt++] = (Val >>  8) & 0xff;
942
          pDest->Disp[pDest->DispCnt++] = (Val >>  0) & 0xff;
943
        }
944
        break;
945
      }
946
      case eSymbolSize64Bit:
947
      {
948
        LargeWord Val = EvalStrIntExpression(pArg, LargeIntType, &OK);
949
        if (OK)
950
        {
951
#ifdef HAS64
952
          pDest->Disp[pDest->DispCnt++] = (Val >> 56) & 0xff;
953
          pDest->Disp[pDest->DispCnt++] = (Val >> 48) & 0xff;
954
          pDest->Disp[pDest->DispCnt++] = (Val >> 40) & 0xff;
955
          pDest->Disp[pDest->DispCnt++] = (Val >> 32) & 0xff;
956
#else
957
          pDest->Disp[pDest->DispCnt + 0] =
958
          pDest->Disp[pDest->DispCnt + 1] =
959
          pDest->Disp[pDest->DispCnt + 2] =
960
          pDest->Disp[pDest->DispCnt + 3] = (Val & 0x80000000ul) ? 0xff : 0x00;
961
          pDest->DispCnt += 4;
962
#endif
963
          pDest->Disp[pDest->DispCnt++] = (Val >> 24) & 0xff;
964
          pDest->Disp[pDest->DispCnt++] = (Val >> 16) & 0xff;
965
          pDest->Disp[pDest->DispCnt++] = (Val >>  8) & 0xff;
966
          pDest->Disp[pDest->DispCnt++] = (Val >>  0) & 0xff;
967
        }
968
        break;
969
      }
970
      case eSymbolSizeFloat32Bit:
971
      {
972
        as_float_t Val = EvalStrFloatExpression(pArg, &OK);
973
        if (OK)
974
        {
975
          int ret;
976
 
977
          if ((ret = as_float_2_ieee4(Val, pDest->Disp, True)) < 0)
978
          {
979
            asmerr_check_fp_dispose_result(ret, pArg);
980
            OK = False;
981
          }
982
        }
983
        if (OK)
984
          pDest->DispCnt = 4;
985
        break;
986
      }
987
      case eSymbolSizeFloat64Bit:
988
      {
989
        as_float_t Val = EvalStrFloatExpression(pArg, &OK);
990
        if (OK)
991
        {
992
          int ret;
993
 
994
          if ((ret = as_float_2_ieee8(Val, pDest->Disp, True)) < 0)
995
          {
996
            asmerr_check_fp_dispose_result(ret, pArg);
997
            OK = False;
998
          }
999
        }
1000
        if (OK)
1001
          pDest->DispCnt = 8;
1002
        break;
1003
      }
1004
      default:
1005
        WrStrErrorPos(ErrNum_UndefOpSizes, pArg);
1006
    }
1007
    if (pDest->DispCnt)
1008
      pDest->Code = AddrCode_Immediate;
1009
    else
1010
      return False;
1011
  }
1012
  else if (!EncodePCRel(pArg, pDest))
1013
    return False;
1014
 
1015
chk:
1016
  /* if we have an index code, check it's not immedate, otherwise relocate */
1017
 
1018
  if (IndexCode)
1019
  {
1020
    if (pDest->Code == AddrCode_Immediate)
1021
    {
1022
      WrStrErrorPos(ErrNum_InvAddrMode, pArg);
1023
      return False;
1024
    }
1025
    pDest->Index[pDest->IndexCnt++] = (pDest->Code << 3) | IndexReg;
1026
    pDest->Code = IndexCode;
1027
  }
1028
  return True;
1029
}
1030
 
1031
/*!------------------------------------------------------------------------
1032
 * \fn     AppendIndex(const tAdrVals *pVals)
1033
 * \brief  append optional index byte to code
1034
 * \param  pVals encoded addressing mode
1035
 * ------------------------------------------------------------------------ */
1036
 
1037
static void AppendIndex(const tAdrVals *pVals)
1038
{
1039
  if (pVals->IndexCnt)
1040
  {
1041
    memcpy(&BAsmCode[CodeLen], pVals->Index, pVals->IndexCnt);
1042
    CodeLen += pVals->IndexCnt;
1043
  }
1044
}
1045
 
1046
/*!------------------------------------------------------------------------
1047
 * \fn     AppendDisp(const tAdrVals *pVals)
1048
 * \brief  append optional displacement to code
1049
 * \param  pVals encoded addressing mode
1050
 * ------------------------------------------------------------------------ */
1051
 
1052
static void AppendDisp(const tAdrVals *pVals)
1053
{
1054
  if (pVals->DispCnt)
1055
  {
1056
    memcpy(&BAsmCode[CodeLen], pVals->Disp, pVals->DispCnt);
1057
    CodeLen += pVals->DispCnt;
1058
  }
1059
}
1060
 
1061
/*--------------------------------------------------------------------------*/
1062
/* Helper Functions */
1063
 
1064
/*!------------------------------------------------------------------------
1065
 * \fn     SizeCodeI(tSymbolSize Size)
1066
 * \brief  transform (integer) operand size to i size in instruction
1067
 * \param  Size Operand Size
1068
 * \return Size Code
1069
 * ------------------------------------------------------------------------ */
1070
 
1071
static LongWord SizeCodeI(tSymbolSize Size)
1072
{
1073
  switch (Size)
1074
  {
1075
    case eSymbolSize8Bit:
1076
      return 0;
1077
    case eSymbolSize16Bit:
1078
      return 1;
1079
    case eSymbolSize32Bit:
1080
      return 3;
1081
    default:
1082
      return 2;
1083
  }
1084
}
1085
 
1086
/*!------------------------------------------------------------------------
1087
 * \fn     SizeCodeF(tSymbolSize Size)
1088
 * \brief  transform (float) operand size to f size in instruction
1089
 * \param  Size Operand Size
1090
 * \return Size Code
1091
 * ------------------------------------------------------------------------ */
1092
 
1093
static LongWord SizeCodeF(tSymbolSize Size)
1094
{
1095
  switch (Size)
1096
  {
1097
    case eSymbolSizeFloat64Bit:
1098
      return 0;
1099
    case eSymbolSizeFloat32Bit:
1100
      return 1;
1101
    default:
1102
      return 0xff;
1103
  }
1104
}
1105
 
1106
/*!------------------------------------------------------------------------
1107
 * \fn     SizeCodeC(tSymbolSize Size)
1108
 * \brief  transform (custom) operand size to c size in instruction
1109
 * \param  Size Operand Size
1110
 * \return Size Code
1111
 * ------------------------------------------------------------------------ */
1112
 
1113
static LongWord SizeCodeC(tSymbolSize Size)
1114
{
1115
  switch (Size)
1116
  {
1117
    case eSymbolSize64Bit:
1118
      return 0;
1119
    case eSymbolSize32Bit:
1120
      return 1;
1121
    default:
1122
      return 0xff;
1123
  }
1124
}
1125
 
1126
/*!------------------------------------------------------------------------
1127
 * \fn     GetOpSizeFromCode(Word Code)
1128
 * \brief  get operand size of instruction from insn name
1129
 * \param  Code contains size in MSB
1130
 * \return operand size
1131
 * ------------------------------------------------------------------------ */
1132
 
1133
static tSymbolSize GetOpSizeFromCode(Word Code)
1134
{
1135
  Byte Size = Hi(Code) & 15;
1136
 
1137
  return (Size == 0xff) ? eSymbolSizeUnknown : (tSymbolSize)Size;
1138
}
1139
 
1140
/*!------------------------------------------------------------------------
1141
 * \fn     SetOpSizeFromCode(Word Code)
1142
 * \brief  set operand size of instruction from insn code MSB
1143
 * \param  Code contains size in MSB
1144
 * \return True if success
1145
 * ------------------------------------------------------------------------ */
1146
 
1147
static Boolean SetOpSizeFromCode(Word Code)
1148
{
1149
  return SetOpSize(GetOpSizeFromCode(Code), &OpPart);
1150
}
1151
 
1152
/*!------------------------------------------------------------------------
1153
 * \fn     SetFOpSizeFromCode(Word Code)
1154
 * \brief  set FP operand size of instruction from insn code
1155
 * \param  Code contains size in LSB
1156
 * \return True if success
1157
 * ------------------------------------------------------------------------ */
1158
 
1159
static Boolean SetFOpSizeFromCode(Word Code)
1160
{
1161
  return SetOpSize((Code & 1) ? eSymbolSizeFloat32Bit : eSymbolSizeFloat64Bit, &OpPart);
1162
}
1163
 
1164
/*!------------------------------------------------------------------------
1165
 * \fn     SetCOpSizeFromCode(Word Code)
1166
 * \brief  set custom operand size of instruction from insn code
1167
 * \param  Code contains size in LSB
1168
 * \return True if success
1169
 * ------------------------------------------------------------------------ */
1170
 
1171
static Boolean SetCOpSizeFromCode(Word Code)
1172
{
1173
  return SetOpSize((Code & 1) ? eSymbolSize32Bit : eSymbolSize64Bit, &OpPart);
1174
}
1175
 
1176
/*!------------------------------------------------------------------------
1177
 * \fn     PutCode(LongWord Code, unsigned Count)
1178
 * \brief  write instruction opcode to output
1179
 * \param  Code opcode to write
1180
 * \param  Count # of bytes to write
1181
 * ------------------------------------------------------------------------ */
1182
 
1183
static void PutCode(LongWord Code, unsigned Count)
1184
{
1185
  BAsmCode[CodeLen++] = Code & 0xff;
1186
  while (Count > 1)
1187
  {
1188
    Code >>= 8;
1189
    Count--;
1190
    BAsmCode[CodeLen++] = Code & 0xff;
1191
  }
1192
}
1193
 
1194
/*!------------------------------------------------------------------------
1195
 * \fn     ChkNoAttrPart(void)
1196
 * \brief  check for no attribute part
1197
 * \return True if no attribute
1198
 * ------------------------------------------------------------------------ */
1199
 
1200
static Boolean ChkNoAttrPart(void)
1201
{
1202
  if (*AttrPart.str.p_str)
1203
  {
1204
    WrError(ErrNum_UseLessAttr);
1205
    return False;
1206
  }
1207
  return True;
1208
}
1209
 
1210
/*--------------------------------------------------------------------------*/
1211
/* Instruction De/Encoders */
1212
 
1213
/*!------------------------------------------------------------------------
1214
 * \fn     DecodeFixed(Word Code)
1215
 * \brief  decode instructions without argument
1216
 * \param  Code machine code
1217
 * ------------------------------------------------------------------------ */
1218
 
1219
static void DecodeFixed(Word Code)
1220
{
1221
  if (ChkArgCnt(0, 0))
1222
    PutCode(Code, !!Hi(Code));
1223
}
1224
 
1225
/*!------------------------------------------------------------------------
1226
 * \fn     DecodeFormat0(Word Code)
1227
 * \brief  Decode Format 0 Instructions
1228
 * \param  Code machine code
1229
 * ------------------------------------------------------------------------ */
1230
 
1231
static void DecodeFormat0(Word Code)
1232
{
1233
  tAdrVals AdrVals;
1234
 
1235
  ClearAdrVals(&AdrVals);
1236
  if (ChkArgCnt(1, 1)
1237
   && ChkNoAttrPart()
1238
   && EncodePCRel(&ArgStr[1], &AdrVals))
1239
  {
1240
    PutCode(Code, 1);
1241
    AppendDisp(&AdrVals);
1242
  }
1243
}
1244
 
1245
/*!------------------------------------------------------------------------
1246
 * \fn     DecodeRET(Word Code)
1247
 * \brief  Decode RET/RETT/RXP Instructions
1248
 * \param  Code Machine Code
1249
 * ------------------------------------------------------------------------ */
1250
 
1251
static void DecodeRET(Word Code)
1252
{
1253
  if (ChkArgCnt(0, 1)
1254
   &&  ChkNoAttrPart())
1255
  {
1256
    tEvalResult EvalResult;
1257
    LongInt Value;
1258
    tAdrVals AdrVals;
1259
 
1260
    if (ArgCnt >= 1)
1261
      Value = EvalStrIntExpressionWithResult(&ArgStr[1], SInt30, &EvalResult);
1262
    else
1263
    {
1264
      Value = 0;
1265
      EvalResult.OK = True;
1266
      EvalResult.Flags = eSymbolFlag_None;
1267
    }
1268
 
1269
    ClearAdrVals(&AdrVals);
1270
    if (EncodeDisplacement(Value, &AdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[1]))
1271
    {
1272
      PutCode(Code, 1);
1273
      AppendDisp(&AdrVals);
1274
    }
1275
  }
1276
}
1277
 
1278
/*!------------------------------------------------------------------------
1279
 * \fn     DecodeCXP(Word Code)
1280
 * \brief  Handle CXP Instruction
1281
 * \param  Code machine code
1282
 * ------------------------------------------------------------------------ */
1283
 
1284
static void DecodeCXP(Word Code)
1285
{
1286
  if (ChkArgCnt(1, 1)
1287
   &&  ChkNoAttrPart())
1288
  {
1289
    tEvalResult EvalResult;
1290
    LongInt Value = EvalStrIntExpressionWithResult(&ArgStr[1], SInt30, &EvalResult);
1291
    tAdrVals AdrVals;
1292
 
1293
    ClearAdrVals(&AdrVals);
1294
    if (EncodeDisplacement(Value, &AdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[1]))
1295
    {
1296
      PutCode(Code, 1);
1297
      AppendDisp(&AdrVals);
1298
    }
1299
  }
1300
}
1301
 
1302
/*!------------------------------------------------------------------------
1303
 * \fn     DecodeENTER(Word Code)
1304
 * \brief  Handle ENTER Instruction (Format 1)
1305
 * \param  Code machine code
1306
 * ------------------------------------------------------------------------ */
1307
 
1308
static void DecodeENTER(Word Code)
1309
{
1310
  Byte RegList;
1311
 
1312
  if (ChkArgCnt(2, 2)
1313
   && ChkNoAttrPart()
1314
   && DecodeRegList(&ArgStr[1], False, &RegList))
1315
  {
1316
    tEvalResult EvalResult;
1317
    LongInt Value = EvalStrIntExpressionWithResult(&ArgStr[2], SInt30, &EvalResult);
1318
    tAdrVals AdrVals;
1319
 
1320
    ClearAdrVals(&AdrVals);
1321
    if (EncodeDisplacement(Value, &AdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[1]))
1322
    {
1323
      PutCode(Code, 1);
1324
      BAsmCode[CodeLen++] = RegList;
1325
      AppendDisp(&AdrVals);
1326
    }
1327
  }
1328
}
1329
 
1330
/*!------------------------------------------------------------------------
1331
 * \fn     DecodeEXIT(Word Code)
1332
 * \brief  Handle EXIT Instruction (Format 1)
1333
 * \param  Code machine code
1334
 * ------------------------------------------------------------------------ */
1335
 
1336
static void DecodeEXIT(Word Code)
1337
{
1338
  Byte RegList;
1339
 
1340
  if (ChkArgCnt(1, 1)
1341
   && ChkNoAttrPart()
1342
   && DecodeRegList(&ArgStr[1], True, &RegList))
1343
  {
1344
    PutCode(Code, 1);
1345
    BAsmCode[CodeLen++] = RegList;
1346
  }
1347
}
1348
 
1349
/*!------------------------------------------------------------------------
1350
 * \fn     DecodeSAVE_RESTORE(Word Code)
1351
 * \brief  Decode SAVE/RESTORE Instructions
1352
 * \param  Code Machine Code
1353
 * ------------------------------------------------------------------------ */
1354
 
1355
static void DecodeSAVE_RESTORE(Word Code)
1356
{
1357
  Byte RegList;
1358
 
1359
  if (ChkArgCnt(1, 1)
1360
   && ChkNoAttrPart()
1361
   && DecodeRegList(&ArgStr[1], !!(Code & 0x10), &RegList))
1362
  {
1363
    PutCode(Code, 1);
1364
    PutCode(RegList, 1);
1365
  }
1366
}
1367
 
1368
/*!------------------------------------------------------------------------
1369
 * \fn     DecodeCINV(Word Code)
1370
 * \brief  handle CINV instruction
1371
 * \param  Code machine code
1372
 * ------------------------------------------------------------------------ */
1373
 
1374
static void DecodeCINV(Word Code)
1375
{
1376
  tAdrVals AdrVals;
1377
 
1378
  if (ChkArgCnt(2, 4)
1379
   && ChkNoAttrPart()
1380
   && CheckCore(1 << eCoreGen2)
1381
   && CheckSup(True, &OpPart)
1382
   && DecodeAdr(&ArgStr[ArgCnt], &AdrVals, MAllowReg))
1383
  {
1384
    LongWord ActCode = (((LongWord)AdrVals.Code) << 19)
1385
                     | Code;
1386
    int z;
1387
 
1388
    for (z = 1; z < ArgCnt; z++)
1389
      if (!as_strcasecmp(ArgStr[z].str.p_str, "A"))
1390
        ActCode |= 1ul << 17;
1391
      else if (!as_strcasecmp(ArgStr[z].str.p_str, "I"))
1392
        ActCode |= 1ul << 16;
1393
      else if (!as_strcasecmp(ArgStr[z].str.p_str, "D"))
1394
        ActCode |= 1ul << 15;
1395
      else
1396
      {
1397
        WrStrErrorPos(ErrNum_InvCacheInvMode, &ArgStr[z]);
1398
        return;
1399
      }
1400
    PutCode(ActCode, 3);
1401
    AppendIndex(&AdrVals);
1402
    AppendDisp(&AdrVals);
1403
  }
1404
}
1405
 
1406
/*!------------------------------------------------------------------------
1407
 * \fn     DecodeLPR_SPR(Word Code)
1408
 * \brief  Decode LPR/SPR Instructions (Format 2)
1409
 * \param  Code Machine Code & Operand Size
1410
 * ------------------------------------------------------------------------ */
1411
 
1412
static void DecodeLPR_SPR(Word Code)
1413
{
1414
  tAdrVals SrcAdrVals;
1415
  Word Reg;
1416
  Boolean IsSPR = (Lo(Code) == 2);
1417
 
1418
  if (ChkArgCnt(2, 2)
1419
   && ChkNoAttrPart()
1420
   && SetOpSizeFromCode(Code)
1421
   && DecodeAdr(&ArgStr[2], &SrcAdrVals, MAllowReg | (IsSPR ? 0 : MAllowImm))
1422
   && DecodeCtlReg(&ArgStr[1], &Reg))
1423
  {
1424
    PutCode((((Word)SrcAdrVals.Code) << 11)
1425
          | (Reg << 7)
1426
          | (Lo(Code) << 4)
1427
          | (SizeCodeI(OpSize) << 0)
1428
          | 0x0c, 2);
1429
    AppendIndex(&SrcAdrVals);
1430
    AppendDisp(&SrcAdrVals);
1431
  }
1432
}
1433
 
1434
/*!------------------------------------------------------------------------
1435
 * \fn     DecodeScond(Word Code)
1436
 * \brief  Handloe Scond Instructions
1437
 * \param  Code condition & operand size
1438
 * ------------------------------------------------------------------------ */
1439
 
1440
static void DecodeScond(Word Code)
1441
{
1442
  tAdrVals AdrVals;
1443
 
1444
  if (ChkArgCnt(1, 1)
1445
   && ChkNoAttrPart()
1446
   && SetOpSizeFromCode(Code)
1447
   && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg))
1448
  {
1449
    PutCode((((Word)AdrVals.Code) << 11)
1450
          | ((Code & 0xff) << 7)
1451
          | (SizeCodeI(OpSize) << 0)
1452
          | 0x3c, 2);
1453
    AppendIndex(&AdrVals);
1454
    AppendDisp(&AdrVals);
1455
  }
1456
}
1457
 
1458
/*!------------------------------------------------------------------------
1459
 * \fn     DecodeMOVQ(Word Code)
1460
 * \brief  Handle MOVQ/ADDQ/CMPQ Instructions
1461
 * \param  Code Machine Code & Operand Size
1462
 * ------------------------------------------------------------------------ */
1463
 
1464
#define MOVQ_DESTMAYIMM 0x80
1465
 
1466
static void DecodeMOVQ(Word Code)
1467
{
1468
  tAdrVals DestAdrVals;
1469
  Boolean DestMayImm = !!(Code & MOVQ_DESTMAYIMM);
1470
 
1471
  Code &= ~MOVQ_DESTMAYIMM;
1472
  if (ChkArgCnt(2, 2)
1473
   && ChkNoAttrPart()
1474
   && SetOpSizeFromCode(Code)
1475
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
1476
  {
1477
    Boolean OK;
1478
    Integer Val = EvalStrIntExpression(&ArgStr[1], SInt4, &OK);
1479
 
1480
    if (OK)
1481
    {
1482
      PutCode((((Word)DestAdrVals.Code) << 11)
1483
            | ((Val & 0x0f) << 7)
1484
            | (Lo(Code) << 4)
1485
            | (SizeCodeI(OpSize) << 0)
1486
            | 0x0c, 2);
1487
      AppendIndex(&DestAdrVals);
1488
      AppendDisp(&DestAdrVals);
1489
    }
1490
  }
1491
}
1492
 
1493
/*!------------------------------------------------------------------------
1494
 * \fn     DecodeACB(Word Code)
1495
 * \brief  handle ACBi Instrucion
1496
 * \param  Code machine code & operand size
1497
 * ------------------------------------------------------------------------ */
1498
 
1499
static void DecodeACB(Word Code)
1500
{
1501
  tAdrVals DestAdrVals;
1502
 
1503
  if (ChkArgCnt(3, 3)
1504
   && ChkNoAttrPart()
1505
   && SetOpSizeFromCode(Code)
1506
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
1507
  {
1508
    Boolean OK;
1509
    tAdrVals DistAdrVals;
1510
    Integer Val = EvalStrIntExpression(&ArgStr[1], SInt4, &OK);
1511
 
1512
    if (OK && EncodePCRel(&ArgStr[3], &DistAdrVals))
1513
    {
1514
      PutCode((((Word)DestAdrVals.Code) << 11)
1515
            | ((Val & 0x0f) << 7)
1516
            | (Lo(Code) << 4)
1517
            | (SizeCodeI(OpSize) << 0)
1518
            | 0x0c, 2);
1519
      AppendIndex(&DestAdrVals);
1520
      AppendDisp(&DestAdrVals);
1521
      AppendDisp(&DistAdrVals);
1522
    }
1523
  }
1524
}
1525
 
1526
/*!------------------------------------------------------------------------
1527
 * \fn     DecodeFormat3(Word Code)
1528
 * \brief  Decode Format 3 Instructions
1529
 * \param  Code Machine Code
1530
 * ------------------------------------------------------------------------ */
1531
 
1532
static void DecodeFormat3(Word Code)
1533
{
1534
  tAdrVals AdrVals;
1535
 
1536
  if (ChkArgCnt(1, 1)
1537
   && ChkNoAttrPart()
1538
   && SetOpSizeFromCode(Code)
1539
   && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | MAllowImm))
1540
  {
1541
    PutCode((((Word)AdrVals.Code) << 11)
1542
          | (Lo(Code) << 7)
1543
          | (SizeCodeI(OpSize) << 0)
1544
          | 0x7c, 2);
1545
    AppendIndex(&AdrVals);
1546
    AppendDisp(&AdrVals);
1547
  }
1548
}
1549
 
1550
/*!------------------------------------------------------------------------
1551
 * \fn     DecodeFormat4(Word Code)
1552
 * \brief  decode Format 4 instructions
1553
 * \param  Code machine code
1554
 * ------------------------------------------------------------------------ */
1555
 
1556
#define FMT4_SRCISADDR 0x80
1557
#define FMT4_DESTMAYIMM 0x40
1558
 
1559
static void DecodeFormat4(Word Code)
1560
{
1561
  tAdrVals SrcAdrVals, DestAdrVals;
1562
  Boolean SrcIsAddr = !!(Code & FMT4_SRCISADDR),
1563
          DestMayImm = !!(Code & FMT4_DESTMAYIMM);
1564
 
1565
  Code &= ~(FMT4_SRCISADDR | FMT4_DESTMAYIMM);
1566
  if (ChkArgCnt(2, 2)
1567
   && ChkNoAttrPart()
1568
   && SetOpSizeFromCode(Code)
1569
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | (SrcIsAddr ? 0 : MAllowImm))
1570
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
1571
  {
1572
    PutCode((((Word)SrcAdrVals.Code) << 11)
1573
          | (((Word)DestAdrVals.Code) << 6)
1574
          | (Lo(Code) << 2)
1575
          | (SizeCodeI(OpSize)), 2);
1576
    AppendIndex(&SrcAdrVals);
1577
    AppendIndex(&DestAdrVals);
1578
    AppendDisp(&SrcAdrVals);
1579
    AppendDisp(&DestAdrVals);
1580
  }
1581
}
1582
 
1583
/*!------------------------------------------------------------------------
1584
 * \fn     DecodeMOVS_CMPS_SKPS(Word Code)
1585
 * \brief  Handle MOVSi/CMPSi/SKPSi Instructions (Format 5)
1586
 * \param  Code machine code & operand size
1587
 * ------------------------------------------------------------------------ */
1588
 
1589
static void DecodeMOVS_CMPS_SKPS(Word Code)
1590
{
1591
  if (ChkArgCnt(0, 2)
1592
   && ChkNoAttrPart()
1593
   && SetOpSizeFromCode(Code))
1594
  {
1595
    Byte Options = 0;
1596
    int z;
1597
 
1598
    for (z = 1; z <= ArgCnt; z++)
1599
    {
1600
      if (!as_strcasecmp(ArgStr[z].str.p_str, "B"))
1601
        Options |= 1;
1602
      else if (!as_strcasecmp(ArgStr[z].str.p_str, "U"))
1603
      {
1604
        if (Options & 6)
1605
        {
1606
          WrStrErrorPos(ErrNum_ConfStringOpt, &ArgStr[z]);
1607
          return;
1608
        }
1609
        else
1610
          Options |= 6;
1611
      }
1612
      else if (!as_strcasecmp(ArgStr[z].str.p_str, "W"))
1613
      {
1614
        if (Options & 6)
1615
        {
1616
          WrStrErrorPos(ErrNum_ConfStringOpt, &ArgStr[z]);
1617
          return;
1618
        }
1619
        else
1620
          Options |= 2;
1621
      }
1622
      else
1623
      {
1624
        WrStrErrorPos(ErrNum_UnknownStringOpt, &ArgStr[z]);
1625
        return;
1626
      }
1627
    }
1628
    PutCode((((LongWord)Options) << 16)
1629
          | ((Code & 0xff) << 10)
1630
          | (SizeCodeI(OpSize) << 8)
1631
          | 0x0e, 3);
1632
  }
1633
}
1634
 
1635
/*!------------------------------------------------------------------------
1636
 * \fn     DecodeSETCFG(Word Code)
1637
 * \brief  Handle SETCFG Instruction
1638
 * \param  Code machine code
1639
 * ------------------------------------------------------------------------ */
1640
 
1641
static void DecodeSETCFG(Word Code)
1642
{
1643
  Byte CfgOpts;
1644
 
1645
  if (ChkArgCnt(1, 1)
1646
   && ChkNoAttrPart()
1647
   && CheckSup(True, &OpPart)
1648
   && DecodeCfgList(&ArgStr[1], &CfgOpts))
1649
    PutCode((((LongWord)CfgOpts) << 15)
1650
            | Code, 3);
1651
}
1652
 
1653
/*!------------------------------------------------------------------------
1654
 * \fn     DecodeFormat6(Word Code)
1655
 * \brief  Decode Format 6 Instructions
1656
 * \param  Code machine code
1657
 * ------------------------------------------------------------------------ */
1658
 
1659
#define FMT6_SRC8BIT 0x80
1660
 
1661
static void DecodeFormat6(Word Code)
1662
{
1663
  tAdrVals SrcAdrVals, DestAdrVals;
1664
  Boolean SrcIs8Bit = !!(Code & FMT6_SRC8BIT);
1665
 
1666
  Code &= ~FMT6_SRC8BIT;
1667
  if (ChkArgCnt(2, 2)
1668
   && ChkNoAttrPart()
1669
   && SetOpSizeFromCode(SrcIs8Bit ? 0x0000 : Code)
1670
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
1671
   && ResetOpSize() && SetOpSizeFromCode(Code)
1672
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
1673
  {
1674
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
1675
          | (((LongWord)DestAdrVals.Code) << 14)
1676
          | (Lo(Code) << 10)
1677
          | (SizeCodeI(OpSize) << 8)
1678
          | 0x4e, 3);
1679
    AppendIndex(&SrcAdrVals);
1680
    AppendIndex(&DestAdrVals);
1681
    AppendDisp(&SrcAdrVals);
1682
    AppendDisp(&DestAdrVals);
1683
  }
1684
}
1685
 
1686
/*!------------------------------------------------------------------------
1687
 * \fn     DecodeFormat7(Word Code)
1688
 * \brief  Decode Format 7 Instructions
1689
 * \param  Code machine code
1690
 * ------------------------------------------------------------------------ */
1691
 
1692
static void DecodeFormat7(Word Code)
1693
{
1694
  tAdrVals SrcAdrVals, DestAdrVals;
1695
 
1696
  if (ChkArgCnt(2, 2)
1697
   && ChkNoAttrPart()
1698
   && SetOpSizeFromCode(Code)
1699
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
1700
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
1701
  {
1702
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
1703
          | (((LongWord)DestAdrVals.Code) << 14)
1704
          | (Lo(Code) << 10)
1705
          | (SizeCodeI(OpSize) << 8)
1706
          | 0xce, 3);
1707
    AppendIndex(&SrcAdrVals);
1708
    AppendIndex(&DestAdrVals);
1709
    AppendDisp(&SrcAdrVals);
1710
    AppendDisp(&DestAdrVals);
1711
  }
1712
}
1713
 
1714
/*!------------------------------------------------------------------------
1715
 * \fn     DecodeMOVM_CMPM(Word Code)
1716
 * \brief  Decode MOVMi/CMPMi Instruction (Format 7)
1717
 * \param  Code machine code & size
1718
 * ------------------------------------------------------------------------ */
1719
 
1720
static void DecodeMOVM_CMPM(Word Code)
1721
{
1722
  tAdrVals SrcAdrVals, DestAdrVals;
1723
 
1724
  if (ChkArgCnt(3, 3)
1725
   && ChkNoAttrPart()
1726
   && SetOpSizeFromCode(Code)
1727
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg)
1728
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
1729
  {
1730
    tEvalResult EvalResult;
1731
    LongWord Count = EvalStrIntExpressionWithResult(&ArgStr[3], UInt30, &EvalResult);
1732
 
1733
    if (EvalResult.OK)
1734
    {
1735
      tAdrVals CntAdrVals;
1736
 
1737
      Count = (Count - 1) << OpSize;
1738
      ClearAdrVals(&CntAdrVals);
1739
      if (EncodeDisplacement(Count, &CntAdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[3]))
1740
      {
1741
        PutCode((((LongWord)SrcAdrVals.Code) << 19)
1742
            | (((LongWord)DestAdrVals.Code) << 14)
1743
            | (Lo(Code) << 10)
1744
            | (SizeCodeI(OpSize) << 8)
1745
            | 0xce, 3);
1746
        AppendIndex(&SrcAdrVals);
1747
        AppendIndex(&DestAdrVals);
1748
        AppendDisp(&SrcAdrVals);
1749
        AppendDisp(&DestAdrVals);
1750
        AppendDisp(&CntAdrVals);
1751
      }
1752
    }
1753
  }
1754
}
1755
 
1756
/*!------------------------------------------------------------------------
1757
 * \fn     DecodeINSS_EXTS(Word Code)
1758
 * \brief  Handle INSS/EXTS Instructions (Format 7)
1759
 * \param  Code machine code & operand size
1760
 * ------------------------------------------------------------------------ */
1761
 
1762
static void DecodeINSS_EXTS(Word Code)
1763
{
1764
  tAdrVals Arg1AdrVals, Arg2AdrVals;
1765
 
1766
  if (ChkArgCnt(4, 4)
1767
   && ChkNoAttrPart()
1768
   && SetOpSizeFromCode(Code)
1769
   && DecodeAdr(&ArgStr[1], &Arg1AdrVals, MAllowReg | ((Lo(Code) == 2) ? MAllowImm : 0))
1770
   && DecodeAdr(&ArgStr[2], &Arg2AdrVals, MAllowReg))
1771
  {
1772
    tEvalResult EvalResult;
1773
    Byte Offs, Length;
1774
 
1775
    Offs = EvalStrIntExpressionWithResult(&ArgStr[3], UInt3, &EvalResult);
1776
    if (!EvalResult.OK)
1777
      return;
1778
 
1779
    Length = EvalStrIntExpressionWithResult(&ArgStr[4], UInt5, &EvalResult);
1780
    if (!EvalResult.OK)
1781
      return;
1782
    if (mFirstPassUnknownOrQuestionable(EvalResult.Flags))
1783
      Length = (Length & 31) + 1;
1784
    if (ChkRange(Length, 1, 32))
1785
    {
1786
      PutCode((((LongWord)Arg1AdrVals.Code) << 19)
1787
            | (((LongWord)Arg2AdrVals.Code) << 14)
1788
            | (SizeCodeI(OpSize) << 8)
1789
            | (Lo(Code) << 10)
1790
            | 0xce, 3);
1791
      AppendIndex(&Arg1AdrVals);
1792
      AppendIndex(&Arg2AdrVals);
1793
      AppendDisp(&Arg1AdrVals);
1794
      AppendDisp(&Arg2AdrVals);
1795
      BAsmCode[CodeLen++] = ((Offs & 7) << 5) | ((Length - 1) & 31);
1796
    }
1797
  }
1798
}
1799
 
1800
/*!------------------------------------------------------------------------
1801
 * \fn     DecodeMOVExt(Word Code)
1802
 * \brief  Decode MOV{X|Z}{BW|BD|WD} Instructions (Format 7)
1803
 * \param  Code machine code & operand sizes
1804
 * ------------------------------------------------------------------------ */
1805
 
1806
static void DecodeMOVExt(Word Code)
1807
{
1808
  tAdrVals SrcAdrVals, DestAdrVals;
1809
  Byte SrcOpSize = (Code >> 8) & 15,
1810
       DestOpSize = (Code >> 12) & 15;
1811
 
1812
  if (ChkArgCnt(2, 2)
1813
   && ChkNoAttrPart()
1814
   && SetOpSize((tSymbolSize)SrcOpSize, &OpPart)
1815
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm))
1816
  {
1817
    OpSize = (tSymbolSize)DestOpSize;
1818
 
1819
    if (DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
1820
    {
1821
      Code = ((DestOpSize == eSymbolSize32Bit) ? 6 : 5) ^ (Code & 1);
1822
      PutCode((((LongWord)SrcAdrVals.Code) << 19)
1823
            | (((LongWord)DestAdrVals.Code) << 14)
1824
            | (Code << 10)
1825
            | (((LongWord)SrcOpSize) << 8)
1826
            | 0xce, 3);
1827
      AppendIndex(&SrcAdrVals);
1828
      AppendIndex(&DestAdrVals);
1829
      AppendDisp(&SrcAdrVals);
1830
      AppendDisp(&DestAdrVals);
1831
    }
1832
  }
1833
}
1834
 
1835
/*!------------------------------------------------------------------------
1836
 * \fn     DecodeDoubleDest(Word Code)
1837
 * \brief  handle instruction with double-sized dest operand (Format 8)
1838
 * \param  Code machine code
1839
 * ------------------------------------------------------------------------ */
1840
 
1841
static void DecodeDoubleDest(Word Code)
1842
{
1843
  tAdrVals SrcAdrVals, DestAdrVals;
1844
 
1845
  if (ChkArgCnt(2, 2)
1846
   && ChkNoAttrPart()
1847
   && SetOpSizeFromCode(Code)
1848
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
1849
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowRegPair))
1850
  {
1851
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
1852
          | (((LongWord)DestAdrVals.Code) << 14)
1853
          | (Lo(Code) << 10)
1854
          | (SizeCodeI(OpSize) << 8)
1855
          | 0xce, 3);
1856
    AppendIndex(&SrcAdrVals);
1857
    AppendIndex(&DestAdrVals);
1858
    AppendDisp(&SrcAdrVals);
1859
    AppendDisp(&DestAdrVals);
1860
  }
1861
}
1862
 
1863
/*!------------------------------------------------------------------------
1864
 * \fn     DecodeCHECK_INDEX(Word Code)
1865
 * \brief  Handle CHECK/CVTP/INDEX Instructions (Format 8)
1866
 * \param  Code machine code & operand size
1867
 * ------------------------------------------------------------------------ */
1868
 
1869
static void DecodeCHECK_INDEX(Word Code)
1870
{
1871
  tAdrVals BoundsAdrVals, SrcAdrVals;
1872
  Word DestReg;
1873
  Boolean IsINDEX = Lo(Code) == 0x42,
1874
          IsCVTP = Lo(Code) == 0x06;
1875
 
1876
 
1877
  if (ChkArgCnt(3, 3)
1878
   && ChkNoAttrPart()
1879
   && SetOpSizeFromCode(Code)
1880
   && DecodeAdr(&ArgStr[2], &BoundsAdrVals, IsINDEX ? (MAllowReg | MAllowImm) : 0)
1881
   && DecodeAdr(&ArgStr[3], &SrcAdrVals, MAllowReg | (IsCVTP ? 0 : MAllowImm))
1882
   && DecodeReg(&ArgStr[1], &DestReg, NULL, eSymbolSize32Bit, True))
1883
  {
1884
    PutCode((((LongWord)BoundsAdrVals.Code) << 19)
1885
        | (((LongWord)SrcAdrVals.Code) << 14)
1886
        | (DestReg << 11)
1887
        | (SizeCodeI(OpSize) << 8)
1888
        | (Lo(Code) << 4)
1889
        | 0x0e, 3);
1890
    AppendIndex(&BoundsAdrVals);
1891
    AppendIndex(&SrcAdrVals);
1892
    AppendDisp(&BoundsAdrVals);
1893
    AppendDisp(&SrcAdrVals);
1894
  }
1895
}
1896
 
1897
/*!------------------------------------------------------------------------
1898
 * \fn     DecodeINS_EXT(Word Code)
1899
 * \brief  Handle INS/EXT Instructions (Format 8)
1900
 * \param  IsINS 1 for INS, 0 for EXT
1901
 * ------------------------------------------------------------------------ */
1902
 
1903
static void DecodeINS_EXT(Word IsINS)
1904
{
1905
  tAdrVals Arg2AdrVals, Arg3AdrVals;
1906
  Word OffsetReg;
1907
 
1908
  if (ChkArgCnt(4, 4)
1909
   && ChkNoAttrPart()
1910
   && SetOpSizeFromCode(IsINS)
1911
   && DecodeReg(&ArgStr[1], &OffsetReg, NULL, eSymbolSize32Bit, True)
1912
   && DecodeAdr(&ArgStr[2], &Arg2AdrVals, MAllowReg | (Lo(IsINS) ? MAllowImm : 0))
1913
   && DecodeAdr(&ArgStr[3], &Arg3AdrVals, MAllowReg))
1914
  {
1915
    tEvalResult EvalResult;
1916
    LongInt Disp = EvalStrIntExpressionWithResult(&ArgStr[4], SInt30, &EvalResult);
1917
 
1918
    if (EvalResult.OK)
1919
    {
1920
      tAdrVals DispAdrVals;
1921
 
1922
      ClearAdrVals(&DispAdrVals);
1923
      if (EncodeDisplacement(Disp, &DispAdrVals, ErrNum_OverRange, &ArgStr[4]))
1924
      {
1925
        PutCode((((LongWord)Arg2AdrVals.Code) << 19)
1926
              | (((LongWord)Arg3AdrVals.Code) << 14)
1927
              | (OffsetReg << 11)
1928
              | (SizeCodeI(OpSize) << 8)
1929
              | (Lo(IsINS) << 7)
1930
              | 0x2e, 3);
1931
        AppendIndex(&Arg2AdrVals);
1932
        AppendIndex(&Arg3AdrVals);
1933
        AppendDisp(&Arg2AdrVals);
1934
        AppendDisp(&Arg3AdrVals);
1935
        AppendDisp(&DispAdrVals);
1936
      }
1937
    }
1938
  }
1939
}
1940
 
1941
/*!------------------------------------------------------------------------
1942
 * \fn     DecodeFFS(Word Code)
1943
 * \brief  Handle FFS Instruction
1944
 * \param  Code machine code & operand size
1945
 * ------------------------------------------------------------------------ */
1946
 
1947
static void DecodeFFS(Word Code)
1948
{
1949
  tAdrVals BaseAdrVals, OffsetAdrVals;
1950
 
1951
  if (ChkArgCnt(2, 2)
1952
   && ChkNoAttrPart()
1953
   && SetOpSizeFromCode(Code)
1954
   && DecodeAdr(&ArgStr[1], &BaseAdrVals, MAllowReg | MAllowImm)
1955
   && DecodeAdr(&ArgStr[2], &OffsetAdrVals, MAllowReg))
1956
  {
1957
    PutCode((((LongWord)BaseAdrVals.Code) << 19)
1958
          | (((LongWord)OffsetAdrVals.Code) << 14)
1959
          | (Lo(Code) << 10)
1960
          | (SizeCodeI(OpSize) << 8)
1961
          | 0x6e, 3);
1962
    AppendIndex(&BaseAdrVals);
1963
    AppendIndex(&OffsetAdrVals);
1964
    AppendDisp(&BaseAdrVals);
1965
    AppendDisp(&OffsetAdrVals);
1966
  }
1967
}
1968
 
1969
/*!------------------------------------------------------------------------
1970
 * \fn     DecodeMOVSU(Word Code)
1971
 * \brief  Handle MOVSU/MOVUS Instruction
1972
 * \param  Code machine code & operand size
1973
 * ------------------------------------------------------------------------ */
1974
 
1975
static void DecodeMOVSU(Word Code)
1976
{
1977
  tAdrVals SrcAdrVals, DestAdrVals;
1978
 
1979
  if (ChkArgCnt(2, 2)
1980
   && ChkNoAttrPart()
1981
   && CheckSup(True, &OpPart)
1982
   && CheckCore((1 << eCoreGen1) | (1 << eCoreGen2))
1983
   && SetOpSizeFromCode(Code)
1984
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, 0)
1985
   && DecodeAdr(&ArgStr[2], &DestAdrVals, 0))
1986
  {
1987
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
1988
          | (((LongWord)DestAdrVals.Code) << 14)
1989
          | ((Code & 0xff) << 10)
1990
          | (SizeCodeI(OpSize) << 8)
1991
          | 0xae, 3);
1992
    AppendIndex(&SrcAdrVals);
1993
    AppendIndex(&DestAdrVals);
1994
    AppendDisp(&SrcAdrVals);
1995
    AppendDisp(&DestAdrVals);
1996
  }
1997
}
1998
 
1999
/*!------------------------------------------------------------------------
2000
 * \fn     DecodeFLOOR_ROUND_TRUNC(Word Code)
2001
 * \brief  Handle FLOOR.../ROUND.../TRUNC... instructions (Format 9)
2002
 * \param  Code machine code & (integer) op size
2003
 * ------------------------------------------------------------------------ */
2004
 
2005
static void DecodeFLOOR_ROUND_TRUNC(Word Code)
2006
{
2007
  tAdrVals SrcAdrVals, DestAdrVals;
2008
 
2009
  if (ChkArgCnt(2, 2)
2010
   && ChkNoAttrPart()
2011
   && CheckFPUAvail(eFPU16081)
2012
   && SetFOpSizeFromCode(Code & 0x1)
2013
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
2014
   && ResetOpSize() && SetOpSizeFromCode(Code)
2015
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
2016
  {
2017
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
2018
          | (((LongWord)DestAdrVals.Code) << 14)
2019
          | (Lo(Code) << 10)
2020
          | (SizeCodeI(OpSize) << 8)
2021
          | 0x3e, 3);
2022
    AppendIndex(&SrcAdrVals);
2023
    AppendIndex(&DestAdrVals);
2024
    AppendDisp(&SrcAdrVals);
2025
    AppendDisp(&DestAdrVals);
2026
  }
2027
}
2028
 
2029
/*!------------------------------------------------------------------------
2030
 * \fn     DecodeMOVif(Word Code)
2031
 * \brief  Handle MOV i->f Instructions (Format 9)
2032
 * \param  Code machine code & (integer) op size
2033
 * ------------------------------------------------------------------------ */
2034
 
2035
static void DecodeMOVif(Word Code)
2036
{
2037
  tAdrVals SrcAdrVals, DestAdrVals;
2038
 
2039
  if (ChkArgCnt(2, 2)
2040
   && ChkNoAttrPart()
2041
   && CheckFPUAvail(eFPU16081)
2042
   && SetOpSizeFromCode(Code)
2043
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
2044
   && ResetOpSize() && SetFOpSizeFromCode(Code & 0x1)
2045
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
2046
  {
2047
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
2048
          | (((LongWord)DestAdrVals.Code) << 14)
2049
          | ((Code & 0xff) << 10)
2050
          | (SizeCodeI(GetOpSizeFromCode(Code)) << 8)
2051
          | 0x3e, 3);
2052
    AppendIndex(&SrcAdrVals);
2053
    AppendIndex(&DestAdrVals);
2054
    AppendDisp(&SrcAdrVals);
2055
    AppendDisp(&DestAdrVals);
2056
  }
2057
}
2058
 
2059
/*!------------------------------------------------------------------------
2060
 * \fn     DecodeFormatLFSR_SFSR(Word Code)
2061
 * \brief  Handle LFSR/SFSR Instructions (Format 9)
2062
 * \param  Code Machine Code & Flags
2063
 * ------------------------------------------------------------------------ */
2064
 
2065
#define FMT9_MAYIMM (1 << 15)
2066
 
2067
static void DecodeLFSR_SFSR(Word Code)
2068
{
2069
  Boolean MayImm = !!(Code & FMT9_MAYIMM);
2070
  tAdrVals AdrVals;
2071
 
2072
  Code &= ~FMT9_MAYIMM;
2073
  if (ChkArgCnt(1, 1)
2074
   && ChkNoAttrPart()
2075
   && CheckFPUAvail(eFPU16081)
2076
   && SetOpSize(eSymbolSize32Bit, &OpPart)
2077
   && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | (MayImm ? MAllowImm : 0)))
2078
  {
2079
    PutCode((((LongWord)AdrVals.Code) << (MayImm ? 19 : 14))
2080
          | (((LongWord)Code) << 8)
2081
          | 0x3e, 3);
2082
    AppendIndex(&AdrVals);
2083
    AppendDisp(&AdrVals);
2084
  }
2085
}
2086
 
2087
/*!------------------------------------------------------------------------
2088
 * \fn     DecodeMOVF(Word Code)
2089
 * \brief  Handle MOVFL/MOVLF Instructions (Format 9)
2090
 * \param  Code Machine Code & Flags
2091
 * ------------------------------------------------------------------------ */
2092
 
2093
static void DecodeMOVF(Word Code)
2094
{
2095
  tAdrVals SrcAdrVals, DestAdrVals;
2096
  Byte OpSize = (Code >> 8) & 1;
2097
 
2098
  if (ChkArgCnt(2, 2)
2099
   && ChkNoAttrPart()
2100
   && CheckFPUAvail(eFPU16081)
2101
   && SetFOpSizeFromCode(OpSize)
2102
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
2103
   && ResetOpSize() && SetFOpSizeFromCode(OpSize ^ 1)
2104
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
2105
  {
2106
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
2107
          | (((LongWord)DestAdrVals.Code) << 14)
2108
          | Code, 3);
2109
    AppendIndex(&SrcAdrVals);
2110
    AppendIndex(&DestAdrVals);
2111
    AppendDisp(&SrcAdrVals);
2112
    AppendDisp(&DestAdrVals);
2113
  }
2114
}
2115
 
2116
/*!------------------------------------------------------------------------
2117
 * \fn     DecodeFormat11(Word Code)
2118
 * \brief  Handle Format 11 Instructions
2119
 * \param  Code Machine Code & Operand Size
2120
 * ------------------------------------------------------------------------ */
2121
 
2122
#define FMT11_DESTMAYIMM 0x80
2123
 
2124
static void DecodeFormat11(Word Code)
2125
{
2126
  tAdrVals SrcAdrVals, DestAdrVals;
2127
  Boolean DestMayImm = !!(Code & FMT11_DESTMAYIMM);
2128
 
2129
  Code &= ~FMT11_DESTMAYIMM;
2130
  if (ChkArgCnt(2, 2)
2131
   && ChkNoAttrPart()
2132
   && CheckFPUAvail(eFPU16081)
2133
   && SetOpSizeFromCode(Code)
2134
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
2135
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
2136
  {
2137
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
2138
          | (((LongWord)DestAdrVals.Code) << 14)
2139
          | ((Code & 0xff) << 10)
2140
          | (SizeCodeF(OpSize) << 8)
2141
          | 0xbe, 3);
2142
    AppendIndex(&SrcAdrVals);
2143
    AppendIndex(&DestAdrVals);
2144
    AppendDisp(&SrcAdrVals);
2145
    AppendDisp(&DestAdrVals);
2146
  }
2147
}
2148
 
2149
/*!------------------------------------------------------------------------
2150
 * \fn     DecodeFormat12(Word Code)
2151
 * \brief  Handle Format 12 Instructions
2152
 * \param  Code Machine Code & Operand Size
2153
 * ------------------------------------------------------------------------ */
2154
 
2155
#define FMT12_DESTMAYIMM 0x40
2156
#define FMT12_580 0x20
2157
 
2158
static void DecodeFormat12(Word Code)
2159
{
2160
  tAdrVals SrcAdrVals, DestAdrVals;
2161
  Boolean DestMayImm = !!(Code & FMT12_DESTMAYIMM),
2162
          Req580 = !!(Code & FMT12_580);
2163
 
2164
  Code &= ~(FMT12_DESTMAYIMM | FMT12_580);
2165
  if (ChkArgCnt(2, 2)
2166
   && ChkNoAttrPart()
2167
   && CheckFPUAvail(Req580 ? eFPU32580 : eFPU32181)
2168
   && SetOpSizeFromCode(Code)
2169
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
2170
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
2171
  {
2172
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
2173
          | (((LongWord)DestAdrVals.Code) << 14)
2174
          | ((Code & 0xff) << 10)
2175
          | (SizeCodeF(OpSize) << 8)
2176
          | 0xfe, 3);
2177
    AppendIndex(&SrcAdrVals);
2178
    AppendIndex(&DestAdrVals);
2179
    AppendDisp(&SrcAdrVals);
2180
    AppendDisp(&DestAdrVals);
2181
  }
2182
}
2183
 
2184
/*!------------------------------------------------------------------------
2185
 * \fn     DecodeLMR_SMR(Word Code)
2186
 * \brief  Decode LMR/SMR Instructions (Format 14)
2187
 * \param  Code Machine Code & Operand Size
2188
 * ------------------------------------------------------------------------ */
2189
 
2190
static void DecodeLMR_SMR(Word Code)
2191
{
2192
  tAdrVals AdrVals;
2193
  Word Reg;
2194
  Boolean IsStore = (Code == 3);
2195
 
2196
  if (ChkArgCnt(2, 2)
2197
   && ChkNoAttrPart()
2198
   && CheckPMMUAvail()
2199
   && SetOpSizeFromCode(Code)
2200
   && DecodeAdr(&ArgStr[2], &AdrVals, MAllowReg | (IsStore ? 0 : MAllowImm))
2201
   && DecodeMMUReg(&ArgStr[1], &Reg))
2202
  {
2203
    if (!IsStore && (Reg >= 14))
2204
      WrStrErrorPos(ErrNum_Unpredictable, &ArgStr[1]);
2205
    PutCode((((LongWord)AdrVals.Code) << 19)
2206
          | ((LongWord)Reg << 15)
2207
          | (Lo(Code) << 10)
2208
          | (SizeCodeI(OpSize) << 8)
2209
          | 0x1e, 3);
2210
    AppendIndex(&AdrVals);
2211
    AppendDisp(&AdrVals);
2212
  }
2213
}
2214
 
2215
/*!------------------------------------------------------------------------
2216
 * \fn     DecodeRDVAL_WRVAL(Word Code)
2217
 * \brief  Handle RDVAL/WRVAL Instructions
2218
 * \param  Code Machine code & operand size
2219
 * ------------------------------------------------------------------------ */
2220
 
2221
static void DecodeRDVAL_WRVAL(Word Code)
2222
{
2223
  tAdrVals AdrVals;
2224
 
2225
  if (ChkArgCnt(1, 1)
2226
   && ChkNoAttrPart()
2227
   && CheckSup(True, &OpPart)
2228
   && SetOpSizeFromCode(Code)
2229
   && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg))
2230
  {
2231
    PutCode((((LongWord)AdrVals.Code) << 19)
2232
        | (Lo(Code) << 10)
2233
        | (SizeCodeI(OpSize) << 8)
2234
        | 0x1e, 3);
2235
    AppendIndex(&AdrVals);
2236
    AppendDisp(&AdrVals);
2237
  }
2238
}
2239
 
2240
/*!------------------------------------------------------------------------
2241
 * \fn     DecodeCCVci(Word Code)
2242
 * \brief  Handle CCVnci Instructions (Format 15.1)
2243
 * \param  Code Machine code & (integer) operand size
2244
 * ------------------------------------------------------------------------ */
2245
 
2246
static void DecodeCCVci(Word Code)
2247
{
2248
  tAdrVals SrcAdrVals, DestAdrVals;
2249
 
2250
  if (ChkArgCnt(2, 2)
2251
   && ChkNoAttrPart()
2252
   && CheckCustomAvail()
2253
   && SetCOpSizeFromCode(Code & 0x01)
2254
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
2255
   && ResetOpSize() && SetOpSizeFromCode(Code)
2256
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
2257
  {
2258
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
2259
          | (((LongWord)DestAdrVals.Code) << 14)
2260
          | (Lo(Code) << 10)
2261
          | (SizeCodeI(OpSize) << 8)
2262
          | 0x36, 3);
2263
    AppendIndex(&SrcAdrVals);
2264
    AppendIndex(&DestAdrVals);
2265
    AppendDisp(&SrcAdrVals);
2266
    AppendDisp(&DestAdrVals);
2267
  }
2268
}
2269
 
2270
/*!------------------------------------------------------------------------
2271
 * \fn     DecodeCCVic(Word Code)
2272
 * \brief  Handle CCVnic Instructions (Format 15.1)
2273
 * \param  Code Machine code & (integer) operand size
2274
 * ------------------------------------------------------------------------ */
2275
 
2276
static void DecodeCCVic(Word Code)
2277
{
2278
  tAdrVals SrcAdrVals, DestAdrVals;
2279
 
2280
  if (ChkArgCnt(2, 2)
2281
   && ChkNoAttrPart()
2282
   && CheckCustomAvail()
2283
   && SetOpSizeFromCode(Code)
2284
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
2285
   && ResetOpSize() && SetCOpSizeFromCode(Code & 0x01)
2286
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
2287
  {
2288
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
2289
          | (((LongWord)DestAdrVals.Code) << 14)
2290
          | (Lo(Code) << 10)
2291
          | (SizeCodeI(GetOpSizeFromCode(Code)) << 8)
2292
          | 0x36, 3);
2293
    AppendIndex(&SrcAdrVals);
2294
    AppendIndex(&DestAdrVals);
2295
    AppendDisp(&SrcAdrVals);
2296
    AppendDisp(&DestAdrVals);
2297
  }
2298
}
2299
 
2300
/*!------------------------------------------------------------------------
2301
 * \fn     DecodeCCVcc(Word Code)
2302
 * \brief  Handle CCVncc Instructions (Format 15.1)
2303
 * \param  Code Machine Code & Flags
2304
 * ------------------------------------------------------------------------ */
2305
 
2306
static void DecodeCCVcc(Word Code)
2307
{
2308
  tAdrVals SrcAdrVals, DestAdrVals;
2309
  Byte OpSize = Code & 1;
2310
 
2311
  if (ChkArgCnt(2, 2)
2312
   && ChkNoAttrPart()
2313
   && CheckCustomAvail()
2314
   && SetCOpSizeFromCode(OpSize)
2315
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
2316
   && ResetOpSize() && SetCOpSizeFromCode(OpSize ^ 1)
2317
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
2318
  {
2319
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
2320
          | (((LongWord)DestAdrVals.Code) << 14)
2321
          | (Code << 10)
2322
          | 0x36, 3);
2323
    AppendIndex(&SrcAdrVals);
2324
    AppendIndex(&DestAdrVals);
2325
    AppendDisp(&SrcAdrVals);
2326
    AppendDisp(&DestAdrVals);
2327
  }
2328
}
2329
 
2330
/*!------------------------------------------------------------------------
2331
 * \fn     DecodeCATST(Word Code)
2332
 * \brief  Decode CATSTx Instructions (Format 15.0)
2333
 * \param  Code Machine Code
2334
 * ------------------------------------------------------------------------ */
2335
 
2336
static void DecodeCATST(Word Code)
2337
{
2338
  tAdrVals AdrVals;
2339
 
2340
  if (ChkArgCnt(1, 1)
2341
   && ChkNoAttrPart()
2342
   && SetOpSize(eSymbolSize32Bit, &OpPart)
2343
   && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | MAllowImm))
2344
  {
2345
    PutCode((((LongWord)AdrVals.Code) << 19)
2346
          | (Code << 10)
2347
          | (SizeCodeI(OpSize) << 8)
2348
          | 0x16, 3);
2349
    AppendIndex(&AdrVals);
2350
    AppendDisp(&AdrVals);
2351
  }
2352
}
2353
 
2354
/*!------------------------------------------------------------------------
2355
 * \fn     DecodeLCR_SCR(Word Code)
2356
 * \brief  Handle LCR/SCR Instructions (Format 15.0)
2357
 * \param  Code Machine Code & Flags
2358
 * ------------------------------------------------------------------------ */
2359
 
2360
#define FMT15_0_MAYIMM (1 << 7)
2361
 
2362
static void DecodeLCR_SCR(Word Code)
2363
{
2364
  Boolean MayImm = !!(Code & FMT15_0_MAYIMM);
2365
  tAdrVals AdrVals;
2366
 
2367
  Code &= ~FMT15_0_MAYIMM;
2368
  if (ChkArgCnt(2, 2)
2369
   && ChkNoAttrPart()
2370
   && CheckCustomAvail()
2371
   && CheckSup(True, &OpPart)
2372
   && SetOpSize(eSymbolSize32Bit, &OpPart)
2373
   && DecodeAdr(&ArgStr[2], &AdrVals, MAllowReg | (MayImm ? MAllowImm : 0)))
2374
  {
2375
    Boolean OK;
2376
    LongWord Reg = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
2377
 
2378
    if (OK)
2379
    {
2380
      PutCode((((LongWord)AdrVals.Code) << 19)
2381
           | (Reg << 15)
2382
           | (Code << 10)
2383
           |  (SizeCodeI(OpSize) << 8)
2384
           | 0x16, 3);
2385
      AppendIndex(&AdrVals);
2386
      AppendDisp(&AdrVals);
2387
    }
2388
  }
2389
}
2390
 
2391
/*!------------------------------------------------------------------------
2392
 * \fn     DecodeFormatLCSR_SCSR(Word Code)
2393
 * \brief  Handle LCSR/SCSR Instructions (Format 15.1)
2394
 * \param  Code Machine Code & Flags
2395
 * ------------------------------------------------------------------------ */
2396
 
2397
#define FMT15_1_MAYIMM (1 << 7)
2398
 
2399
static void DecodeLCSR_SCSR(Word Code)
2400
{
2401
  Boolean MayImm = !!(Code & FMT15_1_MAYIMM);
2402
  tAdrVals AdrVals;
2403
 
2404
  Code &= ~FMT15_1_MAYIMM;
2405
  if (ChkArgCnt(1, 1)
2406
   && ChkNoAttrPart()
2407
   && CheckCustomAvail()
2408
   && SetOpSize(eSymbolSize32Bit, &OpPart)
2409
   && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | (MayImm ? MAllowImm : 0)))
2410
  {
2411
    PutCode((((LongWord)AdrVals.Code) << (MayImm ? 19 : 14))
2412
          | (((LongWord)Code) << 10)
2413
          | (SizeCodeI(OpSize) << 8)
2414
          | 0x36, 3);
2415
    AppendIndex(&AdrVals);
2416
    AppendDisp(&AdrVals);
2417
  }
2418
}
2419
 
2420
/*!------------------------------------------------------------------------
2421
 * \fn     DecodeFormat15_5_7(Word Code)
2422
 * \brief  Handle Format 15.5/15.7 Instructions
2423
 * \param  Code Machine code & operand size
2424
 * ------------------------------------------------------------------------ */
2425
 
2426
#define FMT15_5_DESTMAYIMM 0x80
2427
#define FMT15_7 0x40
2428
 
2429
static void DecodeFormat15_5_7(Word Code)
2430
{
2431
  tAdrVals SrcAdrVals, DestAdrVals;
2432
  unsigned DestMayImm = (Code & FMT15_5_DESTMAYIMM) ? MAllowImm : 0,
2433
           Is7 = !!(Code & FMT15_7);
2434
 
2435
  Code &= ~(FMT15_5_DESTMAYIMM | FMT15_7);
2436
  if (ChkArgCnt(2, 2)
2437
   && ChkNoAttrPart()
2438
   && CheckCustomAvail()
2439
   && (!Is7 || CheckCore((1 << eCoreGen1Ext) | (1 << eCoreGen2)))
2440
   && SetOpSizeFromCode(Code)
2441
   && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
2442
   && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg| DestMayImm))
2443
  {
2444
    PutCode((((LongWord)SrcAdrVals.Code) << 19)
2445
          | (((LongWord)DestAdrVals.Code) << 14)
2446
          | (Lo(Code) << 10)
2447
          | (SizeCodeC(OpSize) << 8)
2448
          | (Is7 << 6)
2449
          | 0xb6, 3);
2450
    AppendIndex(&SrcAdrVals);
2451
    AppendIndex(&DestAdrVals);
2452
    AppendDisp(&SrcAdrVals);
2453
    AppendDisp(&DestAdrVals);
2454
  }
2455
}
2456
 
2457
/*!------------------------------------------------------------------------
2458
 * \fn     void CodeFPU(Word Code)
2459
 * \brief  Handle FPU Instruction
2460
 * ------------------------------------------------------------------------ */
2461
 
2462
static void CodeFPU(Word Code)
2463
{
2464
  UNUSED(Code);
2465
 
2466
  if (ChkArgCnt(1, 1))
2467
  {
2468
    if (!as_strcasecmp(ArgStr[1].str.p_str, "OFF"))
2469
    {
2470
      SetFlag(&FPUAvail, FPUAvailName, False);
2471
      SetMomFPU(eFPUNone);
2472
    }
2473
    else if (!as_strcasecmp(ArgStr[1].str.p_str, "ON"))
2474
    {
2475
      SetFlag(&FPUAvail, FPUAvailName, True);
2476
      if (!MomFPU)
2477
        SetMomFPU((tFPU)pCurrCPUProps->DefFPU);
2478
    }
2479
    else
2480
    {
2481
      tFPU FPU;
2482
 
2483
      for (FPU = (tFPU)1; FPU < eFPUCount; FPU++)
2484
        if (!as_strcasecmp(ArgStr[1].str.p_str, FPUNames[FPU]))
2485
        {
2486
          SetFlag(&FPUAvail, FPUAvailName, True);
2487
          SetMomFPU(FPU);
2488
          break;
2489
        }
2490
      if (FPU >= eFPUCount)
2491
        WrStrErrorPos(ErrNum_InvFPUType, &ArgStr[1]);
2492
    }
2493
  }
2494
}
2495
 
2496
/*!------------------------------------------------------------------------
2497
 * \fn     void CodePMMU(Word Code)
2498
 * \brief  Handle PMMU Instruction
2499
 * ------------------------------------------------------------------------ */
2500
 
2501
static void CodePMMU(Word Code)
2502
{
2503
  UNUSED(Code);
2504
 
2505
  if (ChkArgCnt(1, 1))
2506
  {
2507
    if (!as_strcasecmp(ArgStr[1].str.p_str, "OFF"))
2508
    {
2509
      SetFlag(&PMMUAvail, PMMUAvailName, False);
2510
      SetMomPMMU(ePMMUNone);
2511
    }
2512
    else if (!as_strcasecmp(ArgStr[1].str.p_str, "ON"))
2513
    {
2514
      SetFlag(&PMMUAvail, PMMUAvailName, True);
2515
      if (!MomPMMU)
2516
        SetMomPMMU((tPMMU)pCurrCPUProps->DefPMMU);
2517
    }
2518
    else
2519
    {
2520
      tPMMU PMMU;
2521
 
2522
      for (PMMU = (tPMMU)1; PMMU < ePMMUCount; PMMU++)
2523
        if (!as_strcasecmp(ArgStr[1].str.p_str, PMMUNames[PMMU]))
2524
        {
2525
          SetFlag(&PMMUAvail, PMMUAvailName, True);
2526
          SetMomPMMU(PMMU);
2527
          break;
2528
        }
2529
      if (PMMU >= ePMMUCount)
2530
        WrStrErrorPos(ErrNum_InvPMMUType, &ArgStr[1]);
2531
    }
2532
  }
2533
}
2534
 
2535
/*!------------------------------------------------------------------------
2536
 * \fn     DecodeBB(Word Code)
2537
 * \brief  Handle BitBLT Instructions
2538
 * \param  Code Machine Code & Options
2539
 * ------------------------------------------------------------------------ */
2540
 
2541
#define BB_NOOPT (1 << 15)
2542
 
2543
typedef struct
2544
{
2545
  char Name[3];
2546
  Byte Pos, Value;
2547
} tBitBltOpt;
2548
 
2549
static const tBitBltOpt BitBltOpts[] =
2550
{
2551
  { "DA" , 17, 1 },
2552
  { "-S" , 15, 1 },
2553
  { "IA" , 17, 0 },
2554
  { "S"  , 15, 0 },
2555
  { ""   , 0 , 0 }
2556
};
2557
 
2558
static void DecodeBB(Word Code)
2559
{
2560
  if (ChkArgCnt(0, 2)
2561
   && ChkNoAttrPart()
2562
   && CheckCore(1 << eCoreGenE))
2563
  {
2564
    LongWord OpCode = 0x0e | ((LongWord)(Code & ~BB_NOOPT) << 8), OptMask = 0;
2565
    tStrComp *pArg;
2566
    const tBitBltOpt *pOpt;
2567
 
2568
    forallargs(pArg, True)
2569
    {
2570
      for (pOpt = BitBltOpts + ((Code & BB_NOOPT) ? 2 : 0); pOpt->Name[0]; pOpt++)
2571
        if (!as_strcasecmp(pArg->str.p_str, pOpt->Name))
2572
        {
2573
          LongWord ThisMask = 1ul << pOpt->Pos;
2574
 
2575
          if (OptMask & ThisMask)
2576
          {
2577
            WrStrErrorPos(ErrNum_ConfBitBltOpt, pArg);
2578
            return;
2579
          }
2580
          OptMask |= ThisMask;
2581
          OpCode = pOpt->Value ? (OpCode | ThisMask) : (OpCode & ~ThisMask);
2582
          break;
2583
        }
2584
      if (!pOpt->Name[0])
2585
      {
2586
        WrStrErrorPos(ErrNum_UnknownBitBltOpt, pArg);
2587
        return;
2588
      }
2589
    }
2590
    PutCode(OpCode, 3);
2591
  }
2592
}
2593
 
2594
/*!------------------------------------------------------------------------
2595
 * \fn     DecodeBITxT(Word Code)
2596
 * \brief  Handle BITBLT instructions without argument
2597
 * \param  Code Machine Code
2598
 * ------------------------------------------------------------------------ */
2599
 
2600
static void DecodeBITxT(Word Code)
2601
{
2602
  if (ChkArgCnt(0, 0)
2603
   && ChkNoAttrPart()
2604
   && CheckCore(1 << eCoreGenE))
2605
    PutCode(((LongWord)Code) << 8 | 0x0e, 3);
2606
}
2607
 
2608
/*!------------------------------------------------------------------------
2609
 * \fn     DecodeTBITS(Word Code)
2610
 * \brief  Handle TBITS Instruction
2611
 * \param  Code Machine Code
2612
 * ------------------------------------------------------------------------ */
2613
 
2614
static void DecodeTBITS(Word Code)
2615
{
2616
  if (ChkArgCnt(1, 1)
2617
   && ChkNoAttrPart()
2618
   && CheckCore(1 << eCoreGenE))
2619
  {
2620
    Boolean OK;
2621
    LongWord Arg = EvalStrIntExpression(&ArgStr[1], UInt1, &OK);
2622
 
2623
    if (OK)
2624
      PutCode((Arg << 15)
2625
            | (((LongWord)Code) << 8)
2626
            | 0x0e, 3);
2627
  }
2628
}
2629
 
2630
/*--------------------------------------------------------------------------*/
2631
/* Instruction Lookup Table */
2632
 
2633
/*!------------------------------------------------------------------------
2634
 * \fn     InitFields(void)
2635
 * \brief  create lookup table
2636
 * ------------------------------------------------------------------------ */
2637
 
2638
static void AddSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
2639
{
2640
  char Name[20];
2641
  tSymbolSize Size;
2642
 
2643
  for (Size = eSymbolSize8Bit; Size <= eSymbolSize32Bit; Size++)
2644
    if (SizeMask & (1 << Size))
2645
    {
2646
      as_snprintf(Name, sizeof(Name), "%s%c", pName, "BWD"[Size - eSymbolSize8Bit]);
2647
      AddInstTable(InstTable, Name, Code | (Size << 8), Proc);
2648
    }
2649
}
2650
 
2651
static void AddFSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
2652
{
2653
  char Name[20];
2654
  tSymbolSize Size;
2655
 
2656
  for (Size = eSymbolSizeFloat32Bit; Size <= eSymbolSizeFloat64Bit; Size++)
2657
    if (SizeMask & (1 << Size))
2658
    {
2659
      as_snprintf(Name, sizeof(Name), "%s%c", pName, "FL"[Size - eSymbolSizeFloat32Bit]);
2660
      AddInstTable(InstTable, Name, Code | (Size << 8), Proc);
2661
    }
2662
}
2663
 
2664
static void AddCSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
2665
{
2666
  char Name[20];
2667
  tSymbolSize Size;
2668
 
2669
  for (Size = eSymbolSize32Bit; Size <= eSymbolSize64Bit; Size++)
2670
    if (SizeMask & (1 << Size))
2671
    {
2672
      as_snprintf(Name, sizeof(Name), "%s%c", pName, "DQ"[Size - eSymbolSize32Bit]);
2673
      AddInstTable(InstTable, Name, Code | (Size << 8), Proc);
2674
    }
2675
}
2676
 
2677
static void AddCondition(const char *pCondition, Word Code)
2678
{
2679
  char Str[20];
2680
 
2681
  as_snprintf(Str, sizeof(Str), "B%s", pCondition);
2682
  AddInstTable(InstTable, Str, (Code << 4) | 0x0a, DecodeFormat0);
2683
  as_snprintf(Str, sizeof(Str), "S%s", pCondition);
2684
  AddSizeInstTable(Str, (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), Code, DecodeScond);
2685
}
2686
 
2687
static void AddCtl(const char *pName, Word Code, Boolean Privileged)
2688
{
2689
  order_array_rsv_end(CtlRegs, tCtlReg);
2690
  CtlRegs[InstrZ  ].pName      = pName;
2691
  CtlRegs[InstrZ  ].Code       = Code;
2692
  CtlRegs[InstrZ++].Privileged = Privileged;
2693
}
2694
 
2695
static void AddMMU(const char *pName, Word Code, Word Mask, Boolean Privileged)
2696
{
2697
  order_array_rsv_end(MMURegs, tCtlReg);
2698
  MMURegs[InstrZ  ].pName      = pName;
2699
  MMURegs[InstrZ  ].Code       = Code;
2700
  MMURegs[InstrZ  ].Mask       = Mask;
2701
  MMURegs[InstrZ++].Privileged = Privileged;
2702
}
2703
 
2704
static void InitFields(void)
2705
{
2706
  InstTable = CreateInstTable(605);
2707
  SetDynamicInstTable(InstTable);
2708
 
2709
  add_null_pseudo(InstTable);
2710
 
2711
  InstrZ = 0;
2712
  AddCtl("UPSR"   , 0x00, True );
2713
  AddCtl("DCR"    , 0x01, True );
2714
  AddCtl("BPC"    , 0x02, True );
2715
  AddCtl("DSR"    , 0x03, True );
2716
  AddCtl("CAR"    , 0x04, True );
2717
  AddCtl("FP"     , 0x08, False);
2718
  AddCtl("SP"     , 0x09, False);
2719
  AddCtl("SB"     , 0x0a, False);
2720
  AddCtl("USP"    , 0x0b, True );
2721
  AddCtl("CFG"    , 0x0c, True );
2722
  AddCtl("PSR"    , 0x0d, False);
2723
  AddCtl("INTBASE", 0x0e, True );
2724
  AddCtl("MOD"    , 0x0f, False);
2725
  AddCtl(NULL     , 0   , False);
2726
 
2727
  InstrZ = 0;
2728
  AddMMU("BPR0"   , 0x00, (1 << ePMMU16082) | (1 << ePMMU32082)                                        , True );
2729
  AddMMU("BPR1"   , 0x01, (1 << ePMMU16082) | (1 << ePMMU32082)                                        , True );
2730
  AddMMU("MSR"    , 0x0a, (1 << ePMMU16082) | (1 << ePMMU32082)                     | (1 << ePMMU32532), True );
2731
  AddMMU("BCNT"   , 0x0b, (1 << ePMMU16082) | (1 << ePMMU32082)                                        , True );
2732
  AddMMU("PTB0"   , 0x0c, (1 << ePMMU16082) | (1 << ePMMU32082) | (1 << ePMMU32382) | (1 << ePMMU32532), True );
2733
  AddMMU("PTB1"   , 0x0d, (1 << ePMMU16082) | (1 << ePMMU32082) | (1 << ePMMU32382) | (1 << ePMMU32532), True );
2734
  AddMMU("EIA"    , 0x0f, (1 << ePMMU16082) | (1 << ePMMU32082)                                        , True );
2735
  AddMMU("BAR"    , 0x00,                                         (1 << ePMMU32382)                    , True );
2736
  AddMMU("BMR"    , 0x02,                                         (1 << ePMMU32382)                    , True );
2737
  AddMMU("BDR"    , 0x03,                                         (1 << ePMMU32382)                    , True );
2738
  AddMMU("BEAR"   , 0x06,                                         (1 << ePMMU32382)                    , True );
2739
  AddMMU("FEW"    , 0x09,                                         (1 << ePMMU32382)                    , True );
2740
  AddMMU("ASR"    , 0x0a,                                         (1 << ePMMU32382)                    , True );
2741
  AddMMU("TEAR"   , 0x0b,                                         (1 << ePMMU32382) | (1 << ePMMU32532), True );
2742
  /* TODO: 8 according to National docu, but 9 according to sample code */
2743
  AddMMU("MCR"    , 0x09,                                                             (1 << ePMMU32532), True );
2744
  AddMMU("IVAR0"  , 0x0e,                                         (1 << ePMMU32382) | (1 << ePMMU32532), True );/* w/o */
2745
  AddMMU("IVAR1"  , 0x0f,                                         (1 << ePMMU32382) | (1 << ePMMU32532), True );/* w/o */
2746
  AddMMU(NULL     , 0, 0, False);
2747
 
2748
  AddCondition("EQ",  0);
2749
  AddCondition("NE",  1);
2750
  AddCondition("CS",  2);
2751
  AddCondition("CC",  3);
2752
  AddCondition("HI",  4);
2753
  AddCondition("LS",  5);
2754
  AddCondition("GT",  6);
2755
  AddCondition("LE",  7);
2756
  AddCondition("FS",  8);
2757
  AddCondition("FC",  9);
2758
  AddCondition("LO", 10);
2759
  AddCondition("HS", 11);
2760
  AddCondition("LT", 12);
2761
  AddCondition("GE", 13);
2762
 
2763
  /* Format 0 */
2764
 
2765
  AddInstTable(InstTable, "BR" , 0xea, DecodeFormat0);
2766
  AddInstTable(InstTable, "BSR", 0x02, DecodeFormat0);
2767
 
2768
  /* Format 1 */
2769
 
2770
  AddInstTable(InstTable, "BPT" , 0xf2, DecodeFixed);
2771
  AddInstTable(InstTable, "DIA" , 0xc2, DecodeFixed);
2772
  AddInstTable(InstTable, "FLAG", 0xd2, DecodeFixed);
2773
  AddInstTable(InstTable, "NOP" , NOPCode, DecodeFixed);
2774
  AddInstTable(InstTable, "RETI", 0x52, DecodeFixed);
2775
  AddInstTable(InstTable, "SVC" , 0xe2, DecodeFixed);
2776
  AddInstTable(InstTable, "WAIT", 0xb2, DecodeFixed);
2777
  AddInstTable(InstTable, "RET" , 0x12, DecodeRET);
2778
  AddInstTable(InstTable, "RETT", 0x42, DecodeRET);
2779
  AddInstTable(InstTable, "RXP" , 0x32, DecodeRET);
2780
  AddInstTable(InstTable, "SAVE", 0x62, DecodeSAVE_RESTORE);
2781
  AddInstTable(InstTable, "RESTORE", 0x72, DecodeSAVE_RESTORE);
2782
 
2783
  AddInstTable(InstTable, "CINV", 0x271e, DecodeCINV);
2784
  AddInstTable(InstTable, "CXP" , 0x22, DecodeCXP);
2785
  AddInstTable(InstTable, "ENTER", 0x82, DecodeENTER);
2786
  AddInstTable(InstTable, "EXIT", 0x92, DecodeEXIT);
2787
 
2788
  /* Format 2 */
2789
 
2790
  AddSizeInstTable("ADDQ" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0, DecodeMOVQ);
2791
  AddSizeInstTable("LPR"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 6, DecodeLPR_SPR);
2792
  AddSizeInstTable("SPR"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 2, DecodeLPR_SPR);
2793
  AddSizeInstTable("MOVQ" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 5, DecodeMOVQ);
2794
  AddSizeInstTable("ACB"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 4, DecodeACB);
2795
  AddSizeInstTable("CMPQ" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 1 | MOVQ_DESTMAYIMM, DecodeMOVQ);
2796
 
2797
  /* Format 3 */
2798
 
2799
  AddInstTable(InstTable, "JUMP"  , 0x04 | (eSymbolSize32Bit << 8), DecodeFormat3);
2800
  AddInstTable(InstTable, "JSR"   , 0x0c | (eSymbolSize32Bit << 8), DecodeFormat3);
2801
  AddSizeInstTable("ADJSP" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeFormat3);
2802
  AddSizeInstTable("BICPSR", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit), 0x02, DecodeFormat3);
2803
  AddSizeInstTable("BISPSR", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit), 0x06, DecodeFormat3);
2804
  AddSizeInstTable("CASE"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat3);
2805
  AddInstTable(InstTable, "CXPD"  , 0x00 | (eSymbolSize32Bit << 8), DecodeFormat3);
2806
 
2807
  /* Format 4 */
2808
 
2809
  AddSizeInstTable("MOV" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x05, DecodeFormat4);
2810
  AddSizeInstTable("ADD" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x00, DecodeFormat4);
2811
  AddSizeInstTable("ADDC", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x04, DecodeFormat4);
2812
  AddInstTable(InstTable, "ADDR", (eSymbolSize32Bit << 8) | FMT4_SRCISADDR | 0x09, DecodeFormat4);
2813
  AddSizeInstTable("AND" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeFormat4);
2814
  AddSizeInstTable("BIC" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x02, DecodeFormat4);
2815
  AddSizeInstTable("CMP" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT4_DESTMAYIMM | 0x01, DecodeFormat4);
2816
  AddSizeInstTable("OR"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x06, DecodeFormat4);
2817
  AddSizeInstTable("SUB" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFormat4);
2818
  AddSizeInstTable("SUBC", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeFormat4);
2819
  AddSizeInstTable("TBIT", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0d, DecodeFormat4);
2820
  AddSizeInstTable("XOR" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat4);
2821
 
2822
  /* Format 5 */
2823
 
2824
  AddSizeInstTable("MOVS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x00, DecodeMOVS_CMPS_SKPS);
2825
  AddSizeInstTable("CMPS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeMOVS_CMPS_SKPS);
2826
  AddSizeInstTable("SKPS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeMOVS_CMPS_SKPS);
2827
  AddInstTable(InstTable, "MOVST", (eSymbolSize8Bit << 8) | 0x20, DecodeMOVS_CMPS_SKPS);
2828
  AddInstTable(InstTable, "CMPST", (eSymbolSize8Bit << 8) | 0x21, DecodeMOVS_CMPS_SKPS);
2829
  AddInstTable(InstTable, "SKPST", (eSymbolSize8Bit << 8) | 0x23, DecodeMOVS_CMPS_SKPS);
2830
  AddInstTable(InstTable, "SETCFG", 0xb0e, DecodeSETCFG);
2831
 
2832
  /* Format 6 */
2833
 
2834
  AddSizeInstTable("ABS"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeFormat6);
2835
  AddSizeInstTable("ADDP"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeFormat6);
2836
  AddSizeInstTable("ASH"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT6_SRC8BIT | 0x01, DecodeFormat6);
2837
  AddSizeInstTable("CBIT"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x02, DecodeFormat6);
2838
  AddSizeInstTable("CBITI" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeFormat6);
2839
  AddSizeInstTable("COM"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0d, DecodeFormat6);
2840
  AddSizeInstTable("IBIT"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat6);
2841
  AddSizeInstTable("LSH"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT6_SRC8BIT | 0x05, DecodeFormat6);
2842
  AddSizeInstTable("NEG"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFormat6);
2843
  AddSizeInstTable("NOT"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeFormat6);
2844
  AddSizeInstTable("ROT"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT6_SRC8BIT | 0x00, DecodeFormat6);
2845
  AddSizeInstTable("SBIT"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x06, DecodeFormat6);
2846
  AddSizeInstTable("SBITI" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x07, DecodeFormat6);
2847
  AddSizeInstTable("SUBP"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeFormat6);
2848
 
2849
  /* Format 7 */
2850
 
2851
  AddSizeInstTable("DIV"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeFormat7);
2852
  AddSizeInstTable("MOD"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat7);
2853
  AddSizeInstTable("MUL"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFormat7);
2854
  AddSizeInstTable("QUO"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeFormat7);
2855
  AddSizeInstTable("REM"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0d, DecodeFormat7);
2856
 
2857
  AddInstTable(InstTable, "MOVXBW", (eSymbolSize8Bit  << 8) | (eSymbolSize16Bit << 12) | 1, DecodeMOVExt);
2858
  AddInstTable(InstTable, "MOVXBD", (eSymbolSize8Bit  << 8) | (eSymbolSize32Bit << 12) | 1, DecodeMOVExt);
2859
  AddInstTable(InstTable, "MOVXWD", (eSymbolSize16Bit << 8) | (eSymbolSize32Bit << 12) | 1, DecodeMOVExt);
2860
  AddInstTable(InstTable, "MOVZBW", (eSymbolSize8Bit  << 8) | (eSymbolSize16Bit << 12) | 0, DecodeMOVExt);
2861
  AddInstTable(InstTable, "MOVZBD", (eSymbolSize8Bit  << 8) | (eSymbolSize32Bit << 12) | 0, DecodeMOVExt);
2862
  AddInstTable(InstTable, "MOVZWD", (eSymbolSize16Bit << 8) | (eSymbolSize32Bit << 12) | 0, DecodeMOVExt);
2863
 
2864
  AddSizeInstTable("MOVM", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x00, DecodeMOVM_CMPM);
2865
  AddSizeInstTable("CMPM", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeMOVM_CMPM);
2866
 
2867
  AddSizeInstTable("DEI", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeDoubleDest);
2868
  AddSizeInstTable("MEI", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeDoubleDest);
2869
 
2870
  AddSizeInstTable("EXTS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeINSS_EXTS);
2871
  AddSizeInstTable("INSS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x02, DecodeINSS_EXTS);
2872
 
2873
  /* Format 8 */
2874
 
2875
  AddSizeInstTable("CHECK", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeCHECK_INDEX);
2876
  AddInstTable(InstTable, "CVTP", (eSymbolSize32Bit << 8) | 0x06, DecodeCHECK_INDEX);
2877
  AddSizeInstTable("INDEX", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x42, DecodeCHECK_INDEX);
2878
 
2879
  AddSizeInstTable("EXT", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0, DecodeINS_EXT);
2880
  AddSizeInstTable("INS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 1, DecodeINS_EXT);
2881
 
2882
  AddSizeInstTable("FFS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeFFS);
2883
 
2884
  AddSizeInstTable("MOVSU", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x3, DecodeMOVSU);
2885
  AddSizeInstTable("MOVUS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x7, DecodeMOVSU);
2886
 
2887
  /* Format 9 */
2888
 
2889
  AddSizeInstTable("FLOORF", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeFLOOR_ROUND_TRUNC);
2890
  AddSizeInstTable("FLOORL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFLOOR_ROUND_TRUNC);
2891
  AddSizeInstTable("ROUNDF", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeFLOOR_ROUND_TRUNC);
2892
  AddSizeInstTable("ROUNDL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFLOOR_ROUND_TRUNC);
2893
  AddSizeInstTable("TRUNCF", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeFLOOR_ROUND_TRUNC);
2894
  AddSizeInstTable("TRUNCL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeFLOOR_ROUND_TRUNC);
2895
  AddInstTable(InstTable, "MOVBF", 0x01 | (eSymbolSize8Bit << 8), DecodeMOVif);
2896
  AddInstTable(InstTable, "MOVWF", 0x01 | (eSymbolSize16Bit << 8), DecodeMOVif);
2897
  AddInstTable(InstTable, "MOVDF", 0x01 | (eSymbolSize32Bit << 8), DecodeMOVif);
2898
  AddInstTable(InstTable, "MOVBL", 0x00 | (eSymbolSize8Bit << 8), DecodeMOVif);
2899
  AddInstTable(InstTable, "MOVWL", 0x00 | (eSymbolSize16Bit << 8), DecodeMOVif);
2900
  AddInstTable(InstTable, "MOVDL", 0x00 | (eSymbolSize32Bit << 8), DecodeMOVif);
2901
 
2902
  AddInstTable(InstTable, "LFSR", 0x0f | FMT9_MAYIMM, DecodeLFSR_SFSR);
2903
  AddInstTable(InstTable, "SFSR", 0x37, DecodeLFSR_SFSR);
2904
 
2905
  AddInstTable(InstTable, "MOVFL"  , 0x1b3e, DecodeMOVF);
2906
  AddInstTable(InstTable, "MOVLF"  , 0x163e, DecodeMOVF);
2907
 
2908
  /* Format 11 */
2909
 
2910
  AddFSizeInstTable("ABS", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x0d, DecodeFormat11);
2911
  AddFSizeInstTable("ADD", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x00, DecodeFormat11);
2912
  AddFSizeInstTable("CMP", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x02 | FMT11_DESTMAYIMM, DecodeFormat11);
2913
  AddFSizeInstTable("DIV", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x08, DecodeFormat11);
2914
  AddFSizeInstTable("MOV", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x01, DecodeFormat11);
2915
  AddFSizeInstTable("MUL", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x0c, DecodeFormat11);
2916
  AddFSizeInstTable("NEG", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x05, DecodeFormat11);
2917
  AddFSizeInstTable("SUB", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x04, DecodeFormat11);
2918
 
2919
  /* Format 12 - only newer FPUs? */
2920
 
2921
  AddFSizeInstTable("DOT"  , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x03 | FMT12_DESTMAYIMM, DecodeFormat12);
2922
  AddFSizeInstTable("LOGB" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x05, DecodeFormat12);
2923
  AddFSizeInstTable("POLY" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x02 | FMT12_DESTMAYIMM, DecodeFormat12);
2924
  AddFSizeInstTable("SCALB", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x04, DecodeFormat12);
2925
  AddFSizeInstTable("REM"  , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x00, DecodeFormat12);
2926
  AddFSizeInstTable("SQRT" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), FMT12_580 | 0x01, DecodeFormat12);
2927
  AddFSizeInstTable("ATAN2", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), FMT12_580 | 0x0c, DecodeFormat12);
2928
  AddFSizeInstTable("SICOS", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), FMT12_580 | 0x0d, DecodeFormat12);
2929
 
2930
  /* Format 14 */
2931
 
2932
  AddInstTable(InstTable, "LMR"  , 0x02 | (eSymbolSize32Bit << 8), DecodeLMR_SMR);
2933
  AddInstTable(InstTable, "SMR"  , 0x03 | (eSymbolSize32Bit << 8), DecodeLMR_SMR);
2934
  AddInstTable(InstTable, "RDVAL", 0x00 | (eSymbolSize32Bit << 8), DecodeRDVAL_WRVAL);
2935
  AddInstTable(InstTable, "WRVAL", 0x01 | (eSymbolSize32Bit << 8), DecodeRDVAL_WRVAL);
2936
 
2937
  AddInstTable(InstTable, "REG" , 0, CodeREG);
2938
  AddInstTable(InstTable, "BYTE"   , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString , DecodeIntelDB);
2939
  AddInstTable(InstTable, "WORD"   , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString , DecodeIntelDW);
2940
  AddInstTable(InstTable, "DOUBLE" , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString , DecodeIntelDD);
2941
  AddInstTable(InstTable, "FLOAT"  , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat , DecodeIntelDD);
2942
  AddInstTable(InstTable, "LONG"   , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat , DecodeIntelDQ);
2943
  AddInstTable(InstTable, "FPU"    , 0, CodeFPU);
2944
  AddInstTable(InstTable, "PMMU"   , 0, CodePMMU);
2945
 
2946
  /* Format 15.0 */
2947
 
2948
  AddInstTable(InstTable, "LCR", 0x0a | FMT15_0_MAYIMM, DecodeLCR_SCR);
2949
  AddInstTable(InstTable, "SCR", 0x0b                 , DecodeLCR_SCR);
2950
  AddInstTable(InstTable, "CATST0", 0x00, DecodeCATST);
2951
  AddInstTable(InstTable, "CATST1", 0x01, DecodeCATST);
2952
 
2953
  /* Format 15.1 */
2954
 
2955
  AddSizeInstTable("CCV0Q", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeCCVci);
2956
  AddSizeInstTable("CCV0D", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeCCVci);
2957
  AddSizeInstTable("CCV1Q", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeCCVci);
2958
  AddSizeInstTable("CCV1D", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeCCVci);
2959
  AddSizeInstTable("CCV2Q", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeCCVci);
2960
  AddSizeInstTable("CCV2D", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeCCVci);
2961
  AddInstTable(InstTable, "CCV3BQ", (eSymbolSize8Bit  << 8) | 0x00, DecodeCCVic);
2962
  AddInstTable(InstTable, "CCV3WQ", (eSymbolSize16Bit << 8) | 0x00, DecodeCCVic);
2963
  AddInstTable(InstTable, "CCV3DQ", (eSymbolSize32Bit << 8) | 0x00, DecodeCCVic);
2964
  AddInstTable(InstTable, "CCV3BD", (eSymbolSize8Bit  << 8) | 0x01, DecodeCCVic);
2965
  AddInstTable(InstTable, "CCV3WD", (eSymbolSize16Bit << 8) | 0x01, DecodeCCVic);
2966
  AddInstTable(InstTable, "CCV3DD", (eSymbolSize32Bit << 8) | 0x01, DecodeCCVic);
2967
  AddInstTable(InstTable, "CCV4DQ", 0x07, DecodeCCVcc);
2968
  AddInstTable(InstTable, "CCV5QD", 0x04, DecodeCCVcc);
2969
  AddInstTable(InstTable, "LCSR", 0x01 | FMT15_1_MAYIMM, DecodeLCSR_SCSR);
2970
  AddInstTable(InstTable, "SCSR", 0x06, DecodeLCSR_SCSR);
2971
 
2972
  /* Format 15.5/15.7 */
2973
 
2974
  AddCSizeInstTable("CCAL0", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x00, DecodeFormat15_5_7);
2975
  AddCSizeInstTable("CMOV0", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x01, DecodeFormat15_5_7);
2976
  AddCSizeInstTable("CCMP" , (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_5_DESTMAYIMM | 0x02, DecodeFormat15_5_7);
2977
  AddCSizeInstTable("CCMP1", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_5_DESTMAYIMM | 0x03, DecodeFormat15_5_7);
2978
  AddCSizeInstTable("CCAL1", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x04, DecodeFormat15_5_7);
2979
  AddCSizeInstTable("CMOV2", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x05, DecodeFormat15_5_7);
2980
  AddCSizeInstTable("CCAL3", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x08, DecodeFormat15_5_7);
2981
  AddCSizeInstTable("CMOV3", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x09, DecodeFormat15_5_7);
2982
  AddCSizeInstTable("CCAL2", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x0c, DecodeFormat15_5_7);
2983
  AddCSizeInstTable("CMOV1", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x0d, DecodeFormat15_5_7);
2984
  AddCSizeInstTable("CCAL4", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x00, DecodeFormat15_5_7);
2985
  AddCSizeInstTable("CMOV4", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x01, DecodeFormat15_5_7);
2986
  AddCSizeInstTable("CCAL8", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x02, DecodeFormat15_5_7);
2987
  AddCSizeInstTable("CCAL9", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x03, DecodeFormat15_5_7);
2988
  AddCSizeInstTable("CCAL5", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x04, DecodeFormat15_5_7);
2989
  AddCSizeInstTable("CMOV6", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x05, DecodeFormat15_5_7);
2990
  AddCSizeInstTable("CCAL7", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x08, DecodeFormat15_5_7);
2991
  AddCSizeInstTable("CMOV7", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x09, DecodeFormat15_5_7);
2992
  AddCSizeInstTable("CCAL6", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x0c, DecodeFormat15_5_7);
2993
  AddCSizeInstTable("CMOV5", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x0d, DecodeFormat15_5_7);
2994
 
2995
  /* BITBLT */
2996
 
2997
  AddInstTable(InstTable, "BBAND"  , 0x12b, DecodeBB);
2998
  AddInstTable(InstTable, "BBOR"   , 0x019, DecodeBB);
2999
  AddInstTable(InstTable, "BBXOR"  , 0x039, DecodeBB);
3000
  AddInstTable(InstTable, "BBFOR"  , BB_NOOPT | 0x031, DecodeBB);
3001
  AddInstTable(InstTable, "BBSTOD" , 0x011, DecodeBB);
3002
 
3003
  AddInstTable(InstTable, "BITWT"  , 0x21, DecodeBITxT);
3004
  AddInstTable(InstTable, "EXTBLT" , 0x17, DecodeBITxT);
3005
  AddInstTable(InstTable, "MOVMPB" , 0x1c, DecodeBITxT);
3006
  AddInstTable(InstTable, "MOVMPW" , 0x1d, DecodeBITxT);
3007
  AddInstTable(InstTable, "MOVMPD" , 0x1f, DecodeBITxT);
3008
  AddInstTable(InstTable, "SBITS"  , 0x37, DecodeBITxT);
3009
  AddInstTable(InstTable, "SBITPS" , 0x2f, DecodeBITxT);
3010
 
3011
  AddInstTable(InstTable, "TBITS"  , 0x27, DecodeTBITS);
3012
 
3013
  AddIntelPseudo(InstTable, eIntPseudoFlag_DynEndian);
3014
}
3015
 
3016
/*!------------------------------------------------------------------------
3017
 * \fn     DeinitFields(void)
3018
 * \brief  destroy/cleanup lookup table
3019
 * ------------------------------------------------------------------------ */
3020
 
3021
static void DeinitFields(void)
3022
{
3023
  DestroyInstTable(InstTable);
3024
  order_array_free(CtlRegs);
3025
  order_array_free(MMURegs);
3026
}
3027
 
3028
/*--------------------------------------------------------------------------*/
3029
/* Interface Functions */
3030
 
3031
/*!------------------------------------------------------------------------
3032
 * \fn     MakeCode_NS32K(void)
3033
 * \brief  encode machine instruction
3034
 * ------------------------------------------------------------------------ */
3035
 
3036
static void MakeCode_NS32K(void)
3037
{
3038
  OpSize = eSymbolSizeUnknown;
3039
 
3040
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
3041
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
3042
}
3043
 
3044
/*!------------------------------------------------------------------------
3045
 * \fn     InternSymbol_NS32K(char *pArg, TempResult *pResult)
3046
 * \brief  handle built-in symbols on NS32000
3047
 * \param  pArg source argument
3048
 * \param  pResult result buffer
3049
 * ------------------------------------------------------------------------ */
3050
 
3051
static void InternSymbol_NS32K(char *pArg, TempResult *pResult)
3052
{
3053
  Word Reg;
3054
  tSymbolSize Size;
3055
 
3056
  if (DecodeRegCore(pArg, &Reg, &Size))
3057
  {
3058
    pResult->Typ = TempReg;
3059
    pResult->DataSize = Size;
3060
    pResult->Contents.RegDescr.Reg = Reg;
3061
    pResult->Contents.RegDescr.Dissect = DissectReg_NS32K;
3062
    pResult->Contents.RegDescr.compare = NULL;
3063
  }
3064
}
3065
 
3066
/*!------------------------------------------------------------------------
3067
 * \fn     InitCode_NS32K(void)
3068
 * \brief  target-specific initializations before starting a pass
3069
 * ------------------------------------------------------------------------ */
3070
 
3071
static void InitCode_NS32K(void)
3072
{
3073
  SetMomFPU(eFPUNone);
3074
  SetMomPMMU(ePMMUNone);
3075
}
3076
 
3077
/*!------------------------------------------------------------------------
3078
 * \fn     IsDef_NS32K(void)
3079
 * \brief  check whether insn makes own use of label
3080
 * \return True if yes
3081
 * ------------------------------------------------------------------------ */
3082
 
3083
static Boolean IsDef_NS32K(void)
3084
{
3085
  return Memo("REG");
3086
}
3087
 
3088
/*!------------------------------------------------------------------------
3089
 * \fn     SwitchTo_NS32K(void *pUser)
3090
 * \brief  prepare to assemble code for this target
3091
 * \param  pUser CPU properties
3092
 * ------------------------------------------------------------------------ */
3093
 
3094
static Boolean ChkMoreZeroArg(void)
3095
{
3096
  return (ArgCnt > 0);
3097
}
3098
 
3099
static void SwitchTo_NS32K(void *pUser)
3100
{
3101
  const TFamilyDescr *pDescr = FindFamilyByName("NS32000");
3102
 
3103
  TurnWords = True;
3104
  SetIntConstMode(eIntConstModeIntel);
3105
  SaveIsOccupiedFnc = ChkMoreZeroArg;
3106
  RestoreIsOccupiedFnc = ChkMoreZeroArg;
3107
 
3108
  pCurrCPUProps = (const tCPUProps*)pUser;
3109
 
3110
  /* default selection of "typical" companion FPU/PMMU: */
3111
 
3112
  SetMomFPU((tFPU)pCurrCPUProps->DefFPU);
3113
  SetMomPMMU((tPMMU)pCurrCPUProps->DefPMMU);
3114
 
3115
  PCSymbol = "*"; HeaderID = pDescr->Id;
3116
  NOPCode = 0xa2;
3117
  DivideChars = ",";
3118
  HasAttrs = True; AttrChars = ".";
3119
 
3120
  ValidSegs = (1 << SegCode);
3121
  Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
3122
  SegLimits[SegCode] = IntTypeDefs[pCurrCPUProps->MemIntType].Max;
3123
 
3124
  MakeCode = MakeCode_NS32K;
3125
  IsDef = IsDef_NS32K;
3126
  DissectReg = DissectReg_NS32K;
3127
  InternSymbol = InternSymbol_NS32K;
3128
  SwitchFrom = DeinitFields;
3129
  IntConstModeIBMNoTerm = True;
3130
  QualifyQuote = QualifyQuote_SingleQuoteConstant;
3131
  InitFields();
3132
  onoff_supmode_add();
3133
  onoff_bigendian_add();
3134
  if (!onoff_test_and_set(e_onoff_reg_custom))
3135
    SetFlag(&CustomAvail, CustomAvailSymName, False);
3136
  AddONOFF(CustomAvailCmdName, &CustomAvail, CustomAvailSymName, False);
3137
}
3138
 
3139
/*!------------------------------------------------------------------------
3140
 * \fn     codens32000_init(void)
3141
 * \brief  register target to AS
3142
 * ------------------------------------------------------------------------ */
3143
 
3144
static const tCPUProps CPUProps[] =
3145
{
3146
  { "NS16008", eCoreGen1   , eFPU16081, ePMMU16082, UInt24 },
3147
  { "NS32008", eCoreGen1   , eFPU32081, ePMMU32082, UInt24 },
3148
  { "NS08032", eCoreGen1   , eFPU32081, ePMMU32082, UInt24 },
3149
  { "NS16032", eCoreGen1   , eFPU16081, ePMMU16082, UInt24 },
3150
  { "NS32016", eCoreGen1   , eFPU32081, ePMMU32082, UInt24 },
3151
  { "NS32032", eCoreGen1   , eFPU32081, ePMMU32082, UInt24 },
3152
  { "NS32332", eCoreGen1Ext, eFPU32381, ePMMU32382, UInt32 },
3153
  { "NS32CG16",eCoreGenE   , eFPU32181, ePMMU32082, UInt24 },
3154
  { "NS32532", eCoreGen2   , eFPU32381, ePMMU32532, UInt32 },
3155
  { NULL     , eCoreNone   , eFPUNone , ePMMUNone , UInt1  }
3156
};
3157
 
3158
void codens32k_init(void)
3159
{
3160
  const tCPUProps *pRun;
3161
 
3162
  for (pRun = CPUProps; pRun->pName; pRun++)
3163
    (void)AddCPUUser(pRun->pName, SwitchTo_NS32K, (void*)pRun, NULL);
3164
 
3165
  AddInitPassProc(InitCode_NS32K);
3166
}