1 /* code3206x.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator TMS320C6x */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 #include "endian.h"
15
16 #include "strutil.h"
17 #include "bpemu.h"
18 #include "nls.h"
19 #include "asmdef.h"
20 #include "asmsub.h"
21 #include "asmpars.h"
22 #include "asmcode.h"
23 #include "errmsg.h"
24 #include "ieeefloat.h"
25 #include "codepseudo.h"
26 #include "asmitree.h"
27 #include "codevars.h"
28 #include "nlmessages.h"
29 #include "as.rsc"
30
31 /*---------------------------------------------------------------------------*/
32
33 typedef enum
34 {
35 NoUnit, L1, L2, S1, S2, M1, M2, D1, D2, LastUnit, UnitCnt
36 } TUnit;
37
38 #ifdef __cplusplus
39 # include "code3206x.hpp"
40 #endif
41
42 typedef struct
43 {
44 LongInt OpCode;
45 LongInt SrcMask, SrcMask2, DestMask;
46 Byte CrossUsed; /* Bit 0 -->X1 benutzt, Bit 1 -->X2 benutzt */
47 Byte AddrUsed; /* Bit 0 -->Addr1 benutzt, Bit 1 -->Addr2 benutzt
48 Bit 2 -->LdSt1 benutzt, Bit 3 -->LdSt2 benutzt */
49 Byte LongUsed; /* Bit 0 -->lange Quelle, Bit 1-->langes Ziel */
50 Boolean AbsBranch;
51 Boolean StoreUsed, LongSrc, LongDest;
52 TUnit U;
53 } InstrRec;
54
55 typedef struct
56 {
57 LongInt Code;
58 } FixedOrder;
59
60 typedef struct
61 {
62 LongInt Code;
63 Boolean WithImm;
64 } CmpOrder;
65
66 typedef struct
67 {
68 LongInt Code;
69 LongInt Scale;
70 } MemOrder;
71
72 typedef struct
73 {
74 LongInt Code;
75 Boolean DSign,SSign1,SSign2;
76 Boolean MayImm;
77 } MulOrder;
78
79 typedef struct
80 {
81 const char *Name;
82 LongInt Code;
83 Boolean Rd,Wr;
84 } CtrlReg;
85
86 static const char UnitNames[UnitCnt][3] =
87 {
88 " ", "L1", "L2", "S1", "S2", "M1", "M2", "D1", "D2", " "
89 };
90
91 #define MaxParCnt 8
92 #define FirstUnit L1
93
94 #define LinAddCnt 6
95 #define CmpCnt 5
96 #define MemCnt 8
97 #define MulCnt 20
98 #define CtrlCnt 13
99
100 enum
101 {
102 ModNone = -1,
103 ModReg = 0,
104 ModLReg = 1,
105 ModImm = 2
106 };
107
108 #define MModReg (1 << ModReg)
109 #define MModLReg (1 << ModLReg)
110 #define MModImm (1 << ModImm)
111
112 static ShortInt AdrMode;
113
114 static CPUVar CPU32060;
115
116 static Boolean ThisPar, ThisCross, ThisStore, ThisAbsBranch;
117 static Byte ThisAddr, ThisLong;
118 static LongInt ThisSrc, ThisSrc2, ThisDest;
119 static LongInt Condition;
120 static TUnit ThisUnit;
121 static LongWord UnitFlag, ThisInst;
122 static Integer ParCnt;
123 static LongWord PacketAddr;
124
125 static InstrRec *ParRecs;
126
127 static FixedOrder *LinAddOrders;
128 static CmpOrder *CmpOrders;
129 static MemOrder *MemOrders;
130 static MulOrder *MulOrders;
131 static CtrlReg *CtrlRegs;
132
133 /*-------------------------------------------------------------------------*/
134
CheckOpt(char * Asc)135 static Boolean CheckOpt(char *Asc)
136 {
137 Boolean Flag, erg = True;
138 int l = strlen(Asc);
139
140 if (!strcmp(Asc, "||"))
141 ThisPar = True;
142 else if ((*Asc == '[') && (Asc[l - 1] == ']'))
143 {
144 Asc++;
145 Asc[l - 2] = '\0';
146 l -= 2;
147 if (*Asc == '!')
148 {
149 Asc++;
150 l--;
151 Condition = 1;
152 }
153 else
154 Condition = 0;
155 Flag = True;
156 if (l != 2)
157 Flag = False;
158 else if (as_toupper(*Asc) == 'A')
159 {
160 if ((Asc[1] >= '1') && (Asc[1] <= '2'))
161 Condition += (Asc[1] - '0' + 3) << 1;
162 else
163 Flag = False;
164 }
165 else if (as_toupper(*Asc) == 'B')
166 {
167 if ((Asc[1] >= '0') && (Asc[1] <= '2'))
168 Condition += (Asc[1] - '0' + 1) << 1;
169 else
170 Flag = False;
171 }
172 if (!Flag)
173 WrXError(ErrNum_InvReg, Asc);
174 erg = Flag;
175 }
176 else
177 erg = False;
178
179 return erg;
180 }
181
ReiterateOpPart(void)182 static Boolean ReiterateOpPart(void)
183 {
184 char *p;
185 int z;
186
187 if (!CheckOpt(OpPart.Str))
188 return False;
189
190 if (ArgCnt<1)
191 {
192 WrError(ErrNum_WrongArgCnt);
193 return False;
194 }
195 p = FirstBlank(ArgStr[1].Str);
196 if (!p)
197 {
198 StrCompCopy(&OpPart, &ArgStr[1]);
199 for (z = 2; z <= ArgCnt; z++)
200 StrCompCopy(&ArgStr[z - 1], &ArgStr[z]);
201 ArgCnt--;
202 }
203 else
204 {
205 StrCompSplitLeft(&ArgStr[1], &OpPart, p);
206 KillPrefBlanksStrComp(&ArgStr[1]);
207 }
208 NLS_UpString(OpPart.Str);
209 p = strchr(OpPart.Str, '.');
210 if (!p)
211 *AttrPart.Str = '\0';
212 else
213 {
214 strcpy(AttrPart.Str, p + 1);
215 *p = '\0';
216 }
217 return True;
218 }
219
220 /*-------------------------------------------------------------------------*/
221
AddSrc(LongWord Reg)222 static void AddSrc(LongWord Reg)
223 {
224 LongWord Mask = 1 << Reg;
225
226 if (!(ThisSrc & Mask))
227 ThisSrc |= Mask;
228 else
229 ThisSrc2 |= Mask;
230 }
231
AddLSrc(LongWord Reg)232 static void AddLSrc(LongWord Reg)
233 {
234 AddSrc(Reg);
235 AddSrc(Reg + 1);
236 ThisLong |= 1;
237 }
238
AddDest(LongWord Reg)239 static void AddDest(LongWord Reg)
240 {
241 ThisDest |= (1 << Reg);
242 }
243
AddLDest(LongWord Reg)244 static void AddLDest(LongWord Reg)
245 {
246 ThisDest |= (3 << Reg);
247 ThisLong |= 2;
248 }
249
FindReg(LongInt Mask)250 static LongInt FindReg(LongInt Mask)
251 {
252 int z;
253
254 for (z = 0; z < 32; z++)
255 {
256 if (Mask & 1)
257 break;
258 Mask = Mask >> 1;
259 }
260 return z;
261 }
262
RegName(LongInt Num)263 static char *RegName(LongInt Num)
264 {
265 static char s[5];
266
267 Num &= 31;
268 as_snprintf(s, sizeof(s), "%c%ld", 'A' + (Num >> 4), (long) (Num & 15));
269 return s;
270 }
271
DecodeSReg(char * Asc,LongWord * Reg,Boolean Quarrel)272 static Boolean DecodeSReg(char *Asc, LongWord *Reg, Boolean Quarrel)
273 {
274 char *end;
275 Byte RVal;
276 Boolean TFlag;
277
278 TFlag = True;
279 switch (as_toupper(*Asc))
280 {
281 case 'A':
282 *Reg = 0; break;
283 case 'B':
284 *Reg = 16; break;
285 default:
286 TFlag = False;
287 }
288 if (TFlag)
289 {
290 RVal = strtol(Asc + 1, &end, 10);
291 if (*end != '\0')
292 TFlag = False;
293 else if
294 (RVal>15) TFlag = False;
295 else
296 *Reg += RVal;
297 }
298 if ((!TFlag) && (Quarrel))
299 WrXError(ErrNum_InvReg, Asc);
300 return TFlag;
301 }
302
DecodeReg(char * Asc,LongWord * Reg,Boolean * PFlag,Boolean Quarrel)303 static Boolean DecodeReg(char *Asc, LongWord *Reg, Boolean *PFlag, Boolean Quarrel)
304 {
305 char *p;
306 LongWord NextReg;
307
308 p = strchr(Asc, ':');
309 if (p == 0)
310 {
311 *PFlag = False;
312 return DecodeSReg(Asc, Reg, Quarrel);
313 }
314 else
315 {
316 *PFlag = True;
317 *p = '\0';
318 if (!DecodeSReg(Asc, &NextReg, Quarrel))
319 return False;
320 else if (!DecodeSReg(p + 1, Reg, Quarrel))
321 return False;
322 else if ((Odd(*Reg)) || (NextReg != (*Reg) + 1) || ((((*Reg) ^ NextReg) & 0x10) != 0))
323 {
324 if (Quarrel)
325 WrXError(ErrNum_InvRegPair, Asc);
326 return False;
327 }
328 else
329 return True;
330 }
331 }
332
DecodeCtrlReg(char * Asc,LongWord * Erg,Boolean Write)333 static Boolean DecodeCtrlReg(char *Asc, LongWord *Erg, Boolean Write)
334 {
335 int z;
336
337 for (z = 0; z < CtrlCnt; z++)
338 if (!as_strcasecmp(Asc, CtrlRegs[z].Name))
339 {
340 *Erg = CtrlRegs[z].Code;
341 return (Write && CtrlRegs[z].Wr) || ((!Write) && CtrlRegs[z].Rd);
342 }
343 return False;
344 }
345
346 /* Was bedeutet das r-Feld im Adressoperanden mit kurzem Offset ???
347 und wie ist das genau mit der Skalierung gemeint ??? */
348
DecodeMem(const tStrComp * pArg,LongWord * Erg,LongWord Scale)349 static Boolean DecodeMem(const tStrComp *pArg, LongWord *Erg, LongWord Scale)
350 {
351 LongInt DispAcc, Mode;
352 LongWord BaseReg, IndReg;
353 int l;
354 char Counter;
355 char *p, EmptyStr[] = "";
356 Boolean OK;
357 tStrComp Arg = *pArg, DispArg, RegArg;
358
359 /* das muss da sein */
360
361 if (*pArg->Str != '*')
362 {
363 WrError(ErrNum_InvAddrMode);
364 return False;
365 }
366 StrCompIncRefLeft(&Arg, 1);
367
368 /* teilen */
369
370 p = strchr(Arg.Str, '[');
371 Counter = ']';
372 if (!p)
373 {
374 p = strchr(Arg.Str, '(');
375 Counter = ')';
376 }
377 if (p)
378 {
379 if (Arg.Str[strlen(Arg.Str) - 1] != Counter)
380 {
381 WrError(ErrNum_InvAddrMode);
382 return False;
383 }
384 StrCompSplitRef(&RegArg, &DispArg, &Arg, p);
385 StrCompShorten(&DispArg, 1);
386 }
387 else
388 {
389 RegArg = Arg;
390 StrCompMkTemp(&DispArg, EmptyStr);
391 }
392
393 /* Registerfeld entschluesseln */
394
395 l = strlen(RegArg.Str);
396 Mode = 1; /* Default ist *+R */
397 if (*RegArg.Str == '+')
398 {
399 StrCompIncRefLeft(&RegArg, 1);
400 Mode = 1;
401 if (*RegArg.Str == '+')
402 {
403 StrCompIncRefLeft(&RegArg, 1);
404 Mode = 9;
405 }
406 }
407 else if (*RegArg.Str == '-')
408 {
409 StrCompIncRefLeft(&RegArg, 1);
410 Mode = 0;
411 if (*RegArg.Str == '-')
412 {
413 StrCompIncRefLeft(&RegArg, 1);
414 Mode = 8;
415 }
416 }
417 else if (RegArg.Str[l - 1] == '+')
418 {
419 if (RegArg.Str[l - 2] != '+')
420 {
421 WrError(ErrNum_InvAddrMode);
422 return False;
423 }
424 StrCompShorten(&RegArg, 2);
425 Mode = 11;
426 }
427 else if (RegArg.Str[l - 1] == '-')
428 {
429 if (RegArg.Str[l - 2] != '-')
430 {
431 WrError(ErrNum_InvAddrMode);
432 return False;
433 }
434 StrCompShorten(&RegArg, 2);
435 Mode = 10;
436 }
437 if (!DecodeSReg(RegArg.Str, &BaseReg, False))
438 {
439 WrStrErrorPos(ErrNum_InvReg, &RegArg);
440 return False;
441 }
442 AddSrc(BaseReg);
443
444 /* kein Offsetfeld ? --> Skalierungsgroesse bei Autoinkrement/De-
445 krement, sonst 0 */
446
447 if (*DispArg.Str == '\0')
448 DispAcc = (Mode < 2) ? 0 : Scale;
449
450 /* Register als Offsetfeld? Dann Bit 2 in Modus setzen */
451
452 else if (DecodeSReg(DispArg.Str, &IndReg, False))
453 {
454 if ((IndReg ^ BaseReg) > 15)
455 {
456 WrError(ErrNum_InvAddrMode);
457 return False;
458 }
459 Mode += 4;
460 AddSrc(DispAcc = IndReg);
461 }
462
463 /* ansonsten normaler Offset */
464
465 else
466 {
467 tSymbolFlags Flags;
468
469 DispAcc = EvalStrIntExpressionWithFlags(&DispArg, UInt15, &OK, &Flags);
470 if (!OK)
471 return False;
472 if (mFirstPassUnknown(Flags))
473 DispAcc &= 7;
474 if (Counter == ')')
475 {
476 if (DispAcc % Scale != 0)
477 {
478 WrError(ErrNum_NotAligned);
479 return False;
480 }
481 else
482 DispAcc /= Scale;
483 }
484 }
485
486 /* Benutzung des Adressierers markieren */
487
488 ThisAddr |= (BaseReg > 15) ? 2 : 1;
489
490 /* Wenn Offset>31, muessen wir Variante 2 benutzen */
491
492 if (((Mode & 4) == 0) && (DispAcc > 31))
493 {
494 if ((BaseReg < 0x1e) || (Mode != 1)) WrError(ErrNum_InvAddrMode);
495 else
496 {
497 *Erg = ((DispAcc & 0x7fff) << 8) + ((BaseReg & 1) << 7) + 12;
498 return True;
499 }
500 }
501
502 else
503 {
504 *Erg = (BaseReg << 18) + ((DispAcc & 0x1f) << 13) + (Mode << 9)
505 + ((BaseReg & 0x10) << 3) + 4;
506 return True;
507 }
508
509 return False;
510 }
511
DecodeAdr(const tStrComp * pArg,Byte Mask,Boolean Signed,LongWord * AdrVal)512 static Boolean DecodeAdr(const tStrComp *pArg, Byte Mask, Boolean Signed, LongWord *AdrVal)
513 {
514 Boolean OK;
515
516 AdrMode = ModNone;
517
518 if (DecodeReg(pArg->Str, AdrVal, &OK, False))
519 {
520 AdrMode = (OK) ? ModLReg : ModReg;
521 }
522 else
523 {
524 *AdrVal = Signed ?
525 EvalStrIntExpression(pArg, SInt5, &OK) & 0x1f :
526 EvalStrIntExpression(pArg, UInt5, &OK);
527 if (OK)
528 AdrMode = ModImm;
529 }
530
531 if ((AdrMode != ModNone) && (((1 << AdrMode) & Mask) == 0))
532 {
533 WrError(ErrNum_InvAddrMode);
534 AdrMode = ModNone;
535 return False;
536 }
537 else return True;
538 }
539
ChkUnit(LongWord Reg,TUnit U1,TUnit U2)540 static Boolean ChkUnit(LongWord Reg, TUnit U1, TUnit U2)
541 {
542 UnitFlag = Ord(Reg>15);
543 if (ThisUnit == NoUnit)
544 {
545 ThisUnit = (Reg>15) ? U2 : U1;
546 return True;
547 }
548 else if (((ThisUnit == U1) && (Reg < 16)) || ((ThisUnit == U2) && (Reg>15)))
549 return True;
550 else
551 {
552 WrError(ErrNum_UndefAttr);
553 return False;
554 }
555 }
556
UnitCode(char c)557 static TUnit UnitCode(char c)
558 {
559 switch (c)
560 {
561 case 'L': return L1;
562 case 'S': return S1;
563 case 'D': return D1;
564 case 'M': return M1;
565 default: return NoUnit;
566 }
567 }
568
UnitUsed(TUnit TestUnit)569 static Boolean UnitUsed(TUnit TestUnit)
570 {
571 Integer z;
572
573 for (z = 0; z < ParCnt; z++)
574 if (ParRecs[z].U == TestUnit)
575 return True;
576
577 return False;
578 }
579
IsCross(LongWord Reg)580 static Boolean IsCross(LongWord Reg)
581 {
582 return (Reg >> 4) != UnitFlag;
583 }
584
SetCross(LongWord Reg)585 static void SetCross(LongWord Reg)
586 {
587 ThisCross = ((Reg >> 4) != UnitFlag);
588 }
589
DecideUnit(LongWord Reg,const char * Units)590 static Boolean DecideUnit(LongWord Reg, const char *Units)
591 {
592 Integer z;
593 TUnit TestUnit;
594
595 if (ThisUnit == NoUnit)
596 {
597 z = 0;
598 while ((Units[z] != '\0') && (ThisUnit == NoUnit))
599 {
600 TestUnit = UnitCode(Units[z]);
601 if (Reg >= 16) TestUnit++;
602 if (!UnitUsed(TestUnit))
603 ThisUnit = TestUnit;
604 z++;
605 }
606 if (ThisUnit == NoUnit)
607 {
608 ThisUnit = UnitCode(*Units);
609 if (Reg > 16)
610 TestUnit++;
611 }
612 }
613 UnitFlag = (ThisUnit - FirstUnit) & 1;
614 if (IsCross(Reg))
615 {
616 WrError(ErrNum_UndefAttr);
617 return False;
618 }
619 else
620 return True;
621 }
622
SwapReg(LongWord * r1,LongWord * r2)623 static void SwapReg(LongWord *r1, LongWord *r2)
624 {
625 LongWord tmp;
626
627 tmp = (*r1);
628 *r1 = (*r2);
629 *r2 = tmp;
630 }
631
DecodePseudo(void)632 static Boolean DecodePseudo(void)
633 {
634 Boolean OK;
635 int z, cnt;
636 TempResult t;
637 LongInt Size;
638
639 if (Memo("SINGLE"))
640 {
641 if (ChkArgCnt(1, ArgCntMax))
642 {
643 OK = True;
644 for (z = 0; z < ArgCnt; z++)
645 {
646 t.Contents.Float = EvalStrFloatExpression(&ArgStr[z + 1], Float32, &OK);
647 if (!OK)
648 break;
649 Double_2_ieee4(t.Contents.Float, (Byte *) (DAsmCode + z), BigEndian);
650 }
651 if (OK) CodeLen = ArgCnt << 2;
652 }
653 return True;
654 }
655
656 if (Memo("DOUBLE"))
657 {
658 if (ChkArgCnt(1, ArgCntMax))
659 {
660 int z2;
661
662 OK = True;
663 for (z = 0; z < ArgCnt; z++)
664 {
665 z2 = z << 1;
666 t.Contents.Float = EvalStrFloatExpression(&ArgStr[z + 1], Float64, &OK);
667 if (!OK)
668 break;
669 Double_2_ieee8(t.Contents.Float, (Byte *) (DAsmCode + z2), BigEndian);
670 if (!BigEndian)
671 {
672 DAsmCode[z2 + 2] = DAsmCode[z2 + 0];
673 DAsmCode[z2 + 0] = DAsmCode[z2 + 1];
674 DAsmCode[z2 + 1] = DAsmCode[z2 + 2];
675 }
676 }
677 if (OK)
678 CodeLen = ArgCnt << 3;
679 }
680 return True;
681 }
682
683 if (Memo("DATA"))
684 {
685 if (ChkArgCnt(1, ArgCntMax))
686 {
687 OK = True;
688 cnt = 0;
689 for (z = 1; z <= ArgCnt; z++)
690 if (OK)
691 {
692 EvalStrExpression(&ArgStr[z], &t);
693 switch (t.Typ)
694 {
695 case TempString:
696 {
697 unsigned z2;
698
699 if (MultiCharToInt(&t, 4))
700 goto ToInt;
701
702 for (z2 = 0; z2 < t.Contents.Ascii.Length; z2++)
703 {
704 if ((z2 & 3) == 0) DAsmCode[cnt++] = 0;
705 DAsmCode[cnt - 1] +=
706 (((LongWord)CharTransTable[((usint)t.Contents.Ascii.Contents[z2]) & 0xff])) << (8 * (3 - (z2 & 3)));
707 }
708 break;
709 }
710 case TempInt:
711 ToInt:
712 #ifdef HAS64
713 if (!RangeCheck(t.Contents.Int, Int32))
714 {
715 OK = False;
716 WrError(ErrNum_OverRange);
717 }
718 else
719 #endif
720 DAsmCode[cnt++] = t.Contents.Int;
721 break;
722 case TempFloat:
723 if (!FloatRangeCheck(t.Contents.Float, Float32))
724 {
725 OK = False;
726 WrError(ErrNum_OverRange);
727 }
728 else
729 {
730 Double_2_ieee4(t.Contents.Float, (Byte *) (DAsmCode + cnt), BigEndian);
731 cnt++;
732 }
733 break;
734 default:
735 OK = False;
736 }
737 }
738 if (OK)
739 CodeLen = cnt << 2;
740 }
741 return True;
742 }
743
744 if (Memo("BSS"))
745 {
746 if (ChkArgCnt(1, 1))
747 {
748 tSymbolFlags Flags;
749
750 Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags);
751 if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
752 if (OK && !mFirstPassUnknown(Flags))
753 {
754 DontPrint = True;
755 if (!Size) WrError(ErrNum_NullResMem);
756 CodeLen = Size;
757 BookKeeping();
758 }
759 }
760 return True;
761 }
762
763 return False;
764 }
765
766
CodeL(LongWord OpCode,LongWord Dest,LongWord Src1,LongWord Src2)767 static Boolean CodeL(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
768 {
769 ThisInst = 0x18 + (OpCode << 5) + (UnitFlag << 1) + (Ord(ThisCross) << 12)
770 + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
771 return True;
772 }
773
CodeM(LongWord OpCode,LongWord Dest,LongWord Src1,LongWord Src2)774 static Boolean CodeM(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
775 {
776 ThisInst = 0x00 + (OpCode << 7) + (UnitFlag << 1) + (Ord(ThisCross) << 12)
777 + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
778 return True;
779 }
780
CodeS(LongWord OpCode,LongWord Dest,LongWord Src1,LongWord Src2)781 static Boolean CodeS(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
782 {
783 ThisInst = 0x20 + (OpCode << 6) + (UnitFlag << 1) + (Ord(ThisCross) << 12)
784 + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
785 return True;
786 }
787
CodeD(LongWord OpCode,LongWord Dest,LongWord Src1,LongWord Src2)788 static Boolean CodeD(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
789 {
790 ThisInst = 0x40 + (OpCode << 7) + (UnitFlag << 1)
791 + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
792 return True;
793 }
794
795 /*-------------------------------------------------------------------------*/
796
797 static Boolean __erg;
798
DecodeIDLE(Word Index)799 static void DecodeIDLE(Word Index)
800 {
801 UNUSED(Index);
802
803 if (!ChkArgCnt(0, 0));
804 else if ((ThisCross) || (ThisUnit != NoUnit)) WrError(ErrNum_UndefAttr);
805 else
806 {
807 ThisInst = 0x0001e000;
808 __erg = True;
809 }
810 }
811
DecodeNOP(Word Index)812 static void DecodeNOP(Word Index)
813 {
814 LongInt Count;
815 Boolean OK;
816 UNUSED(Index);
817
818 if (!ChkArgCnt(0, 1));
819 else if ((ThisCross) || (ThisUnit != NoUnit)) WrError(ErrNum_UndefAttr);
820 else
821 {
822 if (ArgCnt == 0)
823 {
824 OK = True;
825 Count = 0;
826 }
827 else
828 {
829 tSymbolFlags Flags;
830
831 Count = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt4, &OK, &Flags);
832 Count = mFirstPassUnknown(Flags) ? 0 : Count - 1;
833 OK = ChkRange(Count, 0, 8);
834 }
835 if (OK)
836 {
837 ThisInst = Count << 13;
838 __erg = True;
839 }
840 }
841 }
842
DecodeMul(Word Index)843 static void DecodeMul(Word Index)
844 {
845 LongWord DReg, S1Reg, S2Reg;
846 MulOrder *POrder = MulOrders + Index;
847
848 if (ChkArgCnt(3, 3))
849 {
850 if ((DecodeAdr(&ArgStr[3], MModReg, POrder->DSign, &DReg))
851 && (ChkUnit(DReg, M1, M2)))
852 {
853 if (DecodeAdr(&ArgStr[2], MModReg, POrder->SSign2, &S2Reg))
854 {
855 AddSrc(S2Reg);
856 DecodeAdr(&ArgStr[1], (POrder->MayImm ? MModImm : 0) + MModReg, POrder->SSign1, &S1Reg);
857 switch (AdrMode)
858 {
859 case ModReg:
860 if ((ThisCross) && (!IsCross(S2Reg)) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
861 else if ((IsCross(S2Reg)) && (IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
862 else
863 {
864 if (IsCross(S1Reg))
865 SwapReg(&S1Reg, &S2Reg);
866 SetCross(S2Reg);
867 AddSrc(S1Reg);
868 __erg = CodeM(POrder->Code, DReg, S1Reg, S2Reg);
869 }
870 break;
871 case ModImm:
872 __erg = Memo("MPY") ?
873 CodeM(POrder->Code - 1, DReg, S1Reg, S2Reg) :
874 CodeM(POrder->Code + 3, DReg, S1Reg, S2Reg);
875 break;
876 }
877 }
878 }
879 }
880 }
881
DecodeMemO(Word Index)882 static void DecodeMemO(Word Index)
883 {
884 LongWord DReg, S1Reg;
885 MemOrder *POrder = MemOrders + Index;
886 Boolean OK, IsStore;
887
888 if (ChkArgCnt(2, 2))
889 {
890 const tStrComp *pArg1, *pArg2;
891
892 IsStore = (*OpPart.Str) == 'S';
893 pArg1 = IsStore ? &ArgStr[2] : &ArgStr[1];
894 pArg2 = IsStore ? &ArgStr[1] : &ArgStr[2];
895 if (IsStore)
896 ThisStore = True;
897 if (DecodeAdr(pArg2, MModReg, False, &DReg))
898 {
899 if (IsStore)
900 AddSrc(DReg);
901 ThisAddr |= (DReg > 15) ? 8 : 4;
902 /* Zielregister 4 Takte verzoegert, nicht als Dest eintragen */
903 OK = DecodeMem(pArg1, &S1Reg, POrder->Scale);
904 if (OK)
905 {
906 OK = (S1Reg & 8) ?
907 ChkUnit(0x1e, D1, D2) :
908 ChkUnit((S1Reg >> 18) & 31, D1, D2);
909 }
910 if (OK)
911 {
912 ThisInst = S1Reg + (DReg << 23) + (POrder->Code << 4)
913 + ((DReg & 16) >> 3);
914 __erg = True;
915 }
916 }
917 }
918 }
919
DecodeSTP(Word Index)920 static void DecodeSTP(Word Index)
921 {
922 LongWord S2Reg;
923 UNUSED(Index);
924
925 if (ChkArgCnt(1, 1)
926 && ChkUnit(0x10, S1, S2))
927 {
928 if (DecodeAdr(&ArgStr[1], MModReg, False, &S2Reg))
929 {
930 if ((ThisCross) || (S2Reg < 16)) WrError(ErrNum_InvAddrMode);
931 else
932 {
933 AddSrc(S2Reg);
934 __erg = CodeS(0x0c, 0, 0, S2Reg);
935 }
936 }
937 }
938 }
939
DecodeABS(Word Index)940 static void DecodeABS(Word Index)
941 {
942 Boolean DPFlag, S1Flag;
943 LongWord DReg, S1Reg;
944 UNUSED(Index);
945
946 if (ChkArgCnt(2, 2)
947 && DecodeReg(ArgStr[2].Str, &DReg, &DPFlag, True)
948 && ChkUnit(DReg, L1, L2)
949 && DecodeReg(ArgStr[1].Str, &S1Reg, &S1Flag, True))
950 {
951 if (DPFlag != S1Flag) WrError(ErrNum_InvAddrMode);
952 else if ((ThisCross) && ((S1Reg >> 4) == UnitFlag)) WrError(ErrNum_InvAddrMode);
953 else
954 {
955 SetCross(S1Reg);
956 if (DPFlag)
957 {
958 __erg = CodeL(0x38, DReg, 0, S1Reg);
959 AddLSrc(S1Reg);
960 AddLDest(DReg);
961 }
962 else
963 {
964 __erg = CodeL(0x1a, DReg, 0, S1Reg);
965 AddSrc(S1Reg);
966 AddDest(DReg);
967 }
968 }
969 }
970 }
971
DecodeADD(Word Index)972 static void DecodeADD(Word Index)
973 {
974 LongWord S1Reg, S2Reg, DReg;
975 Boolean OK;
976 UNUSED(Index);
977
978 if (ChkArgCnt(3, 3))
979 {
980 DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
981 UnitFlag = DReg >> 4;
982 switch (AdrMode)
983 {
984 case ModLReg: /* ADD ?,?,long */
985 AddLDest(DReg);
986 DecodeAdr(&ArgStr[1], MModReg + MModLReg + MModImm, True, &S1Reg);
987 switch (AdrMode)
988 {
989 case ModReg: /* ADD int,?,long */
990 AddSrc(S1Reg);
991 DecodeAdr(&ArgStr[2], MModReg + MModLReg, True, &S2Reg);
992 switch (AdrMode)
993 {
994 case ModReg: /* ADD int,int,long */
995 if (ChkUnit(DReg, L1, L2))
996 {
997 if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
998 else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
999 else
1000 {
1001 AddSrc(S2Reg);
1002 if (IsCross(S1Reg))
1003 SwapReg(&S1Reg, &S2Reg);
1004 SetCross(S2Reg);
1005 __erg = CodeL(0x23, DReg, S1Reg, S2Reg);
1006 }
1007 }
1008 break;
1009 case ModLReg:/* ADD int,long,long */
1010 if (ChkUnit(DReg, L1, L2))
1011 {
1012 if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1013 else if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
1014 else
1015 {
1016 AddLSrc(S2Reg);
1017 SetCross(S1Reg);
1018 __erg = CodeL(0x21, DReg, S1Reg, S2Reg);
1019 }
1020 }
1021 break;
1022 }
1023 break;
1024 case ModLReg: /* ADD long,?,long */
1025 AddLSrc(S1Reg);
1026 DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
1027 switch (AdrMode)
1028 {
1029 case ModReg: /* ADD long,int,long */
1030 if (ChkUnit(DReg, L1, L2))
1031 {
1032 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1033 else if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1034 else
1035 {
1036 AddSrc(S2Reg);
1037 SetCross(S2Reg);
1038 __erg = CodeL(0x21, DReg, S2Reg, S1Reg);
1039 }
1040 }
1041 break;
1042 case ModImm: /* ADD long,imm,long */
1043 if (ChkUnit(DReg, L1, L2))
1044 {
1045 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1046 else if (ThisCross) WrError(ErrNum_InvAddrMode);
1047 else
1048 __erg = CodeL(0x20, DReg, S2Reg, S1Reg);
1049 }
1050 break;
1051 }
1052 break;
1053 case ModImm: /* ADD imm,?,long */
1054 if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
1055 { /* ADD imm,long,long */
1056 if (ChkUnit(DReg, L1, L2))
1057 {
1058 if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1059 else if (ThisCross) WrError(ErrNum_InvAddrMode);
1060 else
1061 {
1062 AddLSrc(S2Reg);
1063 __erg = CodeL(0x20, DReg, S1Reg, S2Reg);
1064 }
1065 }
1066 }
1067 break;
1068 }
1069 break;
1070 case ModReg: /* ADD ?,?,int */
1071 AddDest(DReg);
1072 DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
1073 switch (AdrMode)
1074 {
1075 case ModReg: /* ADD int,?,int */
1076 AddSrc(S1Reg);
1077 DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
1078 switch (AdrMode)
1079 {
1080 case ModReg: /* ADD int,int,int */
1081 AddSrc(S2Reg);
1082 if (((DReg ^ S1Reg) > 15) && ((DReg ^ S2Reg)>15)) WrError(ErrNum_InvAddrMode);
1083 else if ((ThisCross) && ((DReg ^ S1Reg) < 16) && ((DReg ^ S2Reg) < 15)) WrError(ErrNum_InvAddrMode);
1084 else
1085 {
1086 if ((S1Reg ^ DReg) > 15)
1087 SwapReg(&S1Reg, &S2Reg);
1088 OK = DecideUnit(DReg, ((S2Reg ^ DReg)>15) ? "LS" : "LSD");
1089 if (OK)
1090 {
1091 switch (ThisUnit)
1092 {
1093 case L1: case L2: /* ADD.Lx int,int,int */
1094 __erg = CodeL(0x03, DReg, S1Reg, S2Reg);
1095 break;
1096 case S1: case S2: /* ADD.Sx int,int,int */
1097 __erg = CodeS(0x07, DReg, S1Reg, S2Reg);
1098 break;
1099 case D1: case D2: /* ADD.Dx int,int,int */
1100 __erg = CodeD(0x10, DReg, S1Reg, S2Reg);
1101 break;
1102 default:
1103 WrError(ErrNum_CannotUseUnit);
1104 }
1105 }
1106 }
1107 break;
1108 case ModImm: /* ADD int,imm,int */
1109 if ((ThisCross) && ((S1Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1110 else
1111 {
1112 SetCross(S1Reg);
1113 if (DecideUnit(DReg, "LS"))
1114 switch (ThisUnit)
1115 {
1116 case L1: case L2:
1117 __erg = CodeL(0x02, DReg, S2Reg, S1Reg);
1118 break;
1119 case S1: case S2:
1120 __erg = CodeS(0x06, DReg, S2Reg, S1Reg);
1121 break;
1122 default:
1123 WrError(ErrNum_CannotUseUnit);
1124 }
1125 }
1126 break;
1127 }
1128 break;
1129 case ModImm: /* ADD imm,?,int */
1130 if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
1131 {
1132 AddSrc(S2Reg);
1133 if ((ThisCross) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1134 else
1135 {
1136 SetCross(S2Reg);
1137 if (DecideUnit(DReg, "LS"))
1138 switch (ThisUnit)
1139 {
1140 case L1: case L2:
1141 __erg = CodeL(0x02, DReg, S1Reg, S2Reg);
1142 break;
1143 case S1: case S2:
1144 __erg = CodeS(0x06, DReg, S1Reg, S2Reg);
1145 break;
1146 default:
1147 WrError(ErrNum_CannotUseUnit);
1148 }
1149 }
1150 }
1151 break;
1152 }
1153 break;
1154 }
1155 }
1156 }
1157
DecodeADDU(Word Index)1158 static void DecodeADDU(Word Index)
1159 {
1160 LongWord DReg, S1Reg, S2Reg;
1161 UNUSED(Index);
1162
1163 if (ChkArgCnt(3, 3))
1164 {
1165 DecodeAdr(&ArgStr[3], MModReg + MModLReg, False, &DReg);
1166 switch (AdrMode)
1167 {
1168 case ModReg: /* ADDU ?,?,int */
1169 if (ChkUnit(DReg, D1, D2))
1170 {
1171 AddDest(DReg);
1172 DecodeAdr(&ArgStr[1], MModReg + MModImm, False, &S1Reg);
1173 switch (AdrMode)
1174 {
1175 case ModReg: /* ADDU int,?,int */
1176 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1177 else
1178 {
1179 AddSrc(S1Reg);
1180 if (DecodeAdr(&ArgStr[2], MModImm, False, &S2Reg))
1181 __erg = CodeD(0x12, DReg, S2Reg, S1Reg);
1182 }
1183 break;
1184 case ModImm: /* ADDU imm,?,int */
1185 if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1186 {
1187 if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1188 else
1189 {
1190 AddSrc(S2Reg);
1191 __erg = CodeD(0x12, DReg, S1Reg, S2Reg);
1192 }
1193 }
1194 break;
1195 }
1196 }
1197 break;
1198 case ModLReg: /* ADDU ?,?,long */
1199 if (ChkUnit(DReg, L1, L2))
1200 {
1201 AddLDest(DReg);
1202 DecodeAdr(&ArgStr[1], MModReg + MModLReg, False, &S1Reg);
1203 switch (AdrMode)
1204 {
1205 case ModReg: /* ADDU int,?,long */
1206 AddSrc(S1Reg);
1207 DecodeAdr(&ArgStr[2], MModReg + MModLReg, False, &S2Reg);
1208 switch (AdrMode)
1209 {
1210 case ModReg: /* ADDU int,int,long */
1211 if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1212 else if ((ThisCross) && (((S1Reg ^ DReg) < 16) && ((S2Reg ^ DReg) < 16))) WrError(ErrNum_InvAddrMode);
1213 else
1214 {
1215 if ((S1Reg ^ DReg) > 15)
1216 SwapReg(&S1Reg, &S2Reg);
1217 SetCross(S2Reg);
1218 __erg = CodeL(0x2b, DReg, S1Reg, S2Reg);
1219 }
1220 break;
1221 case ModLReg: /* ADDU int,long,long */
1222 if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1223 else if ((ThisCross) && ((S1Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1224 else
1225 {
1226 AddLSrc(S2Reg);
1227 SetCross(S1Reg);
1228 __erg = CodeL(0x29, DReg, S1Reg, S2Reg);
1229 }
1230 break;
1231 }
1232 break;
1233 case ModLReg:
1234 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1235 else
1236 {
1237 AddLSrc(S1Reg);
1238 if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1239 {
1240 if ((ThisCross) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1241 else
1242 {
1243 AddSrc(S2Reg); SetCross(S2Reg);
1244 __erg = CodeL(0x29, DReg, S2Reg, S1Reg);
1245 }
1246 }
1247 }
1248 break;
1249 }
1250 }
1251 break;
1252 }
1253 }
1254 }
1255
DecodeSUB(Word Index)1256 static void DecodeSUB(Word Index)
1257 {
1258 LongWord DReg, S1Reg, S2Reg;
1259 Boolean OK;
1260 UNUSED(Index);
1261
1262 if (ChkArgCnt(3, 3))
1263 {
1264 DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
1265 switch (AdrMode)
1266 {
1267 case ModReg:
1268 AddDest(DReg);
1269 DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
1270 switch (AdrMode)
1271 {
1272 case ModReg:
1273 AddSrc(S1Reg);
1274 DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
1275 switch (AdrMode)
1276 {
1277 case ModReg:
1278 if ((ThisCross) && ((S1Reg ^ DReg) < 16) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1279 else if (((S1Reg ^ DReg) > 15) && ((S2Reg ^ DReg) > 15)) WrError(ErrNum_InvAddrMode);
1280 else
1281 {
1282 AddSrc(S2Reg);
1283 ThisCross = ((S1Reg ^ DReg) > 15) || ((S2Reg ^ DReg) > 15);
1284 if ((S1Reg ^ DReg) > 15) OK = DecideUnit(DReg, "L");
1285 else if ((S2Reg ^ DReg) > 15) OK = DecideUnit(DReg, "LS");
1286 else OK = DecideUnit(DReg, "LSD");
1287 if (OK)
1288 switch (ThisUnit)
1289 {
1290 case L1: case L2:
1291 if ((S1Reg ^ DReg) > 15) __erg = CodeL(0x17, DReg, S1Reg, S2Reg);
1292 else __erg = CodeL(0x07, DReg, S1Reg, S2Reg);
1293 break;
1294 case S1: case S2:
1295 __erg = CodeS(0x17, DReg, S1Reg, S2Reg);
1296 break;
1297 case D1: case D2:
1298 __erg = CodeD(0x11, DReg, S2Reg, S1Reg);
1299 break;
1300 default:
1301 WrError(ErrNum_CannotUseUnit);
1302 }
1303 }
1304 break;
1305 case ModImm:
1306 if (ChkUnit(DReg, D1, D2))
1307 {
1308 if ((ThisCross) || ((S1Reg ^ DReg) > 15)) WrError(ErrNum_InvAddrMode);
1309 else __erg = CodeD(0x13, DReg, S2Reg, S1Reg);
1310 }
1311 break;
1312 }
1313 break;
1314 case ModImm:
1315 if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
1316 {
1317 if ((ThisCross) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1318 else
1319 {
1320 AddSrc(S2Reg);
1321 if (DecideUnit(DReg, "LS"))
1322 switch (ThisUnit)
1323 {
1324 case L1: case L2:
1325 __erg = CodeL(0x06, DReg, S1Reg, S2Reg);
1326 break;
1327 case S1: case S2:
1328 __erg = CodeS(0x16, DReg, S1Reg, S2Reg);
1329 break;
1330 default:
1331 WrError(ErrNum_CannotUseUnit);
1332 }
1333 }
1334 }
1335 break;
1336 }
1337 break;
1338 case ModLReg:
1339 AddLDest(DReg);
1340 if (ChkUnit(DReg, L1, L2))
1341 {
1342 DecodeAdr(&ArgStr[1], MModImm + MModReg, True, &S1Reg);
1343 switch (AdrMode)
1344 {
1345 case ModImm:
1346 if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
1347 {
1348 if ((ThisCross) || (/*NOT*/ IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1349 else
1350 {
1351 AddLSrc(S2Reg);
1352 __erg = CodeL(0x24, DReg, S1Reg, S2Reg);
1353 }
1354 }
1355 break;
1356 case ModReg:
1357 AddSrc(S1Reg);
1358 if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
1359 {
1360 if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1361 else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1362 else
1363 {
1364 AddSrc(S2Reg);
1365 ThisCross = (IsCross(S1Reg)) || (IsCross(S2Reg));
1366 /* what did I do here? */
1367 __erg = IsCross(S1Reg) ?
1368 CodeL(0x37, DReg, S1Reg, S2Reg) :
1369 CodeL(0x47, DReg, S1Reg, S2Reg);
1370 }
1371 }
1372 break;
1373 }
1374 }
1375 break;
1376 }
1377 }
1378 }
1379
DecodeSUBU(Word Index)1380 static void DecodeSUBU(Word Index)
1381 {
1382 LongWord S1Reg, S2Reg, DReg;
1383 UNUSED(Index);
1384
1385 if (ChkArgCnt(3, 3)
1386 && DecodeAdr(&ArgStr[3], MModLReg, False, &DReg)
1387 && ChkUnit(DReg, L1, L2))
1388 {
1389 AddLDest(DReg);
1390 if (DecodeAdr(&ArgStr[1], MModReg, False, &S1Reg))
1391 {
1392 AddSrc(S1Reg);
1393 if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1394 {
1395 if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1396 else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1397 else
1398 {
1399 AddSrc(S2Reg);
1400 ThisCross = IsCross(S1Reg) || IsCross(S2Reg);
1401 __erg = IsCross(S1Reg) ?
1402 CodeL(0x3f, DReg, S1Reg, S2Reg) :
1403 CodeL(0x2f, DReg, S1Reg, S2Reg);
1404 }
1405 }
1406 }
1407 }
1408 }
1409
DecodeSUBC(Word Index)1410 static void DecodeSUBC(Word Index)
1411 {
1412 LongWord DReg, S1Reg, S2Reg;
1413 UNUSED(Index);
1414
1415 if (ChkArgCnt(3, 3)
1416 && DecodeAdr(&ArgStr[3], MModReg, False, &DReg)
1417 && ChkUnit(DReg, L1, L2))
1418 {
1419 AddLDest(DReg);
1420 if (DecodeAdr(&ArgStr[1], MModReg, False, &S1Reg))
1421 {
1422 if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1423 {
1424 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1425 else if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1426 else
1427 {
1428 AddSrc(S2Reg);
1429 SetCross(S2Reg);
1430 __erg = CodeL(0x4b, DReg, S1Reg, S2Reg);
1431 }
1432 }
1433 }
1434 }
1435 }
1436
DecodeLinAdd(Word Index)1437 static void DecodeLinAdd(Word Index)
1438 {
1439 LongWord DReg, S1Reg, S2Reg;
1440 FixedOrder *POrder = LinAddOrders + Index;
1441
1442 if (!ChkArgCnt(3, 3));
1443 else if (ThisCross) WrError(ErrNum_InvAddrMode);
1444 else
1445 {
1446 if ((DecodeAdr(&ArgStr[3], MModReg, True, &DReg))
1447 && (ChkUnit(DReg, D1, D2)))
1448 {
1449 AddDest(DReg);
1450 if (DecodeAdr(&ArgStr[1], MModReg, True, &S2Reg))
1451 {
1452 if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1453 else
1454 {
1455 AddSrc(S2Reg);
1456 DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
1457 switch (AdrMode)
1458 {
1459 case ModReg:
1460 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1461 else
1462 {
1463 AddSrc(S1Reg);
1464 __erg = CodeD(POrder->Code, DReg, S1Reg, S2Reg);
1465 }
1466 break;
1467 case ModImm:
1468 __erg = CodeD(POrder->Code + 2, DReg, S1Reg, S2Reg);
1469 break;
1470 }
1471 }
1472 }
1473 }
1474 }
1475 }
1476
DecodeADDK(Word Index)1477 static void DecodeADDK(Word Index)
1478 {
1479 LongInt Value;
1480 LongWord DReg;
1481 Boolean OK;
1482 UNUSED(Index);
1483
1484 if (ChkArgCnt(2, 2)
1485 && DecodeAdr(&ArgStr[2], MModReg, False, &DReg)
1486 && ChkUnit(DReg, S1, S2))
1487 {
1488 AddDest(DReg);
1489 Value = EvalStrIntExpression(&ArgStr[1], SInt16, &OK);
1490 if (OK)
1491 {
1492 ThisInst = 0x50 + (UnitFlag << 1) + ((Value & 0xffff) << 7) + (DReg << 23);
1493 __erg = True;
1494 }
1495 }
1496 }
1497
DecodeADD2_SUB2(Word Index)1498 static void DecodeADD2_SUB2(Word Index)
1499 {
1500 LongWord DReg, S1Reg, S2Reg;
1501 Boolean OK;
1502
1503 Index = (Index << 5) + 1;
1504 if (ChkArgCnt(3, 3)
1505 && DecodeAdr(&ArgStr[3], MModReg, True, &DReg)
1506 && ChkUnit(DReg, S1, S2))
1507 {
1508 AddDest(DReg);
1509 if (DecodeAdr(&ArgStr[1], MModReg, True, &S1Reg))
1510 {
1511 AddSrc(S1Reg);
1512 if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
1513 {
1514 if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1515 else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1516 else
1517 {
1518 OK = True; AddSrc(S2Reg);
1519 if (IsCross(S1Reg))
1520 {
1521 if (Index > 1)
1522 {
1523 WrError(ErrNum_InvAddrMode);
1524 OK = False;
1525 }
1526 else SwapReg(&S1Reg, &S2Reg);
1527 }
1528 if (OK)
1529 {
1530 SetCross(S2Reg);
1531 __erg = CodeS(Index, DReg, S1Reg, S2Reg);
1532 }
1533 }
1534 }
1535 }
1536 }
1537 }
1538
DecodeMV(Word Index)1539 static void DecodeMV(Word Index)
1540 {
1541 LongWord SReg, DReg;
1542 UNUSED(Index);
1543
1544 /* MV src,dst == ADD 0,src,dst */
1545
1546 if (ChkArgCnt(2, 2))
1547 {
1548 DecodeAdr(&ArgStr[2], MModReg + MModLReg, True, &DReg);
1549 UnitFlag = DReg >> 4;
1550 switch (AdrMode)
1551 {
1552 case ModLReg: /* MV ?,long */
1553 AddLDest(DReg);
1554 if (DecodeAdr(&ArgStr[1], MModLReg, True, &SReg))
1555 { /* MV long,long */
1556 if (ChkUnit(DReg, L1, L2))
1557 {
1558 if (IsCross(SReg)) WrError(ErrNum_InvAddrMode);
1559 else if (ThisCross) WrError(ErrNum_InvAddrMode);
1560 else
1561 {
1562 AddLSrc(SReg);
1563 __erg = CodeL(0x20, DReg, 0, SReg);
1564 }
1565 }
1566 }
1567 break;
1568
1569 case ModReg: /* MV ?,int */
1570 AddDest(DReg);
1571 if (DecodeAdr(&ArgStr[1], MModReg, True, &SReg))
1572 {
1573 AddSrc(SReg);
1574 if ((ThisCross) && ((SReg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1575 else
1576 {
1577 SetCross(SReg);
1578 if (DecideUnit(DReg, "LSD"))
1579 switch (ThisUnit)
1580 {
1581 case L1: case L2:
1582 __erg = CodeL(0x02, DReg, 0, SReg);
1583 break;
1584 case S1: case S2:
1585 __erg = CodeS(0x06, DReg, 0, SReg);
1586 break;
1587 case D1: case D2:
1588 __erg = CodeD(0x12, DReg, 0, SReg);
1589 break;
1590 default:
1591 WrError(ErrNum_CannotUseUnit);
1592 }
1593 }
1594 }
1595 break;
1596 }
1597 }
1598 }
1599
DecodeNEG(Word Index)1600 static void DecodeNEG(Word Index)
1601 {
1602 LongWord DReg, SReg;
1603 UNUSED(Index);
1604
1605 /* NEG src,dst == SUB 0,src,dst */
1606
1607 if (ChkArgCnt(2, 2))
1608 {
1609 DecodeAdr(&ArgStr[2], MModReg + MModLReg, True, &DReg);
1610 switch (AdrMode)
1611 {
1612 case ModReg:
1613 AddDest(DReg);
1614 if (DecodeAdr(&ArgStr[1], MModReg, True, &SReg))
1615 {
1616 if ((ThisCross) && ((SReg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1617 else
1618 {
1619 AddSrc(SReg);
1620 if (DecideUnit(DReg, "LS"))
1621 switch (ThisUnit)
1622 {
1623 case L1: case L2:
1624 __erg = CodeL(0x06, DReg, 0, SReg);
1625 break;
1626 case S1: case S2:
1627 __erg = CodeS(0x16, DReg, 0, SReg);
1628 break;
1629 default:
1630 WrError(ErrNum_CannotUseUnit);
1631 }
1632 }
1633 }
1634 break;
1635 case ModLReg:
1636 AddLDest(DReg);
1637 if (ChkUnit(DReg, L1, L2))
1638 {
1639 if (DecodeAdr(&ArgStr[1], MModLReg, True, &SReg))
1640 {
1641 if ((ThisCross) || (IsCross(SReg))) WrError(ErrNum_InvAddrMode);
1642 else
1643 {
1644 AddLSrc(SReg);
1645 __erg = CodeL(0x24, DReg, 0, SReg);
1646 }
1647 }
1648 }
1649 break;
1650 }
1651 }
1652 }
1653
DecodeLogic(Word Index)1654 static void DecodeLogic(Word Index)
1655 {
1656 LongWord S1Reg, S2Reg, DReg;
1657 LongWord Code1, Code2;
1658 Boolean OK, WithImm;
1659
1660 Code1 = Lo(Index);
1661 Code2 = Hi(Index);
1662
1663 if (ChkArgCnt(3, 3))
1664 {
1665 if (DecodeAdr(&ArgStr[3], MModReg, True, &DReg))
1666 {
1667 AddDest(DReg);
1668 DecodeAdr(&ArgStr[1], MModImm + MModReg, True, &S1Reg);
1669 WithImm = False;
1670 switch (AdrMode)
1671 {
1672 case ModImm:
1673 OK = DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg);
1674 if (OK) AddSrc(S2Reg);
1675 WithImm = True;
1676 break;
1677 case ModReg:
1678 AddSrc(S1Reg);
1679 OK = DecodeAdr(&ArgStr[2], MModImm + MModReg, True, &S2Reg);
1680 switch (AdrMode)
1681 {
1682 case ModImm:
1683 SwapReg(&S1Reg, &S2Reg);
1684 WithImm = True;
1685 break;
1686 case ModReg:
1687 AddSrc(S2Reg);
1688 WithImm = False;
1689 break;
1690 default:
1691 OK = False;
1692 }
1693 break;
1694 default:
1695 OK = False;
1696 }
1697 if ((OK) && (DecideUnit(DReg, "LS")))
1698 {
1699 if ((!WithImm) && (IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1700 else if ((ThisCross) && (!IsCross(S2Reg)) && ((WithImm) || (!IsCross(S1Reg)))) WrError(ErrNum_InvAddrMode);
1701 else
1702 {
1703 if ((!WithImm) && (IsCross(S1Reg)))
1704 SwapReg(&S1Reg, &S2Reg);
1705 SetCross(S2Reg);
1706 switch (ThisUnit)
1707 {
1708 case L1: case L2:
1709 __erg = CodeL(Code1 - Ord(WithImm), DReg, S1Reg, S2Reg);
1710 break;
1711 case S1: case S2:
1712 __erg = CodeS(Code2 - Ord(WithImm), DReg, S1Reg, S2Reg);
1713 break;
1714 default:
1715 WrError(ErrNum_CannotUseUnit);
1716 }
1717 }
1718 }
1719 }
1720 }
1721 }
1722
DecodeNOT(Word Index)1723 static void DecodeNOT(Word Index)
1724 {
1725 LongWord SReg, DReg;
1726
1727 UNUSED(Index);
1728
1729 /* NOT src,dst == XOR -1,src,dst */
1730
1731 if (ChkArgCnt(2, 2))
1732 {
1733 if (DecodeAdr(&ArgStr[2], MModReg, True, &DReg))
1734 {
1735 AddDest(DReg);
1736 if (DecodeAdr(&ArgStr[1], MModReg, True, &SReg))
1737 {
1738 AddSrc(SReg);
1739 if (DecideUnit(DReg, "LS"))
1740 {
1741 if ((ThisCross) && (!IsCross(SReg))) WrError(ErrNum_InvAddrMode);
1742 else
1743 {
1744 SetCross(SReg);
1745 switch (ThisUnit)
1746 {
1747 case L1: case L2:
1748 __erg = CodeL(0x6e, DReg, 0x1f, SReg);
1749 break;
1750 case S1: case S2:
1751 __erg = CodeS(0x0a, DReg, 0x1f, SReg);
1752 break;
1753 default:
1754 WrError(ErrNum_CannotUseUnit);
1755 }
1756 }
1757 }
1758 }
1759 }
1760 }
1761 }
1762
DecodeZERO(Word Index)1763 static void DecodeZERO(Word Index)
1764 {
1765 LongWord DReg;
1766 UNUSED(Index);
1767
1768 /* ZERO dst == SUB dst,dst,dst */
1769
1770 if (ChkArgCnt(1, 1))
1771 {
1772 DecodeAdr(&ArgStr[1], MModReg + MModLReg, True, &DReg);
1773 if ((ThisCross) || (IsCross(DReg))) WrError(ErrNum_InvAddrMode);
1774 else
1775 switch (AdrMode)
1776 {
1777 case ModReg:
1778 AddDest(DReg);
1779 AddSrc(DReg);
1780 if (DecideUnit(DReg, "LSD"))
1781 switch (ThisUnit)
1782 {
1783 case L1: case L2:
1784 __erg = CodeL(0x17, DReg, DReg, DReg);
1785 break;
1786 case S1: case S2:
1787 __erg = CodeS(0x17, DReg, DReg, DReg);
1788 break;
1789 case D1: case D2:
1790 __erg = CodeD(0x11, DReg, DReg, DReg);
1791 break;
1792 default:
1793 WrError(ErrNum_CannotUseUnit);
1794 }
1795 break;
1796 case ModLReg:
1797 AddLDest(DReg);
1798 AddLSrc(DReg);
1799 if (ChkUnit(DReg, L1, L2))
1800 __erg = CodeL(0x37, DReg, DReg, DReg);
1801 break;
1802 }
1803 }
1804 }
1805
DecodeCLR_EXT_EXTU_SET(Word Code)1806 static void DecodeCLR_EXT_EXTU_SET(Word Code)
1807 {
1808 LongWord DReg, S1Reg, S2Reg, HReg;
1809 Boolean OK, IsEXT = (Code == 0x2f48);
1810
1811 if (ChkArgCnt(3, 4))
1812 {
1813 if ((DecodeAdr(&ArgStr[ArgCnt], MModReg, IsEXT, &DReg))
1814 && (ChkUnit(DReg, S1, S2)))
1815 {
1816 AddDest(DReg);
1817 if (DecodeAdr(&ArgStr[1], MModReg, IsEXT, &S2Reg))
1818 {
1819 AddSrc(S2Reg);
1820 if (ArgCnt == 3)
1821 {
1822 if (DecodeAdr(&ArgStr[2], MModReg, False, &S1Reg))
1823 {
1824 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1825 else if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1826 else
1827 {
1828 SetCross(S2Reg);
1829 __erg = CodeS(Hi(Code), DReg, S1Reg, S2Reg);
1830 }
1831 }
1832 }
1833 else if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1834 else
1835 {
1836 S1Reg = EvalStrIntExpression(&ArgStr[2], UInt5, &OK);
1837 if (OK)
1838 {
1839 HReg = EvalStrIntExpression(&ArgStr[3], UInt5, &OK);
1840 if (OK)
1841 {
1842 ThisInst = (DReg << 23) + (S2Reg << 18) + (S1Reg << 13)
1843 + (HReg << 8) + (UnitFlag << 1) + Lo(Code);
1844 __erg = True;
1845 }
1846 }
1847 }
1848 }
1849 }
1850 }
1851 }
1852
DecodeCmp(Word Index)1853 static void DecodeCmp(Word Index)
1854 {
1855 const CmpOrder *pOrder = CmpOrders + Index;
1856 LongWord DReg, S1Reg, S2Reg;
1857
1858 if (ChkArgCnt(3, 3)
1859 && DecodeAdr(&ArgStr[3], MModReg, False, &DReg)
1860 && ChkUnit(DReg, L1, L2))
1861 {
1862 AddDest(DReg);
1863 DecodeAdr(&ArgStr[1], MModReg + MModImm, pOrder->WithImm, &S1Reg);
1864 switch (AdrMode)
1865 {
1866 case ModReg:
1867 AddSrc(S1Reg);
1868 DecodeAdr(&ArgStr[2], MModReg + MModLReg, pOrder->WithImm, &S2Reg);
1869 switch (AdrMode)
1870 {
1871 case ModReg:
1872 if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1873 else if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1874 else
1875 {
1876 AddSrc(S2Reg);
1877 if (IsCross(S1Reg)) SwapReg(&S1Reg, &S2Reg);
1878 SetCross(S2Reg);
1879 __erg = CodeL(pOrder->Code + 3, DReg, S1Reg, S2Reg);
1880 }
1881 break;
1882 case ModLReg:
1883 if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1884 else if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
1885 else
1886 {
1887 AddLSrc(S2Reg); SetCross(S1Reg);
1888 __erg = CodeL(pOrder->Code + 1, DReg, S1Reg, S2Reg);
1889 }
1890 break;
1891 }
1892 break;
1893 case ModImm:
1894 DecodeAdr(&ArgStr[2], MModReg + MModLReg, pOrder->WithImm, &S2Reg);
1895 switch (AdrMode)
1896 {
1897 case ModReg:
1898 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1899 else
1900 {
1901 AddSrc(S2Reg); SetCross(S2Reg);
1902 __erg = CodeL(pOrder->Code + 2, DReg, S1Reg, S2Reg);
1903 }
1904 break;
1905 case ModLReg:
1906 if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1907 else
1908 {
1909 AddLSrc(S2Reg);
1910 __erg = CodeL(pOrder->Code, DReg, S1Reg, S2Reg);
1911 }
1912 break;
1913 }
1914 break;
1915 }
1916 }
1917 }
1918
DecodeLMBD(Word Code)1919 static void DecodeLMBD(Word Code)
1920 {
1921 LongWord DReg, S1Reg, S2Reg;
1922 UNUSED(Code);
1923
1924 if (ChkArgCnt(3, 3)
1925 && DecodeAdr(&ArgStr[3], MModReg, False, &DReg)
1926 && ChkUnit(DReg, L1, L2))
1927 {
1928 AddDest(DReg);
1929 if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1930 {
1931 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1932 else
1933 {
1934 SetCross(S2Reg);
1935 if (DecodeAdr(&ArgStr[1], MModImm + MModReg, False, &S1Reg))
1936 {
1937 if (AdrMode == ModReg)
1938 AddSrc(S1Reg);
1939 __erg = CodeL(0x6a + Ord(AdrMode == ModImm), DReg, S1Reg, S2Reg);
1940 }
1941 }
1942 }
1943 }
1944 }
1945
DecodeNORM(Word Code)1946 static void DecodeNORM(Word Code)
1947 {
1948 LongWord DReg, S2Reg;
1949
1950 UNUSED(Code);
1951
1952 if (ChkArgCnt(2, 2)
1953 && DecodeAdr(&ArgStr[2], MModReg, False, &DReg)
1954 && ChkUnit(DReg, L1, L2))
1955 {
1956 AddDest(DReg);
1957 DecodeAdr(&ArgStr[1], MModReg + MModLReg, True, &S2Reg);
1958 switch (AdrMode)
1959 {
1960 case ModReg:
1961 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1962 else
1963 {
1964 SetCross(S2Reg); AddSrc(S2Reg);
1965 __erg = CodeL(0x63, DReg, 0, S2Reg);
1966 }
1967 break;
1968 case ModLReg:
1969 if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1970 else
1971 {
1972 AddLSrc(S2Reg);
1973 __erg = CodeL(0x60, DReg, 0, S2Reg);
1974 }
1975 break;
1976 }
1977 }
1978 }
1979
DecodeSADD(Word Code)1980 static void DecodeSADD(Word Code)
1981 {
1982 LongWord DReg, S1Reg, S2Reg;
1983
1984 UNUSED(Code);
1985
1986 if (ChkArgCnt(3, 3)
1987 && DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg)
1988 && ChkUnit(DReg, L1, L2))
1989 {
1990 switch (AdrMode)
1991 {
1992 case ModReg:
1993 AddDest(DReg);
1994 DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
1995 switch (AdrMode)
1996 {
1997 case ModReg:
1998 AddSrc(S1Reg);
1999 DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
2000 switch (AdrMode)
2001 {
2002 case ModReg:
2003 if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2004 else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2005 else
2006 {
2007 AddSrc(S2Reg);
2008 if (IsCross(S1Reg)) SwapReg(&S1Reg, &S2Reg);
2009 SetCross(S2Reg);
2010 __erg = CodeL(0x13, DReg, S1Reg, S2Reg);
2011 }
2012 break;
2013 case ModImm:
2014 if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
2015 else
2016 {
2017 SetCross(S1Reg);
2018 __erg = CodeL(0x12, DReg, S2Reg, S1Reg);
2019 }
2020 break;
2021 }
2022 break;
2023 case ModImm:
2024 if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
2025 {
2026 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2027 else
2028 {
2029 SetCross(S2Reg);
2030 __erg = CodeL(0x12, DReg, S1Reg, S2Reg);
2031 }
2032 }
2033 break;
2034 }
2035 break;
2036 case ModLReg:
2037 AddLDest(DReg);
2038 DecodeAdr(&ArgStr[1], MModReg + MModLReg + MModImm, True, &S1Reg);
2039 switch (AdrMode)
2040 {
2041 case ModReg:
2042 AddSrc(S1Reg);
2043 if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
2044 {
2045 if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
2046 else
2047 {
2048 AddLSrc(S2Reg); SetCross(S1Reg);
2049 __erg = CodeL(0x31, DReg, S1Reg, S2Reg);
2050 }
2051 }
2052 break;
2053 case ModLReg:
2054 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2055 else
2056 {
2057 AddLSrc(S1Reg);
2058 DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
2059 switch (AdrMode)
2060 {
2061 case ModReg:
2062 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2063 else
2064 {
2065 AddSrc(S2Reg); SetCross(S2Reg);
2066 __erg = CodeL(0x31, DReg, S2Reg, S1Reg);
2067 }
2068 break;
2069 case ModImm:
2070 __erg = CodeL(0x30, DReg, S2Reg, S1Reg);
2071 break;
2072 }
2073 }
2074 break;
2075 case ModImm:
2076 if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
2077 {
2078 if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
2079 else
2080 {
2081 AddLSrc(S2Reg);
2082 __erg = CodeL(0x30, DReg, S1Reg, S2Reg);
2083 }
2084 }
2085 break;
2086 }
2087 break;
2088 }
2089 }
2090 }
2091
DecodeSAT(Word Code)2092 static void DecodeSAT(Word Code)
2093 {
2094 LongWord DReg, S2Reg;
2095
2096 UNUSED(Code);
2097
2098 if (ChkArgCnt(2, 2)
2099 && DecodeAdr(&ArgStr[2], MModReg, True, &DReg)
2100 && ChkUnit(DReg, L1, L2))
2101 {
2102 AddDest(DReg);
2103 if (DecodeAdr(&ArgStr[1], MModLReg, True, &S2Reg))
2104 {
2105 if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2106 else
2107 {
2108 AddLSrc(S2Reg);
2109 __erg = CodeL(0x40, DReg, 0, S2Reg);
2110 }
2111 }
2112 }
2113 }
2114
DecodeMVC(Word Code)2115 static void DecodeMVC(Word Code)
2116 {
2117 LongWord S1Reg, CReg;
2118
2119 UNUSED(Code);
2120
2121 if ((ThisUnit != NoUnit) && (ThisUnit != S2)) WrError(ErrNum_InvAddrMode);
2122 else if (ChkArgCnt(2, 2))
2123 {
2124 int z;
2125
2126 z = 0;
2127 ThisUnit = S2;
2128 UnitFlag = 1;
2129 if (DecodeCtrlReg(ArgStr[1].Str, &CReg, False))
2130 z = 2;
2131 else if (DecodeCtrlReg(ArgStr[2].Str, &CReg, True))
2132 z = 1;
2133 else
2134 WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
2135 if (z > 0)
2136 {
2137 if (DecodeAdr(&ArgStr[z], MModReg, False, &S1Reg))
2138 {
2139 if ((ThisCross) && ((z == 2) || (IsCross(S1Reg)))) WrError(ErrNum_InvAddrMode);
2140 else
2141 {
2142 if (z == 1)
2143 {
2144 AddSrc(S1Reg);
2145 SetCross(S1Reg);
2146 __erg = CodeS(0x0e, CReg, 0, S1Reg);
2147 }
2148 else
2149 {
2150 AddDest(S1Reg);
2151 __erg = CodeS(0x0f, S1Reg, 0, CReg);
2152 }
2153 }
2154 }
2155 }
2156 }
2157 }
2158
DecodeMVK(Word Code)2159 static void DecodeMVK(Word Code)
2160 {
2161 LongWord DReg, S1Reg;
2162 Boolean OK;
2163
2164 if (ChkArgCnt(2, 2))
2165 {
2166 if (DecodeAdr(&ArgStr[2], MModReg, True, &DReg))
2167 if (ChkUnit(DReg, S1, S2))
2168 {
2169 if (Memo("MVKLH"))
2170 S1Reg = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
2171 else if (Memo("MVKL"))
2172 S1Reg = EvalStrIntExpression(&ArgStr[1], SInt16, &OK);
2173 else
2174 S1Reg = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
2175 if (OK)
2176 {
2177 AddDest(DReg);
2178 ThisInst = (DReg << 23) + (((S1Reg >> Hi(Code)) & 0xffff) << 7) + (UnitFlag << 1) + Lo(Code);
2179 __erg = True;
2180 }
2181 }
2182 }
2183 }
2184
DecodeSHL(Word Code)2185 static void DecodeSHL(Word Code)
2186 {
2187 LongWord DReg, S1Reg, S2Reg;
2188
2189 UNUSED(Code);
2190
2191 if (ChkArgCnt(3, 3))
2192 {
2193 DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
2194 if ((AdrMode != ModNone) && (ChkUnit(DReg, S1, S2)))
2195 switch (AdrMode)
2196 {
2197 case ModReg:
2198 AddDest(DReg);
2199 if (DecodeAdr(&ArgStr[1], MModReg, True, &S2Reg))
2200 {
2201 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2202 else
2203 {
2204 AddSrc(S2Reg);
2205 SetCross(S2Reg);
2206 DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
2207 switch (AdrMode)
2208 {
2209 case ModReg:
2210 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2211 else
2212 {
2213 AddSrc(S1Reg);
2214 __erg = CodeS(0x33, DReg, S1Reg, S2Reg);
2215 }
2216 break;
2217 case ModImm:
2218 __erg = CodeS(0x32, DReg, S1Reg, S2Reg);
2219 break;
2220 }
2221 }
2222 }
2223 break;
2224 case ModLReg:
2225 AddLDest(DReg);
2226 DecodeAdr(&ArgStr[1], MModReg + MModLReg, True, &S2Reg);
2227 switch (AdrMode)
2228 {
2229 case ModReg:
2230 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2231 else
2232 {
2233 AddSrc(S2Reg); SetCross(S2Reg);
2234 DecodeAdr(&ArgStr[2], MModImm + MModReg, False, &S1Reg);
2235 switch (AdrMode)
2236 {
2237 case ModReg:
2238 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2239 else
2240 {
2241 AddSrc(S1Reg);
2242 __erg = CodeS(0x13, DReg, S1Reg, S2Reg);
2243 }
2244 break;
2245 case ModImm:
2246 __erg = CodeS(0x12, DReg, S1Reg, S2Reg);
2247 break;
2248 }
2249 }
2250 break;
2251 case ModLReg:
2252 if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2253 else
2254 {
2255 AddLSrc(S2Reg);
2256 DecodeAdr(&ArgStr[2], MModImm + MModReg, False, &S1Reg);
2257 switch (AdrMode)
2258 {
2259 case ModReg:
2260 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2261 else
2262 {
2263 AddSrc(S1Reg);
2264 __erg = CodeS(0x31, DReg, S1Reg, S2Reg);
2265 }
2266 break;
2267 case ModImm:
2268 __erg = CodeS(0x30, DReg, S1Reg, S2Reg);
2269 break;
2270 }
2271 }
2272 break;
2273 }
2274 break;
2275 }
2276 }
2277 }
2278
DecodeSHR_SHRU(Word Code)2279 static void DecodeSHR_SHRU(Word Code)
2280 {
2281 LongWord DReg, S1Reg, S2Reg;
2282 Boolean HasSign = Code != 0;
2283
2284 if (ChkArgCnt(3, 3))
2285 {
2286 DecodeAdr(&ArgStr[3], MModReg + MModLReg, HasSign, &DReg);
2287 if ((AdrMode != ModNone) && (ChkUnit(DReg, S1, S2)))
2288 switch (AdrMode)
2289 {
2290 case ModReg:
2291 AddDest(DReg);
2292 if (DecodeAdr(&ArgStr[1], MModReg, HasSign, &S2Reg))
2293 {
2294 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2295 else
2296 {
2297 AddSrc(S2Reg); SetCross(S2Reg);
2298 DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
2299 switch (AdrMode)
2300 {
2301 case ModReg:
2302 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2303 else
2304 {
2305 AddSrc(S1Reg);
2306 __erg = CodeS(0x27 + Code, DReg, S1Reg, S2Reg);
2307 }
2308 break;
2309 case ModImm:
2310 __erg = CodeS(0x26 + Code, DReg, S1Reg, S2Reg);
2311 break;
2312 }
2313 }
2314 }
2315 break;
2316 case ModLReg:
2317 AddLDest(DReg);
2318 if (DecodeAdr(&ArgStr[1], MModLReg, HasSign, &S2Reg))
2319 {
2320 if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2321 else
2322 {
2323 AddLSrc(S2Reg);
2324 DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
2325 switch (AdrMode)
2326 {
2327 case ModReg:
2328 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2329 else
2330 {
2331 AddSrc(S1Reg);
2332 __erg = CodeS(0x25 + Code, DReg, S1Reg, S2Reg);
2333 }
2334 break;
2335 case ModImm:
2336 __erg = CodeS(0x24 + Code, DReg, S1Reg, S2Reg);
2337 break;
2338 }
2339 }
2340 }
2341 break;
2342 }
2343 }
2344 }
2345
DecodeSSHL(Word Code)2346 static void DecodeSSHL(Word Code)
2347 {
2348 LongWord DReg, S1Reg, S2Reg;
2349
2350 UNUSED(Code);
2351
2352 if (ChkArgCnt(3, 3))
2353 {
2354 if (DecodeAdr(&ArgStr[3], MModReg, True, &DReg))
2355 if (ChkUnit(DReg, S1, S2))
2356 {
2357 AddDest(DReg);
2358 if (DecodeAdr(&ArgStr[1], MModReg, True, &S2Reg))
2359 {
2360 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2361 else
2362 {
2363 AddSrc(S2Reg); SetCross(S2Reg);
2364 DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
2365 switch (AdrMode)
2366 {
2367 case ModReg:
2368 if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2369 else
2370 {
2371 AddSrc(S1Reg);
2372 __erg = CodeS(0x23, DReg, S1Reg, S2Reg);
2373 }
2374 break;
2375 case ModImm:
2376 __erg = CodeS(0x22, DReg, S1Reg, S2Reg);
2377 break;
2378 }
2379 }
2380 }
2381 }
2382 }
2383 }
2384
DecodeSSUB(Word Code)2385 static void DecodeSSUB(Word Code)
2386 {
2387 LongWord DReg, S1Reg, S2Reg;
2388
2389 UNUSED(Code);
2390
2391 if (ChkArgCnt(3, 3))
2392 {
2393 DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
2394 if ((AdrMode != ModNone) && (ChkUnit(DReg, L1, L2)))
2395 switch (AdrMode)
2396 {
2397 case ModReg:
2398 AddDest(DReg);
2399 DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
2400 switch (AdrMode)
2401 {
2402 case ModReg:
2403 AddSrc(S1Reg);
2404 if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
2405 {
2406 if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2407 else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2408 else if (IsCross(S1Reg))
2409 {
2410 ThisCross = True;
2411 __erg = CodeL(0x1f, DReg, S1Reg, S2Reg);
2412 }
2413 else
2414 {
2415 SetCross(S2Reg);
2416 __erg = CodeL(0x0f, DReg, S1Reg, S2Reg);
2417 }
2418 }
2419 break;
2420 case ModImm:
2421 if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
2422 {
2423 if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2424 else
2425 {
2426 AddSrc(S2Reg); SetCross(S2Reg);
2427 __erg = CodeL(0x0e, DReg, S1Reg, S2Reg);
2428 }
2429 }
2430 break;
2431 }
2432 break;
2433 case ModLReg:
2434 AddLDest(DReg);
2435 if (DecodeAdr(&ArgStr[1], MModImm, True, &S1Reg))
2436 {
2437 if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
2438 {
2439 if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2440 else
2441 {
2442 AddLSrc(S2Reg);
2443 __erg = CodeL(0x2c, DReg, S1Reg, S2Reg);
2444 }
2445 }
2446 }
2447 break;
2448 }
2449 }
2450 }
2451
2452 /* Spruenge */
2453
DecodeB(Word Code)2454 static void DecodeB(Word Code)
2455 {
2456 LongWord S2Reg, Code1;
2457 LongInt Dist;
2458 Boolean WithImm, OK;
2459
2460 UNUSED(Code);
2461
2462 if (ArgCnt != 1) WrError(ErrNum_InvAddrMode);
2463 else if (ThisCross) WrError(ErrNum_InvAddrMode);
2464 else if ((ThisUnit != NoUnit) && (ThisUnit != S1) && (ThisUnit != S2)) WrError(ErrNum_InvAddrMode);
2465 else
2466 {
2467 OK = True;
2468 S2Reg = 0;
2469 WithImm = False;
2470 Code1 = 0;
2471 if (!as_strcasecmp(ArgStr[1].Str, "IRP"))
2472 {
2473 Code1 = 0x03;
2474 S2Reg = 0x06;
2475 }
2476 else if (!as_strcasecmp(ArgStr[1].Str, "NRP"))
2477 {
2478 Code1 = 0x03;
2479 S2Reg = 0x07;
2480 }
2481 else if (DecodeReg(ArgStr[1].Str, &S2Reg, &OK, False))
2482 {
2483 if (OK) WrError(ErrNum_InvAddrMode);
2484 OK = !OK;
2485 Code1 = 0x0d;
2486 }
2487 else
2488 WithImm = OK = True;
2489 if (OK)
2490 {
2491 if (WithImm)
2492 {
2493 tSymbolFlags Flags;
2494
2495 if (ThisUnit == NoUnit)
2496 ThisUnit = (UnitUsed(S1)) ? S2 : S1;
2497 UnitFlag = Ord(ThisUnit == S2);
2498
2499 /* branches relative to fetch packet */
2500
2501 Dist = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags) - (PacketAddr & (~31));
2502 if (OK)
2503 {
2504 if ((Dist & 3) != 0) WrError(ErrNum_NotAligned);
2505 else if (!mSymbolQuestionable(Flags) && ((Dist > 0x3fffff) || (Dist < -0x400000))) WrError(ErrNum_JmpDistTooBig);
2506 else
2507 {
2508 ThisInst = 0x10 + ((Dist & 0x007ffffc) << 5) + (UnitFlag << 1);
2509 ThisAbsBranch = True;
2510 __erg = True;
2511 }
2512 }
2513 }
2514 else
2515 {
2516 if (ChkUnit(0x10, S1, S2))
2517 {
2518 SetCross(S2Reg);
2519 __erg = CodeS(Code1, 0, 0, S2Reg);
2520 }
2521 }
2522 }
2523 }
2524 }
2525
DecodeInst(void)2526 static Boolean DecodeInst(void)
2527 {
2528 __erg = False;
2529
2530 /* ueber Tabelle: */
2531
2532 if (LookupInstTable(InstTable, OpPart.Str))
2533 return __erg;
2534
2535 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2536 return False;
2537 }
2538
ChkPacket(void)2539 static void ChkPacket(void)
2540 {
2541 LongWord EndAddr, Mask;
2542 LongInt z, z1, z2;
2543 Integer RegReads[32];
2544 char TestUnit[4];
2545 int BranchCnt;
2546
2547 /* nicht ueber 8er-Grenze */
2548
2549 EndAddr = PacketAddr + ((ParCnt << 2) - 1);
2550 if ((PacketAddr >> 5) != (EndAddr >> 5))
2551 WrError(ErrNum_PackCrossBoundary);
2552
2553 /* doppelte Units,Crosspaths,Adressierer,Zielregister */
2554
2555 for (z1 = 0; z1 < ParCnt; z1++)
2556 for (z2 = z1 + 1; z2 < ParCnt; z2++)
2557 if ((ParRecs[z1].OpCode >> 28) == (ParRecs[z2].OpCode >> 28))
2558 {
2559 /* doppelte Units */
2560
2561 if ((ParRecs[z1].U != NoUnit) && (ParRecs[z1].U == ParRecs[z2].U))
2562 WrXError(ErrNum_UnitMultipleUsed, UnitNames[ParRecs[z1].U]);
2563
2564 /* Crosspaths */
2565
2566 z = ParRecs[z1].CrossUsed & ParRecs[z2].CrossUsed;
2567 if (z != 0)
2568 {
2569 *TestUnit = z + '0';
2570 TestUnit[1] = 'X';
2571 TestUnit[2] = '\0';
2572 WrXError(ErrNum_UnitMultipleUsed, TestUnit);
2573 }
2574
2575 z = ParRecs[z1].AddrUsed & ParRecs[z2].AddrUsed;
2576
2577 /* Adressgeneratoren */
2578
2579 if ((z & 1) == 1) WrXError(ErrNum_UnitMultipleUsed, "Addr. A");
2580 if ((z & 2) == 2) WrXError(ErrNum_UnitMultipleUsed, "Addr. B");
2581
2582 /* Hauptspeicherpfade */
2583
2584 if ((z & 4) == 4) WrXError(ErrNum_UnitMultipleUsed, "LdSt. A");
2585 if ((z & 8) == 8) WrXError(ErrNum_UnitMultipleUsed, "LdSt. B");
2586
2587 /* ueberlappende Zielregister */
2588
2589 z = ParRecs[z1].DestMask & ParRecs[z2].DestMask;
2590 if (z != 0)
2591 WrXError(ErrNum_OverlapDests, RegName(FindReg(z)));
2592
2593 if ((ParRecs[z1].U & 1) == (ParRecs[z2].U & 1))
2594 {
2595 TestUnit[0] = ParRecs[z1].U - NoUnit - 1 + 'A';
2596 TestUnit[1] = '\0';
2597
2598 /* mehrere Long-Reads */
2599
2600 if ((ParRecs[z1].LongSrc) && (ParRecs[z2].LongSrc))
2601 WrXError(ErrNum_MultipleLongRead, TestUnit);
2602
2603 /* mehrere Long-Writes */
2604
2605 if ((ParRecs[z1].LongDest) && (ParRecs[z2].LongDest))
2606 WrXError(ErrNum_MultipleLongWrite, TestUnit);
2607
2608 /* Long-Read mit Store */
2609
2610 if ((ParRecs[z1].StoreUsed) && (ParRecs[z2].LongSrc))
2611 WrXError(ErrNum_LongReadWithStore, TestUnit);
2612 if ((ParRecs[z2].StoreUsed) && (ParRecs[z1].LongSrc))
2613 WrXError(ErrNum_LongReadWithStore, TestUnit);
2614 }
2615 }
2616
2617 for (z2 = 0; z2 < 32; z2++)
2618 RegReads[z2] = 0;
2619 for (z1 = 0; z1 < ParCnt; z1++)
2620 {
2621 Mask = 1;
2622 for (z2 = 0; z2 < 32; z2++)
2623 {
2624 if ((ParRecs[z1].SrcMask & Mask) != 0)
2625 RegReads[z2]++;
2626 if ((ParRecs[z1].SrcMask2 & Mask) != 0)
2627 RegReads[z2]++;
2628 Mask = Mask << 1;
2629 }
2630 }
2631
2632 /* Register mehr als 4mal gelesen */
2633
2634 for (z1 = 0; z1 < 32; z1++)
2635 if (RegReads[z1] > 4)
2636 WrXError(ErrNum_TooManyRegisterReads, RegName(z1));
2637
2638 /* more than one branch to an absolute address */
2639
2640 BranchCnt = 0;
2641 for (z1 = 0; z1 < ParCnt; z1++)
2642 if (ParRecs[z1].AbsBranch)
2643 BranchCnt++;
2644 if (BranchCnt > 1)
2645 WrError(ErrNum_TooManyBranchesInExPacket);
2646 }
2647
MakeCode_3206X(void)2648 static void MakeCode_3206X(void)
2649 {
2650 CodeLen = 0; DontPrint = False;
2651
2652 /* zu ignorierendes */
2653
2654 if ((*OpPart.Str == '\0') && (*LabPart.Str == '\0'))
2655 return;
2656
2657 /* Pseudoanweisungen */
2658
2659 if (DecodePseudo())
2660 return;
2661
2662 /* Flags zuruecksetzen */
2663
2664 ThisPar = False;
2665 Condition = 0;
2666
2667 /* Optionen aus Label holen */
2668
2669 if (*LabPart.Str != '\0')
2670 if ((!strcmp(LabPart.Str, "||")) || (*LabPart.Str == '['))
2671 if (!CheckOpt(LabPart.Str))
2672 return;
2673
2674 /* eventuell falsche Mnemonics verwerten */
2675
2676 if (!strcmp(OpPart.Str, "||"))
2677 if (!ReiterateOpPart())
2678 return;
2679 if (*OpPart.Str == '[')
2680 if (!ReiterateOpPart())
2681 return;
2682
2683 if (Memo(""))
2684 return;
2685
2686 /* Attribut auswerten */
2687
2688 ThisUnit = NoUnit;
2689 ThisCross = False;
2690 if (*AttrPart.Str)
2691 {
2692 if (as_toupper(AttrPart.Str[strlen(AttrPart.Str) - 1]) == 'X')
2693 {
2694 ThisCross = True;
2695 AttrPart.Str[strlen(AttrPart.Str) - 1] = '\0';
2696 }
2697 if (*AttrPart.Str == '\0') ThisUnit = NoUnit;
2698 else
2699 for (; ThisUnit != LastUnit; ThisUnit++)
2700 if (!as_strcasecmp(AttrPart.Str, UnitNames[ThisUnit]))
2701 break;
2702 if (ThisUnit == LastUnit)
2703 {
2704 WrError(ErrNum_UndefAttr);
2705 return;
2706 }
2707 if (((ThisUnit == D1) || (ThisUnit == D2)) && (ThisCross))
2708 {
2709 WrError(ErrNum_InvAddrMode);
2710 return;
2711 }
2712 }
2713
2714 /* falls nicht parallel, vorherigen Stack durchpruefen und verwerfen */
2715
2716 if ((!ThisPar) && (ParCnt > 0))
2717 {
2718 ChkPacket();
2719 ParCnt = 0;
2720 PacketAddr = EProgCounter();
2721 }
2722
2723 /* dekodieren */
2724
2725 ThisSrc = 0;
2726 ThisSrc2 = 0;
2727 ThisDest = 0;
2728 ThisAddr = 0;
2729 ThisStore = ThisAbsBranch = False;
2730 ThisLong = 0;
2731 if (!DecodeInst())
2732 return;
2733
2734 /* einsortieren */
2735
2736 ParRecs[ParCnt].OpCode = (Condition << 28) + ThisInst;
2737 ParRecs[ParCnt].U = ThisUnit;
2738 if (ThisCross)
2739 switch (ThisUnit)
2740 {
2741 case L1: case S1: case M1: case D1:
2742 ParRecs[ParCnt].CrossUsed = 1;
2743 break;
2744 default:
2745 ParRecs[ParCnt].CrossUsed = 2;
2746 }
2747 else
2748 ParRecs[ParCnt].CrossUsed = 0;
2749 ParRecs[ParCnt].AddrUsed = ThisAddr;
2750 ParRecs[ParCnt].SrcMask = ThisSrc;
2751 ParRecs[ParCnt].SrcMask2 = ThisSrc2;
2752 ParRecs[ParCnt].DestMask = ThisDest;
2753 ParRecs[ParCnt].LongSrc = ((ThisLong & 1) == 1);
2754 ParRecs[ParCnt].LongDest = ((ThisLong & 2) == 2);
2755 ParRecs[ParCnt].StoreUsed = ThisStore;
2756 ParRecs[ParCnt].AbsBranch = ThisAbsBranch;
2757 ParCnt++;
2758
2759 /* wenn mehr als eine Instruktion, Ressourcenkonflikte abklopfen und
2760 vorherige Instruktion zuruecknehmen */
2761
2762 if (ParCnt > 1)
2763 {
2764 RetractWords(4);
2765 DAsmCode[CodeLen >> 2] = ParRecs[ParCnt - 2].OpCode | 1;
2766 CodeLen += 4;
2767 }
2768
2769 /* aktuelle Instruktion auswerfen: fuer letzte kein Parallelflag setzen */
2770
2771 DAsmCode[CodeLen >> 2] = ParRecs[ParCnt - 1].OpCode;
2772 CodeLen += 4;
2773 }
2774
2775 /*-------------------------------------------------------------------------*/
2776
AddLinAdd(const char * NName,LongInt NCode)2777 static void AddLinAdd(const char *NName, LongInt NCode)
2778 {
2779 if (InstrZ >= LinAddCnt) exit(255);
2780 LinAddOrders[InstrZ].Code = NCode;
2781 AddInstTable(InstTable, NName, InstrZ++, DecodeLinAdd);
2782 }
2783
AddCmp(const char * NName,LongInt NCode)2784 static void AddCmp(const char *NName, LongInt NCode)
2785 {
2786 if (InstrZ >= CmpCnt) exit(255);
2787 CmpOrders[InstrZ].WithImm = NName[strlen(NName) - 1] != 'U';
2788 CmpOrders[InstrZ].Code = NCode;
2789 AddInstTable(InstTable, NName, InstrZ++, DecodeCmp);
2790 }
2791
AddMem(const char * NName,LongInt NCode,LongInt NScale)2792 static void AddMem(const char *NName, LongInt NCode, LongInt NScale)
2793 {
2794 if (InstrZ >= MemCnt) exit(255);
2795 MemOrders[InstrZ].Code = NCode;
2796 MemOrders[InstrZ].Scale = NScale;
2797 AddInstTable(InstTable,NName, InstrZ++, DecodeMemO);
2798 }
2799
AddMul(const char * NName,LongInt NCode,Boolean NDSign,Boolean NSSign1,Boolean NSSign2,Boolean NMay)2800 static void AddMul(const char *NName, LongInt NCode,
2801 Boolean NDSign, Boolean NSSign1, Boolean NSSign2, Boolean NMay)
2802 {
2803 if (InstrZ >= MulCnt) exit(255);
2804 MulOrders[InstrZ].Code = NCode;
2805 MulOrders[InstrZ].DSign = NDSign;
2806 MulOrders[InstrZ].SSign1 = NSSign1;
2807 MulOrders[InstrZ].SSign2 = NSSign2;
2808 MulOrders[InstrZ].MayImm = NMay;
2809 AddInstTable(InstTable, NName, InstrZ++, DecodeMul);
2810 }
2811
AddCtrl(const char * NName,LongInt NCode,Boolean NWr,Boolean NRd)2812 static void AddCtrl(const char *NName, LongInt NCode,
2813 Boolean NWr, Boolean NRd)
2814 {
2815 if (InstrZ >= CtrlCnt) exit(255);
2816 CtrlRegs[InstrZ].Name = NName;
2817 CtrlRegs[InstrZ].Code = NCode;
2818 CtrlRegs[InstrZ].Wr = NWr;
2819 CtrlRegs[InstrZ++].Rd = NRd;
2820 }
2821
InitFields(void)2822 static void InitFields(void)
2823 {
2824 InstTable = CreateInstTable(203);
2825
2826 AddInstTable(InstTable, "IDLE", 0, DecodeIDLE);
2827 AddInstTable(InstTable, "NOP", 0, DecodeNOP);
2828 AddInstTable(InstTable, "STP", 0, DecodeSTP);
2829 AddInstTable(InstTable, "ABS", 0, DecodeABS);
2830 AddInstTable(InstTable, "ADD", 0, DecodeADD);
2831 AddInstTable(InstTable, "ADDU", 0, DecodeADDU);
2832 AddInstTable(InstTable, "SUB", 0, DecodeSUB);
2833 AddInstTable(InstTable, "SUBU", 0, DecodeSUBU);
2834 AddInstTable(InstTable, "SUBC", 0, DecodeSUBC);
2835 AddInstTable(InstTable, "ADDK", 0, DecodeADDK);
2836 AddInstTable(InstTable, "ADD2", 0, DecodeADD2_SUB2);
2837 AddInstTable(InstTable, "SUB2", 1, DecodeADD2_SUB2);
2838 AddInstTable(InstTable, "AND", 0x1f7b, DecodeLogic);
2839 AddInstTable(InstTable, "OR", 0x1b7f, DecodeLogic);
2840 AddInstTable(InstTable, "XOR", 0x0b6f, DecodeLogic);
2841 AddInstTable(InstTable, "MV", 0, DecodeMV);
2842 AddInstTable(InstTable, "NEG", 0, DecodeNEG);
2843 AddInstTable(InstTable, "NOT", 0, DecodeNOT);
2844 AddInstTable(InstTable, "ZERO", 0, DecodeZERO);
2845 AddInstTable(InstTable, "CLR", 0x3fc8, DecodeCLR_EXT_EXTU_SET);
2846 AddInstTable(InstTable, "EXT", 0x2f48, DecodeCLR_EXT_EXTU_SET);
2847 AddInstTable(InstTable, "EXTU", 0x2b08, DecodeCLR_EXT_EXTU_SET);
2848 AddInstTable(InstTable, "SET", 0x3b88, DecodeCLR_EXT_EXTU_SET);
2849 AddInstTable(InstTable, "LMBD", 0, DecodeLMBD);
2850 AddInstTable(InstTable, "NORM", 0, DecodeNORM);
2851 AddInstTable(InstTable, "SADD", 0, DecodeSADD);
2852 AddInstTable(InstTable, "SAT", 0, DecodeSAT);
2853 AddInstTable(InstTable, "MVC", 0, DecodeMVC);
2854 AddInstTable(InstTable, "MVKL", 0x0028, DecodeMVK);
2855 AddInstTable(InstTable, "MVK", 0x0028, DecodeMVK);
2856 AddInstTable(InstTable, "MVKH", 0x1068, DecodeMVK);
2857 AddInstTable(InstTable, "MVKLH", 0x0068, DecodeMVK);
2858 AddInstTable(InstTable, "SHL", 0, DecodeSHL);
2859 AddInstTable(InstTable, "SHR", 16, DecodeSHR_SHRU);
2860 AddInstTable(InstTable, "SHRU", 0, DecodeSHR_SHRU);
2861 AddInstTable(InstTable, "SSHL", 0, DecodeSSHL);
2862 AddInstTable(InstTable, "SSUB", 0, DecodeSSUB);
2863 AddInstTable(InstTable, "B", 0, DecodeB);
2864
2865 LinAddOrders = (FixedOrder *) malloc(sizeof(FixedOrder)*LinAddCnt); InstrZ = 0;
2866 AddLinAdd("ADDAB", 0x30); AddLinAdd("ADDAH", 0x34); AddLinAdd("ADDAW", 0x38);
2867 AddLinAdd("SUBAB", 0x31); AddLinAdd("SUBAH", 0x35); AddLinAdd("SUBAW", 0x39);
2868
2869 CmpOrders = (CmpOrder *) malloc(sizeof(CmpOrder)*CmpCnt); InstrZ = 0;
2870 AddCmp("CMPEQ", 0x50); AddCmp("CMPGT", 0x44); AddCmp("CMPGTU", 0x4c);
2871 AddCmp("CMPLT", 0x54); AddCmp("CMPLTU", 0x5c);
2872
2873 MemOrders = (MemOrder *) malloc(sizeof(MemOrder)*MemCnt); InstrZ = 0;
2874 AddMem("LDB", 2, 1); AddMem("LDH", 4, 2); AddMem("LDW", 6, 4);
2875 AddMem("LDBU", 1, 1); AddMem("LDHU", 0, 2); AddMem("STB", 3, 1);
2876 AddMem("STH", 5, 2); AddMem("STW", 7, 4);
2877
2878 MulOrders = (MulOrder *) malloc(sizeof(MulOrder)*MulCnt); InstrZ = 0;
2879 AddMul("MPY" , 0x19, True , True , True , True );
2880 AddMul("MPYU" , 0x1f, False, False, False, False);
2881 AddMul("MPYUS" , 0x1d, True , False, True , False);
2882 AddMul("MPYSU" , 0x1b, True , True , False, True );
2883 AddMul("MPYH" , 0x01, True , True , True , False);
2884 AddMul("MPYHU" , 0x07, False, False, False, False);
2885 AddMul("MPYHUS" , 0x05, True , False, True , False);
2886 AddMul("MPYHSU" , 0x03, True , True , False, False);
2887 AddMul("MPYHL" , 0x09, True , True , True , False);
2888 AddMul("MPYHLU" , 0x0f, False, False, False, False);
2889 AddMul("MPYHULS", 0x0d, True , False, True , False);
2890 AddMul("MPYHSLU", 0x0b, True , True , False, False);
2891 AddMul("MPYLH" , 0x11, True , True , True , False);
2892 AddMul("MPYLHU" , 0x17, False, False, False, False);
2893 AddMul("MPYLUHS", 0x15, True , False, True , False);
2894 AddMul("MPYLSHU", 0x13, True , True , False, False);
2895 AddMul("SMPY" , 0x1a, True , True , True , False);
2896 AddMul("SMPYHL" , 0x0a, True , True , True , False);
2897 AddMul("SMPYLH" , 0x12, True , True , True , False);
2898 AddMul("SMPYH" , 0x02, True , True , True , False);
2899
2900 CtrlRegs = (CtrlReg *) malloc(sizeof(CtrlReg)*CtrlCnt); InstrZ = 0;
2901 AddCtrl("AMR" , 0, True , True );
2902 AddCtrl("CSR" , 1, True , True );
2903 AddCtrl("IFR" , 2, False, True );
2904 AddCtrl("ISR" , 2, True , False);
2905 AddCtrl("ICR" , 3, True , False);
2906 AddCtrl("IER" , 4, True , True );
2907 AddCtrl("ISTP" , 5, True , True );
2908 AddCtrl("IRP" , 6, True , True );
2909 AddCtrl("NRP" , 7, True , True );
2910 AddCtrl("IN" , 8, False, True );
2911 AddCtrl("OUT" , 9, True , True );
2912 AddCtrl("PCE1" , 16, False, True );
2913 AddCtrl("PDATA_O", 15, True , True );
2914 }
2915
DeinitFields(void)2916 static void DeinitFields(void)
2917 {
2918 DestroyInstTable(InstTable);
2919 free(LinAddOrders);
2920 free(CmpOrders);
2921 free(MemOrders);
2922 free(MulOrders);
2923 free(CtrlRegs);
2924 }
2925
2926 /*------------------------------------------------------------------------*/
2927
IsDef_3206X(void)2928 static Boolean IsDef_3206X(void)
2929 {
2930 return (!strcmp(LabPart.Str, "||")) || (*LabPart.Str == '[');
2931 }
2932
SwitchFrom_3206X(void)2933 static void SwitchFrom_3206X(void)
2934 {
2935 if (ParCnt > 1)
2936 ChkPacket();
2937 DeinitFields();
2938 if (ParRecs)
2939 {
2940 free(ParRecs);
2941 ParRecs = NULL;
2942 }
2943 }
2944
Chk34Arg(void)2945 static Boolean Chk34Arg(void)
2946 {
2947 return (ArgCnt >= 3);
2948 }
2949
SwitchTo_3206X(void)2950 static void SwitchTo_3206X(void)
2951 {
2952 TurnWords = False;
2953 ConstMode = ConstModeIntel;
2954 SetIsOccupiedFnc = Chk34Arg;
2955
2956 PCSymbol = "$";
2957 HeaderID = 0x47;
2958 NOPCode = 0x00000000;
2959 DivideChars = ",";
2960 HasAttrs = True;
2961 AttrChars = ".";
2962
2963 ValidSegs = 1 << SegCode;
2964 Grans[SegCode] = 1; ListGrans[SegCode] = 4; SegInits[SegCode] = 0;
2965 SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
2966
2967 MakeCode = MakeCode_3206X;
2968 IsDef = IsDef_3206X;
2969 SwitchFrom = SwitchFrom_3206X;
2970 ParRecs = (InstrRec*)malloc(sizeof(InstrRec) * MaxParCnt);
2971 InitFields();
2972
2973 ParCnt = 0;
2974 PacketAddr = 0;
2975 }
2976
code3206x_init(void)2977 void code3206x_init(void)
2978 {
2979 CPU32060 = AddCPU("32060", SwitchTo_3206X);
2980 }
2981