Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* code3203x.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Codegenerator TMS320C3x/C4x-Familie                                       */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <ctype.h>
13
#include <string.h>
14
 
15
#include "nls.h"
16
#include "be_le.h"
17
#include "bpemu.h"
18
#include "strutil.h"
19
#include "chunks.h"
20
#include "asmdef.h"
21
#include "asmsub.h"
22
#include "asmpars.h"
23
#include "asmcode.h"
24
#include "asmitree.h"
25
#include "codepseudo.h"
26
#include "codevars.h"
27
#include "tipseudo.h"
28
#include "tifloat.h"
29
#include "headids.h"
30
#include "onoff_common.h"
31
#include "errmsg.h"
32
 
33
#include "code3203x.h"
34
 
35
typedef struct
36
{
37
  LongWord Code;
38
} FixedOrder;
39
 
40
typedef struct
41
{
42
  int NameLen;
43
  CPUVar MinCPU;
44
  Boolean May1, May3;
45
  Word Code, Code3;
46
  Boolean OnlyMem;
47
  Boolean SwapOps;
48
  Boolean ImmFloat;
49
  Boolean Commutative;
50
  ShortInt ParMask, Par3Mask;
51
  unsigned ParIndex, ParIndex3;
52
  Byte PCodes[8], P3Codes[8];
53
} GenOrder;
54
 
55
typedef struct
56
{
57
  LongWord Code;
58
  Byte Mask;
59
} SingOrder;
60
 
61
typedef struct
62
{
63
  const GenOrder *pOrder;
64
  Boolean Is3;
65
  ShortInt Src2Mode, Src1Mode, DestMode;
66
  Word Src2Part, Src1Part, DestPart;
67
} tGenOrderInfo;
68
 
69
static CPUVar CPU32030, CPU32031,
70
              CPU32040, CPU32044;
71
 
72
static Boolean NextPar, ThisPar;
73
static Byte PrevARs, ARs;
74
static char PrevOp[7];
75
static tGenOrderInfo PrevGenInfo;
76
 
77
static FixedOrder *FixedOrders;
78
static GenOrder *GenOrders;
79
static SingOrder *SingOrders;
80
 
81
static LongInt DPValue;
82
 
83
static const char ParOrders[][6] =
84
{
85
  "LDF",   "LDI",
86
  "STF",   "STI",
87
  "ADDF3", "SUBF3",
88
  "ADDI3", "SUBI3"
89
};
90
 
91
/*-------------------------------------------------------------------------*/
92
/* Adressparser */
93
 
94
/* do not change this enum, since it is defined the way as needed in the machine
95
   code G field! */
96
 
97
#define ModNone (-1)
98
#define ModReg 0
99
#define MModReg (1 << ModReg)
100
#define ModDir 1
101
#define MModDir (1 << ModDir)
102
#define ModInd 2
103
#define MModInd (1 << ModInd)
104
#define ModImm 3
105
#define MModImm (1 << ModImm)
106
 
107
static ShortInt AdrMode;
108
static LongInt AdrPart;
109
 
110
/* special registers with address 0x10... vary: */
111
 
112
#define ARxRegStart 0x08
113
#define CxxRegStart 0x10
114
static const char *C4XRegs[] =
115
{ "DP", "IR0", "IR1", "BK", "SP", "ST", "DIE", "IIE", "IIF", "RS", "RE", "RC", NULL },
116
                  *C3XRegs[] =
117
{ "DP", "IR0", "IR1", "BK", "SP", "ST", "IE" , "IF" , "IOF", "RS", "RE", "RC", NULL },
118
                  **CxxRegs;
119
static const char *ExpRegs[] =
120
{ "IVTP", "TVTP", NULL };
121
 
122
static Boolean Is4x(void)
123
{
124
  return MomCPU >= CPU32040;
125
}
126
 
127
static Boolean DecodeReg(const char *Asc, Byte *Erg)
128
{
129
  if ((as_toupper(*Asc) == 'R') && (strlen(Asc) <= 3) && (strlen(Asc) >= 2))
130
  {
131
    Boolean OK;
132
 
133
    *Erg = ConstLongInt(Asc + 1, &OK, 10);
134
 
135
    /* For C3x, tolerate R8...R27 as aliases for other registers for backward compatibility.
136
       For C4x, four new registers R8...R11 are mapped at register file address 28..31.
137
       So for C4x, only allow the defined R0..11 registers: */
138
 
139
    if (OK)
140
      OK = *Erg <= Is4x() ? 11 : 27;
141
    if (OK)
142
    {
143
      if (Is4x() && (*Erg >= 8))
144
        *Erg += 20;
145
      return True;
146
    }
147
  }
148
 
149
  if ((strlen(Asc) == 3)
150
   && (as_toupper(*Asc) == 'A') && (as_toupper(Asc[1]) == 'R')
151
   && (Asc[2] >= '0') && (Asc[2] <= '7'))
152
  {
153
    *Erg = Asc[2] - '0' + ARxRegStart;
154
    return True;
155
  }
156
 
157
  for (*Erg = 0; CxxRegs[*Erg]; (*Erg)++)
158
    if (!as_strcasecmp(CxxRegs[*Erg], Asc))
159
    {
160
      *Erg += CxxRegStart;
161
      return True;
162
    }
163
 
164
  return False;
165
}
166
 
167
static Boolean DecodeExpReg(const char *Asc, Byte *Erg)
168
{
169
  for (*Erg = 0; ExpRegs[*Erg]; (*Erg)++)
170
    if (!as_strcasecmp(ExpRegs[*Erg], Asc))
171
      return True;
172
 
173
  return False;
174
}
175
 
176
static void DecodeAdr(const tStrComp *pArg, Byte Erl, Boolean ImmFloat)
177
{
178
  Byte HReg;
179
  Integer Disp;
180
  char *p;
181
  int l;
182
  as_float_t f;
183
  Word fi;
184
  LongInt AdrLong;
185
  Boolean BitRev, Circ;
186
  Boolean OK;
187
  enum
188
  {
189
    ModBase, ModAdd, ModSub, ModPreInc, ModPreDec, ModPostInc, ModPostDec
190
  } Mode;
191
  tStrComp Arg;
192
 
193
  StrCompRefRight(&Arg, pArg, 0);
194
  KillPrefBlanksStrCompRef(&Arg);
195
  KillPostBlanksStrComp(&Arg);
196
 
197
  AdrMode = ModNone;
198
 
199
  /* I. Register? */
200
 
201
  if (DecodeReg(Arg.str.p_str, &HReg))
202
  {
203
    AdrMode = ModReg; AdrPart = HReg;
204
    goto chk;
205
  }
206
 
207
  /* II. indirekt ? */
208
 
209
  if (*Arg.str.p_str == '*')
210
  {
211
    /* II.1. Erkennungszeichen entfernen */
212
 
213
    StrCompIncRefLeft(&Arg, 1);;
214
 
215
    /* II.2. Extrawuerste erledigen */
216
 
217
    BitRev = False;
218
    Circ = False;
219
    l = strlen(Arg.str.p_str);
220
    if ((l > 0) && (as_toupper(Arg.str.p_str[l - 1]) == 'B'))
221
    {
222
      BitRev = True;
223
      StrCompShorten(&Arg, 1);
224
      --l;
225
    }
226
    else if ((l > 0) && (Arg.str.p_str[l - 1] == '%'))
227
    {
228
      Circ = True;
229
      StrCompShorten(&Arg, 1);
230
      --l;
231
    }
232
 
233
    /* II.3. Displacement entfernen und auswerten:
234
            0..255-->Displacement
235
            -1,-2 -->IR0,IR1
236
            -3    -->Default */
237
 
238
    p = QuotPos(Arg.str.p_str, '(');
239
    if (p)
240
    {
241
      tStrComp NDisp;
242
 
243
      if (Arg.str.p_str[l - 1] != ')')
244
      {
245
        WrError(ErrNum_InvAddrMode);
246
        return;
247
      }
248
      StrCompSplitRef(&Arg, &NDisp, &Arg, p);
249
      StrCompShorten(&NDisp, 1);
250
      if (!as_strcasecmp(NDisp.str.p_str, "IR0"))
251
        Disp = -1;
252
      else if (!as_strcasecmp(NDisp.str.p_str, "IR1"))
253
        Disp = -2;
254
      else
255
      {
256
        Disp = EvalStrIntExpression(&NDisp, UInt8, &OK);
257
        if (!OK)
258
          return;
259
      }
260
    }
261
    else
262
      Disp = -3;
263
 
264
    /* II.4. Addieren/Subtrahieren mit/ohne Update? */
265
 
266
    l = strlen(Arg.str.p_str);
267
    if (*Arg.str.p_str == '-')
268
    {
269
      if (Arg.str.p_str[1] == '-')
270
      {
271
        Mode = ModPreDec;
272
        StrCompIncRefLeft(&Arg, 2);
273
      }
274
      else
275
      {
276
        Mode = ModSub;
277
        StrCompIncRefLeft(&Arg, 1);
278
      }
279
    }
280
    else if (*Arg.str.p_str == '+')
281
    {
282
      if (Arg.str.p_str[1] == '+')
283
      {
284
        Mode = ModPreInc;
285
        StrCompIncRefLeft(&Arg, 2);
286
      }
287
      else
288
      {
289
        Mode = ModAdd;
290
        StrCompIncRefLeft(&Arg, 1);
291
      }
292
    }
293
    else if (Arg.str.p_str[l - 1] == '-')
294
    {
295
      if (Arg.str.p_str[l - 2] == '-')
296
      {
297
        Mode = ModPostDec;
298
        StrCompShorten(&Arg, 2);
299
      }
300
      else
301
      {
302
        WrError(ErrNum_InvAddrMode);
303
        return;
304
      }
305
    }
306
    else if (Arg.str.p_str[l - 1] == '+')
307
    {
308
      if (Arg.str.p_str[l - 2] == '+')
309
      {
310
        Mode = ModPostInc;
311
        StrCompShorten(&Arg, 2);
312
      }
313
      else
314
      {
315
        WrError(ErrNum_InvAddrMode);
316
        return;
317
      }
318
    }
319
    else
320
      Mode = ModBase;
321
 
322
    /* II.5. Rest muss Basisregister sein */
323
 
324
    if ((!DecodeReg(Arg.str.p_str, &HReg)) || (HReg < 8) || (HReg > 15))
325
    {
326
      WrError(ErrNum_InvAddrMode);
327
      return;
328
    }
329
    HReg -= 8;
330
    if ((ARs & (1l << HReg)) == 0)
331
      ARs += 1l << HReg;
332
    else
333
      WrStrErrorPos(ErrNum_DoubleAdrRegUse, &Arg);
334
 
335
    /* II.6. Default-Displacement explizit machen */
336
 
337
    if (Disp == -3)
338
     Disp = (Mode == ModBase) ? 0 : 1;
339
 
340
    /* II.7. Entscheidungsbaum */
341
 
342
    switch (Mode)
343
    {
344
      case ModBase:
345
      case ModAdd:
346
        if ((Circ) || (BitRev)) WrError(ErrNum_InvAddrMode);
347
        else
348
        {
349
          switch (Disp)
350
          {
351
            case -2: AdrPart = 0x8000; break;
352
            case -1: AdrPart = 0x4000; break;
353
            case  0: AdrPart = 0xc000; break;
354
            default: AdrPart = Disp;
355
          }
356
          AdrPart += ((Word)HReg) << 8;
357
          AdrMode = ModInd;
358
        }
359
        break;
360
      case ModSub:
361
        if ((Circ) || (BitRev)) WrError(ErrNum_InvAddrMode);
362
        else
363
        {
364
          switch (Disp)
365
          {
366
            case -2: AdrPart = 0x8800; break;
367
            case -1: AdrPart = 0x4800; break;
368
            case  0: AdrPart = 0xc000; break;
369
            default: AdrPart = 0x0800 + Disp;
370
          }
371
          AdrPart += ((Word)HReg) << 8;
372
          AdrMode = ModInd;
373
        }
374
        break;
375
      case ModPreInc:
376
        if ((Circ) || (BitRev)) WrError(ErrNum_InvAddrMode);
377
        else
378
        {
379
          switch (Disp)
380
          {
381
            case -2: AdrPart = 0x9000; break;
382
            case -1: AdrPart = 0x5000; break;
383
            default: AdrPart = 0x1000 + Disp;
384
          }
385
          AdrPart += ((Word)HReg) << 8;
386
          AdrMode = ModInd;
387
        }
388
        break;
389
      case ModPreDec:
390
        if ((Circ) || (BitRev)) WrError(ErrNum_InvAddrMode);
391
        else
392
        {
393
          switch (Disp)
394
          {
395
            case -2: AdrPart = 0x9800; break;
396
            case -1: AdrPart = 0x5800; break;
397
            default: AdrPart = 0x1800 + Disp;
398
          }
399
          AdrPart += ((Word)HReg) << 8;
400
          AdrMode = ModInd;
401
        }
402
        break;
403
      case ModPostInc:
404
        if (BitRev)
405
        {
406
          if (Disp != -1) WrError(ErrNum_InvAddrMode);
407
          else
408
          {
409
            AdrPart = 0xc800 + (((Word)HReg) << 8);
410
            AdrMode = ModInd;
411
          }
412
        }
413
        else
414
        {
415
          switch (Disp)
416
          {
417
            case -2: AdrPart = 0xa000; break;
418
            case -1: AdrPart = 0x6000; break;
419
            default: AdrPart = 0x2000 + Disp;
420
          }
421
          if (Circ)
422
            AdrPart += 0x1000;
423
          AdrPart += ((Word)HReg) << 8;
424
          AdrMode = ModInd;
425
        }
426
        break;
427
      case ModPostDec:
428
        if (BitRev) WrError(ErrNum_InvAddrMode);
429
        else
430
        {
431
          switch (Disp)
432
          {
433
            case -2: AdrPart = 0xa800; break;
434
            case -1: AdrPart = 0x6800; break;
435
            default: AdrPart = 0x2800 + Disp; break;
436
          }
437
          if (Circ)
438
             AdrPart += 0x1000;
439
          AdrPart += ((Word)HReg) << 8;
440
          AdrMode = ModInd;
441
        }
442
        break;
443
    }
444
 
445
    goto chk;
446
  }
447
 
448
  /* III. absolut */
449
 
450
  if (*Arg.str.p_str == '@')
451
  {
452
    AdrLong = EvalStrIntExpressionOffs(&Arg, 1, UInt24, &OK);
453
    if (OK)
454
    {
455
      if ((DPValue != -1) && ((AdrLong >> 16) != DPValue))
456
        WrError(ErrNum_InAccPage);
457
      AdrMode = ModDir;
458
      AdrPart = AdrLong & 0xffff;
459
    }
460
    goto chk;
461
  }
462
 
463
  /* IV. immediate */
464
 
465
  if (ImmFloat)
466
  {
467
    f = EvalStrFloatExpression(&Arg, &OK);
468
    if (OK)
469
    {
470
      int ret = as_float_2_ti2(f, &fi);
471
      if (ret < 0)
472
      {
473
        asmerr_check_fp_dispose_result(ret, pArg);
474
        OK = False;
475
      }
476
    }
477
    if (OK)
478
    {
479
      AdrPart = fi;
480
      AdrMode = ModImm;
481
    }
482
  }
483
  else
484
  {
485
    AdrPart = EvalStrIntExpression(&Arg, Int16, &OK);
486
    if (OK)
487
    {
488
      AdrPart &= 0xffff;
489
      AdrMode = ModImm;
490
    }
491
  }
492
 
493
chk:
494
  if ((AdrMode != ModNone) && (!(Erl & (1 << AdrMode))))
495
  {
496
    AdrMode = ModNone;
497
    WrError(ErrNum_InvAddrMode);
498
  }
499
}
500
 
501
static Word EffPart(Byte Mode, Word Part)
502
{
503
  switch (Mode)
504
  {
505
    case ModReg:
506
    case ModImm:
507
      return Lo(Part);
508
    case ModInd:
509
      return Hi(Part);
510
    default:
511
      WrError(ErrNum_InternalError);
512
      return 0;
513
  }
514
}
515
 
516
/*-------------------------------------------------------------------------*/
517
/* Code-Erzeugung */
518
 
519
static void JudgePar(const GenOrder *Prim, int Sec, Byte *ErgMode, Byte *ErgCode)
520
{
521
  if (Sec > 3)
522
    *ErgMode = 3;
523
  else if (Prim->May3)
524
    *ErgMode = 1;
525
  else
526
    *ErgMode = 2;
527
  *ErgCode = (*ErgMode == 2) ? Prim->PCodes[Sec] : Prim->P3Codes[Sec];
528
}
529
 
530
static LongWord EvalAdrExpression(const tStrComp *pArg, Boolean *OK, tSymbolFlags *pFlags)
531
{
532
  return EvalStrIntExpressionOffsWithFlags(pArg, !!(*pArg->str.p_str == '@'), UInt24, OK, pFlags);
533
}
534
 
535
static void SwapMode(ShortInt *M1, ShortInt *M2)
536
{
537
  AdrMode = (*M1);
538
  *M1 = (*M2);
539
  *M2 = AdrMode;
540
}
541
 
542
static void SwapPart(Word *P1, Word *P2)
543
{
544
  AdrPart = (*P1);
545
  *P1 = (*P2);
546
  *P2 = AdrPart;
547
}
548
 
549
static int MatchParIndex(Byte Mask, int Index)
550
{
551
  return ((Index >= 0) && (Mask & (1 << Index))) ? Index : -1;
552
}
553
 
554
/*-------------------------------------------------------------------------*/
555
/* Instruction Decoders */
556
 
557
 /* ohne Argument */
558
 
559
static void DecodeFixed(Word Index)
560
{
561
  if (!ChkArgCnt(0, 0));
562
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
563
  else
564
  {
565
    DAsmCode[0] = FixedOrders[Index].Code;
566
    CodeLen = 1;
567
  }
568
  NextPar = False;
569
}
570
 
571
/* Arithmetik/Logik */
572
 
573
static Boolean Gen3IndirectAllowed(LongWord ThisAdrPart)
574
{
575
  /* indirect addressing mode fits into 3-op, non-par instruction if it needs no
576
     displacement, i.e. the 'displacement' is IR0/IR1/special, or it is one: */
577
 
578
  return ((ThisAdrPart & 0xc000) || (Lo(ThisAdrPart) == 1));
579
}
580
 
581
static Boolean Is4xArDisp(ShortInt ThisAdrMode, LongWord ThisAdrPart)
582
{
583
  return (ThisAdrMode == ModInd)
584
      && ((ThisAdrPart & 0xf800) == 0x0000)
585
      && (Lo(ThisAdrPart) != 1)  /* prefer C3x format if displacement=1 */
586
      && (Lo(ThisAdrPart) <= 31);
587
}
588
 
589
static void DecodeGen(Word Index)
590
{
591
  Byte HReg, HReg2, Sum;
592
  String Form;
593
  tGenOrderInfo CurrGenInfo;
594
  LongWord T21_22 = 0, T28 = 0;
595
  const tStrComp *pArg[4];
596
  int ActArgCnt;
597
 
598
  NextPar = False;
599
 
600
  CurrGenInfo.pOrder = GenOrders + (Index & ~0x8000);
601
  CurrGenInfo.Is3 = (Index & 0x8000) || FALSE;
602
 
603
  if (!ChkMinCPU(CurrGenInfo.pOrder->MinCPU))
604
    return;
605
 
606
  for (ActArgCnt = 0; ActArgCnt <= ArgCnt; ActArgCnt++)
607
    pArg[ActArgCnt] = &ArgStr[ActArgCnt];
608
  ActArgCnt = ArgCnt;
609
 
610
  /* Argumentzahl abgleichen */
611
 
612
  if (ActArgCnt == 1)
613
  {
614
    if (CurrGenInfo.pOrder->May1)
615
    {
616
      ActArgCnt = 2;
617
      pArg[2] = pArg[1];
618
    }
619
    else
620
    {
621
      (void)ChkArgCntExt(ActArgCnt, 2, 2);
622
      return;
623
    }
624
  }
625
  if ((ActArgCnt == 3) && (!CurrGenInfo.Is3))
626
    CurrGenInfo.Is3 = True;
627
 
628
  if ((CurrGenInfo.pOrder->SwapOps) && (!CurrGenInfo.Is3))
629
  {
630
    pArg[3] = pArg[1];
631
    pArg[1] = pArg[2];
632
    pArg[2] = pArg[3];
633
  }
634
  if ((CurrGenInfo.Is3) && (ActArgCnt == 2))
635
  {
636
    ActArgCnt = 3;
637
    pArg[3] = pArg[2];
638
  }
639
  if ((ActArgCnt < 2) || (ActArgCnt > 3) || ((CurrGenInfo.Is3) && (!CurrGenInfo.pOrder->May3)))
640
  {
641
    (void)ChkArgCntExt(ActArgCnt, 3, 3);
642
    return;
643
  }
644
 
645
  /* Argumente parsen */
646
 
647
  if (CurrGenInfo.Is3)
648
  {
649
    if (Memo("TSTB3"))
650
    {
651
      CurrGenInfo.DestMode = ModReg;
652
      CurrGenInfo.DestPart = 0;
653
    }
654
    else
655
    {
656
      DecodeAdr(pArg[3], MModReg, CurrGenInfo.pOrder->ImmFloat);
657
      if (AdrMode == ModNone)
658
        return;
659
      CurrGenInfo.DestMode = AdrMode;
660
      CurrGenInfo.DestPart = AdrPart;
661
    }
662
 
663
    /* The C4x type 2 format may use an immediate operand only if it is an
664
       integer operation - there is no 8-bit represenataion of floats. */
665
 
666
    DecodeAdr(pArg[1],
667
              MModReg | MModInd | ((Is4x() && !CurrGenInfo.pOrder->ImmFloat) ? MModImm : 0),
668
              CurrGenInfo.pOrder->ImmFloat);
669
    if (AdrMode == ModNone)
670
      return;
671
 
672
    /* src2 is immediate or *+ARn(udisp5): C4x type 2 format */
673
 
674
    if (AdrMode == ModImm)
675
    {
676
      T28 = 1ul << 28;
677
    }
678
    else if (Is4x() && Is4xArDisp(AdrMode, AdrPart))
679
    {
680
      /* note that for type 2, bit 21 defines addressing mode of src2 and bit 22
681
         defines addressing mode of src1, which is the opposite of the type 1 format! */
682
 
683
      T21_22 |= 1ul << 21;
684
      T28 = 1ul << 28;
685
      AdrPart = ((Word)(Hi(AdrPart) & 7) | (Lo(AdrPart) << 3)) << 8;
686
    }
687
 
688
    /* type 1/C3x format: check whether indirect mode is 'short': */
689
 
690
    else if (AdrMode == ModInd)
691
    {
692
      if (!Gen3IndirectAllowed(AdrPart))
693
      {
694
        WrError(ErrNum_InvAddrMode);
695
        return;
696
      }
697
      T21_22 |= 1ul << 22;
698
    }
699
    CurrGenInfo.Src2Mode = AdrMode;
700
    CurrGenInfo.Src2Part = AdrPart;
701
 
702
    DecodeAdr(pArg[2], MModReg | MModInd, CurrGenInfo.pOrder->ImmFloat);
703
    if (AdrMode == ModNone)
704
      return;
705
 
706
    /* if type 2, the only indirect mode allowed for src1 is *+ARn(udisp5): */
707
 
708
    if (T28)
709
    {
710
      if (AdrMode == ModInd)
711
      {
712
        if (!Is4xArDisp(AdrMode, AdrPart))
713
        {
714
          WrError(ErrNum_InvAddrMode);
715
          return;
716
        }
717
        else
718
          AdrPart = ((Word)(Hi(AdrPart) & 7) | (Lo(AdrPart) << 3)) << 8;
719
        T21_22 |= 1ul << 22;
720
      }
721
    }
722
 
723
    /* type 1/C3x format: similar check for src1 for 'short' adressing: */
724
 
725
    else if (AdrMode == ModInd)
726
    {
727
      if (!Gen3IndirectAllowed(AdrPart))
728
      {
729
        WrError(ErrNum_InvAddrMode);
730
        return;
731
      }
732
      T21_22 |= 1ul << 21;
733
    }
734
    CurrGenInfo.Src1Mode = AdrMode;
735
    CurrGenInfo.Src1Part = AdrPart;
736
  }
737
  else /* !CurrGenInfo.Is3 */
738
  {
739
    DecodeAdr(pArg[1], MModDir + MModInd + ((CurrGenInfo.pOrder->OnlyMem) ? 0 : MModReg + MModImm), CurrGenInfo.pOrder->ImmFloat);
740
    if (AdrMode == ModNone)
741
      return;
742
    CurrGenInfo.Src2Mode = AdrMode;
743
    CurrGenInfo.Src2Part = AdrPart;
744
    DecodeAdr(pArg[2], MModReg + MModInd, CurrGenInfo.pOrder->ImmFloat);
745
    switch (AdrMode)
746
    {
747
      case ModReg:
748
        CurrGenInfo.DestMode = AdrMode;
749
        CurrGenInfo.DestPart = AdrPart;
750
        CurrGenInfo.Src1Mode = CurrGenInfo.Src2Mode;
751
        CurrGenInfo.Src1Part = CurrGenInfo.Src2Part;
752
        break;
753
      case ModInd:
754
        if (((strcmp(OpPart.str.p_str, "TSTB")) && (strcmp(OpPart.str.p_str, "CMPI")) && (strcmp(OpPart.str.p_str, "CMPF")))
755
        ||  ((CurrGenInfo.Src2Mode == ModDir) || (CurrGenInfo.Src2Mode == ModImm))
756
        ||  ((CurrGenInfo.Src2Mode == ModInd) && ((CurrGenInfo.Src2Part & 0xe000) == 0) && (Lo(CurrGenInfo.Src2Part) != 1))
757
        ||  (((AdrPart & 0xe000) == 0) && (Lo(AdrPart) != 1)))
758
        {
759
          WrError(ErrNum_InvAddrMode);
760
          return;
761
        }
762
        else
763
        {
764
          CurrGenInfo.Is3 = True;
765
          CurrGenInfo.DestMode = ModReg;
766
          CurrGenInfo.DestPart = 0;
767
          CurrGenInfo.Src1Mode = AdrMode;
768
          CurrGenInfo.Src1Part = AdrPart;
769
        }
770
        break;
771
      case ModNone:
772
        return;
773
    }
774
  }
775
 
776
  /* auswerten: parallel... */
777
 
778
  if (ThisPar)
779
  {
780
    int ParIndex;
781
    unsigned ARIndex;
782
 
783
    if (!PrevGenInfo.pOrder)
784
    {
785
      WrError(ErrNum_ParNotPossible);
786
      return;
787
    }
788
 
789
    /* in Standardreihenfolge suchen */
790
 
791
    ParIndex = MatchParIndex(PrevGenInfo.Is3 ? PrevGenInfo.pOrder->Par3Mask : PrevGenInfo.pOrder->ParMask,
792
                             CurrGenInfo.Is3 ? CurrGenInfo.pOrder->ParIndex3 : CurrGenInfo.pOrder->ParIndex);
793
    if (ParIndex >= 0)
794
      JudgePar(PrevGenInfo.pOrder, ParIndex, &HReg, &HReg2);
795
 
796
    /* in gedrehter Reihenfolge suchen */
797
 
798
    else
799
    {
800
      ParIndex = MatchParIndex(CurrGenInfo.Is3 ? CurrGenInfo.pOrder->Par3Mask : CurrGenInfo.pOrder->ParMask,
801
                               PrevGenInfo.Is3 ? PrevGenInfo.pOrder->ParIndex3 : PrevGenInfo.pOrder->ParIndex);
802
      if (ParIndex >= 0)
803
      {
804
        JudgePar(CurrGenInfo.pOrder, ParIndex, &HReg, &HReg2);
805
        SwapMode(&CurrGenInfo.DestMode, &PrevGenInfo.DestMode);
806
        SwapMode(&CurrGenInfo.Src2Mode, &PrevGenInfo.Src2Mode);
807
        SwapMode(&CurrGenInfo.Src1Mode, &PrevGenInfo.Src1Mode);
808
        SwapPart(&CurrGenInfo.DestPart, &PrevGenInfo.DestPart);
809
        SwapPart(&CurrGenInfo.Src2Part, &PrevGenInfo.Src2Part);
810
        SwapPart(&CurrGenInfo.Src1Part, &PrevGenInfo.Src1Part);
811
      }
812
      else
813
      {
814
        WrError(ErrNum_ParNotPossible);
815
        return;
816
      }
817
    }
818
 
819
    /* mehrfache Registernutzung ? */
820
 
821
    for (ARIndex = 0; ARIndex < 8; ARIndex++)
822
      if (ARs & PrevARs & (1l << ARIndex))
823
      {
824
        as_snprintf(Form, sizeof(Form), "AR%d", (int)ARIndex);
825
        WrXError(ErrNum_DoubleAdrRegUse, Form);
826
      }
827
 
828
    /* 3 Basisfaelle */
829
 
830
    switch (HReg)
831
    {
832
      case 1:
833
        if ((!strcmp(PrevOp, "LSH3")) || (!strcmp(PrevOp, "ASH3")) || (!strcmp(PrevOp, "SUBF3")) || (!strcmp(PrevOp, "SUBI3")))
834
        {
835
          SwapMode(&PrevGenInfo.Src2Mode, &PrevGenInfo.Src1Mode);
836
          SwapPart(&PrevGenInfo.Src2Part, &PrevGenInfo.Src1Part);
837
        }
838
        if ((PrevGenInfo.DestPart > 7) || (CurrGenInfo.DestPart > 7))
839
        {
840
          WrError(ErrNum_InvReg);
841
          return;
842
        }
843
 
844
        /* Bei Addition und Multiplikation Kommutativitaet nutzen */
845
 
846
        if  ((PrevGenInfo.Src1Mode == ModInd) && (PrevGenInfo.Src2Mode == ModReg) && (PrevGenInfo.pOrder->Commutative))
847
        {
848
          SwapMode(&PrevGenInfo.Src2Mode, &PrevGenInfo.Src1Mode);
849
          SwapPart(&PrevGenInfo.Src2Part, &PrevGenInfo.Src1Part);
850
        }
851
        if ((PrevGenInfo.Src1Mode != ModReg) || (PrevGenInfo.Src1Part > 7)
852
         || (PrevGenInfo.Src2Mode != ModInd) || (CurrGenInfo.Src2Mode != ModInd))
853
        {
854
          WrError(ErrNum_InvParAddrMode);
855
          return;
856
        }
857
        RetractWords(1);
858
        DAsmCode[0] = 0xc0000000 + (((LongWord)HReg2) << 25)
859
                    + (((LongWord)PrevGenInfo.DestPart) << 22)
860
                    + (((LongWord)PrevGenInfo.Src1Part) << 19)
861
                    + (((LongWord)CurrGenInfo.DestPart) << 16)
862
                    + (CurrGenInfo.Src2Part & 0xff00) + Hi(PrevGenInfo.Src2Part);
863
        CodeLen = 1;
864
        NextPar = False;
865
        break;
866
      case 2:
867
        if ((PrevGenInfo.DestPart > 7) || (CurrGenInfo.DestPart > 7))
868
        {
869
          WrError(ErrNum_InvReg);
870
          return;
871
        }
872
        if ((PrevGenInfo.Src2Mode != ModInd) || (CurrGenInfo.Src2Mode != ModInd))
873
        {
874
          WrError(ErrNum_InvParAddrMode);
875
          return;
876
        }
877
        RetractWords(1);
878
        DAsmCode[0] = 0xc0000000 + (((LongWord)HReg2) << 25)
879
                    + (((LongWord)PrevGenInfo.DestPart) << 22)
880
                    + (CurrGenInfo.Src2Part & 0xff00) + Hi(PrevGenInfo.Src2Part);
881
        if ((!strcmp(PrevOp, OpPart.str.p_str)) && (*OpPart.str.p_str == 'L'))
882
        {
883
          DAsmCode[0] += ((LongWord)CurrGenInfo.DestPart) << 19;
884
          if (PrevGenInfo.DestPart == CurrGenInfo.DestPart) WrError(ErrNum_Unpredictable);
885
        }
886
        else
887
          DAsmCode[0] += ((LongWord)CurrGenInfo.DestPart) << 16;
888
        CodeLen = 1;
889
        NextPar = False;
890
        break;
891
      case 3:
892
        if ((PrevGenInfo.DestPart > 1) || (CurrGenInfo.DestPart<2) || (CurrGenInfo.DestPart > 3))
893
        {
894
          WrError(ErrNum_InvReg);
895
          return;
896
        }
897
        Sum = 0;
898
        if (PrevGenInfo.Src2Mode == ModInd) Sum++;
899
        if (PrevGenInfo.Src1Mode == ModInd) Sum++;
900
        if (CurrGenInfo.Src2Mode == ModInd) Sum++;
901
        if (CurrGenInfo.Src1Mode == ModInd) Sum++;
902
        if (Sum != 2)
903
        {
904
          WrError(ErrNum_InvParAddrMode);
905
          return;
906
        }
907
        RetractWords(1);
908
        DAsmCode[0] = 0x80000000 + (((LongWord)HReg2) << 26)
909
                    + (((LongWord)PrevGenInfo.DestPart & 1) << 23)
910
                    + (((LongWord)CurrGenInfo.DestPart & 1) << 22);
911
        CodeLen = 1;
912
        if (CurrGenInfo.Src1Mode == ModReg)
913
        {
914
          if (CurrGenInfo.Src2Mode == ModReg)
915
          {
916
            DAsmCode[0] += ((LongWord)0x00000000)
917
                         + (((LongWord)CurrGenInfo.Src1Part) << 19)
918
                         + (((LongWord)CurrGenInfo.Src2Part) << 16)
919
                         + (PrevGenInfo.Src1Part & 0xff00) + Hi(PrevGenInfo.Src2Part);
920
          }
921
          else
922
          {
923
            DAsmCode[0] += ((LongWord)0x03000000)
924
                         + (((LongWord)CurrGenInfo.Src1Part) << 16)
925
                         + Hi(CurrGenInfo.Src2Part);
926
            if (PrevGenInfo.Src2Mode == ModReg)
927
              DAsmCode[0] += (((LongWord)PrevGenInfo.Src2Part) << 19) + (PrevGenInfo.Src1Part & 0xff00);
928
            else
929
              DAsmCode[0] += (((LongWord)PrevGenInfo.Src1Part) << 19) + (PrevGenInfo.Src2Part & 0xff00);
930
          }
931
        }
932
        else
933
        {
934
          if (CurrGenInfo.Src2Mode == ModReg)
935
          {
936
            DAsmCode[0] += ((LongWord)0x01000000)
937
                         + (((LongWord)CurrGenInfo.Src2Part) << 16)
938
                         + Hi(CurrGenInfo.Src1Part);
939
            if (PrevGenInfo.Src2Mode == ModReg)
940
              DAsmCode[0] += (((LongWord)PrevGenInfo.Src2Part) << 19) + (PrevGenInfo.Src1Part & 0xff00);
941
            else
942
              DAsmCode[0] += (((LongWord)PrevGenInfo.Src1Part) << 19) + (PrevGenInfo.Src2Part & 0xff00);
943
          }
944
          else
945
          {
946
            DAsmCode[0] += ((LongWord)0x02000000)
947
                         + (((LongWord)PrevGenInfo.Src1Part) << 19)
948
                         + (((LongWord)PrevGenInfo.Src2Part) << 16)
949
                         + (CurrGenInfo.Src1Part & 0xff00) + Hi(CurrGenInfo.Src2Part);
950
          }
951
        }
952
        break;
953
    }
954
  }
955
  /* ...sequentiell */
956
  else
957
  {
958
    strcpy(PrevOp, OpPart.str.p_str);
959
    PrevARs = ARs;
960
    PrevGenInfo = CurrGenInfo;
961
    if (CurrGenInfo.Is3)
962
      DAsmCode[0] = 0x20000000 | T28 | (((LongWord)CurrGenInfo.pOrder->Code3) << 23) | T21_22
963
                  | (((LongWord)CurrGenInfo.DestPart) << 16)
964
                  | (EffPart(CurrGenInfo.Src1Mode, CurrGenInfo.Src1Part) << 8)
965
                  | EffPart(CurrGenInfo.Src2Mode, CurrGenInfo.Src2Part);
966
    else
967
      DAsmCode[0] = 0x00000000 | (((LongWord)CurrGenInfo.pOrder->Code) << 23)
968
                  | (((LongWord)CurrGenInfo.Src2Mode) << 21)
969
                  | CurrGenInfo.Src2Part
970
                  | (((LongWord)CurrGenInfo.DestPart) << 16);
971
    CodeLen = 1;
972
    NextPar = True;
973
  }
974
}
975
 
976
/* Due to the way it is executed in the instruction pipeline, LDA has some restrictions
977
   on its operands: only ARx, DP-SP allowed as destination, and source+dest reg cannot be same register */
978
 
979
static void DecodeLDA(Word Code)
980
{
981
  Byte HReg;
982
 
983
  if (!ChkArgCnt(2, 2));
984
  else if (!ChkMinCPU(CPU32040));
985
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
986
  else if (!DecodeReg(ArgStr[2].str.p_str, &HReg)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
987
  else if ((HReg < 8) || (HReg > 20)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
988
  else
989
  {
990
    Boolean RegClash;
991
 
992
    DecodeAdr(&ArgStr[1], MModReg | MModInd | MModDir | MModImm, False);
993
    switch (AdrMode)
994
    {
995
      case ModDir:
996
      case ModImm:
997
        RegClash = False;
998
        break;
999
      case ModReg:
1000
        RegClash = (AdrPart == HReg);
1001
        break;
1002
      case ModInd:
1003
        if ((Hi(AdrPart) & 7) + ARxRegStart == HReg)
1004
          RegClash = True;
1005
        else if (((AdrPart & 0xc000) == 0x4000) && (HReg == 0x11))
1006
          RegClash = True;
1007
        else if (((AdrPart & 0xc000) == 0x8000) && (HReg == 0x12))
1008
          RegClash = True;
1009
        else if (((AdrPart & 0xf800) == 0xc800) && (HReg == 0x11))
1010
          RegClash = True;
1011
        else
1012
          RegClash = False;
1013
        break;
1014
      default:
1015
        return;
1016
    }
1017
    if (RegClash) WrError(ErrNum_InvRegPair);
1018
    else
1019
    {
1020
      DAsmCode[0] = (((LongWord)Code) << 23)
1021
                  | (((LongWord)AdrMode) << 21)
1022
                  | (((LongWord)HReg) << 16)
1023
                  | AdrPart;
1024
      CodeLen = 1;
1025
    }
1026
  }
1027
  NextPar = False;
1028
}
1029
 
1030
static void DecodeRot(Word Code)
1031
{
1032
  Byte HReg;
1033
 
1034
  if (!ChkArgCnt(1, 1));
1035
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1036
  else if (!DecodeReg(ArgStr[1].str.p_str, &HReg)) WrError(ErrNum_InvAddrMode);
1037
  else
1038
  {
1039
    DAsmCode[0] = 0x11e00000 + (((LongWord)Code) << 23) + (((LongWord)HReg) << 16);
1040
    CodeLen = 1;
1041
  }
1042
  NextPar = False;
1043
}
1044
 
1045
static void DecodeStk(Word Code)
1046
{
1047
  Byte HReg;
1048
 
1049
  if (!ChkArgCnt(1, 1));
1050
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1051
  else if (!DecodeReg(ArgStr[1].str.p_str, &HReg)) WrError(ErrNum_InvAddrMode);
1052
  else
1053
  {
1054
    DAsmCode[0] = 0x0e200000 + (((LongWord)Code) << 23) + (((LongWord)HReg) << 16);
1055
    CodeLen = 1;
1056
  }
1057
  NextPar = False;
1058
}
1059
 
1060
/* Datentransfer */
1061
 
1062
static void DecodeLDIcc_LDFcc(Word Code)
1063
{
1064
  LongWord CondCode = Lo(Code), InstrCode = ((LongWord)Hi(Code)) << 24;
1065
  Byte HReg;
1066
 
1067
  if (!ChkArgCnt(2, 2));
1068
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1069
  else
1070
  {
1071
    DecodeAdr(&ArgStr[2], MModReg, False);
1072
    if (AdrMode != ModNone)
1073
    {
1074
      HReg = AdrPart;
1075
      DecodeAdr(&ArgStr[1], MModReg + MModDir + MModInd + MModImm, InstrCode == 0x40000000);
1076
      if (AdrMode != ModNone)
1077
      {
1078
        DAsmCode[0] = InstrCode + (((LongWord)HReg) << 16)
1079
                    + (CondCode << 23)
1080
                    + (((LongWord)AdrMode) << 21) + AdrPart;
1081
        CodeLen = 1;
1082
      }
1083
    }
1084
    NextPar = False;
1085
  }
1086
}
1087
 
1088
/* Sonderfall NOP auch ohne Argumente */
1089
 
1090
static void DecodeNOP(Word Code)
1091
{
1092
  UNUSED(Code);
1093
 
1094
  if (ArgCnt == 0)
1095
  {
1096
    CodeLen = 1;
1097
    DAsmCode[0] = NOPCode;
1098
  }
1099
  else if (!ChkArgCnt(1, 1));
1100
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1101
  else
1102
  {
1103
    DecodeAdr(&ArgStr[1], 5, False);
1104
    if (AdrMode != ModNone)
1105
    {
1106
      DAsmCode[0] = 0x0c800000 + (((LongWord)AdrMode) << 21) + AdrPart;
1107
      CodeLen = 1;
1108
    }
1109
  }
1110
  NextPar = False;
1111
}
1112
 
1113
/* Sonderfaelle */
1114
 
1115
static void DecodeSing(Word Index)
1116
{
1117
  const SingOrder *pOrder = SingOrders + Index;
1118
 
1119
  if (!ChkArgCnt(1, 1));
1120
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1121
  else
1122
  {
1123
    DecodeAdr(&ArgStr[1], pOrder->Mask, False);
1124
    if (AdrMode != ModNone)
1125
    {
1126
      DAsmCode[0] = pOrder->Code + (((LongWord)AdrMode) << 21) + AdrPart;
1127
      CodeLen = 1;
1128
    }
1129
  }
1130
  NextPar = False;
1131
}
1132
 
1133
static void DecodeLDP(Word Code)
1134
{
1135
  UNUSED(Code);
1136
 
1137
  if (!ChkArgCnt(1, 2));
1138
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1139
  else if ((ArgCnt == 2) && (as_strcasecmp(ArgStr[2].str.p_str, "DP"))) WrError(ErrNum_InvAddrMode);
1140
  else
1141
  {
1142
    Boolean OK;
1143
    tSymbolFlags Flags;
1144
    LongInt AdrLong = EvalAdrExpression(&ArgStr[1], &OK, &Flags);
1145
 
1146
    if (OK)
1147
    {
1148
      DAsmCode[0] = 0x08700000 + (AdrLong >> 16);
1149
      CodeLen = 1;
1150
    }
1151
  }
1152
  NextPar = False;
1153
}
1154
 
1155
static void DecodeLdExp(Word Code)
1156
{
1157
  Boolean Swapped = (Code & 1) || False;
1158
  Byte Src, Dest;
1159
 
1160
  if (!ChkArgCnt(2, 2));
1161
  else if (!ChkMinCPU(CPU32040));
1162
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1163
  else if (!(Swapped ? DecodeReg(ArgStr[1].str.p_str, &Src) : DecodeExpReg(ArgStr[1].str.p_str, &Src))) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
1164
  else if (!(Swapped ? DecodeExpReg(ArgStr[2].str.p_str, &Dest) : DecodeReg(ArgStr[2].str.p_str, &Dest))) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
1165
  else
1166
  {
1167
    DAsmCode[0] = (((LongWord)Code) << 23)
1168
                | (((LongWord)Dest) << 16)
1169
                | (((LongWord)Src) << 0);
1170
    CodeLen = 1;
1171
  }
1172
  NextPar = False;
1173
}
1174
 
1175
static void DecodeRegImm(Word Code)
1176
{
1177
  Byte Dest;
1178
 
1179
  if (!ChkArgCnt(2, 2));
1180
  else if (!ChkMinCPU(CPU32040));
1181
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1182
  else if (!DecodeReg(ArgStr[2].str.p_str, &Dest)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
1183
  else
1184
  {
1185
    DecodeAdr(&ArgStr[1], MModImm, False);
1186
    if (AdrMode == ModImm)
1187
    {
1188
      DAsmCode[0] = (((LongWord)Code) << 23)
1189
                  | (((LongWord)AdrMode) << 21)
1190
                  | (((LongWord)Dest) << 16)
1191
                  | AdrPart;
1192
      CodeLen = 1;
1193
    }
1194
  }
1195
  NextPar = False;
1196
}
1197
 
1198
static void DecodeLDPK(Word Code)
1199
{
1200
  Byte Dest;
1201
 
1202
  if (!ChkArgCnt(1, 1));
1203
  else if (!ChkMinCPU(CPU32040));
1204
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1205
  else if (!DecodeReg("DP", &Dest)) WrXError(ErrNum_InvReg, "DP");
1206
  else
1207
  {
1208
    DecodeAdr(&ArgStr[1], MModImm, False);
1209
    if (AdrMode == ModImm)
1210
    {
1211
      DAsmCode[0] = (((LongWord)Code) << 23)
1212
                  | (((LongWord)AdrMode) << 21)
1213
                  | (((LongWord)Dest) << 16)
1214
                  | AdrPart;
1215
      CodeLen = 1;
1216
    }
1217
  }
1218
  NextPar = False;
1219
}
1220
 
1221
static void DecodeSTIK(Word Code)
1222
{
1223
  if (!ChkArgCnt(2, 2));
1224
  else if (!ChkMinCPU(CPU32040));
1225
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1226
  else
1227
  {
1228
    Boolean OK;
1229
    LongInt Src = EvalStrIntExpression(&ArgStr[1], SInt5, &OK);
1230
 
1231
    if (OK)
1232
    {
1233
      DecodeAdr(&ArgStr[2], MModInd | MModDir, False);
1234
 
1235
      if (AdrMode != ModNone)
1236
      {
1237
        AdrMode = (AdrMode == ModInd) ? 3 : 0;
1238
        Src = (Src << 16) & 0x001f0000ul;
1239
        DAsmCode[0] = (((LongWord)Code) << 23)
1240
                    | (((LongWord)AdrMode) << 21)
1241
                    | Src
1242
                    | AdrPart;
1243
        CodeLen = 1;
1244
      }
1245
    }
1246
  }
1247
  NextPar = False;
1248
}
1249
 
1250
/* Schleifen */
1251
 
1252
static void DecodeRPTB_C3x(Word Code)
1253
{
1254
  UNUSED(Code);
1255
 
1256
  if (!ChkArgCnt(1, 1));
1257
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1258
  else
1259
  {
1260
    Boolean OK;
1261
    tSymbolFlags Flags;
1262
    LongInt AdrLong = EvalAdrExpression(&ArgStr[1], &OK, &Flags);
1263
 
1264
    if (OK)
1265
    {
1266
      DAsmCode[0] = 0x64000000 + AdrLong;
1267
      CodeLen = 1;
1268
    }
1269
  }
1270
  NextPar = False;
1271
}
1272
 
1273
static void DecodeRPTB_C4x(Word Code)
1274
{
1275
  Byte Reg;
1276
 
1277
  UNUSED(Code);
1278
 
1279
  if (!ChkArgCnt(1, 1));
1280
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1281
  else if (DecodeReg(ArgStr[1].str.p_str, &Reg))
1282
  {
1283
    DAsmCode[0] = 0x79000000 | Reg;
1284
    CodeLen = 1;
1285
  }
1286
  else
1287
  {
1288
    Boolean OK;
1289
    tSymbolFlags Flags;
1290
    LongInt AdrLong = EvalAdrExpression(&ArgStr[1], &OK, &Flags) - (EProgCounter() + 1);
1291
 
1292
    if (OK)
1293
    {
1294
      if (!mSymbolQuestionable(Flags) && ((AdrLong > 0x7fffffl) || (AdrLong < -0x800000l))) WrError(ErrNum_JmpDistTooBig);
1295
      else
1296
      {
1297
        DAsmCode[0] = 0x64000000 + AdrLong;
1298
        CodeLen = 1;
1299
      }
1300
    }
1301
  }
1302
  NextPar = False;
1303
}
1304
 
1305
/* Spruenge */
1306
 
1307
/* note that BR/BRD/CALL/(LAJ) take an absolute 24-bit address on C3x,
1308
   but a 24-bit displacement on C4x. So we use different decoders for
1309
   C3x and C4x: */
1310
 
1311
static void DecodeBR_BRD_CALL_C3x(Word Code)
1312
{
1313
  Byte InstrCode = Lo(Code);
1314
 
1315
  if (!ChkArgCnt(1, 1));
1316
  else if (InstrCode == 0x63) (void)ChkMinCPU(CPU32040); /* no LAJ on C3x */
1317
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1318
  else
1319
  {
1320
    Boolean OK;
1321
    tSymbolFlags Flags;
1322
    LongInt AdrLong = EvalAdrExpression(&ArgStr[1], &OK, &Flags);
1323
 
1324
    if (OK)
1325
    {
1326
      DAsmCode[0] = (((LongWord)Code) << 24) + AdrLong;
1327
      CodeLen = 1;
1328
    }
1329
  }
1330
  NextPar = False;
1331
}
1332
 
1333
static void DecodeBR_BRD_CALL_LAJ_C4x(Word Code)
1334
{
1335
  Byte InstrCode = Lo(Code), Dist = Hi(Code);
1336
 
1337
  if (!ChkArgCnt(1, 1));
1338
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1339
  else
1340
  {
1341
    Boolean OK;
1342
    tSymbolFlags Flags;
1343
    LongInt AdrLong = EvalAdrExpression(&ArgStr[1], &OK, &Flags) - (EProgCounter() + Dist);
1344
 
1345
    if (OK)
1346
    {
1347
      if (!mSymbolQuestionable(Flags) && ((AdrLong > 0x7fffffl) || (AdrLong < -0x800000l))) WrError(ErrNum_JmpDistTooBig);
1348
      else
1349
      {
1350
        DAsmCode[0] = (((LongWord)InstrCode) << 24) + (AdrLong & 0xffffff);
1351
        CodeLen = 1;
1352
      }
1353
    }
1354
  }
1355
  NextPar = False;
1356
}
1357
 
1358
static void DecodeBcc(Word Code)
1359
{
1360
  LongWord CondCode = Lo(Code) & 0x7f,
1361
           DFlag = ((LongWord)Hi(Code)) << 21;
1362
  LongInt Disp = DFlag ? 3 : 1;
1363
  Byte HReg;
1364
 
1365
  if (!ChkArgCnt(1, 1));
1366
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1367
  else if ((Code & 0x80) && !ChkMinCPU(CPU32040));
1368
  else if (DecodeReg(ArgStr[1].str.p_str, &HReg))
1369
  {
1370
    DAsmCode[0] = 0x68000000 + (CondCode << 16) + DFlag + HReg;
1371
    CodeLen = 1;
1372
  }
1373
  else
1374
  {
1375
    Boolean OK;
1376
    tSymbolFlags Flags;
1377
    LongInt AdrLong = EvalAdrExpression(&ArgStr[1], &OK, &Flags) - (EProgCounter() + Disp);
1378
 
1379
    if (OK)
1380
    {
1381
      if (!mSymbolQuestionable(Flags) && ((AdrLong > 0x7fffl) || (AdrLong < -0x8000l))) WrError(ErrNum_JmpDistTooBig);
1382
      else
1383
      {
1384
        DAsmCode[0] = 0x6a000000 + (CondCode << 16) + DFlag + (AdrLong & 0xffff);
1385
        CodeLen = 1;
1386
      }
1387
    }
1388
  }
1389
  NextPar = False;
1390
}
1391
 
1392
static void DecodeCALLcc(Word Code)
1393
{
1394
  Byte HReg;
1395
 
1396
  if (!ChkArgCnt(1, 1));
1397
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1398
  else if (DecodeReg(ArgStr[1].str.p_str, &HReg))
1399
  {
1400
    DAsmCode[0] = 0x70000000 + (((LongWord)Code) << 16) + HReg;
1401
    CodeLen = 1;
1402
  }
1403
  else
1404
  {
1405
    Boolean OK;
1406
    tSymbolFlags Flags;
1407
    LongInt AdrLong = EvalAdrExpression(&ArgStr[1], &OK, &Flags) - (EProgCounter() + 1);
1408
 
1409
    if (OK)
1410
    {
1411
      if (!mSymbolQuestionable(Flags) && ((AdrLong > 0x7fffl) || (AdrLong < -0x8000l))) WrError(ErrNum_JmpDistTooBig);
1412
      else
1413
      {
1414
        DAsmCode[0] = 0x72000000 + (((LongWord)Code) << 16) + (AdrLong & 0xffff);
1415
        CodeLen = 1;
1416
      }
1417
    }
1418
  }
1419
  NextPar = False;
1420
}
1421
 
1422
static void DecodeDBcc(Word Code)
1423
{
1424
  LongWord CondCode = Lo(Code),
1425
           DFlag = ((LongWord)Hi(Code)) << 21;
1426
  LongInt Disp = DFlag ? 3 : 1;
1427
  Byte HReg, HReg2;
1428
 
1429
  if (!ChkArgCnt(2, 2));
1430
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1431
  else if (!DecodeReg(ArgStr[1].str.p_str, &HReg2)) WrError(ErrNum_InvAddrMode);
1432
  else if ((HReg2 < 8) || (HReg2 > 15)) WrError(ErrNum_InvAddrMode);
1433
  else
1434
  {
1435
    HReg2 -= 8;
1436
    if (DecodeReg(ArgStr[2].str.p_str, &HReg))
1437
    {
1438
      DAsmCode[0] = 0x6c000000
1439
                  + (CondCode << 16)
1440
                  + DFlag
1441
                  + (((LongWord)HReg2) << 22)
1442
                  + HReg;
1443
      CodeLen = 1;
1444
    }
1445
    else
1446
    {
1447
      Boolean OK;
1448
      tSymbolFlags Flags;
1449
      LongInt AdrLong = EvalAdrExpression(&ArgStr[2], &OK, &Flags) - (EProgCounter() + Disp);
1450
 
1451
      if (OK)
1452
      {
1453
        if (!mSymbolQuestionable(Flags) && ((AdrLong > 0x7fffl) || (AdrLong < -0x8000l))) WrError(ErrNum_JmpDistTooBig);
1454
        else
1455
        {
1456
          DAsmCode[0] = 0x6e000000
1457
                      + (CondCode << 16)
1458
                      + DFlag
1459
                      + (((LongWord)HReg2) << 22)
1460
                      + (AdrLong & 0xffff);
1461
          CodeLen = 1;
1462
        }
1463
      }
1464
    }
1465
  }
1466
  NextPar = False;
1467
}
1468
 
1469
static void DecodeRETIcc_RETScc(Word Code)
1470
{
1471
  LongWord CondCode = Lo(Code),
1472
           DFlag = ((LongWord)Hi(Code)) << 21;
1473
 
1474
  if (!ChkArgCnt(0, 0));
1475
  else if ((DFlag & (1ul << 21)) && !ChkMinCPU(CPU32040));
1476
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1477
  else
1478
  {
1479
    DAsmCode[0] = 0x78000000 + DFlag + (CondCode << 16);
1480
    CodeLen = 1;
1481
  }
1482
  NextPar = False;
1483
}
1484
 
1485
static void DecodeTRAPcc(Word Code)
1486
{
1487
  if (!ChkArgCnt(1, 1));
1488
  else if ((Code & 0x80) && !ChkMinCPU(CPU32040));
1489
  else if (ThisPar) WrError(ErrNum_ParNotPossible);
1490
  else
1491
  {
1492
    Boolean OK;
1493
    LongWord HReg = EvalStrIntExpression(&ArgStr[1], Is4x() ? UInt9 : UInt4, &OK);
1494
 
1495
    if (OK)
1496
    {
1497
      DAsmCode[0] = 0x74000000 + HReg + (((LongWord)Code) << 16);
1498
      CodeLen = 1;
1499
    }
1500
  }
1501
  NextPar = False;
1502
}
1503
 
1504
/*-------------------------------------------------------------------------*/
1505
/* Befehlstabellenverwaltung */
1506
 
1507
static void AddCondition(const char *NName, Byte NCode)
1508
{
1509
  char InstName[30];
1510
 
1511
  if (*NName)
1512
  {
1513
    as_snprintf(InstName, sizeof(InstName), "LDI%s", NName);
1514
    AddInstTable(InstTable, InstName, 0x5000 | NCode, DecodeLDIcc_LDFcc);
1515
    as_snprintf(InstName, sizeof(InstName), "LDF%s", NName);
1516
    AddInstTable(InstTable, InstName, 0x4000 | NCode, DecodeLDIcc_LDFcc);
1517
  }
1518
  as_snprintf(InstName, sizeof(InstName), "B%s", NName);
1519
  AddInstTable(InstTable, InstName, 0x0000 | NCode, DecodeBcc);
1520
  as_snprintf(InstName, sizeof(InstName), "B%sD", NName);
1521
  AddInstTable(InstTable, InstName, 0x0100 | NCode, DecodeBcc);
1522
  as_snprintf(InstName, sizeof(InstName), "B%sAF", NName);
1523
  AddInstTable(InstTable, InstName, 0x0580 | NCode, DecodeBcc);
1524
  as_snprintf(InstName, sizeof(InstName), "B%sAT", NName);
1525
  AddInstTable(InstTable, InstName, 0x0380 | NCode, DecodeBcc);
1526
  if (*NName)
1527
  {
1528
    as_snprintf(InstName, sizeof(InstName), "LAJ%s", NName);
1529
    AddInstTable(InstTable, InstName, 0x4180 | NCode, DecodeBcc);
1530
    as_snprintf(InstName, sizeof(InstName), "CALL%s", NName);
1531
    AddInstTable(InstTable, InstName, NCode, DecodeCALLcc);
1532
  }
1533
  as_snprintf(InstName, sizeof(InstName), "DB%s", NName);
1534
  AddInstTable(InstTable, InstName, NCode, DecodeDBcc);
1535
  as_snprintf(InstName, sizeof(InstName), "DB%sD", NName);
1536
  AddInstTable(InstTable, InstName, 0x100 | NCode, DecodeDBcc);
1537
  as_snprintf(InstName, sizeof(InstName), "RETI%s", NName);
1538
  AddInstTable(InstTable, InstName, NCode, DecodeRETIcc_RETScc);
1539
  as_snprintf(InstName, sizeof(InstName), "RETI%sD", NName);
1540
  AddInstTable(InstTable, InstName, 0x100 | NCode, DecodeRETIcc_RETScc);
1541
  as_snprintf(InstName, sizeof(InstName), "RETS%s", NName);
1542
  AddInstTable(InstTable, InstName, 0x400 | NCode, DecodeRETIcc_RETScc);
1543
  as_snprintf(InstName, sizeof(InstName), "TRAP%s", NName);
1544
  AddInstTable(InstTable, InstName, NCode, DecodeTRAPcc);
1545
  as_snprintf(InstName, sizeof(InstName), "LAT%s", NName);
1546
  AddInstTable(InstTable, InstName, 0x80 | NCode, DecodeTRAPcc);
1547
}
1548
 
1549
static void AddFixed(const char *NName, LongWord NCode)
1550
{
1551
  order_array_rsv_end(FixedOrders, FixedOrder);
1552
  FixedOrders[InstrZ].Code = NCode;
1553
  AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
1554
}
1555
 
1556
static void AddSing(const char *NName, LongWord NCode, Byte NMask)
1557
{
1558
  order_array_rsv_end(SingOrders, SingOrder);
1559
  SingOrders[InstrZ].Code = NCode;
1560
  SingOrders[InstrZ].Mask = NMask;
1561
  AddInstTable(InstTable, NName, InstrZ++, DecodeSing);
1562
}
1563
 
1564
static void AddGen(const char *NName, CPUVar NMin, Boolean NMay1, Boolean NMay3,
1565
                   Word NCode, Word NCode3,
1566
                   Boolean NOnly, Boolean NSwap, Boolean NImm, Boolean NComm,
1567
                   Byte NMask1, Byte NMask3,
1568
                   Byte C20, Byte C21, Byte C22, Byte C23, Byte C24,
1569
                   Byte C25, Byte C26, Byte C27, Byte C30, Byte C31,
1570
                   Byte C32, Byte C33, Byte C34, Byte C35, Byte C36,
1571
                   Byte C37)
1572
{
1573
  char NName3[30];
1574
  size_t z;
1575
 
1576
  order_array_rsv_end(GenOrders, GenOrder);
1577
 
1578
  as_snprintf(NName3, sizeof(NName3), "%s3", NName);
1579
 
1580
  GenOrders[InstrZ].ParIndex =
1581
  GenOrders[InstrZ].ParIndex3 = -1;
1582
  for (z = 0; z < as_array_size(ParOrders); z++)
1583
  {
1584
    if (!strcmp(ParOrders[z], NName))
1585
      GenOrders[InstrZ].ParIndex = z;
1586
    if (!strcmp(ParOrders[z], NName3))
1587
      GenOrders[InstrZ].ParIndex3 = z;
1588
  }
1589
 
1590
  GenOrders[InstrZ].NameLen = strlen(NName);
1591
  GenOrders[InstrZ].MinCPU = NMin;
1592
  GenOrders[InstrZ].May1 = NMay1; GenOrders[InstrZ].May3 = NMay3;
1593
  GenOrders[InstrZ].Code = NCode; GenOrders[InstrZ].Code3 = NCode3;
1594
  GenOrders[InstrZ].OnlyMem = NOnly; GenOrders[InstrZ].SwapOps = NSwap;
1595
  GenOrders[InstrZ].ImmFloat = NImm;
1596
  GenOrders[InstrZ].Commutative = NComm;
1597
  GenOrders[InstrZ].ParMask = NMask1; GenOrders[InstrZ].Par3Mask = NMask3;
1598
  GenOrders[InstrZ].PCodes[0] = C20;  GenOrders[InstrZ].PCodes[1] = C21;
1599
  GenOrders[InstrZ].PCodes[2] = C22;  GenOrders[InstrZ].PCodes[3] = C23;
1600
  GenOrders[InstrZ].PCodes[4] = C24;  GenOrders[InstrZ].PCodes[5] = C25;
1601
  GenOrders[InstrZ].PCodes[6] = C26;  GenOrders[InstrZ].PCodes[7] = C27;
1602
  GenOrders[InstrZ].P3Codes[0] = C30; GenOrders[InstrZ].P3Codes[1] = C31;
1603
  GenOrders[InstrZ].P3Codes[2] = C32; GenOrders[InstrZ].P3Codes[3] = C33;
1604
  GenOrders[InstrZ].P3Codes[4] = C34; GenOrders[InstrZ].P3Codes[5] = C35;
1605
  GenOrders[InstrZ].P3Codes[6] = C36; GenOrders[InstrZ].P3Codes[7] = C37;
1606
 
1607
  AddInstTable(InstTable, NName, InstrZ, DecodeGen);
1608
  AddInstTable(InstTable, NName3, InstrZ | 0x8000, DecodeGen);
1609
  InstrZ++;
1610
}
1611
 
1612
static void InitFields(void)
1613
{
1614
  InstTable = CreateInstTable(607);
1615
  SetDynamicInstTable(InstTable);
1616
 
1617
  AddInstTable(InstTable, "NOP", 0, DecodeNOP);
1618
  AddInstTable(InstTable, "LDP", 0, DecodeLDP);
1619
  AddInstTable(InstTable, "RPTB", 0, Is4x() ? DecodeRPTB_C4x : DecodeRPTB_C3x);
1620
  AddInstTable(InstTable, "BR"  , 0x0160, Is4x() ? DecodeBR_BRD_CALL_LAJ_C4x : DecodeBR_BRD_CALL_C3x);
1621
  AddInstTable(InstTable, "BRD" , 0x0361, Is4x() ? DecodeBR_BRD_CALL_LAJ_C4x : DecodeBR_BRD_CALL_C3x);
1622
  AddInstTable(InstTable, "CALL", 0x0162, Is4x() ? DecodeBR_BRD_CALL_LAJ_C4x : DecodeBR_BRD_CALL_C3x);
1623
  AddInstTable(InstTable, "LAJ" , 0x0363, Is4x() ? DecodeBR_BRD_CALL_LAJ_C4x : DecodeBR_BRD_CALL_C3x);
1624
  AddTI34xPseudo(InstTable);
1625
 
1626
  AddCondition("U"  , 0x00); AddCondition("LO" , 0x01);
1627
  AddCondition("LS" , 0x02); AddCondition("HI" , 0x03);
1628
  AddCondition("HS" , 0x04); AddCondition("EQ" , 0x05);
1629
  AddCondition("NE" , 0x06); AddCondition("LT" , 0x07);
1630
  AddCondition("LE" , 0x08); AddCondition("GT" , 0x09);
1631
  AddCondition("GE" , 0x0a); AddCondition("Z"  , 0x05);
1632
  AddCondition("NZ" , 0x06); AddCondition("P"  , 0x09);
1633
  AddCondition("N"  , 0x07); AddCondition("NN" , 0x0a);
1634
  AddCondition("NV" , 0x0c); AddCondition("V"  , 0x0d);
1635
  AddCondition("NUF", 0x0e); AddCondition("UF" , 0x0f);
1636
  AddCondition("NC" , 0x04); AddCondition("C"  , 0x01);
1637
  AddCondition("NLV", 0x10); AddCondition("LV" , 0x11);
1638
  AddCondition("NLUF", 0x12);AddCondition("LUF", 0x13);
1639
  AddCondition("ZUF", 0x14); AddCondition(""   , 0x00);
1640
 
1641
  InstrZ = 0;
1642
  AddFixed("IDLE", 0x06000000); AddFixed("SIGI", 0x16000000);
1643
  AddFixed("SWI" , 0x66000000);
1644
 
1645
  InstrZ = 0;
1646
  AddInstTable(InstTable, "ROL" , InstrZ++, DecodeRot);
1647
  AddInstTable(InstTable, "ROLC", InstrZ++, DecodeRot);
1648
  AddInstTable(InstTable, "ROR" , InstrZ++, DecodeRot);
1649
  AddInstTable(InstTable, "RORC", InstrZ++, DecodeRot);
1650
 
1651
  InstrZ = 0;
1652
  AddInstTable(InstTable, "POP"  , InstrZ++, DecodeStk);
1653
  AddInstTable(InstTable, "POPF" , InstrZ++, DecodeStk);
1654
  AddInstTable(InstTable, "PUSH" , InstrZ++, DecodeStk);
1655
  AddInstTable(InstTable, "PUSHF", InstrZ++, DecodeStk);
1656
 
1657
  AddInstTable(InstTable, "LDEP", 0x00ec, DecodeLdExp);
1658
  AddInstTable(InstTable, "LDPE", 0x00ed, DecodeLdExp);
1659
  AddInstTable(InstTable, "LDHI", 0x007f, DecodeRegImm);
1660
  AddInstTable(InstTable, "LDPK", 0x003e, DecodeLDPK);
1661
  AddInstTable(InstTable, "STIK", 0x002a, DecodeSTIK);
1662
 
1663
  InstrZ = 0;
1664
/*        Name      MinCPU    May1   May3   Cd    Cd3   OnlyM  Swap   ImmF   Comm   PM1 PM3     */
1665
  AddGen("ABSF"   , CPU32030, True , False, 0x00, 0xff, False, False, True , False, 4, 0,
1666
         0xff, 0xff, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1667
  AddGen("ABSI"   , CPU32030, True , False, 0x01, 0xff, False, False, False, False, 8, 0,
1668
         0xff, 0xff, 0xff, 0x05, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1669
  AddGen("ADDC"   , CPU32030, False, True , 0x02, 0x00, False, False, False, True,  0, 0,
1670
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1671
  AddGen("ADDF"   , CPU32030, False, True , 0x03, 0x01, False, False, True , True,  0, 4,
1672
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff);
1673
  AddGen("ADDI"   , CPU32030, False, True , 0x04, 0x02, False, False, False, True,  0, 8,
1674
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff);
1675
  AddGen("AND"    , CPU32030, False, True , 0x05, 0x03, False, False, False, True,  0, 8,
1676
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x08, 0xff, 0xff, 0xff, 0xff);
1677
  AddGen("ANDN"   , CPU32030, False, True , 0x06, 0x04, False, False, False, False, 0, 0,
1678
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1679
  AddGen("ASH"    , CPU32030, False, True , 0x07, 0x05, False, False, False, False, 0, 8,
1680
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x09, 0xff, 0xff, 0xff, 0xff);
1681
  AddGen("CMPF"   , CPU32030, False, True , 0x08, 0x06, False, False, True , False, 0, 0,
1682
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1683
  AddGen("CMPI"   , CPU32030, False, True , 0x09, 0x07, False, False, False, False, 0, 0,
1684
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1685
  AddGen("FIX"    , CPU32030, True , False, 0x0a, 0xff, False, False, True , False, 8, 0,
1686
         0xff, 0xff, 0xff, 0x0a, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1687
  AddGen("FLOAT"  , CPU32030, True , False, 0x0b, 0xff, False, False, False, False, 4, 0,
1688
         0xff, 0xff, 0x0b, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1689
  AddGen("FRIEEE" , CPU32040, False, False, 0x38, 0xff, True , False, True , False, 4, 0,
1690
         0xff, 0xff, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1691
  AddGen("LB0"    , CPU32040, False, False,0x160, 0xff, False, False, False, False, 0, 0,
1692
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1693
  AddGen("LB1"    , CPU32040, False, False,0x161, 0xff, False, False, False, False, 0, 0,
1694
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1695
  AddGen("LB2"    , CPU32040, False, False,0x162, 0xff, False, False, False, False, 0, 0,
1696
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1697
  AddGen("LB3"    , CPU32040, False, False,0x163, 0xff, False, False, False, False, 0, 0,
1698
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1699
  AddGen("LBU0"   , CPU32040, False, False,0x164, 0xff, False, False, False, False, 0, 0,
1700
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1701
  AddGen("LBU1"   , CPU32040, False, False,0x165, 0xff, False, False, False, False, 0, 0,
1702
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1703
  AddGen("LBU2"   , CPU32040, False, False,0x166, 0xff, False, False, False, False, 0, 0,
1704
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1705
  AddGen("LBU3"   , CPU32040, False, False,0x167, 0xff, False, False, False, False, 0, 0,
1706
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1707
  AddGen("LH0"    , CPU32040, False, False,0x174, 0xff, False, False, False, False, 0, 0,
1708
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1709
  AddGen("LH1"    , CPU32040, False, False,0x175, 0xff, False, False, False, False, 0, 0,
1710
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1711
  AddGen("LHU0"   , CPU32040, False, False,0x176, 0xff, False, False, False, False, 0, 0,
1712
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1713
  AddGen("LHU1"   , CPU32040, False, False,0x177, 0xff, False, False, False, False, 0, 0,
1714
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1715
  AddGen("LDE"    , CPU32030, False, False, 0x0d, 0xff, False, False, True , False, 0, 0,
1716
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1717
  AddGen("LDF"    , CPU32030, False, False, 0x0e, 0xff, False, False, True , False, 5, 0,
1718
         0x02, 0xff, 0x0c, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1719
  AddGen("LDFI"   , CPU32030, False, False, 0x0f, 0xff, True , False, True , False, 0, 0,
1720
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1721
  AddGen("LDI"    , CPU32030, False, False, 0x10, 0xff, False, False, False, False, 10, 0,
1722
         0xff, 0x03, 0xff, 0x0d, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1723
  AddGen("LDII"   , CPU32030, False, False, 0x11, 0xff, True , False, False, False, 0, 0,
1724
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1725
  AddGen("LDM"    , CPU32030, False, False, 0x12, 0xff, False, False, True , False, 0, 0,
1726
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1727
  AddGen("LSH"    , CPU32030, False, True , 0x13, 0x08, False, False, False, False, 0, 8,
1728
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1729
  AddGen("LWL0"   , CPU32040, False, False,0x168, 0xff, False, False, False, False, 0, 0,
1730
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1731
  AddGen("LWL1"   , CPU32040, False, False,0x169, 0xff, False, False, False, False, 0, 0,
1732
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1733
  AddGen("LWL2"   , CPU32040, False, False,0x16a, 0xff, False, False, False, False, 0, 0,
1734
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1735
  AddGen("LWL3"   , CPU32040, False, False,0x16b, 0xff, False, False, False, False, 0, 0,
1736
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1737
  AddGen("LWR0"   , CPU32040, False, False,0x16c, 0xff, False, False, False, False, 0, 0,
1738
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1739
  AddGen("LWR1"   , CPU32040, False, False,0x16d, 0xff, False, False, False, False, 0, 0,
1740
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1741
  AddGen("LWR2"   , CPU32040, False, False,0x16e, 0xff, False, False, False, False, 0, 0,
1742
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1743
  AddGen("LWR3"   , CPU32040, False, False,0x16f, 0xff, False, False, False, False, 0, 0,
1744
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1745
  AddGen("MB0"    , CPU32040, False, False,0x170, 0xff, False, False, False, False, 0, 0,
1746
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1747
  AddGen("MB1"    , CPU32040, False, False,0x171, 0xff, False, False, False, False, 0, 0,
1748
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1749
  AddGen("MB2"    , CPU32040, False, False,0x172, 0xff, False, False, False, False, 0, 0,
1750
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1751
  AddGen("MB3"    , CPU32040, False, False,0x173, 0xff, False, False, False, False, 0, 0,
1752
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1753
  AddGen("MH0"    , CPU32040, False, False,0x178, 0xff, False, False, False, False, 0, 0,
1754
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1755
  AddGen("MH1"    , CPU32040, False, False,0x179, 0xff, False, False, False, False, 0, 0,
1756
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff);
1757
  AddGen("MPYF"   , CPU32030, False, True , 0x14, 0x09, False, False, True , True,  0,52,
1758
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0x0f, 0xff, 0x00, 0x01, 0xff, 0xff);
1759
  AddGen("MPYI"   , CPU32030, False, True , 0x15, 0x0a, False, False, False, True,  0,200,
1760
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x10, 0xff, 0xff, 0x02, 0x03);
1761
  AddGen("MPYSHI" , CPU32040, False, True , 0x3b, 0x11, False, False, False, True,  0, 0,
1762
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1763
  AddGen("MPYUHI" , CPU32040, False, True , 0x3c, 0x12, False, False, False, True,  0, 0,
1764
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1765
  AddGen("NEGB"   , CPU32030, True , False, 0x16, 0xff, False, False, False, False, 0, 0,
1766
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1767
  AddGen("NEGF"   , CPU32030, True , False, 0x17, 0xff, False, False, True , False, 4, 0,
1768
         0xff, 0xff, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1769
  AddGen("NEGI"   , CPU32030, True , False, 0x18, 0xff, False, False, False, False, 8, 0,
1770
         0xff, 0xff, 0xff, 0x12, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1771
  AddGen("NORM"   , CPU32030, True , False, 0x1a, 0xff, False, False, True , False, 0, 0,
1772
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1773
  AddGen("NOT"    , CPU32030, True , False, 0x1b, 0xff, False, False, False, False, 8, 0,
1774
         0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1775
  AddGen("OR"     , CPU32030, False, True , 0x20, 0x0b, False, False, False, True,  0, 8,
1776
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x14, 0xff, 0xff, 0xff, 0xff);
1777
  AddGen("RCPF"   , CPU32040, False, False, 0x3a, 0xff, False, False, True , False, 0, 0,
1778
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x14, 0xff, 0xff, 0xff, 0xff);
1779
  AddGen("RND"    , CPU32030, True , False, 0x22, 0xff, False, False, True , False, 0, 0,
1780
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1781
  AddGen("RSQRF"  , CPU32040, False, False, 0x39, 0xff, False, False, True , False, 0, 0,
1782
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x14, 0xff, 0xff, 0xff, 0xff);
1783
  AddGen("STF"    , CPU32030, False, False, 0x28, 0xff, True , True , True , False, 4, 0,
1784
         0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1785
  AddGen("STFI"   , CPU32030, False, False, 0x29, 0xff, True , True , True , False, 0, 0,
1786
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1787
  AddGen("STI"    , CPU32030, False, False, 0x2a, 0xff, True , True , False, False, 8, 0,
1788
         0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1789
  AddGen("STII"   , CPU32030, False, False, 0x2b, 0xff, True , True , False, False, 0, 0,
1790
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1791
  AddGen("SUBB"   , CPU32030, False, True , 0x2d, 0x0c, False, False, False, False, 0, 0,
1792
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1793
  AddGen("SUBC"   , CPU32030, False, False, 0x2e, 0xff, False, False, False, False, 0, 0,
1794
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1795
  AddGen("SUBF"   , CPU32030, False, True , 0x2f, 0x0d, False, False, True , False, 0, 4,
1796
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff);
1797
  AddGen("SUBI"   , CPU32030, False, True , 0x30, 0x0e, False, False, False, False, 0, 8,
1798
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x16, 0xff, 0xff, 0xff, 0xff);
1799
  AddGen("SUBRB"  , CPU32030, False, False, 0x31, 0xff, False, False, False, False, 0, 0,
1800
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1801
  AddGen("SUBRF"  , CPU32030, False, False, 0x32, 0xff, False, False, True , False, 0, 0,
1802
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1803
  AddGen("SUBRI"  , CPU32030, False, False, 0x33, 0xff, False, False, False, False, 0, 0,
1804
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1805
  AddGen("TOIEEE" , CPU32040, False, False, 0x37, 0xff, False, False, True , False, 4, 0,
1806
         0xff, 0xff, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1807
  AddGen("TSTB"   , CPU32030, False, True , 0x34, 0x0f, False, False, False, False, 0, 0,
1808
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
1809
  AddGen("XOR"    , CPU32030, False, True , 0x35, 0x10, False, False, False, True,  0, 8,
1810
         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0xff, 0x17, 0xff, 0xff, 0xff, 0xff);
1811
 
1812
  InstrZ = 0;
1813
  AddSing("IACK", 0x1b000000, 6);
1814
  AddSing("RPTS", 0x139b0000, 15);
1815
 
1816
  AddInstTable(InstTable, "LDA", 0x03d, DecodeLDA);
1817
}
1818
 
1819
static void DeinitFields(void)
1820
{
1821
  DestroyInstTable(InstTable);
1822
 
1823
  order_array_free(FixedOrders);
1824
  order_array_free(GenOrders);
1825
  order_array_free(SingOrders);
1826
}
1827
 
1828
static void MakeCode_3203X(void)
1829
{
1830
  ThisPar = (!strcmp(LabPart.str.p_str, "||"));
1831
  if ((strlen(OpPart.str.p_str) > 2) && (!strncmp(OpPart.str.p_str, "||", 2)))
1832
  {
1833
    ThisPar = True;
1834
    strmov(OpPart.str.p_str, OpPart.str.p_str + 2);
1835
  }
1836
  if ((!NextPar) && (ThisPar))
1837
  {
1838
    WrError(ErrNum_ParNotPossible);
1839
    return;
1840
  }
1841
  ARs = 0;
1842
 
1843
  /* zu ignorierendes */
1844
 
1845
  if (Memo(""))
1846
    return;
1847
 
1848
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
1849
  {
1850
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1851
    NextPar = False;
1852
  }
1853
}
1854
 
1855
static void InitCode_3203x(void)
1856
{
1857
  DPValue = 0;
1858
}
1859
 
1860
static Boolean IsDef_3203X(void)
1861
{
1862
  return (!strcmp(LabPart.str.p_str, "||"));
1863
}
1864
 
1865
static void SwitchFrom_3203X(void)
1866
{
1867
  DeinitFields();
1868
}
1869
 
1870
static void SwitchTo_3203X(void)
1871
{
1872
#define ASSUME3203Count sizeof(ASSUME3203s) / sizeof(*ASSUME3203s)
1873
  static ASSUMERec ASSUME3203s[] =
1874
  {
1875
    { "DP", &DPValue, -1, 0xff, 0x100, NULL }
1876
  };
1877
  const TFamilyDescr *pDescr;
1878
 
1879
  pDescr = FindFamilyByName("TMS320C3x/C4x");
1880
 
1881
  TurnWords = False;
1882
  SetIntConstMode(eIntConstModeIntel);
1883
 
1884
  PCSymbol = "$";
1885
  HeaderID = pDescr->Id;
1886
  NOPCode = 0x0c800000;
1887
  DivideChars = ",";
1888
  HasAttrs = False;
1889
 
1890
  ValidSegs = 1 << SegCode;
1891
  Grans[SegCode] = 4; ListGrans[SegCode] = 4; SegInits[SegCode] = 0;
1892
  if (MomCPU == CPU32040)
1893
  {
1894
    SegLimits[SegCode] = 0xfffffffful;
1895
    CxxRegs = C4XRegs;
1896
  }
1897
  else if (MomCPU == CPU32044)
1898
  {
1899
    SegLimits[SegCode] = 0x1ffffful;
1900
    CxxRegs = C4XRegs;
1901
  }
1902
  else /* C3x */
1903
  {
1904
    SegLimits[SegCode] = 0xfffffful;
1905
    CxxRegs = C3XRegs;
1906
  }
1907
 
1908
  onoff_packing_add(True);
1909
 
1910
  pASSUMERecs = ASSUME3203s;
1911
  ASSUMERecCnt = ASSUME3203Count;
1912
 
1913
  MakeCode = MakeCode_3203X;
1914
  IsDef = IsDef_3203X;
1915
  SwitchFrom = SwitchFrom_3203X;
1916
  InitFields();
1917
  NextPar = False;
1918
}
1919
 
1920
void code3203x_init(void)
1921
{
1922
  CPU32030 = AddCPU("320C30", SwitchTo_3203X);
1923
  CPU32031 = AddCPU("320C31", SwitchTo_3203X);
1924
  CPU32040 = AddCPU("320C40", SwitchTo_3203X);
1925
  CPU32044 = AddCPU("320C44", SwitchTo_3203X);
1926
 
1927
  AddInitPassProc(InitCode_3203x);
1928
}