Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* coderx.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Codegenerator Renesas RX                                                  */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <ctype.h>
13
#include <string.h>
14
 
15
#include "nls.h"
16
#include "strutil.h"
17
#include "chunks.h"
18
#include "asmdef.h"
19
#include "asmsub.h"
20
#include "asmpars.h"
21
#include "asmitree.h"
22
#include "codevars.h"
23
#include "codepseudo.h"
24
#include "headids.h"
25
#include "errmsg.h"
26
#include "ieeefloat.h"
27
#include "onoff_common.h"
28
#include "intpseudo.h"
29
#include "be_le.h"
30
 
31
#include "coderx.h"
32
 
33
/*---------------------------------------------------------------------------*/
34
 
35
/* Define this to use Renesas Assembler like pseudo instructions */
36
#define COMPAT
37
 
38
/*---------------------------------------------------------------------------*/
39
 
40
typedef enum
41
{
42
        eRn,
43
        eDRn,
44
        eDRHn,
45
        eDRLn,
46
        eDCRn
47
} tRegType;
48
 
49
typedef enum
50
{
51
        eRXv1,
52
        eRXv2,
53
        eRXv3
54
} tInstSet;
55
 
56
typedef struct
57
{
58
        char Name[7];
59
        tInstSet InstSet;
60
        Boolean hasFloat;
61
        Boolean hasDouble;
62
        Word RegBank;
63
        Boolean hasMVTIPL;
64
} tCPUProps;
65
 
66
/*---------------------------------------------------------------------------*/
67
 
68
static const tCPUProps *pCurrCPUProps;
69
 
70
static tStrComp Temp1;
71
static tStrComp Temp2;
72
 
73
/*---------------------------------------------------------------------------*/
74
 
75
static Boolean ChkNoAttr(void)
76
{
77
        if (AttrPart.str.p_str[0])
78
        {
79
                WrError(ErrNum_UseLessAttr);
80
                return False;
81
        }
82
 
83
        return True;
84
}
85
 
86
static Boolean CheckSup(void)
87
{
88
        if (SupAllowed) return True;
89
 
90
        WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
91
        return False;
92
}
93
 
94
static Boolean CheckV2(void)
95
{
96
        if (pCurrCPUProps->InstSet >= eRXv2) return True;
97
 
98
        WrError(ErrNum_InstructionNotSupported);
99
        return False;
100
}
101
 
102
static Boolean CheckV3(void)
103
{
104
        if (pCurrCPUProps->InstSet >= eRXv3) return True;
105
 
106
        WrError(ErrNum_InstructionNotSupported);
107
        return False;
108
}
109
 
110
static Boolean CheckFloat(void)
111
{
112
        if (pCurrCPUProps->hasFloat) return True;
113
 
114
        WrError(ErrNum_FPUNotEnabled);
115
        return False;
116
}
117
 
118
static Boolean CheckDouble(void)
119
{
120
        if (pCurrCPUProps->hasDouble) return True;
121
 
122
        WrError(ErrNum_FPUNotEnabled);
123
        return False;
124
}
125
 
126
static const char *DCReg[] = {
127
        "DPSW",
128
        "DCMR",
129
        "DECNT",
130
        "DEPC"
131
};
132
 
133
static Boolean DecodeReg(const tStrComp *pArg, Byte *pResult, tRegType type)
134
{
135
        const char *str = pArg->str.p_str;
136
        const int len = strlen(str);
137
        int i;
138
        int num = 16;
139
 
140
        switch (type)
141
        {
142
        case eRn:
143
                if (as_strncasecmp(str, "R", 1)) return False;
144
                i = 1;
145
                break;
146
        case eDRn:
147
                if (as_strncasecmp(str, "DR", 2)) return False;
148
                i = 2;
149
                break;
150
        case eDRHn:
151
                if (as_strncasecmp(str, "DRH", 3)) return False;
152
                i = 3;
153
                break;
154
        case eDRLn:
155
                if (as_strncasecmp(str, "DRL", 3)) return False;
156
                i = 3;
157
                break;
158
        case eDCRn:
159
                for (i = 0; i < 4; i++)
160
                {
161
                        if (!as_strcasecmp(str, DCReg[i]))
162
                        {
163
                                *pResult = i;
164
                                return True;
165
                        }
166
                }
167
                if (as_strncasecmp(str, "DCR", 3)) return False;
168
                i = 3;
169
                num = 4;
170
                break;
171
        default:
172
                return False;
173
        }
174
        *pResult = 0;
175
        for (; i < len; i++)
176
        {
177
                if (!isdigit(str[i])) return False;
178
                *pResult = *pResult * 10 + (str[i] - '0');
179
        }
180
 
181
        return *pResult < num;
182
}
183
 
184
static Boolean DecodeImm(const tStrComp *pArg, LongInt *pResult, tSymbolFlags *pFlags)
185
{
186
        const char *str = pArg->str.p_str;
187
        tStrComp ImmArg;
188
        Boolean ValOK;
189
        tSymbolFlags flags;
190
 
191
        if (str[0] != '#') return False;
192
 
193
        StrCompRefRight(&ImmArg, pArg, 1);
194
        *pResult = EvalStrIntExpressionWithFlags(&ImmArg, Int32, &ValOK, &flags);
195
        if (pFlags) *pFlags = flags;
196
 
197
        return ValOK;
198
}
199
 
200
static Byte ImmSize32(LongInt value, tSymbolFlags flags)
201
{
202
        if (mFirstPassUnknown(flags)) return 0x00;      /* Temporarily return maximum size */
203
 
204
        if ((value & 0xFFFFFF80) == 0xFFFFFF80 ||
205
                (value & 0xFFFFFF80) == 0x00000000) return 0x01;        /* SIMM:8 */
206
 
207
        if ((value & 0xFFFF8000) == 0xFFFF8000 ||
208
                (value & 0xFFFF8000) == 0x00000000) return 0x02;        /* SIMM:16 */
209
 
210
        if ((value & 0xFF800000) == 0xFF800000 ||
211
                (value & 0xFF800000) == 0x00000000) return 0x03;        /* SIMM:24 */
212
 
213
        return 0x00;    /* IMM:32 */
214
}
215
 
216
static Byte ImmSize16(LongInt value, tSymbolFlags flags)
217
{
218
        if (mFirstPassUnknown(flags)) return 0x02;      /* Temporarily return maximum size */
219
 
220
        if ((value & 0xFFFFFF80) == 0xFFFFFF80 ||
221
                (value & 0xFFFFFF80) == 0x00000000) return 0x01;        /* SIMM:8 */
222
 
223
        return 0x02;    /* IMM:16 */
224
}
225
 
226
static int ImmOut(int pos, Byte size, LongInt imm)
227
{
228
        int i;
229
 
230
        if (size == 0x00) size = 4;
231
        for (i = 0; i < size; i++)
232
        {
233
                BAsmCode[pos+i] = imm & 0xFF;
234
                imm >>= 8;
235
        }
236
        return pos + size;
237
}
238
 
239
static Boolean DecodeIndirectADC(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags)
240
{
241
        const char *str = pArg->str.p_str;
242
        const int len = strlen(str);
243
        int pos;
244
        Boolean ValOK;
245
 
246
        if (str[len-1] != ']') return False;
247
        for (pos = len - 2; pos >= 0; pos--)
248
        {
249
                if (str[pos] == '[') break;
250
        }
251
        if (pos < 0) return False;
252
 
253
        StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 2);
254
        if (!DecodeReg(&Temp1, reg, eRn)) return False;
255
 
256
        if (pos == 0)
257
        {
258
                *flags = eSymbolFlag_None;
259
                *disp = 0;
260
                return True;
261
        }
262
 
263
        StrCompCopySub(&Temp1, pArg, 0, pos);
264
        *disp = EvalStrIntExpressionWithFlags(&Temp1, UInt20, &ValOK, flags);
265
 
266
        return ValOK;
267
}
268
 
269
static Byte DispSize(LongInt disp, tSymbolFlags flags, Byte scale)
270
{
271
        Byte size = 0;
272
        Byte mask = scale - 1;
273
 
274
  UNUSED(flags);
275
 
276
        if (disp & mask)
277
        {
278
                WrStrErrorPos(ErrNum_NotAligned, &ArgStr[1]);
279
                return 0;
280
        }
281
        disp /= scale;
282
 
283
        if (disp == 0) size = 0x00;
284
        else if (disp < 0) size = 0xFF;
285
        else if (disp < 256) size = 0x01;
286
        else if (disp < 65536) size = 0x02;
287
        else size = 0xFF;
288
 
289
        return size;
290
}
291
 
292
static int DispOut(int pos, Byte size, LongInt disp, Byte scale)
293
{
294
        int i;
295
 
296
        disp /= scale;
297
 
298
        if (size > 0x02) size = 0x00;
299
        for (i = 0; i < size; i++ )
300
        {
301
                BAsmCode[pos+i] = disp & 0xFF;
302
                disp >>= 8;
303
        }
304
        return  pos + size;
305
}
306
 
307
static Boolean DecodeIndirectADD(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags, Byte *memex, Byte *scale)
308
{
309
        const char *str = pArg->str.p_str;
310
        const int len = strlen(str);
311
 
312
        if (len > 2 && str[len-2] == '.')
313
        {
314
                switch (as_toupper(str[len-1]))
315
                {
316
                case 'B':
317
                        *memex = 0x00;
318
                        *scale = 1;
319
                        break;
320
                case 'W':
321
                        *memex = 0x01;
322
                        *scale = 2;
323
                        break;
324
                case 'L':
325
                        *memex = 0x02;
326
                        *scale = 4;
327
                        break;
328
                default:
329
                        return False;
330
                }
331
                StrCompCopySub(&Temp2, pArg, 0, len - 2);
332
                pArg = &Temp2;
333
        }
334
        else if (len > 3 && str[len-3] == '.' && as_toupper(str[len-2]) == 'U')
335
        {
336
                switch (as_toupper(str[len-1]))
337
                {
338
                case 'B':
339
                        *memex = 0x80;
340
                        *scale = 1;
341
                        break;
342
                case 'W':
343
                        *memex = 0x03;
344
                        *scale = 2;
345
                        break;
346
                default:
347
                        return False;
348
                }
349
                StrCompCopySub(&Temp2, pArg, 0, len - 3);
350
                pArg = &Temp2;
351
        }
352
 
353
        return DecodeIndirectADC(pArg, reg, disp, flags);
354
}
355
 
356
static Boolean DecodeFloat(const tStrComp *pArg, LongInt *pResult)
357
{
358
        const char *str = pArg->str.p_str;
359
        tStrComp ImmArg;
360
        TempResult temp;
361
  Boolean Result = True;
362
 
363
        if (str[0] != '#') return False;
364
 
365
        StrCompRefRight(&ImmArg, pArg, 1);
366
  as_tempres_ini(&temp);
367
        EvalStrExpression(&ImmArg, &temp);
368
        switch (temp.Typ)
369
        {
370
        case TempInt:
371
                *pResult = temp.Contents.Int;
372
                break;
373
        case TempFloat:
374
                as_float_2_ieee4(temp.Contents.Float, (unsigned char *)pResult, False);
375
    /* TODO: rework this - we should better pass in a byte array as pResult */
376
    if (HostBigEndian)
377
      DSwap(pResult, 4);
378
                break;
379
        default:
380
                Result = False;
381
        }
382
  as_tempres_free(&temp);
383
 
384
        return Result;
385
}
386
 
387
static Boolean DecodeIndirectL(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags)
388
{
389
        Boolean result;
390
        Byte memex = 0x02;      /* L */
391
        Byte scale;
392
 
393
        result = DecodeIndirectADD(pArg, reg, disp, flags, &memex, &scale);
394
 
395
        if (result && memex != 0x02) result = False;
396
 
397
        return result;
398
}
399
 
400
static tSymbolSize DecodeAttrSize(void)
401
{
402
        switch (strlen(AttrPart.str.p_str))
403
        {
404
                case 0:
405
                        WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
406
                        return eSymbolSizeUnknown;
407
                case 1:
408
                        switch (AttrPart.str.p_str[0])
409
                        {
410
                                case 'B':
411
                                        return eSymbolSize8Bit;
412
                                case 'W':
413
                                        return eSymbolSize16Bit;
414
                                case 'L':
415
                                        return eSymbolSize32Bit;
416
                                default:
417
                                        WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
418
                                        return eSymbolSizeUnknown;
419
                        }
420
                default:
421
                        WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart);
422
                        return eSymbolSizeUnknown;
423
                }
424
}
425
 
426
static Boolean DecodeRelative(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags)
427
{       /* dsp:5[Rn] (R0-R7) */
428
        const char *str = pArg->str.p_str;
429
        const int len = strlen(str);
430
        int pos;
431
        Boolean ValOK;
432
 
433
        if (str[len-1] != ']') return False;
434
        for (pos = len - 2; pos > 0; pos--)
435
        {
436
                if (str[pos] == '[') break;
437
        }
438
        if (pos < 1) return False;
439
 
440
        StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 2);
441
        if (!DecodeReg(&Temp1, reg, eRn)) return False;
442
        if (*reg > 7) return False;
443
 
444
        StrCompCopySub(&Temp1, pArg, 0, pos);
445
        *disp = EvalStrIntExpressionWithFlags(&Temp1, UInt20, &ValOK, flags);
446
 
447
        return ValOK;
448
}
449
 
450
static int Size2Scale(Byte size)
451
{
452
        Byte scale;
453
 
454
        switch (size)
455
        {
456
        case 0x00:      /* B */
457
                scale = 1;
458
                break;
459
        case 0x01:      /* W */
460
                scale = 2;
461
                break;
462
        case 0x02:      /* L */
463
                scale = 4;
464
                break;
465
        default:
466
                return -1;
467
        }
468
 
469
        return scale;
470
}
471
 
472
static Boolean ChkDisp5(Byte size, LongInt disp, tSymbolFlags flags)
473
{
474
        const int scale = Size2Scale(size);
475
 
476
        if (scale < 0) return False;
477
 
478
        if (!mFirstPassUnknown(flags))
479
        {
480
                if (disp & (scale - 1))
481
                {
482
                        WrError(ErrNum_AddrMustBeAligned);
483
                        return False;
484
                }
485
 
486
                if (disp / scale > 31 || disp < 0) return False;
487
        }
488
 
489
        return True;
490
}
491
 
492
static Byte DispSize5(Byte size, LongInt disp)
493
{
494
        const Byte scale = Size2Scale(size);
495
 
496
        return disp / scale;
497
}
498
 
499
static Boolean DecodeIndexed(tStrComp *pArg, Byte *regi, Byte *regb)
500
{       /* [Ri,Rb] */
501
        const char *str = pArg->str.p_str;
502
        const int len = strlen(str);
503
        int pos;
504
 
505
        if (str[0] != '[' || str[len-1] != ']') return False;
506
 
507
        for (pos = 2; pos < len - 2; pos++)
508
        {
509
                if (str[pos] == ',') break;
510
        }
511
 
512
        StrCompCopySub(&Temp1, pArg, 1, pos - 1);
513
        if (!DecodeReg(&Temp1, regi, eRn)) return False;
514
 
515
        StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 2);
516
        if (!DecodeReg(&Temp1, regb, eRn)) return False;
517
 
518
        return True;
519
}
520
 
521
static Boolean DecodeIncDec(tStrComp *pArg, Byte *reg, Byte *id)
522
{       /* [Rn+] / [-Rn]] */
523
        const char *str = pArg->str.p_str;
524
        const int len = strlen(str);
525
 
526
        if (len < 5) return False;
527
        if (str[0] != '[' || str[len-1] != ']') return False;
528
 
529
        if (str[len-2] == '+')
530
        {
531
                *id = 0x00;
532
                StrCompCopySub(&Temp1, pArg, 1, len - 3);
533
        }
534
        else if (str[1] == '-')
535
        {
536
                *id = 0x01;
537
                StrCompCopySub(&Temp1, pArg, 2, len - 3);
538
        }
539
        else return False;
540
 
541
        return DecodeReg(&Temp1, reg, eRn);
542
}
543
 
544
static Boolean DecodeRegRange(tStrComp *pArg, Byte *range)
545
{
546
        const char *str = pArg->str.p_str;
547
        const int len = strlen(str);
548
        Byte reg1;
549
        Byte reg2;
550
        int pos;
551
 
552
        if (len < 5) return False;
553
        for (pos = 2; pos < len - 2; pos++)
554
        {
555
                if (str[pos] == '-') break;
556
        }
557
        if (pos >= len - 2) return False;
558
 
559
        StrCompCopySub(&Temp1, pArg, 0, pos);
560
        if (!DecodeReg(&Temp1, &reg1, eRn)) return False;
561
 
562
        StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 1);
563
        if (!DecodeReg(&Temp1, &reg2, eRn)) return False;
564
 
565
        if (reg1 == 0 || reg1 >= reg2) return False;
566
 
567
        *range = (reg1 << 4) | reg2;
568
        return True;
569
}
570
 
571
static Boolean DecodeIndirect(tStrComp *pArg, Byte *reg)
572
{
573
        const char *str = pArg->str.p_str;
574
        const int len = strlen(str);
575
 
576
        if (str[0] != '[') return False;
577
        if (str[len-1] != ']') return False;
578
 
579
        StrCompCopySub(&Temp1, pArg, 1, len - 2);
580
        if (!DecodeReg(&Temp1, reg, eRn)) return False;
581
 
582
        return True;
583
}
584
 
585
static Boolean DecodeAcc(tStrComp *pArg, Byte *acc)
586
{
587
        const char *str = pArg->str.p_str;
588
        const int len = strlen(str);
589
 
590
        if (len != 2) return False;
591
        if (as_toupper(str[0]) != 'A') return False;
592
        if (str[1] != '0' && str[1] != '1') return False;
593
 
594
        *acc = str[1] - '0';
595
        return True;
596
}
597
 
598
static Boolean DecodeAttrDouble(Byte *size)
599
{
600
        if (strlen(AttrPart.str.p_str) != 1)
601
        {
602
                WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart);
603
                return False;
604
        }
605
        switch (as_toupper(AttrPart.str.p_str[0]))
606
        {
607
        case 'L':
608
                *size = 0;
609
                break;
610
        case 'D':
611
                *size = 1;
612
                break;
613
        default:
614
                WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
615
                return False;
616
        }
617
 
618
        return True;
619
}
620
 
621
/*---------------------------------------------------------------------------*/
622
 
623
static void DecodeABS(Word Index)
624
{
625
        if (!ChkNoAttr()) return;
626
        if (!ChkArgCnt(1,2)) return;
627
 
628
        if (ArgCnt == 1)
629
        {
630
                Byte reg;
631
 
632
                if (!DecodeReg(&ArgStr[1], &reg, eRn))
633
                {
634
                        WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
635
                        return;
636
                }
637
 
638
                BAsmCode[0] = 0x7E;
639
                BAsmCode[1] = (Index >> 8) | reg;
640
                CodeLen = 2;
641
        }
642
        else
643
        {
644
                Byte regs;
645
                Byte regd;
646
 
647
                if (!DecodeReg(&ArgStr[1], &regs, eRn))
648
                {
649
                        WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
650
                        return;
651
                }
652
                if (!DecodeReg(&ArgStr[2], &regd, eRn))
653
                {
654
                        WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
655
                        return;
656
                }
657
 
658
                BAsmCode[0] = 0xFC;
659
                BAsmCode[1] = Index & 0xFF;
660
                BAsmCode[2] = (regs << 4) | regd;
661
                CodeLen = 3;
662
        }
663
}
664
 
665
static void DecodeADC(Word Index)
666
{
667
        Byte regs;
668
        Byte regd;
669
        Byte size;
670
        LongInt imm;
671
        tSymbolFlags flags;
672
        LongInt disp;
673
 
674
        if (!ChkNoAttr()) return;
675
        if (!ChkArgCnt(2,2)) return;
676
 
677
        if (!DecodeReg(&ArgStr[2], &regd, eRn))
678
        {
679
                WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
680
                return;
681
        }
682
 
683
        if ((Index & 0x0800) && DecodeImm(&ArgStr[1], &imm, &flags))    /* ADC only */
684
        {
685
                size = ImmSize32(imm, flags);
686
 
687
                BAsmCode[0] = 0xFD;
688
                BAsmCode[1] = 0x70 | (size << 2);
689
                BAsmCode[2] = 0x20 | regd;
690
                CodeLen = ImmOut(3, size, imm);
691
 
692
                return;
693
        }
694
 
695
        if (DecodeReg(&ArgStr[1], &regs, eRn))
696
        {
697
                BAsmCode[0] = 0xFC;
698
                BAsmCode[1] = 0x03 | (Index >> 8);
699
                BAsmCode[2] = (regs << 4) | regd;
700
                CodeLen = 3;
701
 
702
                return;
703
        }
704
 
705
        if (DecodeIndirectL(&ArgStr[1], &regs, &disp, &flags))
706
        {
707
                if (mFirstPassUnknown(flags)) size = 0x02;
708
                else size = DispSize(disp, flags, 4);
709
 
710
                BAsmCode[0] = 0x06;
711
                BAsmCode[1] = 0xA0 | size;
712
                BAsmCode[2] = Index & 0xFF;
713
                BAsmCode[3] = (regs << 4) | regd;
714
                CodeLen = DispOut(4, size, disp, 4);
715
        }
716
}
717
 
718
static const struct {
719
        Byte OpcImm4;   /* #IMM:4,Rd */
720
        Byte OpcImm1;   /* #IMM:*(,Rs),Rd 1st byte */
721
        Byte OpcImm2;   /* 2nd byte */
722
        Byte Opc2;      /* Rs,Rd / [Rs].UB,Rd */
723
        Byte Opc3;      /* Rs,Rs2,Rd */
724
        Byte Opc4;      /* [Rs],Rd */
725
        Byte flags;     /* 1<<0:, 1<<1:, 1<<2:#UIMM8 1<<3:Rs,Rs,Rd */
726
} OpTabADD[] = {
727
        { 0x62, 0x70, 0x00, 0x48, 0x20, 0x08, 0x0B },   /* ADD */
728
        { 0x64, 0x74, 0x20, 0x50, 0x40, 0x10, 0x09 },   /* AND */
729
        { 0x61, 0x74, 0x00, 0x44, 0,    0x04, 0x05 },   /* CMP */
730
        { 0x63, 0x74, 0x10, 0x4C, 0x30, 0x0C, 0x09 },   /* MUL */
731
        { 0x65, 0x74, 0x30, 0x54, 0x50, 0x14, 0x09 },   /* OR */
732
        { 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x08 },   /* SUB */
733
};
734
 
735
static void DecodeADD(Word Index)
736
{
737
        Byte regs1;
738
        Byte regs2;
739
        Byte regd;
740
        Byte size;
741
        LongInt imm;
742
        tSymbolFlags flags;
743
        LongInt disp;
744
        Byte memex;
745
        Byte scale;
746
 
747
        if (!ChkNoAttr()) return;
748
        if (!ChkArgCnt(2,3)) return;
749
 
750
        if (!DecodeReg(&ArgStr[2], &regs2, eRn))
751
        {
752
                WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
753
                return;
754
        }
755
        if (ArgCnt == 2)
756
                regd = regs2;
757
        else
758
        {
759
                if (!DecodeReg(&ArgStr[3], &regd, eRn))
760
                {
761
                        WrStrErrorPos(ErrNum_InvRegName, &ArgStr[3]);
762
                        return;
763
                }
764
        }
765
 
766
        if (DecodeImm(&ArgStr[1], &imm, &flags))
767
        {
768
                if (ArgCnt == 2 && !mFirstPassUnknown(flags) && imm >= 0 && imm < 16 )
769
                {       /* #UIMM:4 */
770
                        BAsmCode[0] = OpTabADD[Index].OpcImm4;
771
                        BAsmCode[1] = (imm << 4) | regd;
772
                        CodeLen = 2;
773
                        return;
774
                }
775
 
776
                if ((OpTabADD[Index].flags & 0x04) && ArgCnt == 2 &&
777
                        !mFirstPassUnknown(flags) && imm >= 0 && imm < 256)
778
                {       /* #UIMM:8 */
779
                        BAsmCode[0] = 0x75;
780
                        BAsmCode[1] = 0x50 | regd;
781
                        BAsmCode[2] = imm;
782
                        CodeLen = 3;
783
                        return;
784
                }
785
 
786
                if (((OpTabADD[Index].flags & 0x01) && ArgCnt == 2) || (OpTabADD[Index].flags & 0x02))
787
                {       /* #SIMM:* */
788
                        size = ImmSize32(imm, flags);
789
 
790
                        BAsmCode[0] = OpTabADD[Index].OpcImm1 | size;
791
                        if (OpTabADD[Index].flags & 0x02)
792
                                if (ArgCnt == 2)
793
                                        BAsmCode[1] = (regd << 4) | regd;       /* #Imm,Rd */
794
                                else
795
                                        BAsmCode[1] = (regs2 << 4) | regd;      /* #imm,Rs,Rd */
796
                        else
797
                                BAsmCode[1] = OpTabADD[Index].OpcImm2 | regd;
798
                        CodeLen = ImmOut(2, size, imm);
799
                        return;
800
                }
801
        }
802
 
803
        if (DecodeReg(&ArgStr[1], &regs1, eRn))
804
        {       /* Rs */
805
                if (ArgCnt == 2)
806
                {
807
                        BAsmCode[0] = OpTabADD[Index].Opc2 | 0x03;
808
                        BAsmCode[1] = (regs1 << 4) | regd;
809
                        CodeLen = 2;
810
                }
811
                else if (OpTabADD[Index].flags & 0x08)
812
                {
813
                        BAsmCode[0] = 0xFF;
814
                        BAsmCode[1] = OpTabADD[Index].Opc3 | regd;
815
                        BAsmCode[2] = (regs1 << 4) | regs2;
816
                        CodeLen = 3;
817
                }
818
                else WrStrErrorPos(ErrNum_TooManyArgs, &ArgStr[3]);
819
                return;
820
        }
821
 
822
        if (ArgCnt == 2 && DecodeIndirectADD(&ArgStr[1], &regs1, &disp, &flags, &memex, &scale))
823
        {
824
                if (memex == 0x80)
825
                {
826
                        size = DispSize(disp, flags, 1);
827
 
828
                        BAsmCode[0] = OpTabADD[Index].Opc2 | size;
829
                        BAsmCode[1] = (regs1 << 4) | regd;
830
                        CodeLen = DispOut(2, size, disp, 1);
831
                        return;
832
                }
833
 
834
                size = DispSize(disp, flags, scale);
835
 
836
                BAsmCode[0] = 0x06;
837
                BAsmCode[1] = OpTabADD[Index].Opc4 | (memex << 6) | size;
838
                BAsmCode[2] = (regs1 << 4) | regd;
839
                CodeLen = DispOut(3, size, disp, scale);
840
                return;
841
        }
842
 
843
        WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
844
}
845
 
846
static const struct {
847
        Byte OpcIM1;    /* Imm3,[Rd] */
848
        Byte OpcIM2;
849
        Byte OpcRM;             /* Rs,[Rd] / Rs,Rd */
850
        Byte OpcIR;     /* #Imm5,Rd */
851
        Byte flags;
852
} OpTabBCLR[] = {
853
        { 0xF0, 0x08, 0x64, 0x7A, 0x00 },       /* BCLR */
854
        { 0xF0, 0x00, 0x6C, 0,    0x01 },       /* BNOT */
855
        { 0xF0, 0x00, 0x60, 0x78, 0x00 },       /* BSET */
856
        { 0xF4, 0x00, 0x68, 0x7C, 0x00 },       /* BTST */
857
};
858
 
859
static void DecodeBCLR(Word Index)
860
{
861
        Byte regs;
862
        Byte regd;
863
        Byte size;
864
        Byte memex;
865
        Byte scale;
866
        LongInt imm;
867
        LongInt disp;
868
        tSymbolFlags flags;
869
 
870
        if (!ChkNoAttr()) return;
871
        if (!ChkArgCnt(2,2)) return;
872
 
873
        memex = 0;
874
        if (DecodeIndirectADD(&ArgStr[2], &regd, &disp, &flags, &memex, &scale))
875
        {
876
                if (memex)
877
                {
878
                        WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
879
                        return;
880
                }
881
                size = DispSize(disp, flags, 1);
882
                if (size > 0x02){
883
                        WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
884
                        return;
885
                }
886
 
887
                if (DecodeImm(&ArgStr[1], &imm, &flags))
888
                {
889
                        if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 7))
890
                        {
891
                                WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
892
                                return;
893
                        }
894
 
895
                        if (OpTabBCLR[Index].flags & 0x01)
896
                        {       /* BNOT */
897
                                BAsmCode[0] = 0xFC;
898
                                BAsmCode[1] = 0xE0 | (imm << 2) | size;
899
                                BAsmCode[2] = 0x0F | (regd << 4);
900
                                CodeLen = DispOut(3, size, disp, 1);
901
                        }
902
                        else
903
                        {       /* BCLR, BSET, BTST */
904
                                BAsmCode[0] = OpTabBCLR[Index].OpcIM1 | size;
905
                                BAsmCode[1] = OpTabBCLR[Index].OpcIM2 | (regd << 4) | imm;
906
                                CodeLen = DispOut(2, size, disp, 1);
907
                        }
908
                        return;
909
                }
910
                if (DecodeReg(&ArgStr[1], &regs, eRn))
911
                {
912
                        BAsmCode[0] = 0xFC;
913
                        BAsmCode[1] = OpTabBCLR[Index].OpcRM | size;
914
                        BAsmCode[2] = regs | (regd << 4);
915
                        CodeLen = DispOut(3, size, disp, 1);
916
                        return;
917
                }
918
 
919
                WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);         
920
        }
921
        else if (DecodeReg(&ArgStr[2], &regd, eRn))
922
        {
923
                if (DecodeImm(&ArgStr[1], &imm, &flags))
924
                {
925
                        if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 31))
926
                        {
927
                                WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
928
                                return;
929
                        }
930
 
931
                        if (OpTabBCLR[Index].flags & 0x01)
932
                        {
933
                                BAsmCode[0] = 0xFD;
934
                                BAsmCode[1] = 0xE0 | imm;
935
                                BAsmCode[2] = 0xF0 | regd;
936
                                CodeLen = 3;
937
                        }
938
                        else
939
                        {
940
                                BAsmCode[0] = OpTabBCLR[Index].OpcIR | (imm >> 4);
941
                                BAsmCode[1] = ((imm & 0x0F) << 4) | regd;
942
                                CodeLen = 2;
943
                        }
944
                        return;
945
                }
946
                if (DecodeReg(&ArgStr[1], &regs, eRn))
947
                {
948
                        BAsmCode[0] = 0xFC;
949
                        BAsmCode[1] = OpTabBCLR[Index].OpcRM | 0x03;
950
                        BAsmCode[2] = regs | (regd << 4);
951
                        CodeLen = 3;
952
                        return;
953
                }
954
 
955
                WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
956
        }
957
 
958
        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
959
}
960
 
961
static void DecodeBCnd(Word Index)
962
{
963
        const char *str = AttrPart.str.p_str;
964
        const int len = strlen(str);
965
        Byte attr = 0;
966
        Byte reg;
967
        LongInt addr;
968
        tSymbolFlags flags;
969
        Boolean ValOK;
970
        LongInt disp;
971
 
972
        if (len > 1)
973
        {
974
                WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart);
975
                return;
976
        }
977
        if (len == 1)
978
        {
979
                attr = as_toupper(str[0]);
980
                switch (attr)
981
                {
982
                case 'S':
983
                        break;
984
                case 'B':
985
                        break;
986
                case 'W':
987
                        break;
988
                case 'A':
989
                case 'L':
990
                        if (Index != 14)
991
                        {
992
                                WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
993
                                return;
994
                        }
995
                        break;
996
                default:
997
                        WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
998
                        return;
999
                }
1000
        }
1001
 
1002
        if (!ChkArgCnt(1,1)) return;
1003
 
1004
        if ((attr == 0 || attr == 'L') && DecodeReg(&ArgStr[1], &reg, eRn))
1005
        {
1006
                BAsmCode[0] = 0x7F;
1007
                BAsmCode[1] = 0x40 | reg;
1008
                CodeLen = 2;
1009
                return;
1010
        }
1011
 
1012
        addr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &flags);
1013
        if (ValOK)
1014
        {
1015
                if (attr == 'L')
1016
                {
1017
                        WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
1018
                        return;
1019
                }
1020
 
1021
                disp = addr - EProgCounter();
1022
 
1023
                /* Try 3 bit */
1024
                if ((attr == 0 || attr == 'S') && disp >= 3 && disp <= 10)
1025
                {
1026
                        if (disp > 7) disp -= 8;
1027
 
1028
                        if (Index == 0 || Index == 1)
1029
                        {
1030
 
1031
                                BAsmCode[0] = 0x10 | (Index << 3) | disp;
1032
                                CodeLen = 1;
1033
                                return;
1034
                        }
1035
 
1036
                        if (Index == 14)
1037
                        {
1038
                                BAsmCode[0] = 0x08 | disp;
1039
                                CodeLen = 1;
1040
                                return;
1041
                        }
1042
 
1043
                        WrError(ErrNum_InternalError);
1044
                }
1045
 
1046
                if (attr == 'S' && !mFirstPassUnknownOrQuestionable(flags))
1047
                {
1048
                        WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
1049
                        return;
1050
                }
1051
 
1052
                /* Try 8 bit */
1053
                if ((attr == 0 || attr == 'B') &&
1054
                        ((disp & 0xFFFFFF80) == 0xFFFFFF80 ||
1055
                         (disp & 0xFFFFFF80) == 0x00000000))
1056
                {
1057
                        BAsmCode[0] = 0x20 | Index;
1058
                        BAsmCode[1] = disp & 0xFF;
1059
                        CodeLen = 2;
1060
                        return;
1061
                }
1062
 
1063
                if (attr == 'B' && !mFirstPassUnknownOrQuestionable(flags))
1064
                {
1065
                        WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
1066
                        return;
1067
                }
1068
 
1069
                /* Try 16 bit */
1070
                if ((attr == 0 || attr == 'W') &&
1071
                        ((disp & 0xFFFF8000) == 0xFFFF8000 ||
1072
                         (disp & 0xFFFF8000) == 0x00000000))
1073
                {
1074
                        if (Index == 0 || Index == 1)
1075
                        {
1076
                                BAsmCode[0] = 0x3A | Index;
1077
                                BAsmCode[1] = disp & 0xFF;
1078
                                BAsmCode[2] = (disp >> 8) & 0xFF;
1079
                                CodeLen = 3;
1080
                                return;
1081
                        }
1082
 
1083
                        if (Index == 14)
1084
                        {
1085
                                BAsmCode[0] = 0x38;
1086
                                BAsmCode[1] = disp & 0xFF;
1087
                                BAsmCode[2] = (disp >> 8) & 0xFF;
1088
                                CodeLen = 3;
1089
                                return;
1090
                        }
1091
 
1092
                        WrError(ErrNum_JmpDistTooBig);
1093
                        return;
1094
                }
1095
 
1096
                if (attr == 'W' && !mFirstPassUnknownOrQuestionable(flags))
1097
                {
1098
                        WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
1099
                        return;
1100
                }
1101
 
1102
                /* Try 24 bit */
1103
                if ((disp & 0xFF800000) == 0xFF800000 ||
1104
                        (disp & 0xFF800000) == 0x00000000)
1105
                {
1106
                        if (Index == 14)
1107
                        {
1108
                                BAsmCode[0] = 0x04;
1109
                                BAsmCode[1] = disp & 0xFF;
1110
                                BAsmCode[2] = (disp >> 8) & 0xFF;
1111
                                BAsmCode[3] = (disp >> 16) & 0xFF;
1112
                                CodeLen = 4;
1113
                                return;
1114
                        }
1115
                }
1116
 
1117
                WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
1118
        }
1119
}
1120
 
1121
static void DecodeBMCnd(Word Index)
1122
{
1123
        Byte regd;
1124
        Byte size;
1125
        Byte memex;
1126
        Byte scale;
1127
        LongInt imm;
1128
        LongInt disp;
1129
        tSymbolFlags flags;
1130
 
1131
        if (!ChkNoAttr()) return;
1132
        if (!ChkArgCnt(2,2)) return;
1133
 
1134
        memex = 0;
1135
        if (DecodeIndirectADD(&ArgStr[2], &regd, &disp, &flags, &memex, &scale))
1136
        {
1137
                if (memex)
1138
                {
1139
                        WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
1140
                        return;
1141
                }
1142
                size = DispSize(disp, flags, 1);
1143
                if (size > 0x02){
1144
                        WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
1145
                        return;
1146
                }
1147
        }
1148
        else if (DecodeReg(&ArgStr[2], &regd, eRn))
1149
        {
1150
                size = 0x03;
1151
        }
1152
        else
1153
        {
1154
                WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
1155
                return;
1156
        }
1157
 
1158
        if (DecodeImm(&ArgStr[1], &imm, &flags))
1159
        {
1160
                if (size < 0x03)
1161
                {
1162
                        /* #imm,disp[Rd] */
1163
                        if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 7))
1164
                        {
1165
                                WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
1166
                                return;
1167
                        }
1168
 
1169
                        BAsmCode[0] = 0xFC;
1170
                        BAsmCode[1] = 0xE0 | (imm << 2) | size;
1171
                        BAsmCode[2] = (regd << 4) | Index;
1172
                        CodeLen = DispOut(3, size, disp, 1);
1173
                        return;
1174
                }
1175
                else
1176
                {
1177
                        /* #imm,Rd */
1178
                        if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 31))
1179
                        {
1180
                                WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
1181
                                return;
1182
                        }
1183
 
1184
                        BAsmCode[0] = 0xFD;
1185
                        BAsmCode[1] = 0xE0 | imm;
1186
                        BAsmCode[2] = (Index << 4) | regd;
1187
                        CodeLen = 3;
1188
                        return;
1189
                }
1190
        }
1191
 
1192
        WrError(ErrNum_OverRange);
1193
}
1194
 
1195
static void DecodeBRK(Word Index)
1196
{
1197
        if (!ChkNoAttr()) return;
1198
        if (!ChkArgCnt(0,0)) return;
1199
 
1200
        BAsmCode[0] = Index;
1201
        CodeLen = 1;
1202
}
1203
 
1204
static void DecodeBSR(Word Index)
1205
{
1206
        const char *str = AttrPart.str.p_str;
1207
        const int len = strlen(str);
1208
        Byte attr = 0;
1209
        Byte reg;
1210
        LongInt addr;
1211
        tSymbolFlags flags;
1212
        Boolean ValOK;
1213
        LongInt disp;
1214
 
1215
  UNUSED(Index);
1216
 
1217
        if (len > 1)
1218
        {
1219
                WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart);
1220
                return;
1221
        }
1222
        if (len == 1)
1223
        {
1224
                attr = as_toupper(str[0]);
1225
                switch (attr)
1226
                {
1227
                case 'W':
1228
                case 'A':
1229
                case 'L':
1230
                        break;
1231
                default:
1232
                        WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
1233
                        return;
1234
                }
1235
        }
1236
 
1237
        if (!ChkArgCnt(1,1)) return;
1238
 
1239
        if ((attr == 0 || attr == 'L') && DecodeReg(&ArgStr[1], &reg, eRn))
1240
        {
1241
                BAsmCode[0] = 0x7F;
1242
                BAsmCode[1] = 0x50 | reg;
1243
                CodeLen = 2;
1244
                return;
1245
        }
1246
 
1247
        addr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &flags);
1248
        if (ValOK)
1249
        {
1250
                if (attr == 'L')
1251
                {
1252
                        WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
1253
                        return;
1254
                }
1255
 
1256
                disp = addr - EProgCounter();
1257
 
1258
                /* Try 16 bit */
1259
                if ((attr == 0 || attr == 'W') &&
1260
                        ((disp & 0xFFFF8000) == 0xFFFF8000 ||
1261
                         (disp & 0xFFFF8000) == 0x00000000))
1262
                {
1263
                        BAsmCode[0] = 0x39;
1264
                        BAsmCode[1] = disp & 0xFF;
1265
                        BAsmCode[2] = (disp >> 8) & 0xFF;
1266
                        CodeLen = 3;
1267
                        return;
1268
                }
1269
 
1270
                if (attr == 'W' && !mFirstPassUnknownOrQuestionable(flags))
1271
                {
1272
                        WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
1273
                        return;
1274
                }
1275
 
1276
                /* Try 24 bit */
1277
                if ((disp & 0xFF800000) == 0xFF800000 ||
1278
                        (disp & 0xFF800000) == 0x00000000)
1279
                {
1280
                        BAsmCode[0] = 0x05;
1281
                        BAsmCode[1] = disp & 0xFF;
1282
                        BAsmCode[2] = (disp >> 8) & 0xFF;
1283
                        BAsmCode[3] = (disp >> 16) & 0xFF;
1284
                        CodeLen = 4;
1285
                        return;
1286
                }
1287
 
1288
                WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
1289
        }              
1290
}
1291
 
1292
static const char *BitPSW[] = {
1293
        "C",  "Z",  "S",  "O",  NULL, NULL, NULL, NULL,
1294
        "I",  "U",  NULL, NULL, NULL, NULL, NULL, NULL };
1295
 
1296
static void DecodeCLRPSW(Word Index)
1297
{
1298
        int i;
1299
 
1300
        if (!ChkNoAttr()) return;
1301
        if (!ChkArgCnt(1,1)) return;
1302
 
1303
        for (i = 0; i < 16; i++)
1304
        {
1305
                if (BitPSW[i] && !as_strcasecmp(ArgStr[1].str.p_str, BitPSW[i])) break;
1306
        }
1307
 
1308
        if (i < 16)
1309
        {
1310
                BAsmCode[0] = 0x7F;
1311
                BAsmCode[1] = Index | i;
1312
                CodeLen = 2;
1313
        }
1314
        else WrStrErrorPos(ErrNum_UnknownFlag, &ArgStr[1]);
1315
}
1316
 
1317
static const struct {
1318
        Byte OpcI;
1319
        Byte Opc2;
1320
        Byte OpcM;
1321
} OpTabDIV[] = {
1322
        { 0x80, 0x20, 0x08 },   /* DIV */
1323
        { 0x90, 0x24, 0x09 },   /* DIVU */
1324
        { 0x60, 0x18, 0x06 },   /* EMUL */
1325
        { 0x70, 0x1C, 0x07 },   /* EMULU */
1326
        { 0x40, 0x10, 0x04 },   /* MAX */
1327
        { 0x50, 0x14, 0x05 },   /* MIN */
1328
};
1329
 
1330
static void DecodeDIV(Word Index)
1331
{
1332
        Byte regs;
1333
        Byte regd;
1334
        Byte size;
1335
        LongInt imm;
1336
        tSymbolFlags flags;
1337
        LongInt disp;
1338
        Byte memex;
1339
        Byte scale;
1340
 
1341
        if (!ChkNoAttr()) return;
1342
        if (!ChkArgCnt(2,2)) return;
1343
 
1344
        if (!DecodeReg(&ArgStr[2], &regd, eRn))
1345
        {
1346
                WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
1347
                return;
1348
        }
1349
 
1350
        if (DecodeImm(&ArgStr[1], &imm, &flags))
1351
        {
1352
                size = ImmSize32(imm, flags);
1353
 
1354
                BAsmCode[0] = 0xFD;
1355
                BAsmCode[1] = 0x70 | (size << 2);
1356
                BAsmCode[2] = OpTabDIV[Index].OpcI | regd;
1357
                CodeLen = ImmOut(3, size, imm);
1358
                return;
1359
        }
1360
 
1361
        if (DecodeReg(&ArgStr[1], &regs, eRn))
1362
        {
1363
                BAsmCode[0] = 0xFC;
1364
                BAsmCode[1] = OpTabDIV[Index].Opc2 | 0x03;
1365
                BAsmCode[2] = (regs << 4) | regd;
1366
                CodeLen = 3;
1367
                return;
1368
        }
1369
 
1370
        if (DecodeIndirectADD(&ArgStr[1], &regs, &disp, &flags, &memex, &scale))
1371
        {
1372
                if (memex == 0x80)
1373
                {
1374
                        size = DispSize(disp, flags, 1);
1375
 
1376
                        BAsmCode[0] = 0xFC;
1377
                        BAsmCode[1] = OpTabDIV[Index].Opc2 | size;
1378
                        BAsmCode[2] = (regs << 4) | regd;
1379
                        CodeLen = DispOut(3, size, disp, 1);
1380
                        return;
1381
                }
1382
 
1383
                size = DispSize(disp, flags, scale);
1384
 
1385
                BAsmCode[0] = 0x06;
1386
                BAsmCode[1] = 0x20 | (memex << 6) | size;
1387
                BAsmCode[2] = OpTabDIV[Index].OpcM;
1388
                BAsmCode[3] = (regs << 4) | regd;
1389
                CodeLen = DispOut(4, size, disp, scale);
1390
                return;
1391
        }
1392
 
1393
        WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
1394
}
1395
 
1396
static const struct {
1397
        Byte OpcI;
1398
        Byte OpcM;
1399
        Byte Opc3;
1400
        Byte flags;
1401
} OpTabFADD[] = {
1402
        { 0x20, 0x88, 0xA0, 0x03 },     /* FADD */
1403
        { 0x10, 0x84, 0,    0x01 },     /* FCMP */
1404
        { 0x40, 0x90, 0,    0x01 },     /* FDIV */
1405
        { 0x30, 0x8C, 0xB0, 0x03 },     /* FMUL */
1406
        { 0x00, 0x80, 0x80, 0x03 },     /* FSUB */
1407
        { 0,    0x94, 0,    0x00 },     /* FTOI */
1408
        { 0,    0x98, 0,    0x00 },     /* ROUND */
1409
        { 0,    0xA0, 0,    0x10 },     /* FSQRT */
1410
        { 0,    0xA4, 0,    0x10 },     /* FTOU */
1411
};
1412
 
1413
static void DecodeFADD(Word Index)
1414
{
1415
        Byte regs;
1416
        Byte regd;
1417
        Byte size;
1418
        LongInt imm;
1419
        LongInt disp;
1420
        tSymbolFlags flags;
1421
 
1422
        if (!ChkNoAttr()) return;
1423
        if (!CheckFloat()) return;
1424
 
1425
        if ((OpTabFADD[Index].flags & 0x02) && ArgCnt == 3)
1426
        {
1427
                Byte regs2;
1428
 
1429
                if (!DecodeReg(&ArgStr[1], &regs, eRn))
1430
                {
1431
                        WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
1432
                        return;
1433
                }
1434
                if (!DecodeReg(&ArgStr[2], &regs2, eRn))
1435
                {
1436
                        WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
1437
                        return;
1438
                }
1439
                if (!DecodeReg(&ArgStr[3], &regd, eRn))
1440
                {
1441
                        WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[3]);
1442
                        return;
1443
                }
1444
 
1445
                BAsmCode[0] = 0xFF;
1446
                BAsmCode[1] = OpTabFADD[Index].Opc3 | regd;
1447
                BAsmCode[2] = (regs << 4) | regs2;
1448
                CodeLen = 3;
1449
                return;
1450
        }
1451
 
1452
        if (!ChkArgCnt(2,2)) return;
1453
 
1454
        if (OpTabFADD[Index].flags & 0x10)
1455
        {
1456
                if (!CheckV2()) return;
1457
        }
1458
 
1459
        if (!DecodeReg(&ArgStr[2], &regd, eRn))
1460
        {
1461
                WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
1462
                return;
1463
        }
1464
 
1465
        if ((OpTabFADD[Index].flags & 0x01) &&
1466
                DecodeFloat(&ArgStr[1], &imm))
1467
        {
1468
                BAsmCode[0] = 0xFD;
1469
                BAsmCode[1] = 0x72;
1470
                BAsmCode[2] = OpTabFADD[Index].OpcI | regd;
1471
                CodeLen = ImmOut(3, 0, imm);    /* size==0 means 4 byte */
1472
                return;
1473
        }
1474
 
1475
        if (DecodeReg(&ArgStr[1], &regs, eRn))
1476
        {
1477
                size = 0x03;
1478
                disp = 0;
1479
        }
1480
        else if (DecodeIndirectL(&ArgStr[1], &regs, &disp, &flags))
1481
        {
1482
                if (mFirstPassUnknown(flags)) size = 0x02;
1483
                else size = DispSize(disp, flags, 4);
1484
        }
1485
        else
1486
        {
1487
                WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
1488
                return;
1489
        }
1490
 
1491
        BAsmCode[0] = 0xFC;
1492
        BAsmCode[1] = OpTabFADD[Index].OpcM | size;
1493
        BAsmCode[2] = (regs << 4) | regd;
1494
        CodeLen = DispOut(3, size, disp, 4);
1495
}
1496
 
1497
static void DecodeINT(Word Index)
1498
{
1499
        LongInt imm;
1500
        tSymbolFlags flags;
1501
 
1502
        UNUSED(Index);
1503
 
1504
        if (!ChkNoAttr()) return;
1505
        if (!ChkArgCnt(1,1)) return;
1506
 
1507
        if (DecodeImm(&ArgStr[1], &imm, &flags))
1508
        {
1509
                if (!mFirstPassUnknown(flags) && (imm < -128 || imm > 255))
1510
                {
1511
                        WrStrErrorPos(ErrNum_ArgOutOfRange, &ArgStr[1]);
1512
                        return;
1513
                }
1514
 
1515
                BAsmCode[0] = 0x75;
1516
                BAsmCode[1] = 0x60;
1517
                BAsmCode[2] = imm & 0xFF;
1518
                CodeLen = 3;
1519
                return;
1520
        }
1521
 
1522
        WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
1523
}
1524
 
1525
static const struct {
1526
        Byte Opc1;
1527
        Byte Opc2;
1528
        Byte flags;
1529
} OpTabITOF[] = {
1530
        { 0x44, 0x11, 0x00 },   /* ITOF */
1531
        { 0x54, 0x15, 0x10 },   /* UTOF */
1532
};
1533
 
1534
static void DecodeITOF(Word Index)
1535
{
1536
        Byte regs;
1537
        Byte regd;
1538
        Byte size;
1539
        Byte memex;
1540
        Byte scale;
1541
        LongInt disp;
1542
        tSymbolFlags flags;
1543
 
1544
        if (!ChkNoAttr()) return;
1545
        if (!ChkArgCnt(2,2)) return;
1546
        if (!CheckFloat()) return;
1547
 
1548
        if ((OpTabITOF[Index].flags & 0x10) && !CheckV2()) return;
1549
 
1550
        if (!DecodeReg(&ArgStr[2], &regd, eRn))
1551
        {
1552
                WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
1553
                return;
1554
        }
1555
 
1556
        if (DecodeReg(&ArgStr[1], &regs, eRn))
1557
        {
1558
                size = 0x03;
1559
                disp = 0;
1560
                memex = 0;
1561
        }
1562
        else if (DecodeIndirectADD(&ArgStr[1], &regs, &disp, &flags, &memex, &scale))
1563
        {
1564
                if (mFirstPassUnknown(flags)) size = 0x02;
1565
                else size = DispSize(disp, flags, scale);
1566
        }
1567
        else
1568
        {
1569
                WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
1570
                return;
1571
        }
1572
 
1573
        if (memex == 0x80 || size == 0x03)
1574
        {
1575
                BAsmCode[0] = 0xFC;
1576
                BAsmCode[1] = OpTabITOF[Index].Opc1 | size;
1577
                BAsmCode[2] = (regs << 4) | regd;
1578
                if (size < 0x03) CodeLen = DispOut(3, size, disp, scale);
1579
                else CodeLen = 3;
1580
                return;
1581
        }
1582
 
1583
        BAsmCode[0] = 0x06;
1584
        BAsmCode[1] = 0x20 | (memex << 6) | size;
1585
        BAsmCode[2] = OpTabITOF[Index].Opc2;
1586
        BAsmCode[3] = (regs << 4) | regd;
1587
        CodeLen = DispOut(4, size, disp, scale);
1588
}
1589
 
1590
static const struct {
1591
        Byte Opc1;
1592
        Byte Opc2;
1593
} OpTabJMP[] = {
1594
        { 0x7F, 0x00 }, /* JMP */
1595
        { 0x7F, 0x10 }, /* JSR */
1596
        { 0x7E, 0xB0 }, /* POP */
1597
        { 0x7E, 0x50 }, /* ROLC */
1598
        { 0x7E, 0x40 }, /* RORC */
1599
        { 0x7E, 0x30 }, /* SAT */
1600
};
1601
 
1602
static void DecodeJMP(Word Index)
1603
{
1604
        Byte reg;
1605
 
1606
        if (!ChkNoAttr()) return;
1607
        if (!ChkArgCnt(1,1)) return;
1608
 
1609
        if (DecodeReg(&ArgStr[1], &reg, eRn))
1610
        {
1611
                BAsmCode[0] = OpTabJMP[Index].Opc1;
1612
                BAsmCode[1] = OpTabJMP[Index].Opc2 | reg;
1613
                CodeLen = 2;
1614
                return;
1615
        }
1616
 
1617
        WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
1618
}
1619
 
1620
static const struct {
1621
        Byte Opc;
1622
        Byte flags;
1623
} OpTabMACHI[] = {
1624
        { 0x04, 0x01 }, /* MACHI */
1625
        { 0x05, 0x01 }, /* MACLO */
1626
        { 0x00, 0x01 }, /* MULHI */
1627
        { 0x01, 0x01 }, /* MULLO */
1628
        { 0x67, 0x00 }, /* REVL */
1629
 
1630
        { 0x65, 0x00 }, /* REVW */
1631
        { 0x07, 0x11 }, /* EMACA */
1632
        { 0x47, 0x11 }, /* EMSBA */
1633
        { 0x03, 0x11 }, /* EMULA */
1634
        { 0x06, 0x11 }, /* MACLH */
1635
 
1636
        { 0x44, 0x11 }, /* MSBHI */
1637
        { 0x46, 0x11 }, /* MSBLH */
1638
        { 0x45, 0x11 }, /* MSBLO */
1639
        { 0x02, 0x11 }, /* MULLH */
1640
};
1641
 
1642
static void DecodeMACHI(Word Index)
1643
{
1644
        Byte reg1;
1645
        Byte reg2;
1646
        Byte acc = 0;
1647
 
1648
        if ((OpTabMACHI[Index].flags & 0x10) && !CheckV2()) return;
1649
        if (!ChkNoAttr()) return;
1650
        if (pCurrCPUProps->InstSet == eRXv1)
1651
        {
1652
                if (!ChkArgCnt(2,2)) return;
1653
        }
1654
        else
1655
        {
1656
                if (OpTabMACHI[Index].flags & 0x01)
1657
                {
1658
                        if (!ChkArgCnt(3,3)) return;
1659
                        if (!DecodeAcc(&ArgStr[3], &acc))
1660
                        {
1661
                                WrStrErrorPos(ErrNum_InvArg, &ArgStr[3]);
1662
                                return;
1663
                        }
1664
                }
1665
                else
1666
                {
1667
                        if (!ChkArgCnt(2,2)) return;
1668
                }
1669
        }
1670
 
1671
        if (!DecodeReg(&ArgStr[1], &reg1, eRn))
1672
        {
1673
                WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
1674
                return;
1675
        }
1676
 
1677
        if (!DecodeReg(&ArgStr[2], &reg2, eRn))
1678
        {
1679
                WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
1680
                return;
1681
        }
1682
 
1683
        BAsmCode[0] = 0xFD;
1684
        BAsmCode[1] = OpTabMACHI[Index].Opc | (acc << 3);
1685
        BAsmCode[2] = (reg1 << 4) | reg2;
1686
        CodeLen = 3;
1687
}
1688
 
1689
static void DecodeMOV(Word Index)
1690
{
1691
        tSymbolSize size;
1692
        Byte regs;
1693
        Byte regd;
1694
        LongInt imm;
1695
        LongInt disp;
1696
        tSymbolFlags flags;
1697
        tSymbolFlags flags2;
1698
        Byte disp2;
1699
        Byte isize;
1700
        Byte dsize;
1701
        Byte scale;
1702
        Byte regi;
1703
 
1704
        UNUSED(Index);
1705
 
1706
        size = DecodeAttrSize();
1707
        if (size == eSymbolSizeUnknown) return;
1708
        scale = Size2Scale(size);
1709
 
1710
        if (DecodeReg(&ArgStr[1], &regs, eRn) && regs < 8 &&
1711
                DecodeRelative(&ArgStr[2], &regd, &disp, &flags))
1712
        {       /* (1) */
1713
                if (ChkDisp5(size, disp, flags))
1714
                {
1715
                        disp2 = DispSize5(size, disp);
1716
 
1717
                        BAsmCode[0] = 0x80 | (size << 4) | ((disp2 >> 2) & 0x07);
1718
                        BAsmCode[1] = ((disp2 << 6) & 0x80) | (regd << 4) | ((disp2 << 3) & 0x08) | regs;
1719
                        CodeLen = 2;
1720
                        return;
1721
                }
1722
        }
1723
 
1724
        if (DecodeRelative(&ArgStr[1], &regs, &disp, &flags) &&
1725
                DecodeReg(&ArgStr[2], &regd, eRn) && regd < 8)
1726
        {       /* (2) */
1727
                if (ChkDisp5(size, disp, flags))
1728
                {
1729
                        disp2 = DispSize5(size, disp);
1730
 
1731
                        BAsmCode[0] = 0x88 | (size << 4) | ((disp2 >> 2) & 0x07);
1732
                        BAsmCode[1] = ((disp2 << 6) & 0x80) | (regs << 4) | ((disp2 << 3) & 0x08) | regd;
1733
                        CodeLen = 2;
1734
                        return;
1735
                }
1736
        }
1737
 
1738
        if (DecodeImm(&ArgStr[1], &imm, &flags))
1739
        {
1740
                if (size == 0x02 && DecodeReg(&ArgStr[2], &regd, eRn) &&
1741
                        !mFirstPassUnknown(flags) && imm >= 0 && imm < 16)
1742
                {       /* (3) */
1743
                        BAsmCode[0] = 0x66;
1744
                        BAsmCode[1] = (imm << 4) | regd;
1745
                        CodeLen = 2;
1746
                        return;
1747
                }
1748
 
1749
                if (DecodeRelative(&ArgStr[2], &regd, &disp, &flags))
1750
                {       /* (4) */
1751
                        if ((size == 0x00 && imm >= -128 && imm < 256) ||
1752
                                (size != 0x00 && imm >= 0 && imm < 256))
1753
                        {
1754
                                disp2 = DispSize5(size, disp);
1755
 
1756
                                BAsmCode[0] = 0x3C | size;
1757
                                BAsmCode[1] = ((disp2 << 3) & 0x80) | (regd << 4) | (disp2 & 0x0F);
1758
                                BAsmCode[2] = imm;
1759
                                CodeLen = 3;
1760
                                return;
1761
                        }
1762
                }
1763
 
1764
                if (DecodeReg(&ArgStr[2], &regd, eRn))
1765
                {
1766
                        if (size == 0x02 && !mFirstPassUnknown(flags) &&
1767
                                imm >= 0 && imm < 256)
1768
                        {       /* (5) */
1769
                                BAsmCode[0] = 0x75;
1770
                                BAsmCode[1] = 0x40 | regd;
1771
                                BAsmCode[2] = imm;
1772
                                CodeLen = 3;
1773
                                return;
1774
                        }
1775
 
1776
                        /* (6) */
1777
                        isize = ImmSize32(imm, flags);
1778
 
1779
                        BAsmCode[0] = 0xFB;
1780
                        BAsmCode[1] = (regd << 4) | (isize << 2) | 0x02;
1781
 
1782
                        CodeLen = ImmOut(2, isize, imm);
1783
                        return;
1784
                }
1785
 
1786
                if (DecodeIndirectADC(&ArgStr[2], &regd, &disp, &flags2))
1787
                {       /* (8) */
1788
                        switch (size)
1789
                        {
1790
                                case 0x00:      /* B */
1791
                                        if (imm < -128 || imm > 255)
1792
                                        {
1793
                                                WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
1794
                                                return;
1795
                                        }
1796
                                        isize = 0x01;
1797
                                        break;
1798
                                case 0x01:      /* W */
1799
                                        if (imm < -32768 || imm > 65535)
1800
                                        {
1801
                                                WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
1802
                                                return;
1803
                                        }
1804
                                        isize = ImmSize16(imm, flags);
1805
                                        break;
1806
                                case 0x02:      /* L */
1807
                                        isize = ImmSize32(imm, flags);
1808
                                        break;
1809
                                default:
1810
                                        WrError(ErrNum_InternalError);
1811
                                        return;
1812
                        }
1813
 
1814
                        dsize = DispSize(disp, flags2, scale);
1815
 
1816
                        BAsmCode[0] = 0xF8 | dsize;
1817
                        BAsmCode[1] = (regd << 4) | (isize << 2) | size;
1818
                        CodeLen = DispOut(2, dsize, disp, scale);
1819
                        CodeLen = ImmOut(CodeLen, isize, imm);
1820
                        return;
1821
                }
1822
 
1823
                WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);                 
1824
        }
1825
 
1826
        if (DecodeReg(&ArgStr[1], &regs, eRn))
1827
        {
1828
                if (DecodeReg(&ArgStr[2], &regd, eRn))
1829
                {       /* (7) */
1830
                        BAsmCode[0] = 0xCF | (size << 4);
1831
                        BAsmCode[1] = (regs << 4) | regd;
1832
                        CodeLen = 2;
1833
                        return;
1834
                }
1835
 
1836
                if (DecodeIndirectADC(&ArgStr[2], &regd, &disp, &flags))
1837
                {       /* (11) */
1838
                        dsize = DispSize(disp, flags, scale);
1839
 
1840
                        BAsmCode[0] = 0xC3 | (size << 4) | (dsize << 2);
1841
                        BAsmCode[1] = (regd << 4) | regs;
1842
                        CodeLen = DispOut(2, dsize, disp, scale);
1843
                        return;
1844
                }
1845
 
1846
                if (DecodeIndexed(&ArgStr[2], &regi, &regd))
1847
                {       /* (12) */
1848
                        BAsmCode[0] = 0xFE;
1849
                        BAsmCode[1] = (size << 4) | regi;
1850
                        BAsmCode[2] = (regd << 4) | regs;
1851
                        CodeLen = 3;
1852
                        return;
1853
                }
1854
 
1855
                if (DecodeIncDec(&ArgStr[2], &regd, &regi))
1856
                {       /* (14) */
1857
                        BAsmCode[0] = 0xFD;
1858
                        BAsmCode[1] = 0x20 | (regi << 2) | size;
1859
                        BAsmCode[2] = (regd << 4) | regs;
1860
                        CodeLen = 3;
1861
                        return;
1862
                }
1863
        }
1864
 
1865
        if (DecodeIndirectADC(&ArgStr[1], &regs, &disp, &flags))
1866
        {
1867
                if (DecodeReg(&ArgStr[2], &regd, eRn))
1868
                {       /* (9) */
1869
                        dsize = DispSize(disp, flags, scale);
1870
 
1871
                        BAsmCode[0] = 0xCC | (size << 4) | dsize;
1872
                        BAsmCode[1] = (regs << 4) | regd;
1873
                        CodeLen = DispOut(2, dsize, disp, scale);
1874
                        return;
1875
                }
1876
 
1877
                if (DecodeIndirectADC(&ArgStr[2], &regd, &imm, &flags2))
1878
                {       /* (13) */
1879
                        dsize = DispSize(disp, flags, scale);   /* src */
1880
                        isize = DispSize(imm, flags2, scale);   /* dst */
1881
 
1882
                        BAsmCode[0] = 0xC0 | (size << 4) | (isize << 2) | dsize;
1883
                        BAsmCode[1] = (regs << 4) | regd;
1884
                        CodeLen = DispOut(2, dsize, disp, scale);
1885
                        CodeLen = DispOut(CodeLen, isize, imm, scale);
1886
                        return;
1887
                }
1888
        }
1889
 
1890
        if (DecodeIndexed(&ArgStr[1], &regi, &regs) &&
1891
                DecodeReg(&ArgStr[2], &regd, eRn))
1892
        {       /* (10) */
1893
                BAsmCode[0] = 0xFE;
1894
                BAsmCode[1] = 0x40 | (size << 4) | regi;
1895
                BAsmCode[2] = (regs << 4) | regd;
1896
                CodeLen = 3;
1897
                return;
1898
        }
1899
 
1900
        if (DecodeIncDec(&ArgStr[1], &regs, &regi) &&
1901
                DecodeReg(&ArgStr[2], &regd, eRn))
1902
        {
1903
                BAsmCode[0] = 0xFD;
1904
                BAsmCode[1] = 0x28 | (regi << 2) | size;
1905
                BAsmCode[2] = (regs << 4) | regd;
1906
                CodeLen = 3;
1907
                return;
1908
        }
1909
 
1910
        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]); 
1911
}
1912
 
1913
static void DecodeMOVU(Word Index)
1914
{
1915
        tSymbolSize size;
1916
        Byte regs;
1917
        Byte regd;
1918
        Byte scale;
1919
        LongInt disp;
1920
        tSymbolFlags flags;
1921
        Byte disp2;
1922
        Byte dsize;
1923
        Byte regi;
1924
 
1925
        UNUSED(Index);
1926
 
1927
        size = DecodeAttrSize();
1928
        if (size == eSymbolSizeUnknown || size == eSymbolSize32Bit) return;
1929
        scale = Size2Scale(size);
1930
 
1931
        if (DecodeReg(&ArgStr[2], &regd, eRn))
1932
        {
1933
                if (DecodeRelative(&ArgStr[1], &regs, &disp, &flags) &&
1934
                        ChkDisp5(size, disp, flags) && regd < 8)
1935
                {       /* (1) */
1936
                        disp2 = DispSize5(size, disp);
1937
 
1938
                        BAsmCode[0] = 0xB0 | (size << 3) | ((disp2 >> 2) & 0x07);
1939
                        BAsmCode[1] = ((disp2 << 6) & 0x80) | (regs << 4) | ((disp2 << 3) & 0x08) | regd;
1940
                        CodeLen = 2;
1941
                        return;
1942
                }
1943
 
1944
                if (DecodeReg(&ArgStr[1], &regs, eRn))
1945
                {       /* (2)-1 */
1946
                        BAsmCode[0] = 0x5B | (size << 2);
1947
                        BAsmCode[1] = (regs << 4) | regd;
1948
                        CodeLen = 2;
1949
                        return;
1950
                }
1951
 
1952
                if (DecodeIndirectADC(&ArgStr[1], &regs, &disp, &flags))
1953
                {       /* (2)-2 */
1954
                        dsize = DispSize(disp, flags, scale);
1955
 
1956
                        BAsmCode[0] = 0x58 | (size << 2) | dsize;
1957
                        BAsmCode[1] = (regs << 4) | regd;
1958
                        CodeLen = DispOut(2, dsize, disp, scale);
1959
                        return;
1960
                }
1961
 
1962
                if (DecodeIndexed(&ArgStr[1], &regi, &regs))
1963
                {       /* (3) */
1964
                        BAsmCode[0] = 0xFE;
1965
                        BAsmCode[1] = 0xC0 | (size << 4) | regi;
1966
                        BAsmCode[2] = (regs << 4) | regd;
1967
                        CodeLen = 3;
1968
                        return;
1969
                }
1970
 
1971
                if (DecodeIncDec(&ArgStr[1], &regs, &regi))
1972
                {       /* (4) */
1973
                        BAsmCode[0] = 0xFD;
1974
                        BAsmCode[1] = 0x38 | (regi << 2) | size;
1975
                        BAsmCode[2] = (regs << 4) | regd;
1976
                        CodeLen = 3;
1977
                        return;
1978
                }
1979
        }
1980
 
1981
        WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
1982
}
1983
 
1984
static const struct {
1985
        Byte Opc2;
1986
        Byte Opc3;
1987
        Byte flags;
1988
} OpTabMVFACHI[] = {
1989
        { 0x1E, 0x00, 0x00 },   /* MVFACHI */
1990
        { 0x1E, 0x20, 0x00 },   /* MVFACMI */
1991
        { 0x1E, 0x30, 0x10 },   /* MVFACGU */
1992
        { 0x1E, 0x10, 0x10 },   /* MVFACLO */
1993
};
1994
 
1995
static void DecodeMVFACHI(Word Index)
1996
{
1997
        LongInt imm;
1998
        tSymbolFlags flags;
1999
        Byte acc;
2000
        Byte reg;
2001
 
2002
        if ((OpTabMVFACHI[Index].flags & 0x10) && !CheckV2()) return;
2003
        if (!ChkNoAttr()) return;
2004
 
2005
        if (pCurrCPUProps->InstSet == eRXv1)
2006
        {
2007
                if (!ChkArgCnt(1,1)) return;
2008
                imm = 0x02;
2009
                acc = 0x00;
2010
        }
2011
        else
2012
        {
2013
                if (!ChkArgCnt(3,3)) return;
2014
                if (!DecodeImm(&ArgStr[1], &imm, &flags))
2015
                {
2016
                        WrStrErrorPos(ErrNum_OnlyImmAddr, &ArgStr[1]); 
2017
                        return;
2018
                }
2019
                switch (imm)
2020
                {
2021
                case 0:
2022
                        imm = 0x02;
2023
                        break;
2024
                case 1:
2025
                        imm = 0x03;
2026
                        break;
2027
                case 2:
2028
                        imm = 0x00;
2029
                        break;
2030
                default:
2031
                        if (mSymbolQuestionable(flags)) break;
2032
                        WrStrErrorPos(ErrNum_ArgOutOfRange, &ArgStr[1]);
2033
                        return;
2034
                }
2035
 
2036
                if (!DecodeAcc(&ArgStr[2], &acc))
2037
                {
2038
                        WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
2039
                        return;
2040
                }
2041
        }
2042
 
2043
        if (!DecodeReg(&ArgStr[ArgCnt], &reg, eRn))
2044
        {
2045
                WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[ArgCnt]);   
2046
                return;
2047
        }
2048
 
2049
        BAsmCode[0] = 0xFD;
2050
        BAsmCode[1] = OpTabMVFACHI[Index].Opc2 | ((imm >> 1) & 0x01);
2051
        BAsmCode[2] = OpTabMVFACHI[Index].Opc3 | (acc << 7) | ((imm << 6) & 0x40) | reg;
2052
        CodeLen = 3;
2053
}
2054
 
2055
static const char *SPReg[] = {
2056
        "PSW",   "PC",    "USP",   "FPSW",   NULL,    NULL,    NULL,    NULL,
2057
        "BPSW",  "BPC",   "ISP",   "FINTV",  "INTB",  "EXTB",  NULL,    NULL,
2058
};
2059
 
2060
static void DecodeMVFC(Word Index)
2061
{
2062
        Byte reg;
2063
        size_t i;
2064
 
2065
        UNUSED(Index);
2066
 
2067
        if (!ChkNoAttr()) return;
2068
        if (!ChkArgCnt(2,2)) return;
2069
 
2070
        if (DecodeReg(&ArgStr[2], &reg, eRn))
2071
        {
2072
                for (i = 0; i < as_array_size(SPReg); i++)
2073
                {
2074
                        if (i == 13 && pCurrCPUProps->InstSet == eRXv1)
2075
                        {
2076
                                WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
2077
                        }
2078
 
2079
                        if (SPReg[i] && !as_strcasecmp(SPReg[i], ArgStr[1].str.p_str))
2080
                        {
2081
                                BAsmCode[0] = 0xFD;
2082
                                BAsmCode[1] = 0x6A;
2083
                                BAsmCode[2] = (i << 4) | reg;
2084
                                CodeLen = 3;
2085
                                return;
2086
                        }
2087
                }
2088
 
2089
                WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
2090
        }
2091
 
2092
        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);                 
2093
}
2094
 
2095
static const struct {
2096
        Byte Opc2;
2097
        Byte Opc3;
2098
        Byte flags;
2099
} OpTabMVTACHI[] = {
2100
        { 0x17, 0x00, 0x00 },   /* MVTACHI */
2101
        { 0x17, 0x10, 0x00 },   /* MVTACLO */
2102
        { 0x17, 0x30, 0x10 },   /* MVTACGU */
2103
};
2104
 
2105
static void DecodeMVTACHI(Word Index)
2106
{
2107
        Byte acc;
2108
        Byte reg;
2109
 
2110
        if ((OpTabMVTACHI[Index].flags & 0x10) && !CheckV2()) return;
2111
        if (!ChkNoAttr()) return;
2112
 
2113
        if (pCurrCPUProps->InstSet == eRXv1)
2114
        {
2115
                if (!ChkArgCnt(1,1)) return;
2116
                acc = 0x00;
2117
        }
2118
        else
2119
        {
2120
                if (!ChkArgCnt(2,2)) return;
2121
 
2122
                if (!DecodeAcc(&ArgStr[2], &acc))
2123
                {
2124
                        WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
2125
                        return;
2126
                }
2127
        }
2128
 
2129
        if (!DecodeReg(&ArgStr[1], &reg, eRn))
2130
        {
2131
                WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
2132
                return;
2133
        }
2134
 
2135
        BAsmCode[0] = 0xFD;
2136
        BAsmCode[1] = OpTabMVTACHI[Index].Opc2;
2137
        BAsmCode[2] = OpTabMVTACHI[Index].Opc3 | (acc << 7) | reg;
2138
        CodeLen = 3;
2139
}
2140
 
2141
static void DecodeMVTC(Word Index)
2142
{
2143
        Byte reg;
2144
        LongInt imm;
2145
        Byte size;
2146
        tSymbolFlags flags;
2147
        size_t i;
2148
 
2149
        UNUSED(Index);
2150
 
2151
        if (!ChkNoAttr()) return;
2152
        if (!ChkArgCnt(2,2)) return;
2153
 
2154
        for (i = 0; i < as_array_size(SPReg); i++)
2155
        {
2156
                if (SPReg[i] && !as_strcasecmp(SPReg[i], ArgStr[2].str.p_str))
2157
                {
2158
                        if (i == 1)
2159
                        {
2160
                                WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
2161
                                return;
2162
                        }
2163
 
2164
                        if (i == 13 && pCurrCPUProps->InstSet == eRXv1)
2165
                        {
2166
                                WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
2167
                        }
2168
 
2169
                        if (DecodeImm(&ArgStr[1], &imm, &flags))
2170
                        {
2171
                                size = ImmSize32(imm, flags);
2172
 
2173
                                BAsmCode[0] = 0xFD;
2174
                                BAsmCode[1] = 0x73 | (size << 2);
2175
                                BAsmCode[2] = i;
2176
                                CodeLen = ImmOut(3, size, imm);
2177
                                return;
2178
                        }
2179
 
2180
                        if (DecodeReg(&ArgStr[1], &reg, eRn))
2181
                        {
2182
                                BAsmCode[0] = 0xFD;
2183
                                BAsmCode[1] = 0x68;
2184
                                BAsmCode[2] = (reg << 4) | i;
2185
                                CodeLen = 3;
2186
                                return;
2187
                        }
2188
 
2189
                        WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
2190
                }
2191
        }
2192
 
2193
        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);                 
2194
}
2195
 
2196
static void DecodeMVTIPL(Word Index)
2197
{
2198
        LongInt imm;
2199
        tSymbolFlags flags;
2200
 
2201
        UNUSED(Index);
2202
 
2203
        if (!CheckSup()) return;
2204
        if (!ChkNoAttr()) return;
2205
        if (!ChkArgCnt(1,1)) return;
2206
 
2207
        if (!pCurrCPUProps->hasMVTIPL)
2208
        {
2209
                WrError(ErrNum_InstructionNotSupported);
2210
                return;
2211
        }
2212
 
2213
        if (DecodeImm(&ArgStr[1], &imm, &flags))
2214
        {
2215
                if (!mFirstPassUnknown(flags) && (imm < 0 || imm > 15))
2216
                {
2217
                        WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
2218
                        return;
2219
                }
2220
 
2221
                BAsmCode[0] = 0x75;
2222
                BAsmCode[1] = 0x70;
2223
                BAsmCode[2] = imm;
2224
                CodeLen = 3;
2225
                return;
2226
        }
2227
 
2228
        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);                 
2229
}
2230
 
2231
static const Byte OpTabPOPC[] = {
2232
        0xE0,   /* POPC */
2233
        0xC0,   /* PUSHC */
2234
};
2235
 
2236
static void DecodePOPC(Word Index)
2237
{
2238
        size_t i;
2239
 
2240
        UNUSED(Index);
2241
 
2242
        if (!ChkNoAttr()) return;
2243
        if (!ChkArgCnt(1,1)) return;
2244
 
2245
        for (i = 0; i < as_array_size(SPReg); i++)
2246
        {
2247
                if (SPReg[i] && !as_strcasecmp(SPReg[i], ArgStr[1].str.p_str))
2248
                {
2249
                        if (Index == 0 && i == 1)
2250
                        {
2251
                                WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
2252
                                return;
2253
                        }
2254
 
2255
                        if (i == 13 && pCurrCPUProps->InstSet == eRXv1)
2256
                        {
2257
                                WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
2258
                        }
2259
 
2260
                        BAsmCode[0] = 0x7E;
2261
                        BAsmCode[1] = OpTabPOPC[Index] | i;
2262
                        CodeLen = 2;
2263
                        return;
2264
                }
2265
        }
2266
 
2267
        WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
2268
}
2269
 
2270
static const Byte OpTabPOPM[] = {
2271
        0x6F,   /* POPM */
2272
        0x6E,   /* PUSHM */
2273
};
2274
 
2275
static void DecodePOPM(Word Index)
2276
{
2277
        Byte range;
2278
 
2279
        if (!ChkNoAttr()) return;
2280
        if (!ChkArgCnt(1,1)) return;
2281
 
2282
        if (DecodeRegRange(&ArgStr[1], &range))
2283
        {
2284
                BAsmCode[0] = OpTabPOPM[Index];
2285
                BAsmCode[1] = range;
2286
                CodeLen = 2;
2287
                return;
2288
        }
2289
 
2290
        WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
2291
}
2292
 
2293
static void DecodePUSH(Word Index)
2294
{
2295
        tSymbolSize size;
2296
        Byte reg;
2297
        LongInt disp;
2298
        tSymbolFlags flags;
2299
        Byte dsize;
2300
        Byte scale;
2301
 
2302
        UNUSED(Index);
2303
 
2304
        size = DecodeAttrSize();
2305
        if (size == eSymbolSizeUnknown) return;
2306
        if (!ChkArgCnt(1,1)) return;
2307
 
2308
        scale = Size2Scale(size);
2309
 
2310
        if (DecodeReg(&ArgStr[1], &reg, eRn))
2311
        {
2312
                BAsmCode[0] = 0x7E;
2313
                BAsmCode[1] = 0x80 | (size << 4) | reg;
2314
                CodeLen = 2;
2315
                return;
2316
        }
2317
 
2318
        if (DecodeIndirectADC(&ArgStr[1], &reg, &disp, &flags))
2319
        {
2320
                dsize = DispSize(disp, flags, scale);
2321
 
2322
                BAsmCode[0] = 0xF4 | dsize;
2323
                BAsmCode[1] = 0x08 | (reg << 4) | size;
2324
                CodeLen = DispOut(2, dsize, disp, scale);
2325
                return;
2326
        }
2327
 
2328
        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
2329
}
2330
 
2331
static const struct {
2332
        Byte Opc2;
2333
        Byte Opc3;
2334
        Byte flags;
2335
} OpTabRACW[] = {
2336
        { 0x18, 0x00, 0x00 },   /* RACW */
2337
        { 0x19, 0x00, 0x10 },   /* RACL */
2338
        { 0x19, 0x40, 0x10 },   /* RDACL */
2339
        { 0x18, 0x40, 0x10 },   /* RDACW */
2340
};
2341
 
2342
static void DecodeRACW(Word Index)
2343
{
2344
        LongInt imm;
2345
        tSymbolFlags flags;
2346
        Byte acc = 0;
2347
 
2348
        if ((OpTabRACW[Index].flags & 0x10) && !CheckV2()) return;
2349
        if (!ChkNoAttr()) return;
2350
 
2351
        if (pCurrCPUProps->InstSet == eRXv1)
2352
        {
2353
                if (!ChkArgCnt(1,1)) return;
2354
        }
2355
        else
2356
        {
2357
                if (!ChkArgCnt(2,2)) return;
2358
 
2359
                if (!DecodeAcc(&ArgStr[2], &acc))
2360
                {
2361
                        WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
2362
                        return;
2363
                }
2364
        }
2365
 
2366
        if (DecodeImm(&ArgStr[1], &imm, &flags))
2367
        {
2368
                if (mFirstPassUnknown(flags) || imm == 1 || imm == 2)
2369
                {
2370
                        BAsmCode[0] = 0xFD;
2371
                        BAsmCode[1] = OpTabRACW[Index].Opc2;
2372
                        BAsmCode[2] = OpTabRACW[Index].Opc3 | (acc << 7) | ((imm - 1) << 4);
2373
                        CodeLen = 3;
2374
                        return;
2375
                }
2376
        }
2377
 
2378
        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
2379
}
2380
 
2381
static void DecodeRMPA(Word Index)
2382
{
2383
        tSymbolSize size;
2384
 
2385
        size = DecodeAttrSize();
2386
        if (size == eSymbolSizeUnknown) return;
2387
        if (!ChkArgCnt(0,0)) return;
2388
 
2389
        BAsmCode[0] = 0x7F;
2390
        BAsmCode[1] = Index | size;
2391
        CodeLen = 2;
2392
}
2393
 
2394
static const struct {
2395
        Byte Opc1;
2396
        Byte Opc2;
2397
} OpTabROTL[] = {
2398
        { 0x6E, 0x66 }, /* ROTL */
2399
        { 0x6C, 0x64 }, /* ROTR */
2400
};
2401
 
2402
static void DecodeROTL(Word Index)
2403
{
2404
        Byte regs;
2405
        Byte regd;
2406
        LongInt imm;
2407
        tSymbolFlags flags;
2408
 
2409
        if (!ChkNoAttr()) return;
2410
        if (!ChkArgCnt(2,2)) return;
2411
 
2412
        if (!DecodeReg(&ArgStr[2], &regd, eRn))
2413
        {
2414
                WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
2415
                return;
2416
        }
2417
 
2418
        if (DecodeImm(&ArgStr[1], &imm, &flags))
2419
        {
2420
                if (!mFirstPassUnknown(flags) && (imm < 0 || imm > 31))
2421
                {
2422
                        WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
2423
                        return;
2424
                }
2425
 
2426
                BAsmCode[0] = 0xFD;
2427
                BAsmCode[1] = OpTabROTL[Index].Opc1 | ((imm >> 4) & 0x01);
2428
                BAsmCode[2] = ((imm << 4) & 0xF0) | regd;
2429
                CodeLen = 3;
2430
                return;
2431
        }
2432
 
2433
        if (DecodeReg(&ArgStr[1], &regs, eRn))
2434
        {
2435
                BAsmCode[0] = 0xFD;
2436
                BAsmCode[1] = OpTabROTL[Index].Opc2;
2437
                BAsmCode[2] = (regs << 4) | regd;
2438
                CodeLen = 3;
2439
                return;
2440
        }
2441
 
2442
        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
2443
}
2444
 
2445
static void DecodeRTE(Word Index)
2446
{
2447
        if (!ChkNoAttr()) return;
2448
        if (!ChkArgCnt(0,0)) return;
2449
 
2450
        switch (Index)
2451
        {
2452
        case 0x7F95:    /* RTE */
2453
        case 0x7F94:    /* RTFI */
2454
        case 0x7F96:    /* WAIT */
2455
                if (!CheckSup()) return;
2456
        }
2457
 
2458
        BAsmCode[0] = Index >> 8;
2459
        BAsmCode[1] = Index;
2460
        CodeLen = 2;
2461
}
2462
 
2463
static void DecodeRTSD(Word Index)
2464
{
2465
        LongInt imm;
2466
        tSymbolFlags flags;
2467
        Byte range;
2468
 
2469
        UNUSED(Index);
2470
 
2471
        if (!ChkNoAttr()) return;
2472
        if (!ChkArgCnt(1,2)) return;
2473
 
2474
        if (DecodeImm(&ArgStr[1], &imm, &flags))
2475
        {
2476
                if (mSymbolQuestionable(flags) && (imm < 0 || imm > 255))
2477
                {
2478
                        WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
2479
                        return;
2480
                }
2481
 
2482
                if (ArgCnt == 2 && DecodeRegRange(&ArgStr[2], &range))
2483
                {
2484
                        BAsmCode[0] = 0x3F;
2485
                        BAsmCode[1] = range;
2486
                        BAsmCode[2] = imm;
2487
                        CodeLen = 3;
2488
                        return;
2489
                }
2490
 
2491
                if (ArgCnt > 1)
2492
                {
2493
                        WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
2494
                        return;
2495
                }
2496
 
2497
                BAsmCode[0] = 0x67;
2498
                BAsmCode[1] = imm;
2499
                CodeLen = 2;
2500
                return;
2501
        }
2502
 
2503
        WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
2504
}
2505
 
2506
static void DecodeSCCnd(Word Index)
2507
{
2508
        tSymbolSize size;
2509
        Byte reg;
2510
        LongInt disp;
2511
        tSymbolFlags flags;
2512
        Byte dsize;
2513
        Byte scale;
2514
 
2515
        size = DecodeAttrSize();
2516
        if (size == eSymbolSizeUnknown) return;
2517
        if (!ChkArgCnt(1,1)) return;
2518
 
2519
        scale = Size2Scale(size);
2520
 
2521
        if (DecodeReg(&ArgStr[1], &reg, eRn))
2522
        {
2523
                if (size != 0x02)
2524
                {
2525
                        WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
2526
                        return;
2527
                }
2528
 
2529
                BAsmCode[0] = 0xFC;
2530
                BAsmCode[1] = 0xD3 | (size << 2);
2531
                BAsmCode[2] = (reg << 4) | Index;
2532
                CodeLen = 3;
2533
                return;
2534
        }
2535
 
2536
        if (DecodeIndirectADC(&ArgStr[1], &reg, &disp, &flags))
2537
        {
2538
                dsize = DispSize(disp, flags, scale);
2539
 
2540
                BAsmCode[0] = 0xFC;
2541
                BAsmCode[1] = 0xD0 | (size << 2) | dsize;
2542
                BAsmCode[2] = (reg << 4) | Index;
2543
                CodeLen = DispOut(3, dsize, disp, scale);
2544
                return;
2545
        }
2546
 
2547
        WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
2548
}
2549
 
2550
static const struct {
2551
        Byte Opc1;
2552
        Byte Opc2;
2553
        Byte Opc3;
2554
} OpTabSHAR[] = {
2555
        { 0x6A, 0x61, 0xA0 },   /* SHAR */
2556
        { 0x6C, 0x62, 0xC0 },   /* SHLL */
2557
        { 0x68, 0x60, 0x80 },   /* SHLR */
2558
};
2559
 
2560
static void DecodeSHAR(Word Index)
2561
{
2562
        Byte regs;
2563
        Byte regd;
2564
        LongInt imm;
2565
        tSymbolFlags flags;
2566
 
2567
        if (!ChkNoAttr()) return;
2568
        if (!ChkArgCnt(2,3)) return;
2569
 
2570
        if (!DecodeReg(&ArgStr[ArgCnt], &regd, eRn))
2571
        {
2572
                WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
2573
                return;
2574
        }
2575
 
2576
        if (DecodeImm(&ArgStr[1], &imm, &flags))
2577
        {
2578
                if (!mFirstPassUnknown(flags) && (imm < 0 || imm > 31))
2579
                {
2580
                        WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
2581
                        return;
2582
                }
2583
 
2584
                if (ArgCnt == 3)
2585
                {
2586
                        if (DecodeReg(&ArgStr[2], &regs, eRn))
2587
                        {       /* (3) */
2588
                                BAsmCode[0] = 0xFD;
2589
                                BAsmCode[1] = OpTabSHAR[Index].Opc3 | imm;
2590
                                BAsmCode[2] = (regs << 4) | regd;
2591
                                CodeLen = 3;
2592
                                return;
2593
                        }
2594
 
2595
                        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
2596
                        return;
2597
                }
2598
 
2599
                /* (1) */
2600
                BAsmCode[0] = OpTabSHAR[Index].Opc1 | (imm >> 4);
2601
                BAsmCode[1] = ((imm << 4) & 0xF0) | regd;
2602
                CodeLen = 2;
2603
                return;
2604
        }
2605
 
2606
        if (ArgCnt > 2)
2607
        {
2608
                WrStrErrorPos(ErrNum_TooManyArgs, &ArgStr[2]);
2609
                return;
2610
        }
2611
 
2612
        if (DecodeReg(&ArgStr[1], &regs, eRn))
2613
        {       /* (2) */
2614
                BAsmCode[0] = 0xFD;
2615
                BAsmCode[1] = OpTabSHAR[Index].Opc2;
2616
                BAsmCode[2] = (regs << 4) | regd;
2617
                CodeLen = 3;
2618
                return;
2619
        }
2620
 
2621
        WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
2622
}
2623
 
2624
static const struct {
2625
        Byte OpcIR;
2626
        Byte OpcRR;
2627
} OpTabSTNZ[] = {
2628
        { 0xF0, 0x4F }, /* STNZ */
2629
        { 0xE0, 0x4B }, /* STZ */
2630
};
2631
 
2632
static void DecodeSTNZ(Word Index)
2633
{
2634
        LongInt imm;
2635
        tSymbolFlags flags;
2636
        Byte regd;
2637
        Byte regs;
2638
        Byte size;
2639
 
2640
        if (!ChkNoAttr()) return;
2641
        if (!ChkArgCnt(2,2)) return;
2642
 
2643
        if (!DecodeReg(&ArgStr[2], &regd, eRn))
2644
        {
2645
                WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
2646
                return;
2647
        }
2648
 
2649
        if (DecodeImm(&ArgStr[1], &imm, &flags))
2650
        {
2651
                size = ImmSize32(imm, flags);
2652
 
2653
                BAsmCode[0] = 0xFD;
2654
                BAsmCode[1] = 0x70 | (size << 2);
2655
                BAsmCode[2] = OpTabSTNZ[Index].OpcIR | regd;
2656
                CodeLen = ImmOut(3, size, imm);
2657
                return;
2658
        }
2659
 
2660
        if (DecodeReg(&ArgStr[1], &regs, eRn))
2661
        {
2662
                if (!CheckV2()) return;
2663
 
2664
                BAsmCode[0] = 0xFC;
2665
                BAsmCode[1] = OpTabSTNZ[Index].OpcRR;
2666
                BAsmCode[2] = (regs << 4) | regd;
2667
                CodeLen = 3;
2668
                return;
2669
        }
2670
 
2671
        WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
2672
}
2673
 
2674
static const struct {
2675
        Byte Opc1;
2676
        Byte Opc2;
2677
        Byte Opc3;
2678
        Byte flags;
2679
} OpTabTST[] = {
2680
        { 0xC0, 0x30, 0x0C, 0x01 },     /* TST */
2681
        { 0,    0x40, 0x10, 0x00 },     /* XCHG */
2682
        { 0xD0, 0x34, 0x0D, 0x03 },     /* XOR */
2683
};
2684
 
2685
static void DecodeTST(Word Index)
2686
{
2687
        Byte reg1;
2688
        Byte reg2;
2689
        LongInt imm;
2690
        LongInt disp;
2691
        tSymbolFlags flags;
2692
        Byte size;
2693
        Byte memex;
2694
        Byte scale;
2695
 
2696
        if (!ChkNoAttr()) return;
2697
        if ((OpTabTST[Index].flags & 0x02) && ArgCnt == 3)
2698
        {
2699
                Byte reg3;
2700
 
2701
                if (!CheckV3()) return;
2702
 
2703
                if (!DecodeReg(&ArgStr[1], &reg1, eRn))
2704
                {
2705
                        WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
2706
                        return;        
2707
                }
2708
 
2709
                if (!DecodeReg(&ArgStr[2], &reg2, eRn))
2710
                {
2711
                        WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
2712
                        return;        
2713
                }
2714
 
2715
                if (!DecodeReg(&ArgStr[3], &reg3, eRn))
2716
                {
2717
                        WrStrErrorPos(ErrNum_InvArg, &ArgStr[3]);
2718
                        return;        
2719
                }
2720
 
2721
                BAsmCode[0] = 0xFF;
2722
                BAsmCode[1] = 0x60 | reg3;
2723
                BAsmCode[2] = (reg1 << 4) | reg2;
2724
                CodeLen = 3;
2725
                return;
2726
        }
2727
 
2728
        if (!ChkArgCnt(2,2)) return;
2729
 
2730
        if (!DecodeReg(&ArgStr[2], &reg2, eRn))
2731
        {
2732
                WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
2733
                return;        
2734
        }
2735
 
2736
        if ((OpTabTST[Index].flags & 0x01) &&
2737
                DecodeImm(&ArgStr[1], &imm, &flags))
2738
        {
2739
                size = ImmSize32(imm, flags);
2740
 
2741
                BAsmCode[0] = 0xFD;
2742
                BAsmCode[1] = 0x70 | (size << 2);
2743
                BAsmCode[2] = OpTabTST[Index].Opc1 | reg2;
2744
                CodeLen = ImmOut(3, size, imm);
2745
                return;
2746
        }
2747
 
2748
        if (DecodeReg(&ArgStr[1], &reg1, eRn))
2749
        {
2750
                BAsmCode[0] = 0xFC;
2751
                BAsmCode[1] = OpTabTST[Index].Opc2 | 0x03;
2752
                BAsmCode[2] = (reg1 << 4) | reg2;
2753
                CodeLen = 3;
2754
                return;
2755
        }
2756
 
2757
        if (DecodeIndirectADD(&ArgStr[1], &reg1, &disp, &flags, &memex, &scale))
2758
        {
2759
                if (memex == 0x80)
2760
                {
2761
                        size = DispSize(disp, flags, 1);
2762
 
2763
                        BAsmCode[0] = 0xFC;
2764
                        BAsmCode[1] = OpTabTST[Index].Opc2 | size;
2765
                        BAsmCode[2] = (reg1 << 4) | reg2;
2766
                        CodeLen = DispOut(3, size, disp, 1);
2767
                        return;
2768
                }
2769
 
2770
                size = DispSize(disp, flags, scale);
2771
 
2772
                BAsmCode[0] = 0x06;
2773
                BAsmCode[1] = 0x20 | (memex << 6) | size;
2774
                BAsmCode[2] = OpTabTST[Index].Opc3;
2775
                BAsmCode[3] = (reg1 << 4) | reg2;
2776
                CodeLen = DispOut(4, size, disp, scale);
2777
                return;
2778
        }
2779
 
2780
}
2781
 
2782
static void DecodeMOVCO(Word Index)
2783
{
2784
        Byte regs;
2785
        Byte regd;
2786
 
2787
        UNUSED(Index);
2788
 
2789
        if (!CheckV2()) return;
2790
 
2791
        if (!ChkNoAttr()) return;
2792
        if (!ChkArgCnt(2,2)) return;
2793
 
2794
        if (!DecodeReg(&ArgStr[1], &regs, eRn))
2795
        {
2796
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
2797
                return;
2798
        }
2799
 
2800
        if (!DecodeIndirect(&ArgStr[2], &regd))
2801
        {
2802
                WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
2803
                return;
2804
        }
2805
 
2806
        BAsmCode[0] = 0xFD;
2807
        BAsmCode[1] = 0x27;
2808
        BAsmCode[2] = (regd << 4) | regs;
2809
        CodeLen = 3;
2810
}
2811
 
2812
static void DecodeMOVLI(Word Index)
2813
{
2814
        Byte regs;
2815
        Byte regd;
2816
 
2817
        UNUSED(Index);
2818
 
2819
        if (!ChkNoAttr()) return;
2820
        if (!ChkArgCnt(2,2)) return;
2821
 
2822
        if (!DecodeIndirect(&ArgStr[1], &regs))
2823
        {
2824
                WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
2825
                return;
2826
        }
2827
 
2828
        if (!DecodeReg(&ArgStr[2], &regd, eRn))
2829
        {
2830
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
2831
                return;
2832
        }
2833
 
2834
        BAsmCode[0] = 0xFD;
2835
        BAsmCode[1] = 0x2F;
2836
        BAsmCode[2] = (regs << 4) | regd;
2837
        CodeLen = 3;
2838
}
2839
 
2840
static const Byte OpTabBFMOV[] = {
2841
        0x5E,   /* BFMOV */
2842
        0x5A,   /* BFMOVZ */
2843
};
2844
 
2845
static void DecodeBFMOV(Word Index)
2846
{
2847
        LongInt slsb;
2848
        LongInt dlsb;
2849
        LongInt width;
2850
        tSymbolFlags flags;
2851
        Byte regs;
2852
        Byte regd;
2853
 
2854
        if (!ChkNoAttr()) return;
2855
        if (!ChkArgCnt(5,5)) return;
2856
        if (!CheckV3()) return;
2857
 
2858
        if (!DecodeImm(&ArgStr[1], &slsb, &flags))
2859
        {
2860
                WrStrErrorPos(ErrNum_ExpectInt, &ArgStr[1]);
2861
                return;
2862
        }
2863
        if (!mFirstPassUnknownOrQuestionable(flags) && !ChkRange(slsb, 0, 31)) return;
2864
 
2865
        if (!DecodeImm(&ArgStr[2], &dlsb, &flags))
2866
        {
2867
                WrStrErrorPos(ErrNum_ExpectInt, &ArgStr[2]);
2868
                return;
2869
        }
2870
        if (!mFirstPassUnknownOrQuestionable(flags) && !ChkRange(dlsb, 0, 31)) return;
2871
 
2872
        if (!DecodeImm(&ArgStr[3], &width, &flags))
2873
        {
2874
                WrStrErrorPos(ErrNum_ExpectInt, &ArgStr[3]);
2875
                return;
2876
        }
2877
        if (!mFirstPassUnknownOrQuestionable(flags) && !ChkRange(width, 1, 31)) return;
2878
 
2879
        if (!DecodeReg(&ArgStr[4], &regs, eRn))
2880
        {
2881
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[4]);
2882
                return;
2883
        }
2884
 
2885
        if (!DecodeReg(&ArgStr[5], &regd, eRn))
2886
        {
2887
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[5]);
2888
                return;
2889
        }
2890
 
2891
        if (slsb + width > 32 || dlsb + width > 32)
2892
        {
2893
                WrError(ErrNum_OverRange);
2894
                return;
2895
        }
2896
 
2897
        BAsmCode[0] = 0xFC;
2898
        BAsmCode[1] = OpTabBFMOV[Index];
2899
        BAsmCode[2] = (regs << 4) | regd;
2900
        BAsmCode[3] = ((dlsb - slsb) & 0x1f) | ((dlsb << 5) & 0xE0);
2901
        BAsmCode[4] = ((dlsb >> 3) & 0x03) | (((dlsb + width) << 2) & 0x7C);
2902
        CodeLen = 5;
2903
}
2904
 
2905
static const struct {
2906
        Byte OpcI;
2907
        Byte OpcR;
2908
} OpTabRSTR[] = {
2909
        { 0xF0, 0xD0 }, /* RSTR */
2910
        { 0xE0, 0xC0 }, /* SAVE */
2911
};
2912
 
2913
static void DecodeRSTR(Word Index)
2914
{
2915
        LongInt imm;
2916
        tSymbolFlags flags;
2917
        Byte reg;
2918
 
2919
        if (!ChkNoAttr()) return;
2920
        if (!ChkArgCnt(1,1)) return;
2921
        if (!CheckV3()) return;
2922
 
2923
        if (!pCurrCPUProps->RegBank)
2924
        {
2925
                WrError(ErrNum_InstructionNotSupported);
2926
                return;
2927
        }
2928
 
2929
        if (DecodeImm(&ArgStr[1], &imm, &flags))
2930
        {
2931
                if (!ChkRange(imm, 0, pCurrCPUProps->RegBank - 1)) return;
2932
 
2933
                BAsmCode[0] = 0xFD;
2934
                BAsmCode[1] = 0x76;
2935
                BAsmCode[2] = OpTabRSTR[Index].OpcI;
2936
                BAsmCode[3] = imm;
2937
                CodeLen = 4;
2938
                return;
2939
        }
2940
 
2941
        if (DecodeReg(&ArgStr[1], &reg, eRn))
2942
        {
2943
                BAsmCode[0] = 0xFD;
2944
                BAsmCode[1] = 0x76;
2945
                BAsmCode[2] = OpTabRSTR[Index].OpcR | reg;
2946
                BAsmCode[3] = 0x00;
2947
                CodeLen = 4;
2948
                return;
2949
        }
2950
 
2951
        WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
2952
}
2953
 
2954
static const struct {
2955
        Byte Opc1;
2956
        Byte Opc2;
2957
} OpTabDABS[] = {
2958
        { 0x0C, 0x01 }, /* DABS */
2959
        { 0x0C, 0x02 }, /* DNEG */
2960
        { 0x0D, 0x0D }, /* DROUND */
2961
        { 0x0D, 0x00 }, /* DSQRT */
2962
        { 0x0D, 0x0C }, /* DTOF */
2963
        { 0x0D, 0x08 }, /* DTOI */
2964
        { 0x0D, 0x09 }, /* DTOU */
2965
};
2966
 
2967
static void DecodeDABS(Word Index)
2968
{
2969
        Byte regs;
2970
        Byte regd;
2971
 
2972
        if (!ChkNoAttr()) return;
2973
        if (!ChkArgCnt(2,2)) return;
2974
        if (!CheckV3()) return;
2975
        if (!CheckDouble()) return;
2976
 
2977
        if (!DecodeReg(&ArgStr[1], &regs, eDRn))
2978
        {
2979
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
2980
                return;
2981
        }
2982
 
2983
        if (!DecodeReg(&ArgStr[2], &regd, eDRn))
2984
        {
2985
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
2986
                return;
2987
        }
2988
 
2989
        BAsmCode[0] = 0x76;
2990
        BAsmCode[1] = 0x90;
2991
        BAsmCode[2] = OpTabDABS[Index].Opc1 | (regs << 4);
2992
        BAsmCode[3] = OpTabDABS[Index].Opc2 | (regd << 4);
2993
        CodeLen = 4;
2994
}
2995
 
2996
static const struct {
2997
        Byte Opc;
2998
} OpTabDADD[] = {
2999
        { 0x00 },       /* DADD */
3000
        { 0x05 },       /* DDIV */
3001
        { 0x02 },       /* DMUL */
3002
        { 0x01 },       /* DSUB */
3003
};
3004
 
3005
static void DecodeDADD(Word Index)
3006
{
3007
        Byte regs1;
3008
        Byte regs2;
3009
        Byte regd;
3010
 
3011
        if (!ChkNoAttr()) return;
3012
        if (!ChkArgCnt(3,3)) return;
3013
        if (!CheckV3()) return;
3014
        if (!CheckDouble()) return;
3015
 
3016
        if (!DecodeReg(&ArgStr[1], &regs1, eDRn))
3017
        {
3018
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
3019
                return;
3020
        }
3021
 
3022
        if (!DecodeReg(&ArgStr[2], &regs2, eDRn))
3023
        {
3024
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
3025
                return;
3026
        }
3027
 
3028
        if (!DecodeReg(&ArgStr[3], &regd, eDRn))
3029
        {
3030
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[3]);
3031
                return;
3032
        }
3033
 
3034
        BAsmCode[0] = 0x76;
3035
        BAsmCode[1] = 0x90;
3036
        BAsmCode[2] = OpTabDADD[Index].Opc | (regs2 << 4);
3037
        BAsmCode[3] = (regd << 4) | regs1;
3038
        CodeLen = 4;
3039
}
3040
 
3041
static void DecodeDCMPcm(Word Index)
3042
{
3043
        Byte regs1;
3044
        Byte regs2;
3045
 
3046
        if (!ChkNoAttr()) return;
3047
        if (!ChkArgCnt(2,2)) return;
3048
        if (!CheckV3()) return;
3049
        if (!CheckDouble()) return;
3050
 
3051
        if (!DecodeReg(&ArgStr[1], &regs1, eDRn))
3052
        {
3053
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
3054
                return;
3055
        }
3056
 
3057
        if (!DecodeReg(&ArgStr[2], &regs2, eDRn))
3058
        {
3059
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
3060
                return;
3061
        }
3062
 
3063
        BAsmCode[0] = 0x76;
3064
        BAsmCode[1] = 0x90;
3065
        BAsmCode[2] = 0x08 | (regs2 << 4);
3066
        BAsmCode[3] = ((Index << 4) & 0xF0) | regs1;
3067
        CodeLen = 4;
3068
}
3069
 
3070
static void DecodeDMOV(Word Index)
3071
{
3072
        Byte size;
3073
        Byte regs;
3074
        Byte regd;
3075
        LongInt disp;
3076
        LongInt imm;
3077
        tSymbolFlags flags;
3078
        Byte dsize;
3079
 
3080
        UNUSED(Index);
3081
 
3082
        if (!ChkArgCnt(2,2)) return;
3083
        if (!CheckV3()) return;
3084
        if (!CheckDouble()) return;
3085
 
3086
        if (!DecodeAttrDouble(&size)) return;
3087
 
3088
        if (DecodeReg(&ArgStr[1], &regs, eRn))
3089
        {
3090
                if (DecodeReg(&ArgStr[2], &regd, eDRHn))
3091
                {       /* (1) / (2) */
3092
                        BAsmCode[0] = 0xFD;
3093
                        BAsmCode[1] = 0x77;
3094
                        BAsmCode[2] = 0x80 | regs;
3095
                        BAsmCode[3] = 0x02 | (regd << 4) | size;
3096
                        CodeLen = 4;
3097
                        return;
3098
                }
3099
 
3100
                if (DecodeReg(&ArgStr[2], &regd, eDRLn) && !size)
3101
                {       /* (3) */
3102
                        BAsmCode[0] = 0xFD;
3103
                        BAsmCode[1] = 0x77;
3104
                        BAsmCode[2] = 0x80 | regs;
3105
                        BAsmCode[3] = 0x00 | (regd << 4);
3106
                        CodeLen = 4;
3107
                        return;
3108
                }
3109
        }
3110
 
3111
        if (DecodeReg(&ArgStr[2], &regd, eRn))
3112
        {
3113
                if (DecodeReg(&ArgStr[1], &regs, eDRHn) && !size)
3114
                {       /* (4) */
3115
                        BAsmCode[0] = 0xFD;
3116
                        BAsmCode[1] = 0x75;
3117
                        BAsmCode[2] = 0x80 | regd;
3118
                        BAsmCode[3] = 0x02 | (regs << 4);
3119
                        CodeLen = 4;
3120
                        return;
3121
                }
3122
 
3123
                if (DecodeReg(&ArgStr[1], &regs, eDRLn) && !size)
3124
                {       /* (5) */
3125
                        BAsmCode[0] = 0xFD;
3126
                        BAsmCode[1] = 0x75;
3127
                        BAsmCode[2] = 0x80 | regd;
3128
                        BAsmCode[3] = 0x00 | (regs << 4);
3129
                        CodeLen = 4;
3130
                        return;
3131
                }
3132
        }
3133
 
3134
        if (DecodeReg(&ArgStr[1], &regs, eDRn) && size)
3135
        {
3136
                if (DecodeReg(&ArgStr[2], &regd, eDRn))
3137
                {       /* (6) */
3138
                        BAsmCode[0] = 0xFD;
3139
                        BAsmCode[1] = 0x90;
3140
                        BAsmCode[2] = 0x0C | (regs << 4);
3141
                        BAsmCode[3] = 0x00 | (regd << 4);
3142
                        CodeLen = 4;
3143
                        return;
3144
                }
3145
 
3146
                if (DecodeIndirectADC(&ArgStr[2], &regd, &disp, &flags) && size)
3147
                {       /* (7) */
3148
                        dsize = DispSize(disp, flags, 8);
3149
 
3150
                        BAsmCode[0] = 0xFC;
3151
                        BAsmCode[1] = 0x78 | dsize;
3152
                        BAsmCode[2] = 0x08 | (regd << 4);
3153
                        CodeLen = DispOut(3, dsize, disp, 8);
3154
                        BAsmCode[CodeLen++] = 0x00 | (regs << 4);
3155
                        return;
3156
                }
3157
        }
3158
 
3159
        if (DecodeIndirectADC(&ArgStr[1], &regs, &disp, &flags) && size)
3160
        {
3161
                if (DecodeReg(&ArgStr[2], &regd, eDRn))
3162
                {       /* (8) */
3163
                        dsize = DispSize(disp, flags, 8);
3164
 
3165
                        BAsmCode[0] = 0xFC;
3166
                        BAsmCode[1] = 0xC8 | dsize;
3167
                        BAsmCode[2] = 0x08 | (regs << 4);
3168
                        CodeLen = DispOut(3, dsize, disp, 8);
3169
                        BAsmCode[CodeLen++] = 0x00 | (regd << 4);
3170
                        return;
3171
                }
3172
        }
3173
 
3174
        if (DecodeImm(&ArgStr[1], &imm, &flags))
3175
        {
3176
                if (DecodeReg(&ArgStr[2], &regd, eDRHn))
3177
                {       /* (9) / (10) */
3178
                        BAsmCode[0] = 0xF9;
3179
                        BAsmCode[1] = 0x03;
3180
                        BAsmCode[2] = 0x02 | (regd << 4) | size;
3181
                        CodeLen = ImmOut(3, 0, imm);
3182
                        return;
3183
                }
3184
 
3185
                if (DecodeReg(&ArgStr[2], &regd, eDRLn) && !size)
3186
                {       /* (11) */
3187
                        BAsmCode[0] = 0xF9;
3188
                        BAsmCode[1] = 0x03;
3189
                        BAsmCode[2] = 0x00 | (regd << 4);
3190
                        CodeLen = ImmOut(3, 0, imm);
3191
                        return;
3192
                }
3193
        }
3194
 
3195
        WrError(ErrNum_InvArg);
3196
}
3197
 
3198
static const Byte OpTabDPOPM[] = {
3199
        0xA8,   /* DPOPM */
3200
        0xA0    /* DPUSHM */
3201
};
3202
 
3203
static void DecodeDPOPM(Word Index)
3204
{
3205
        const int len = strlen(ArgStr[1].str.p_str);
3206
        Byte size;
3207
        Byte reg1;
3208
        Byte reg2;
3209
        int i;
3210
 
3211
        if (!DecodeAttrDouble(&size)) return;
3212
        if (!ChkArgCnt(1,1)) return;
3213
        if (!CheckV3()) return;
3214
        if (!CheckDouble()) return;
3215
 
3216
        for (i = 0; i < len; i++)
3217
        {
3218
                if (ArgStr[1].str.p_str[i] == '-') break;
3219
        }
3220
        if (i >= len)
3221
        {
3222
                WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
3223
                return;
3224
        }
3225
 
3226
        StrCompCopySub(&Temp1, &ArgStr[1], 0, i);
3227
        if (!DecodeReg(&Temp1, &reg1, size ? eDRn : eDCRn))
3228
        {
3229
                WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
3230
                return;
3231
        }
3232
 
3233
        StrCompCopySub(&Temp1, &ArgStr[1], i + 1, len - i - 1);
3234
        if (!DecodeReg(&Temp1, &reg2, size ? eDRn : eDCRn))
3235
        {
3236
                WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
3237
                return;
3238
        }
3239
 
3240
        if (reg2 >= reg1)
3241
        {
3242
                BAsmCode[0] = 0x75;
3243
                BAsmCode[1] = OpTabDPOPM[Index] | (size << 4);
3244
                BAsmCode[2] = (reg1 << 4) | (reg2 - reg1);
3245
                CodeLen = 3;
3246
                return;
3247
        }
3248
 
3249
        WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
3250
}
3251
 
3252
static const struct {
3253
        Byte Opc1;
3254
        Byte Opc2;
3255
} OpTabFTOD[] = {
3256
        { 0x80, 0x0A }, /* FTOD */
3257
        { 0x80, 0x09 }, /* ITOD */
3258
        { 0x80, 0x0D }, /* UTOD */
3259
};
3260
 
3261
static void DecodeFTOD(Word Index)
3262
{
3263
        Byte regs;
3264
        Byte regd;
3265
 
3266
        UNUSED(Index);
3267
 
3268
        if (!ChkNoAttr()) return;
3269
        if (!ChkArgCnt(2,2)) return;
3270
        if (!CheckV3()) return;
3271
        if (!CheckDouble()) return;
3272
 
3273
        if (!DecodeReg(&ArgStr[1], &regs, eRn))
3274
        {
3275
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
3276
                return;
3277
        }
3278
 
3279
        if (!DecodeReg(&ArgStr[2], &regd, eDRn))
3280
        {
3281
                WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
3282
                return;
3283
        }
3284
 
3285
        BAsmCode[0] = 0xFD;
3286
        BAsmCode[1] = 0x77;
3287
        BAsmCode[2] = OpTabFTOD[Index].Opc1 | regs;
3288
        BAsmCode[3] = OpTabFTOD[Index].Opc2 | (regd << 4);
3289
        CodeLen = 4;
3290
}
3291
 
3292
static void DecodeMVFDC(Word Index)
3293
{
3294
        Byte regc;
3295
        Byte reg;
3296
 
3297
        UNUSED(Index);
3298
 
3299
        if (!ChkNoAttr()) return;
3300
        if (!ChkArgCnt(2,2)) return;
3301
        if (!CheckV3()) return;
3302
        if (!CheckDouble()) return;
3303
 
3304
        if (!DecodeReg(&ArgStr[Index + 1], &regc, eDCRn))
3305
        {
3306
                WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[Index + 1]);
3307
                return;
3308
        }
3309
 
3310
        if (!DecodeReg(&ArgStr[2 - Index], &reg, eRn))
3311
        {
3312
                WrStrErrorPos(ErrNum_InvReg, &ArgStr[2 - Index]);
3313
                return;
3314
        }
3315
 
3316
        BAsmCode[0] = 0xFD;
3317
        BAsmCode[1] = 0x75 | (Index << 1);
3318
        BAsmCode[2] = 0x80 | reg;
3319
        BAsmCode[3] = 0x04 | (regc << 4);
3320
        CodeLen = 4;
3321
}
3322
 
3323
static void DecodeMVFDR(Word Index)
3324
{
3325
        UNUSED(Index);
3326
 
3327
        if (!ChkNoAttr()) return;
3328
        if (!ChkArgCnt(0,0)) return;
3329
        if (!CheckV3()) return;
3330
        if (!CheckDouble()) return;
3331
 
3332
        BAsmCode[0] = 0x75;
3333
        BAsmCode[1] = 0x90;
3334
        BAsmCode[2] = 0x1B;
3335
        CodeLen = 3;
3336
}
3337
 
3338
#ifdef COMPAT
3339
 
3340
#define BigEndianSymName "BIGENDIAN" /* T.B.D. */
3341
static void DecodeENDIAN(Word Index)
3342
{
3343
        const char *str;
3344
 
3345
        UNUSED(Index);
3346
 
3347
        if (!ChkNoAttr()) return;
3348
        if (!ChkArgCnt(1,1)) return;
3349
 
3350
        str = ArgStr[1].str.p_str;
3351
        if (!as_strcasecmp(str, "BIG"))
3352
                SetFlag(&TargetBigEndian, BigEndianSymName, True);
3353
        else if (!as_strcasecmp(str, "LITTLE"))
3354
                SetFlag(&TargetBigEndian, BigEndianSymName, False);
3355
        else
3356
                WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
3357
}
3358
 
3359
#endif /* COMPAT */
3360
 
3361
/*---------------------------------------------------------------------------*/
3362
 
3363
static void AddABS(const char *NName, Word NCode)
3364
{
3365
        AddInstTable(InstTable, NName, NCode, DecodeABS);
3366
}
3367
 
3368
static void AddADC(const char *NName, Word NCode)
3369
{
3370
        AddInstTable(InstTable, NName, NCode, DecodeADC);
3371
}
3372
 
3373
static void AddADD(const char *NName, Word NCode)
3374
{
3375
        AddInstTable(InstTable, NName, NCode, DecodeADD);
3376
}
3377
 
3378
static void AddBCLR(const char *NName, Word NCode)
3379
{
3380
        AddInstTable(InstTable, NName, NCode, DecodeBCLR);
3381
}
3382
 
3383
static void AddBCnd(const char *NName, Word NCode)
3384
{
3385
        AddInstTable(InstTable, NName, NCode, DecodeBCnd);
3386
}
3387
 
3388
static void AddBMCnd(const char *NName, Word NCode)
3389
{
3390
        AddInstTable(InstTable, NName, NCode, DecodeBMCnd);
3391
}
3392
 
3393
static void AddBRK(const char *NName, Word NCode)
3394
{
3395
        AddInstTable(InstTable, NName, NCode, DecodeBRK);
3396
}
3397
 
3398
static void AddBSR(const char *NName, Word NCode)
3399
{
3400
        AddInstTable(InstTable, NName, NCode, DecodeBSR);
3401
}
3402
 
3403
static void AddCLRPSW(const char *NName, Word NCode)
3404
{
3405
        AddInstTable(InstTable, NName, NCode, DecodeCLRPSW);
3406
}
3407
 
3408
static void AddDIV(const char *NName, Word NCode)
3409
{
3410
        AddInstTable(InstTable, NName, NCode, DecodeDIV);
3411
}
3412
 
3413
static void AddFADD(const char *NName, Word NCode)
3414
{
3415
        AddInstTable(InstTable, NName, NCode, DecodeFADD);
3416
}
3417
 
3418
static void AddINT(const char *NName, Word NCode)
3419
{
3420
        AddInstTable(InstTable, NName, NCode, DecodeINT);
3421
}
3422
 
3423
static void AddITOF(const char *NName, Word NCode)
3424
{
3425
        AddInstTable(InstTable, NName, NCode, DecodeITOF);
3426
}
3427
 
3428
static void AddJMP(const char *NName, Word NCode)
3429
{
3430
        AddInstTable(InstTable, NName, NCode, DecodeJMP);
3431
}
3432
 
3433
static void AddMACHI(const char *NName, Word NCode)
3434
{
3435
        AddInstTable(InstTable, NName, NCode, DecodeMACHI);
3436
}
3437
 
3438
static void AddMOV(const char *NName, Word NCode)
3439
{
3440
        AddInstTable(InstTable, NName, NCode, DecodeMOV);
3441
}
3442
 
3443
static void AddMOVU(const char *NName, Word NCode)
3444
{
3445
        AddInstTable(InstTable, NName, NCode, DecodeMOVU);
3446
}
3447
 
3448
static void AddMVFACHI(const char *NName, Word NCode)
3449
{
3450
        AddInstTable(InstTable, NName, NCode, DecodeMVFACHI);
3451
}
3452
 
3453
static void AddMVFC(const char *NName, Word NCode)
3454
{
3455
        AddInstTable(InstTable, NName, NCode, DecodeMVFC);
3456
}
3457
 
3458
static void AddMVTACHI(const char *NName, Word NCode)
3459
{
3460
        AddInstTable(InstTable, NName, NCode, DecodeMVTACHI);
3461
}
3462
 
3463
static void AddMVTC(const char *NName, Word NCode)
3464
{
3465
        AddInstTable(InstTable, NName, NCode, DecodeMVTC);
3466
}
3467
 
3468
static void AddMVTIPL(const char *NName, Word NCode)
3469
{
3470
        AddInstTable(InstTable, NName, NCode, DecodeMVTIPL);
3471
}
3472
 
3473
static void AddPOPC(const char *NName, Word NCode)
3474
{
3475
        AddInstTable(InstTable, NName, NCode, DecodePOPC);
3476
}
3477
 
3478
static void AddPOPM(const char *NName, Word NCode)
3479
{
3480
        AddInstTable(InstTable, NName, NCode, DecodePOPM);
3481
}
3482
 
3483
static void AddPUSH(const char *NName, Word NCode)
3484
{
3485
        AddInstTable(InstTable, NName, NCode, DecodePUSH);
3486
}
3487
 
3488
static void AddRACW(const char *NName, Word NCode)
3489
{
3490
        AddInstTable(InstTable, NName, NCode, DecodeRACW);
3491
}
3492
 
3493
static void AddRMPA(const char *NName, Word NCode)
3494
{
3495
        AddInstTable(InstTable, NName, NCode, DecodeRMPA);
3496
}
3497
 
3498
static void AddROTL(const char *NName, Word NCode)
3499
{
3500
        AddInstTable(InstTable, NName, NCode, DecodeROTL);
3501
}
3502
 
3503
static void AddRTE(const char *NName, Word NCode)
3504
{
3505
        AddInstTable(InstTable, NName, NCode, DecodeRTE);
3506
}
3507
 
3508
static void AddRTSD(const char *NName, Word NCode)
3509
{
3510
        AddInstTable(InstTable, NName, NCode, DecodeRTSD);
3511
}
3512
 
3513
static void AddSCCnd(const char *NName, Word NCode)
3514
{
3515
        AddInstTable(InstTable, NName, NCode, DecodeSCCnd);
3516
}
3517
 
3518
static void AddSHAR(const char *NName, Word NCode)
3519
{
3520
        AddInstTable(InstTable, NName, NCode, DecodeSHAR);
3521
}
3522
 
3523
static void AddSTNZ(const char *NName, Word NCode)
3524
{
3525
        AddInstTable(InstTable, NName, NCode, DecodeSTNZ);
3526
}
3527
 
3528
static void AddTST(const char *NName, Word NCode)
3529
{
3530
        AddInstTable(InstTable, NName, NCode, DecodeTST);
3531
}
3532
 
3533
static void AddMOVCO(const char *NName, Word NCode)
3534
{
3535
        AddInstTable(InstTable, NName, NCode, DecodeMOVCO);
3536
}
3537
 
3538
static void AddMOVLI(const char *NName, Word NCode)
3539
{
3540
        AddInstTable(InstTable, NName, NCode, DecodeMOVLI);
3541
}
3542
 
3543
static void AddBFMOV(const char *NName, Word NCode)
3544
{
3545
        AddInstTable(InstTable, NName, NCode, DecodeBFMOV);
3546
}
3547
 
3548
static void AddRSTR(const char *NName, Word NCode)
3549
{
3550
        AddInstTable(InstTable, NName, NCode, DecodeRSTR);
3551
}
3552
 
3553
static void AddDABS(const char *NName, Word NCode)
3554
{
3555
        AddInstTable(InstTable, NName, NCode, DecodeDABS);
3556
}
3557
 
3558
static void AddDADD(const char *NName, Word NCode)
3559
{
3560
        AddInstTable(InstTable, NName, NCode, DecodeDADD);
3561
}
3562
 
3563
static void AddDCMPcm(const char *NName, Word NCode)
3564
{
3565
        AddInstTable(InstTable, NName, NCode, DecodeDCMPcm);
3566
}
3567
 
3568
static void AddDMOV(const char *NName, Word NCode)
3569
{
3570
        AddInstTable(InstTable, NName, NCode, DecodeDMOV);
3571
}
3572
 
3573
static void AddDPOPM(const char *NName, Word NCode)
3574
{
3575
        AddInstTable(InstTable, NName, NCode, DecodeDPOPM);
3576
}
3577
 
3578
static void AddFTOD(const char *NName, Word NCode)
3579
{
3580
        AddInstTable(InstTable, NName, NCode, DecodeFTOD);
3581
}
3582
 
3583
static void AddMVFDC(const char *NName, Word NCode)
3584
{
3585
        AddInstTable(InstTable, NName, NCode, DecodeMVFDC);
3586
}
3587
 
3588
static void AddMVFDR(const char *NName, Word NCode)
3589
{
3590
        AddInstTable(InstTable, NName, NCode, DecodeMVFDR);
3591
}
3592
 
3593
#ifdef COMPAT
3594
 
3595
static void AddBLK(const char *NName, Word NCode)
3596
{
3597
        AddInstTable(InstTable, NName, NCode, DecodeIntelDS);
3598
}
3599
 
3600
#endif /* COMPAT */
3601
 
3602
static Boolean TrueFnc(void)
3603
{
3604
  return True;
3605
}
3606
 
3607
static void InitFields(void)
3608
{
3609
        InstTable = CreateInstTable(201);
3610
 
3611
  add_null_pseudo(InstTable);
3612
 
3613
        /* RXv1 */
3614
        AddABS("ABS", 0x200F);
3615
        AddADC("ADC", 0x0802);
3616
        AddADD("ADD", 0);
3617
        AddADD("AND", 1);
3618
        AddBCLR("BCLR", 0);
3619
        AddBCnd("BEQ",  0);
3620
        AddBCnd("BZ",   0);
3621
        AddBCnd("BNE",  1);
3622
        AddBCnd("BNZ",  1);
3623
        AddBCnd("BGEU", 2);
3624
        AddBCnd("BC",   2);
3625
        AddBCnd("BLTU", 3);
3626
        AddBCnd("BNC",  3);
3627
        AddBCnd("BGTU", 4);
3628
        AddBCnd("BLEU", 5);
3629
        AddBCnd("BPZ",  6);
3630
        AddBCnd("BN",   7);
3631
        AddBCnd("BGE",  8);
3632
        AddBCnd("BLT",  9);
3633
        AddBCnd("BGT",  10);
3634
        AddBCnd("BLE",  11);
3635
        AddBCnd("BO",   12);
3636
        AddBCnd("BNO",  13);
3637
        AddBMCnd("BMEQ",  0);
3638
        AddBMCnd("BMZ", 0);
3639
        AddBMCnd("BMNE", 1);
3640
        AddBMCnd("BMNZ", 1);
3641
        AddBMCnd("BMGEU", 2);
3642
        AddBMCnd("BMC", 2);
3643
        AddBMCnd("BMLTU", 3);
3644
        AddBMCnd("BMNC", 3);
3645
        AddBMCnd("BMGTU", 4);
3646
        AddBMCnd("BMLEU", 5);
3647
        AddBMCnd("BMPZ", 6);
3648
        AddBMCnd("BMN", 7);
3649
        AddBMCnd("BMGE", 8);
3650
        AddBMCnd("BMLT", 9);
3651
        AddBMCnd("BMGT", 10);
3652
        AddBMCnd("BMLE", 11);
3653
        AddBMCnd("BMO", 12);
3654
        AddBMCnd("BMNO", 13);
3655
        AddBCLR("BNOT", 1);
3656
        AddBCnd("BRA", 14);
3657
        AddBRK("BRK", 0x0000);
3658
        AddBCLR("BSET", 2);
3659
        AddBSR("BSR", 0);
3660
        AddBCLR("BTST", 3);
3661
        AddCLRPSW("CLRPSW", 0xB0);
3662
        AddADD("CMP", 2);
3663
        AddDIV("DIV", 0);
3664
        AddDIV("DIVU", 1);
3665
        AddDIV("EMUL", 2);
3666
        AddDIV("EMULU", 3);
3667
        AddFADD("FADD", 0);
3668
        AddFADD("FCMP", 1);
3669
        AddFADD("FDIV", 2);
3670
        AddFADD("FMUL", 3);
3671
        AddFADD("FSUB", 4);
3672
        AddFADD("FTOI", 5);
3673
        AddINT("INT", 0);
3674
        AddITOF("ITOF", 0);
3675
        AddJMP("JMP", 0);
3676
        AddJMP("JSR", 1);
3677
        AddMACHI("MACHI", 0);
3678
        AddMACHI("MACLO", 1);
3679
        AddDIV("MAX", 4);
3680
        AddDIV("MIN", 5);
3681
        AddMOV("MOV", 0);
3682
        AddMOVU("MOVU", 0);
3683
        AddADD("MUL", 3);
3684
        AddMACHI("MULHI", 2);
3685
        AddMACHI("MULLO", 3);
3686
        AddMVFACHI("MVFACHI", 0);
3687
        AddMVFACHI("MVFACMI", 1);
3688
        AddMVFC("MVFC", 0);
3689
        AddMVTACHI("MVTACHI", 0);
3690
        AddMVTACHI("MVTACLO", 1);
3691
        AddMVTC("MVTC", 0);
3692
        AddMVTIPL("MVTIPL", 0);
3693
        AddABS("NEG", 0x1007);
3694
        AddBRK("NOP", 0x0003);
3695
        AddABS("NOT", 0x003B);
3696
        AddADD("OR", 4);
3697
        AddJMP("POP", 2);
3698
        AddPOPC("POPC", 0);
3699
        AddPOPM("POPM", 0);
3700
        AddPUSH("PUSH", 0);
3701
        AddPOPC("PUSHC", 1);
3702
        AddPOPM("PUSHM", 1);
3703
        AddRACW("RACW", 0);
3704
        AddMACHI("REVL", 4);
3705
        AddMACHI("REVW", 5);
3706
        AddRMPA("RMPA", 0x8C);
3707
        AddJMP("ROLC", 3);
3708
        AddJMP("RORC", 4);
3709
        AddROTL("ROTL", 0);
3710
        AddROTL("ROTR", 1);
3711
        AddFADD("ROUND", 6);
3712
        AddRTE("RTE", 0x7F95);
3713
        AddRTE("RTFI", 0x7F94);
3714
        AddBRK("RTS", 0x0002);
3715
        AddRTSD("RTSD", 0);
3716
        AddJMP("SAT", 5);
3717
        AddRTE("SATR", 0x7F93);
3718
        AddADC("SBB", 0x0000);
3719
        AddSCCnd("SCEQ", 0);
3720
        AddSCCnd("SCZ", 0);
3721
        AddSCCnd("SCNE", 1);
3722
        AddSCCnd("SCNZ", 1);
3723
        AddSCCnd("SCGEU", 2);
3724
        AddSCCnd("SCC", 2);
3725
        AddSCCnd("SCLTU", 3);
3726
        AddSCCnd("SCNC", 3);
3727
        AddSCCnd("SCGTU", 4);
3728
        AddSCCnd("SCLEU", 5);
3729
        AddSCCnd("SCPZ", 6);
3730
        AddSCCnd("SCN", 7);
3731
        AddSCCnd("SCGE", 8);
3732
        AddSCCnd("SCLT", 9);
3733
        AddSCCnd("SCGT", 10);
3734
        AddSCCnd("SCLE", 11);
3735
        AddSCCnd("SCO", 12);
3736
        AddSCCnd("SCNO", 13);
3737
        AddRTE("SCMPU", 0x7F83);
3738
        AddCLRPSW("SETPSW", 0xA0);
3739
        AddSHAR("SHAR", 0);
3740
        AddSHAR("SHLL", 1);
3741
        AddSHAR("SHLR", 2);
3742
        AddRTE("SMOVB", 0x7F8B);
3743
        AddRTE("SMOVF", 0x7F8F);
3744
        AddRTE("SMOVU", 0x7F87);
3745
        AddRMPA("SSTR", 0x88);
3746
        AddSTNZ("STNZ", 0);
3747
        AddSTNZ("STZ", 1);
3748
        AddADD("SUB", 5);
3749
        AddRMPA("SUNTIL", 0x80);
3750
        AddRMPA("SWHILE", 0x84);
3751
        AddTST("TST", 0);
3752
        AddRTE("WAIT", 0x7F96);
3753
        AddTST("XCHG", 1);
3754
        AddTST("XOR", 2);
3755
 
3756
        /* RXv2 */
3757
        AddFADD("FSQRT", 7);
3758
        AddFADD("FTOU", 8);
3759
        AddITOF("UTOF", 1);
3760
        AddMOVCO("MOVCO", 0);
3761
        AddMOVLI("MOVLI", 0);
3762
        AddMACHI("EMACA", 6);
3763
        AddMACHI("EMSBA", 7);
3764
        AddMACHI("EMULA", 8);
3765
        AddMACHI("MACLH", 9);
3766
        AddMACHI("MSBHI", 10);
3767
        AddMACHI("MSBLH", 11);
3768
        AddMACHI("MSBLO", 12);
3769
        AddMACHI("MULLH", 13);
3770
        AddMVFACHI("MVFACGU", 2);
3771
        AddMVFACHI("MVFACLO", 3);
3772
        AddMVTACHI("MVTACGU", 2);
3773
        AddRACW("RACL", 1);
3774
        AddRACW("RDACL", 2);
3775
        AddRACW("RDACW", 3);
3776
 
3777
        /* RXv3 */
3778
        AddBFMOV("BFMOV", 0);
3779
        AddBFMOV("BFMOVZ", 1);
3780
        AddRSTR("RSTR", 0);
3781
        AddRSTR("SAVE", 1); SaveIsOccupiedFnc = TrueFnc;
3782
        AddDABS("DABS", 0);
3783
        AddDADD("DADD", 0);
3784
        AddDCMPcm("DCMPUN", 0x01);
3785
        AddDCMPcm("DCMPEQ", 0x02);
3786
        AddDCMPcm("DCMPLT", 0x04);
3787
        AddDCMPcm("DCMPLE", 0x06);
3788
        AddDADD("DDIV", 1);
3789
        AddDMOV("DMOV", 0);
3790
        AddDADD("DMUL", 2);
3791
        AddDABS("DNEG", 1);
3792
        AddDPOPM("DPOPM", 0);
3793
        AddDPOPM("DPUSHM", 1);
3794
        AddDABS("DROUND", 2);
3795
        AddDABS("DSQRT", 3);
3796
        AddDADD("DSUB", 3);
3797
        AddDABS("DTOF", 4);
3798
        AddDABS("DTOI", 5);
3799
        AddDABS("DTOU", 6);
3800
        AddFTOD("FTOD", 0);
3801
        AddFTOD("ITOD", 1);
3802
        AddMVFDC("MVFDC", 0);
3803
        AddMVFDR("MVFDR", 0);
3804
        AddMVFDC("MVTDC", 1);
3805
        AddFTOD("UTOD", 2);
3806
 
3807
        /* Pseudo Instructions */
3808
#ifdef COMPAT
3809
        AddInstTable(InstTable, "ENDIAN", 0, DecodeENDIAN);
3810
        AddBLK("BLKB", 1);
3811
        AddBLK("BLKW", 2);
3812
        AddBLK("BLKL", 4);
3813
        AddBLK("BLKD", 8);
3814
        AddInstTable(InstTable, "BYTE", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString, DecodeIntelDB);
3815
        AddInstTable(InstTable, "WORD", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowInt, DecodeIntelDW);
3816
        AddInstTable(InstTable, "LWORD", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowInt, DecodeIntelDD);
3817
        AddInstTable(InstTable, "FLOAT", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowFloat, DecodeIntelDD);
3818
        AddInstTable(InstTable, "DOUBLE", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowFloat, DecodeIntelDQ);
3819
#endif
3820
 
3821
        StrCompAlloc(&Temp1, STRINGSIZE);
3822
        StrCompAlloc(&Temp2, STRINGSIZE);
3823
}
3824
 
3825
static void DeinitFields(void)
3826
{
3827
        StrCompFree(&Temp2);
3828
        StrCompFree(&Temp1);
3829
 
3830
        DestroyInstTable(InstTable);
3831
}
3832
 
3833
/*---------------------------------------------------------------------------*/
3834
 
3835
static void MakeCode_RX(void)
3836
{
3837
        if (!LookupInstTable(InstTable, OpPart.str.p_str))
3838
                WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
3839
}
3840
 
3841
static Boolean IsDef_RX(void)
3842
{
3843
        return False;
3844
}
3845
 
3846
static void SwitchFrom_RX(void)
3847
{
3848
        DeinitFields();
3849
}
3850
 
3851
static void SwitchTo_RX(void *pUser)
3852
{
3853
        const TFamilyDescr *pDescr;
3854
 
3855
        TurnWords = False;
3856
        SetIntConstMode(eIntConstModeIntel);
3857
 
3858
        pDescr = FindFamilyByName("RX");
3859
        PCSymbol = "$";
3860
        HeaderID = pDescr->Id;
3861
        NOPCode = 0x03;
3862
        DivideChars = ",";
3863
        HasAttrs = True;
3864
        AttrChars = ".";
3865
 
3866
        ValidSegs = (1 << SegCode);
3867
        Grans[SegCode] = 1;
3868
        ListGrans[SegCode] = 1;
3869
        SegInits[SegCode] = 0x0000;
3870
        SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
3871
 
3872
        MakeCode = MakeCode_RX;
3873
        IsDef = IsDef_RX;
3874
        SwitchFrom = SwitchFrom_RX;
3875
        InitFields();
3876
        onoff_supmode_add();
3877
        onoff_bigendian_add();
3878
 
3879
        pCurrCPUProps = (const tCPUProps *)pUser;
3880
}
3881
 
3882
static const tCPUProps CPUProps[] =
3883
{
3884
        /* Group   InsSet FLT    DBL    RegB MVTIPL */
3885
        { "RXV1",  eRXv1, True,  False, 0,   True  },   /* Generic RXv1 (Full option) */
3886
        { "RX110", eRXv1, False, False, 0,   True  },
3887
        { "RX111", eRXv1, False, False, 0,   True  },
3888
        { "RX113", eRXv1, False, False, 0,   True  },
3889
        { "RX130", eRXv1, False, False, 0,   True  },
3890
        { "RX210", eRXv1, False, False, 0,   True  },
3891
        { "RX21A", eRXv1, False, False, 0,   True  },
3892
        { "RX220", eRXv1, False, False, 0,   True  },
3893
        { "RX610", eRXv1, True,  False, 0,   False },
3894
        { "RX621", eRXv1, True,  False, 0,   True  },
3895
        { "RX62N", eRXv1, True,  False, 0,   True  },
3896
        { "RX630", eRXv1, True,  False, 0,   True  },
3897
        { "RX631", eRXv1, True,  False, 0,   True  },
3898
 
3899
        { "RXV2",  eRXv2, True,  False, 0,   True  },   /* Generic RXv2 */
3900
        { "RX140", eRXv2, True,  False, 0,   True  },
3901
        { "RX230", eRXv2, True,  False, 0,   True  },
3902
        { "RX231", eRXv2, True,  False, 0,   True  },
3903
        { "RX64M", eRXv2, True,  False, 0,   True  },
3904
        { "RX651", eRXv2, True,  False, 0,   True  },
3905
 
3906
        { "RXV3",  eRXv3, True,  True,  256, True  },   /* Generic RXv3 (Full option) */
3907
        { "RX660", eRXv3, True,  False, 16,  True  },
3908
        { "RX671", eRXv3, True,  True,  16,  True  },
3909
        { "RX72M", eRXv3, True,  True,  16,  True  },
3910
        { "RX72N", eRXv3, True,  True,  16,  True  },
3911
 
3912
        { ""     ,    eRXv1, False, False, 0,   False }
3913
};
3914
 
3915
void coderx_init(void)
3916
{
3917
        const tCPUProps *pProp;
3918
 
3919
        for (pProp = CPUProps; pProp->Name[0]; pProp++)
3920
                (void)AddCPUUser(pProp->Name, SwitchTo_RX, (void *)pProp, NULL);
3921
 
3922
        AddCopyright("Renesas RX Generator (C) 2023 Haruo Asano");
3923
}