1 /* code68s12z.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS                                                                        */
6 /*                                                                           */
7 /* Code Generator NXP S12Z                                                   */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 
13 #include <ctype.h>
14 #include <string.h>
15 
16 #include "strutil.h"
17 #include "bpemu.h"
18 #include "asmdef.h"
19 #include "asmpars.h"
20 #include "asmsub.h"
21 #include "asmallg.h"
22 #include "asmitree.h"
23 #include "asmstructs.h"
24 #include "codepseudo.h"
25 #include "motpseudo.h"
26 #include "codevars.h"
27 #include "errmsg.h"
28 #include "headids.h"
29 
30 #include "codes12z.h"
31 
32 typedef enum
33 {
34   AdrModeNone = -1,
35   AdrModeReg = 0,
36   AdrModeAReg = 1,
37   AdrModeImm = 2,
38   AdrModeMemReg = 3
39 } tAdrMode;
40 
41 typedef enum
42 {
43   eIndirModeNone,
44   eIndirModePar,
45   eIndirModeSquare
46 } tIndirMode;
47 
48 typedef enum
49 {
50   eIncModeNone,
51   eIncModePreInc,
52   eIncModePostInc,
53   eIncModePreDec,
54   eIncModePostDec
55 } tIncMode;
56 
57 #define MModeReg (1 << AdrModeReg)
58 #define MModeAReg (1 << AdrModeAReg)
59 #define MModeImm (1 << AdrModeImm)
60 #define MModeMemReg (1 << AdrModeMemReg)
61 
62 #define OpSizeBitPos8 ((tSymbolSize)16)
63 #define OpSizeBitPos16 ((tSymbolSize)17)
64 #define OpSizeBitPos32 ((tSymbolSize)18)
65 #define OpSizeShiftCount ((tSymbolSize)19)
66 
67 typedef struct
68 {
69   tAdrMode Mode;
70   Byte Arg, Vals[4], ShiftLSB;
71   unsigned ValCnt;
72 } tAdrVals;
73 
74 static tSymbolSize OpSize, OpSize2;
75 
76 static const tSymbolSize RegSizes[16] =
77 {
78   eSymbolSize16Bit, eSymbolSize16Bit,   /* D2/D3 */
79   eSymbolSize16Bit, eSymbolSize16Bit,   /* D4/D5 */
80   eSymbolSize8Bit,  eSymbolSize8Bit,    /* D0/D1 */
81   eSymbolSize32Bit, eSymbolSize32Bit,   /* D6/D7 */
82   eSymbolSize24Bit, eSymbolSize24Bit,   /* X/Y */
83   eSymbolSize24Bit, eSymbolSizeUnknown, /* S/- */
84   eSymbolSize8Bit,  eSymbolSize8Bit,    /* CCH/CCL */
85   eSymbolSize16Bit, eSymbolSizeUnknown, /* CCR/- */
86 };
87 
88 /*--------------------------------------------------------------------------*/
89 /* Helper Functions */
90 
PutCode(Word Code)91 static void PutCode(Word Code)
92 {
93   if (Hi(Code))
94     BAsmCode[CodeLen++] = Hi(Code);
95   BAsmCode[CodeLen++] = Lo(Code);
96 }
97 
AppendAdrVals(const tAdrVals * pVals)98 static void AppendAdrVals(const tAdrVals *pVals)
99 {
100   memcpy(BAsmCode + CodeLen, pVals->Vals, pVals->ValCnt);
101   CodeLen += pVals->ValCnt;
102 }
103 
DecodeRegStr(const char * pArg,Byte * pRes)104 static Boolean DecodeRegStr(const char *pArg, Byte *pRes)
105 {
106   if ((strlen(pArg) == 2)
107    && (toupper(*pArg) == 'D')
108    && ((pArg[1] >= '0') && (pArg[1] <= '7')))
109   {
110     static const Byte RegCodes[8] = { 4, 5, 0, 1, 2, 3, 6, 7 };
111 
112     *pRes = RegCodes[pArg[1]- '0'];
113     return True;
114   }
115   else
116     return False;
117 }
118 
DecodeAdrRegStr(const char * pArg,Byte * pRes)119 static Boolean DecodeAdrRegStr(const char *pArg, Byte *pRes)
120 {
121   static const char Regs[4][3] = { "X", "Y", "S", "PC" };
122   unsigned z;
123 
124   for (z = 0; z < 4; z++)
125     if (!as_strcasecmp(pArg, Regs[z]))
126     {
127       *pRes = z;
128       return True;
129     }
130   return False;
131 }
132 
DecodeRegArg(int ArgNum,Byte * pRes,Byte Mask)133 static Boolean DecodeRegArg(int ArgNum, Byte *pRes, Byte Mask)
134 {
135   Boolean Result = DecodeRegStr(ArgStr[ArgNum].Str, pRes);
136 
137   if (!Result || !((Mask >> *pRes) & 1))
138     WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgNum]);
139   return Result;
140 }
141 
DecodeAdrRegArg(int ArgNum,Byte * pRes,Byte Mask)142 static Boolean DecodeAdrRegArg(int ArgNum, Byte *pRes, Byte Mask)
143 {
144   Boolean Result = DecodeAdrRegStr(ArgStr[ArgNum].Str, pRes);
145 
146   if (!Result || !((Mask >> *pRes) & 1))
147     WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgNum]);
148   return Result;
149 }
150 
DecodeGenRegArg(int ArgNum,Byte * pRes)151 static Boolean DecodeGenRegArg(int ArgNum, Byte *pRes)
152 {
153   if (DecodeRegStr(ArgStr[ArgNum].Str, pRes))
154     return True;
155   else if (DecodeAdrRegStr(ArgStr[ArgNum].Str, pRes) && (*pRes != 3))
156   {
157     *pRes += 8;
158     return True;
159   }
160   else if (!as_strcasecmp(ArgStr[ArgNum].Str, "CCH"))
161   {
162     *pRes = 12;
163     return True;
164   }
165   else if (!as_strcasecmp(ArgStr[ArgNum].Str, "CCL"))
166   {
167     *pRes = 13;
168     return True;
169   }
170   else if (!as_strcasecmp(ArgStr[ArgNum].Str, "CCW"))
171   {
172     *pRes = 14;
173     return True;
174   }
175   else
176     return False;
177 }
178 
ShortImm(LongInt Value,ShortInt OpSize,Byte * pShortValue,Byte * pShiftLSB)179 static Boolean ShortImm(LongInt Value, ShortInt OpSize, Byte *pShortValue, Byte *pShiftLSB)
180 {
181   if (OpSize == OpSizeShiftCount)
182   {
183     if ((Value >= 0) && (Value <= 31))
184     {
185       *pShortValue = (Value >> 1 & 15);
186       *pShiftLSB = Value & 1;
187       return True;
188     }
189     else
190       return False;
191   }
192   else if (OpSize < OpSizeBitPos8)
193   {
194     if (Value == -1)
195     {
196       *pShortValue = 0;
197       return True;
198     }
199     else if ((Value >= 1) && (Value <= 15))
200     {
201       *pShortValue = Value;
202       return True;
203     }
204     else if (((Value == (LongInt)0xff) && (OpSize == 0))
205           || ((Value == (LongInt)0xffff) && (OpSize == 1))
206           || ((Value == (LongInt)0xffffff) && (OpSize == eSymbolSize24Bit))
207           || ((Value == (LongInt)0xffffffff) && (OpSize == 2)))
208     {
209       *pShortValue = 0;
210       return True;
211     }
212     else
213       return False;
214   }
215   else
216     return False;
217 }
218 
OpSizeByteLen(ShortInt OpSize)219 static unsigned OpSizeByteLen(ShortInt OpSize)
220 {
221   switch (OpSize)
222   {
223     case -1: return 0;
224     case 1: return 2;
225     case 2: return 4;
226     case eSymbolSize24Bit: return 3;
227     default: return 1;
228   }
229 }
230 
ResetAdrVals(tAdrVals * pVals)231 static void ResetAdrVals(tAdrVals *pVals)
232 {
233   pVals->Mode = AdrModeNone;
234   pVals->Arg = 0;
235   pVals->ValCnt = 0;
236   pVals->ShiftLSB = 0;
237 }
238 
IsIncDec(char ch,char * pRes)239 static Boolean IsIncDec(char ch, char *pRes)
240 {
241   *pRes = ((ch == '+') || (ch == '-')) ? ch : '\0';
242   return !!*pRes;
243 }
244 
CopyIndirect(tStrComp * pDest,const tStrComp * pSrc)245 static void CopyIndirect(tStrComp *pDest, const tStrComp *pSrc)
246 {
247   pDest->Pos.Len = strmemcpy(pDest->Str, STRINGSIZE, pSrc->Str + 1, strlen(pSrc->Str) - 2);
248   pDest->Pos.StartCol = pSrc->Pos.StartCol + 1;
249 }
250 
DecodeAdr(int ArgIndex,unsigned ModeMask,tAdrVals * pVals)251 static Boolean DecodeAdr(int ArgIndex, unsigned ModeMask, tAdrVals *pVals)
252 {
253   String CompStr;
254   tStrComp Comp;
255   int l;
256   tIndirMode IndirMode;
257   LargeWord Address;
258   Boolean OK;
259 
260   ResetAdrVals(pVals);
261   StrCompMkTemp(&Comp, CompStr);
262 
263   /* simple register: */
264 
265   if (DecodeRegStr(ArgStr[ArgIndex].Str, &pVals->Arg))
266   {
267     if (ModeMask & MModeReg)
268       pVals->Mode = AdrModeReg;
269     else
270     {
271       pVals->Mode = AdrModeMemReg;
272       pVals->Arg |= 0xb8;
273     }
274     goto done;
275   }
276 
277   if (DecodeAdrRegStr(ArgStr[ArgIndex].Str, &pVals->Arg))
278   {
279     pVals->Mode = AdrModeAReg;
280     goto done;
281   }
282 
283   /* immediate: */
284 
285   if (*ArgStr[ArgIndex].Str == '#')
286   {
287     Boolean OK;
288     LongInt Value;
289 
290     /* avoid returning AdrModeMemReg if immediate is forbidden */
291 
292     if (!(ModeMask &MModeImm))
293       goto error;
294 
295     switch ((int)OpSize)
296     {
297       case eSymbolSize8Bit:
298         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, Int8, &OK);
299         break;
300       case eSymbolSize16Bit:
301         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, Int16, &OK);
302         break;
303       case eSymbolSize32Bit:
304         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, Int32, &OK);
305         break;
306       case eSymbolSize24Bit:
307         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, Int24, &OK);
308         break;
309       case OpSizeBitPos8:
310         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, UInt3, &OK);
311         break;
312       case OpSizeBitPos16:
313         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, UInt4, &OK);
314         break;
315       case OpSizeBitPos32:
316       case OpSizeShiftCount:
317         Value = EvalStrIntExpressionOffs(&ArgStr[ArgIndex], 1, UInt5, &OK);
318         break;
319       default:
320         WrStrErrorPos(ErrNum_UndefOpSizes, &ArgStr[ArgIndex]);
321         goto done;
322     }
323 
324     if ((ModeMask & MModeMemReg) && (ShortImm(Value, OpSize, &pVals->Arg, &pVals->ShiftLSB)))
325     {
326       pVals->Mode = AdrModeMemReg;
327       pVals->Arg |= 0x70;
328     }
329     else
330     {
331       pVals->Mode = AdrModeImm;
332       if (OpSize == eSymbolSize32Bit)
333         pVals->Vals[pVals->ValCnt++] = (Value >> 24) & 0xff;
334       if ((OpSize == eSymbolSize32Bit) || (OpSize == eSymbolSize24Bit))
335         pVals->Vals[pVals->ValCnt++] = (Value >> 16) & 0xff;
336       if ((OpSize != eSymbolSize8Bit) && (OpSize < OpSizeBitPos8))
337         pVals->Vals[pVals->ValCnt++] = (Value >> 8) & 0xff;
338       pVals->Vals[pVals->ValCnt++] = Value & 0xff;
339     }
340     goto done;
341   }
342 
343   /* indirect () []: */
344 
345   l = strlen(ArgStr[ArgIndex].Str);
346   if (IsIndirect(ArgStr[ArgIndex].Str))
347     IndirMode = eIndirModePar;
348   else if ((l >= 2) && (ArgStr[ArgIndex].Str[0] == '[') && (ArgStr[ArgIndex].Str[l - 1] == ']'))
349     IndirMode = eIndirModeSquare;
350   else
351     IndirMode = eIndirModeNone;
352 
353   if (IndirMode)
354   {
355     char *pSep, IncChar;
356     LongInt DispAcc = 0;
357     Byte DataReg = 0, AdrReg = 0, AdrIncReg = 0;
358     Boolean AdrRegPresent = False, DataRegPresent = False, HasDisp = False;
359     tIncMode IncMode = eIncModeNone;
360     tStrComp Right;
361 
362     CopyIndirect(&Comp, &ArgStr[ArgIndex]);
363 
364     /* split into components */
365 
366     while (True)
367     {
368       pSep = QuotPos(Comp.Str, ',');
369       if (pSep)
370         StrCompSplitRef(&Comp, &Right, &Comp, pSep);
371 
372       /* remove leading/trailing spaces */
373 
374       KillPrefBlanksStrCompRef(&Comp);
375       KillPostBlanksStrComp(&Comp);
376       l = strlen(Comp.Str);
377 
378       if (DecodeRegStr(Comp.Str, &DataReg))
379       {
380         if (DataRegPresent)
381         {
382           WrStrErrorPos(ErrNum_InvAddrMode, &Comp);
383           goto done;
384         }
385         DataRegPresent = True;
386       }
387       else if (DecodeAdrRegStr(Comp.Str, &AdrReg))
388       {
389         if (AdrRegPresent)
390         {
391           WrStrErrorPos(ErrNum_InvAddrMode, &Comp);
392           goto done;
393         }
394         AdrRegPresent = True;
395       }
396       else if (IsIncDec(*Comp.Str, &IncChar) && DecodeAdrRegStr(Comp.Str + 1, &AdrIncReg))
397       {
398         if (IncMode)
399         {
400           WrStrErrorPos(ErrNum_InvAddrMode, &Comp);
401           goto done;
402         }
403         IncMode = (IncChar == '+') ? eIncModePreInc : eIncModePreDec;
404       }
405       else if (IsIncDec(Comp.Str[l - 1], &IncChar))
406       {
407         Comp.Str[l - 1] = '\0';
408         if (!DecodeAdrRegStr(Comp.Str, &AdrIncReg))
409         {
410           WrStrErrorPos(ErrNum_InvReg, &Comp);
411           goto done;
412         }
413         if (IncMode)
414         {
415           WrStrErrorPos(ErrNum_InvAddrMode, &Comp);
416           goto done;
417         }
418         IncMode = (IncChar == '+') ? eIncModePostInc : eIncModePostDec;
419       }
420       else
421       {
422         Boolean OK;
423         LongInt Val = EvalStrIntExpression(&Comp, Int24, &OK);
424 
425         if (!OK)
426           goto done;
427         DispAcc += Val;
428         HasDisp = True;
429       }
430 
431       if (pSep)
432         Comp = Right;
433       else
434         break;
435     }
436 
437     /* pre/pos in/decrement */
438 
439     if ((IndirMode == eIndirModePar) && IncMode && !DispAcc && !AdrRegPresent && !DataRegPresent)
440     {
441       switch (AdrIncReg)
442       {
443         case 0:
444         case 1:
445           pVals->Arg = 0xc3 | (AdrIncReg << 4);
446           if ((IncMode == eIncModePostInc) || (IncMode == eIncModePreInc))
447             pVals->Arg |= 0x20;
448           if ((IncMode == eIncModePostInc) || (IncMode == eIncModePostDec))
449             pVals->Arg |= 0x04;
450           pVals->Mode = AdrModeMemReg;
451           break;
452         case 2:
453           if (IncMode == eIncModePreDec)
454           {
455             pVals->Arg = 0xfb;
456             pVals->Mode = AdrModeMemReg;
457           }
458           else if (IncMode == eIncModePostInc)
459           {
460             pVals->Arg = 0xff;
461             pVals->Mode = AdrModeMemReg;
462           }
463           else
464             goto error;
465           break;
466         default:
467           goto error;
468       }
469     }
470 
471     /* (disp,XYSP) */
472 
473     else if ((IndirMode == eIndirModePar) && AdrRegPresent && !DataRegPresent && !IncMode)
474     {
475       if ((AdrReg == 3) && (HasDisp))
476         DispAcc -= EProgCounter();
477 
478       if ((DispAcc >= 0) && (DispAcc <= 15) && (AdrReg != 3))
479       {
480         pVals->Arg = 0x40 | (AdrReg << 4) | (DispAcc & 15);
481         pVals->Mode = AdrModeMemReg;
482       }
483       else if (RangeCheck(DispAcc, SInt9))
484       {
485         pVals->Arg = 0xc0 | (AdrReg << 4) | ((DispAcc >> 8) & 1);
486         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
487         pVals->Mode = AdrModeMemReg;
488       }
489       else
490       {
491         pVals->Arg = 0xc2 | (AdrReg << 4);
492         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 16) & 0xff;
493         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
494         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
495         pVals->Mode = AdrModeMemReg;
496       }
497     }
498 
499     /* (Dn,XYS) */
500 
501     else if ((IndirMode == eIndirModePar) && AdrRegPresent && DataRegPresent && !IncMode && !DispAcc)
502     {
503       if (AdrReg == 3)
504         goto error;
505       else
506       {
507         pVals->Arg = 0x88 | (AdrReg << 4) | DataReg;
508         pVals->Mode = AdrModeMemReg;
509       }
510     }
511 
512     /* (disp,Dn) */
513 
514     else if ((IndirMode == eIndirModePar) && !AdrRegPresent && DataRegPresent && !IncMode)
515     {
516       if (RangeCheck(DispAcc, UInt18))
517       {
518         pVals->Arg = 0x80 | DataReg | ((DispAcc >> 12) & 0x30);
519         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
520         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
521         pVals->Mode = AdrModeMemReg;
522       }
523       else
524       {
525         pVals->Arg = 0xe8 | DataReg;
526         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 16) & 0xff;
527         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
528         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
529         pVals->Mode = AdrModeMemReg;
530       }
531     }
532 
533     /* [Dn,XY] */
534 
535     else if ((IndirMode == eIndirModeSquare) && AdrRegPresent && DataRegPresent && !IncMode && !DispAcc)
536     {
537       if (AdrReg >= 2)
538         goto error;
539       else
540       {
541         pVals->Arg = 0xc8 | (AdrReg << 4) | DataReg;
542         pVals->Mode = AdrModeMemReg;
543       }
544     }
545 
546     /* [disp,XYSP] */
547 
548     else if ((IndirMode == eIndirModeSquare) && AdrRegPresent && !DataRegPresent && !IncMode)
549     {
550       if ((AdrReg == 3) && (HasDisp))
551         DispAcc -= EProgCounter();
552 
553       if (RangeCheck(DispAcc, SInt9))
554       {
555         pVals->Arg = 0xc4 | (AdrReg << 4) | ((DispAcc >> 8) & 1);
556         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
557         pVals->Mode = AdrModeMemReg;
558       }
559       else
560       {
561         pVals->Arg = 0xc6 | (AdrReg << 4);
562         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 16) & 0xff;
563         pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
564         pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
565         pVals->Mode = AdrModeMemReg;
566       }
567     }
568 
569     /* [disp] */
570 
571     else if ((IndirMode == eIndirModeSquare) && !AdrRegPresent && !DataRegPresent && !IncMode)
572     {
573       pVals->Arg = 0xfe;
574       pVals->Vals[pVals->ValCnt++] = (DispAcc >> 16) & 0xff;
575       pVals->Vals[pVals->ValCnt++] = (DispAcc >> 8) & 0xff;
576       pVals->Vals[pVals->ValCnt++] = DispAcc & 0xff;
577       pVals->Mode = AdrModeMemReg;
578     }
579 
580     else
581       goto error;
582 
583     goto done;
584   }
585 
586   /* absolute: */
587 
588   Address = EvalStrIntExpression(&ArgStr[ArgIndex], UInt24, &OK);
589   if (OK)
590   {
591     if (RangeCheck(Address, UInt14))
592     {
593       pVals->Arg = 0x00 | ((Address >> 8) & 0x3f);
594       pVals->Vals[pVals->ValCnt++] = Address & 0xff;
595     }
596     else if (RangeCheck(Address, UInt18))
597     {
598       pVals->Arg = 0xf8 | ((Address >> 16) & 1) | ((Address >> 15) & 4);
599       pVals->Vals[pVals->ValCnt++] = (Address >> 8) & 0xff;
600       pVals->Vals[pVals->ValCnt++] = Address & 0xff;
601     }
602     else
603     {
604       pVals->Arg = 0xfa;
605       pVals->Vals[pVals->ValCnt++] = (Address >> 16) & 0xff;
606       pVals->Vals[pVals->ValCnt++] = (Address >> 8) & 0xff;
607       pVals->Vals[pVals->ValCnt++] = Address & 0xff;
608     }
609     pVals->Mode = AdrModeMemReg;
610   }
611 
612 done:
613   if ((pVals->Mode != AdrModeNone) && !((ModeMask >> pVals->Mode) & 1))
614   {
615     ResetAdrVals(pVals);
616     goto error;
617   }
618   return (pVals->Mode != AdrModeNone);
619 
620 error:
621   WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[ArgIndex]);
622   return False;
623 }
624 
IsImmediate(const tAdrVals * pVals,ShortInt OpSize,Byte * pImmVal)625 static Boolean IsImmediate(const tAdrVals *pVals, ShortInt OpSize, Byte *pImmVal)
626 {
627   switch (pVals->Mode)
628   {
629     case AdrModeImm:
630       *pImmVal = pVals->Vals[pVals->ValCnt - 1];
631       return True;
632     case AdrModeMemReg:
633       if ((pVals->Arg & 0xf0) == 0x70)
634       {
635         *pImmVal = pVals->Arg & 15;
636         if (OpSize == OpSizeShiftCount)
637           *pImmVal = (*pImmVal << 1) | pVals->ShiftLSB;
638         else if (!*pImmVal && (OpSize < OpSizeBitPos8))
639           *pImmVal = 0xff;
640         return True;
641       }
642       /* else fall-through */
643     default:
644       *pImmVal = 0;
645       return False;
646   }
647 }
648 
ChangeImmediate(tAdrVals * pVals,ShortInt OpSize,Byte ImmVal)649 static void ChangeImmediate(tAdrVals *pVals, ShortInt OpSize, Byte ImmVal)
650 {
651   unsigned z;
652 
653   pVals->Mode = AdrModeImm;
654   pVals->Arg = 0;
655   pVals->ValCnt = OpSizeByteLen(OpSize);
656   pVals->Vals[pVals->ValCnt - 1] = ImmVal;
657   for (z = 1; z < pVals->ValCnt; z++)
658     pVals->Vals[z] = (ImmVal & 0x80) ? 0xff : 0x00;
659 }
660 
IsReg(const tAdrVals * pVals,Byte * pReg)661 static Boolean IsReg(const tAdrVals *pVals, Byte *pReg)
662 {
663   switch (pVals->Mode)
664   {
665     case AdrModeReg:
666       *pReg = pVals->Arg;
667       return True;
668     case AdrModeMemReg:
669       if ((pVals->Arg & 0xf8) == 0xb8)
670       {
671         *pReg = pVals->Arg & 7;
672         return True;
673       }
674       /* else fall-through */
675     default:
676       *pReg = 0;
677       return False;
678   }
679 }
680 
SetOpSize(tSymbolSize NewOpSize)681 static Boolean SetOpSize(tSymbolSize NewOpSize)
682 {
683   if ((OpSize == NewOpSize) || (OpSize == eSymbolSizeUnknown))
684   {
685     OpSize = NewOpSize;
686     return True;
687   }
688   else
689   {
690     char Str[30];
691 
692     as_snprintf(Str, sizeof(Str), "%d -> %d", (int)OpSize, (int)NewOpSize);
693     WrXError(ErrNum_ConfOpSizes, Str);
694     return False;
695   }
696 }
697 
SizeCode2(ShortInt ThisOpSize,Byte * pSizeCode)698 static Boolean SizeCode2(ShortInt ThisOpSize, Byte *pSizeCode)
699 {
700   switch (ThisOpSize)
701   {
702     case eSymbolSize8Bit: *pSizeCode = 0; break;
703     case eSymbolSize16Bit: *pSizeCode = 1; break;
704     case eSymbolSize24Bit: *pSizeCode = 2; break;
705     case eSymbolSize32Bit: *pSizeCode = 3; break;
706     default: return False;
707   }
708   return True;
709 }
710 
DecodeImmBitField(tStrComp * pArg,Word * pResult)711 static Boolean DecodeImmBitField(tStrComp *pArg, Word *pResult)
712 {
713   char *pSplit = strchr(pArg->Str, ':'), Save;
714   tStrComp Left, Right;
715   Boolean OK;
716   tSymbolFlags Flags;
717 
718   if (!pSplit)
719   {
720     WrError(ErrNum_InvBitPos);
721     return False;
722   }
723   Save = StrCompSplitRef(&Left, &Right, pArg, pSplit);
724   *pResult = EvalStrIntExpressionWithFlags(&Left, UInt6, &OK, &Flags);
725   if (mFirstPassUnknown(Flags))
726     *pResult &= 31;
727   *pSplit = Save;
728   if (!OK || !ChkRange(*pResult, 1, 32))
729     return False;
730   *pResult = (*pResult << 5) | (EvalStrIntExpression(&Right, UInt5, &OK) & 31);
731   return OK;
732 }
733 
734 /*--------------------------------------------------------------------------*/
735 /* Bit Symbol Handling */
736 
737 /*
738  * Compact representation of bits and bit fields in symbol table:
739  * bits 0..2/3/4: (start) bit position
740  * bits 3/4/5...14/15/16: register address in I/O space (first 4K)
741  * bits 20/21: register size (0/1/2/3 for 8/16/32/24 bits)
742  * bits 24..28: length of bit field minus one (0 for individual bit)
743  */
744 
745 /*!------------------------------------------------------------------------
746  * \fn     AssembleBitfieldSymbol(Byte BitPos, Byte Width, ShortInt OpSize, Word Address)
747  * \brief  build the compact internal representation of a bit field symbol
748  * \param  BitPos bit position in word
749  * \param  Width width of bit field
750  * \param  OpSize operand size (0..2)
751  * \param  Address register address
752  * \return compact representation
753  * ------------------------------------------------------------------------ */
754 
AssembleBitfieldSymbol(Byte BitPos,Byte Width,ShortInt OpSize,Word Address)755 static LongWord AssembleBitfieldSymbol(Byte BitPos, Byte Width, ShortInt OpSize, Word Address)
756 {
757   LongWord CodeOpSize = (OpSize == eSymbolSize24Bit) ? 3 : OpSize;
758   int AddrShift = (OpSize == eSymbolSize24Bit) ? 5 : (3 + OpSize);
759 
760   return BitPos
761        | (((LongWord)Address & 0xfff) << AddrShift)
762        | (CodeOpSize << 20)
763        | (((LongWord)(Width - 1) & 31) << 24);
764 }
765 
766 /*!------------------------------------------------------------------------
767  * \fn     AssembleBitSymbol(Byte BitPos, ShortInt OpSize, Word Address)
768  * \brief  build the compact internal representation of a bit symbol
769  * \param  BitPos bit position in word
770  * \param  OpSize operand size (0..2)
771  * \param  Address register address
772  * \return compact representation
773  * ------------------------------------------------------------------------ */
774 
AssembleBitSymbol(Byte BitPos,ShortInt OpSize,Word Address)775 static LongWord AssembleBitSymbol(Byte BitPos, ShortInt OpSize, Word Address)
776 {
777   return AssembleBitfieldSymbol(BitPos, 1, OpSize, Address);
778 }
779 
780 /*!------------------------------------------------------------------------
781  * \fn     EvalBitPosition(const char *pBitArg, Boolean *pOK, ShortInt OpSize)
782  * \brief  evaluate constant bit position, with bit range depending on operand size
783  * \param  pBitArg bit position argument
784  * \param  pOK returns True if OK
785  * \param  OpSize operand size (0,1,2 -> 8,16,32 bits)
786  * \return bit position as number
787  * ------------------------------------------------------------------------ */
788 
EvalBitPosition(const tStrComp * pBitArg,Boolean * pOK,ShortInt OpSize)789 static Byte EvalBitPosition(const tStrComp *pBitArg, Boolean *pOK, ShortInt OpSize)
790 {
791   switch (OpSize)
792   {
793     case eSymbolSize8Bit:
794       return EvalStrIntExpression(pBitArg, UInt3, pOK);
795     case eSymbolSize16Bit:
796       return EvalStrIntExpression(pBitArg, UInt4, pOK);
797     case eSymbolSize24Bit:
798     {
799       Byte Result;
800       tSymbolFlags Flags;
801 
802       Result = EvalStrIntExpressionWithFlags(pBitArg, UInt5, pOK, &Flags);
803       if (!*pOK)
804         return Result;
805       if (mFirstPassUnknown(Flags))
806         Result &= 15;
807       *pOK = ChkRange(Result, 0, 23);
808       return Result;
809     }
810     case eSymbolSize32Bit:
811       return EvalStrIntExpression(pBitArg, UInt5, pOK);
812     default:
813       WrError(ErrNum_InvOpSize);
814       *pOK = False;
815       return 0;
816   }
817 }
818 
819 /*!------------------------------------------------------------------------
820  * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg, ShortInt OpSize)
821  * \brief  encode a bit symbol, address & bit position separated
822  * \param  pResult resulting encoded bit
823  * \param  pRegArg register argument
824  * \param  pBitArg bit argument
825  * \param  OpSize register size (0/1/2 = 8/16/32 bit)
826  * \return True if success
827  * ------------------------------------------------------------------------ */
828 
DecodeBitArg2(LongWord * pResult,const tStrComp * pRegArg,const tStrComp * pBitArg,ShortInt OpSize)829 static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg, ShortInt OpSize)
830 {
831   Boolean OK;
832   tSymbolFlags Flags;
833   LongWord Addr;
834   Byte BitPos;
835 
836   BitPos = EvalBitPosition(pBitArg, &OK, OpSize);
837   if (!OK)
838     return False;
839 
840   /* all I/O registers reside in the first 4K of the address space */
841 
842   Addr = EvalStrIntExpressionWithFlags(pRegArg, UInt12, &OK, &Flags);
843   if (!OK)
844     return False;
845 
846   *pResult = AssembleBitSymbol(BitPos, OpSize, Addr);
847 
848   return True;
849 }
850 
851 /*!------------------------------------------------------------------------
852  * \fn     DecodeBitfieldArg2(LongWord *pResult, const tStrComp *pRegArg, tStrComp *pBitArg, ShortInt OpSize)
853  * \brief  encode a bit field symbol, address & bit position separated
854  * \param  pResult resulting encoded bit
855  * \param  pRegArg register argument
856  * \param  pBitArg bit argument
857  * \param  OpSize register size (0/1/2 = 8/16/32 bit)
858  * \return True if success
859  * ------------------------------------------------------------------------ */
860 
DecodeBitfieldArg2(LongWord * pResult,const tStrComp * pRegArg,tStrComp * pBitArg,ShortInt OpSize)861 static Boolean DecodeBitfieldArg2(LongWord *pResult, const tStrComp *pRegArg, tStrComp *pBitArg, ShortInt OpSize)
862 {
863   Boolean OK;
864   LongWord Addr;
865   Word BitSpec;
866 
867   if (!DecodeImmBitField(pBitArg, &BitSpec))
868     return False;
869 
870   /* all I/O registers reside in the first 4K of the address space */
871 
872   Addr = EvalStrIntExpression(pRegArg, UInt12, &OK);
873   if (!OK)
874     return False;
875 
876   *pResult = AssembleBitfieldSymbol(BitSpec & 31, (BitSpec >> 5) & 31, OpSize, Addr);
877 
878   return True;
879 }
880 
881 /*!------------------------------------------------------------------------
882  * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop)
883  * \brief  encode a bit symbol from instruction argument(s)
884  * \param  pResult resulting encoded bit
885  * \param  Start first argument
886  * \param  Stop last argument
887  * \param  OpSize register size (0/1/2 = 8/16/32 bit)
888  * \return True if success
889  * ------------------------------------------------------------------------ */
890 
DecodeBitArg(LongWord * pResult,int Start,int Stop,ShortInt OpSize)891 static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
892 {
893   *pResult = 0;
894 
895   /* Just one argument -> parse as bit argument */
896 
897   if (Start == Stop)
898   {
899     tEvalResult EvalResult;
900 
901     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt32, &EvalResult);
902     if (EvalResult.OK)
903       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
904     return EvalResult.OK;
905   }
906 
907   /* register & bit position are given as separate arguments */
908 
909   else if (Stop == Start + 1)
910     return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop], OpSize);
911 
912   /* other # of arguments not allowed */
913 
914   else
915   {
916     WrError(ErrNum_WrongArgCnt);
917     return False;
918   }
919 }
920 
921 /*!------------------------------------------------------------------------
922  * \fn     DecodeBitfieldArg(LongWord *pResult, int Start, int Stop)
923  * \brief  encode a bit symbol from instruction argument(s)
924  * \param  pResult resulting encoded bit
925  * \param  Start first argument
926  * \param  Stop last argument
927  * \return True if success
928  * ------------------------------------------------------------------------ */
929 
DecodeBitfieldArg(LongWord * pResult,int Start,int Stop,ShortInt OpSize)930 static Boolean DecodeBitfieldArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
931 {
932   *pResult = 0;
933 
934   /* Just one argument -> parse as bit field argument */
935 
936   if (Start == Stop)
937   {
938     tEvalResult EvalResult;
939 
940     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt32, &EvalResult);
941     if (EvalResult.OK)
942       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
943     return EvalResult.OK;
944   }
945 
946   /* register & bit position are given as separate arguments */
947 
948   else if (Stop == Start + 1)
949     return DecodeBitfieldArg2(pResult, &ArgStr[Start], &ArgStr[Stop], OpSize);
950 
951   /* other # of arguments not allowed */
952 
953   else
954   {
955     WrError(ErrNum_WrongArgCnt);
956     return False;
957   }
958 }
959 
960 /*!------------------------------------------------------------------------
961  * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, Byte *pWidth, tSymbolSize *pOpSize)
962  * \brief  transform compact represenation of bit (field) symbol into components
963  * \param  BitSymbol compact storage
964  * \param  pAddress (I/O) register address
965  * \param  pBitPos (start) bit position
966  * \param  pWidth pWidth width of bit field, always one for individual bit
967  * \param  pOpSize returns register size (0/1/2 for 8/16/32 bits)
968  * \return constant True
969  * ------------------------------------------------------------------------ */
970 
DissectBitSymbol(LongWord BitSymbol,Word * pAddress,Byte * pBitPos,Byte * pWidth,tSymbolSize * pOpSize)971 static Boolean DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, Byte *pWidth, tSymbolSize *pOpSize)
972 {
973   *pOpSize = (tSymbolSize)((BitSymbol >> 20) & 3);
974   switch (*pOpSize)
975   {
976     case eSymbolSize8Bit:
977       *pAddress = (BitSymbol >> 3) & 0xfff;
978       *pBitPos = BitSymbol & 7;
979       break;
980     case eSymbolSize16Bit:
981       *pAddress = (BitSymbol >> 4) & 0xfff;
982       *pBitPos = BitSymbol & 15;
983       break;
984     case 3:
985       *pOpSize = eSymbolSize24Bit;
986       /* fall-through */
987     case eSymbolSize32Bit:
988       *pAddress = (BitSymbol >> 5) & 0xfff;
989       *pBitPos = BitSymbol & 31;
990     default:
991       break;
992   }
993   *pWidth = 1 + ((BitSymbol >> 24) & 31);
994   return True;
995 }
996 
997 /*!------------------------------------------------------------------------
998  * \fn     DissectBit_S12Z(char *pDest, size_t DestSize, LargeWord Inp)
999  * \brief  dissect compact storage of bit (field) into readable form for listing
1000  * \param  pDest destination for ASCII representation
1001  * \param  DestSize destination buffer size
1002  * \param  Inp compact storage
1003  * ------------------------------------------------------------------------ */
1004 
DissectBit_S12Z(char * pDest,size_t DestSize,LargeWord Inp)1005 static void DissectBit_S12Z(char *pDest, size_t DestSize, LargeWord Inp)
1006 {
1007   Byte BitPos, BitWidth;
1008   Word Address;
1009   tSymbolSize OpSize;
1010   char Attribute;
1011 
1012   DissectBitSymbol(Inp, &Address, &BitPos, &BitWidth, &OpSize);
1013   Attribute = (OpSize == eSymbolSize24Bit) ? 'p' : "bwl"[OpSize];
1014 
1015   UNUSED(DestSize);
1016   if (BitWidth > 1)
1017     as_snprintf(pDest, DestSize, "$%x(%c).%u:%u", (unsigned)Address, Attribute, (unsigned)BitWidth, (unsigned)BitPos);
1018   else
1019     as_snprintf(pDest, DestSize, "$%x(%c).%u", (unsigned)Address, Attribute, (unsigned)BitPos);
1020 }
1021 
1022 /*!------------------------------------------------------------------------
1023  * \fn     ExpandS12ZBit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
1024  * \brief  expands bit definition when a structure is instantiated
1025  * \param  pVarName desired symbol name
1026  * \param  pStructElem element definition
1027  * \param  Base base address of instantiated structure
1028  * ------------------------------------------------------------------------ */
1029 
ExpandS12ZBit(const tStrComp * pVarName,const struct sStructElem * pStructElem,LargeWord Base)1030 static void ExpandS12ZBit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
1031 {
1032   ShortInt OpSize = (pStructElem->OpSize < 0) ? 0 : pStructElem->OpSize;
1033   LongWord Address = Base + pStructElem->Offset;
1034 
1035   if (!ChkRange(Address, 0, 0xfff)
1036    || !ChkRange(pStructElem->BitPos, 0, (8 << OpSize) - 1))
1037     return;
1038 
1039   PushLocHandle(-1);
1040   EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, OpSize, Address), SegBData, False);
1041   PopLocHandle();
1042   /* TODO: MakeUseList? */
1043 }
1044 
1045 /*!------------------------------------------------------------------------
1046  * \fn     ExpandS12ZBitfield(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
1047  * \brief  expands bit field definition when a structure is instantiated
1048  * \param  pVarName desired symbol name
1049  * \param  pStructElem element definition
1050  * \param  Base base address of instantiated structure
1051  * ------------------------------------------------------------------------ */
1052 
ExpandS12ZBitfield(const tStrComp * pVarName,const struct sStructElem * pStructElem,LargeWord Base)1053 static void ExpandS12ZBitfield(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
1054 {
1055   ShortInt OpSize = (pStructElem->OpSize < 0) ? 0 : pStructElem->OpSize;
1056   LongWord Address = Base + pStructElem->Offset;
1057 
1058   if (!ChkRange(Address, 0, 0xfff)
1059    || !ChkRange(pStructElem->BitPos, 0, (8 << OpSize) - 1)
1060    || !ChkRange(pStructElem->BitPos + pStructElem->BitWidthM1, 0, (8 << OpSize) - 1))
1061     return;
1062 
1063   PushLocHandle(-1);
1064   EnterIntSymbol(pVarName, AssembleBitfieldSymbol(pStructElem->BitPos, pStructElem->BitWidthM1 + 1, OpSize, Address), SegBData, False);
1065   PopLocHandle();
1066   /* TODO: MakeUseList? */
1067 }
1068 
1069 /*--------------------------------------------------------------------------*/
1070 /* Instruction Decoders */
1071 
DecodeFixed(Word Code)1072 static void DecodeFixed(Word Code)
1073 {
1074   if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1075   else if (ChkArgCnt(0, 0))
1076     PutCode(Code);
1077 }
1078 
DecodeBranchCore(int ArgIndex)1079 static Boolean DecodeBranchCore(int ArgIndex)
1080 {
1081   Boolean OK;
1082   tSymbolFlags Flags;
1083   LongInt ShortDist, LongDist;
1084 
1085   /* manual says distance is relative to start of next instruction */
1086 
1087   ShortDist = EvalStrIntExpressionWithFlags(&ArgStr[ArgIndex], UInt24, &OK, &Flags) - (EProgCounter() + CodeLen + 1);
1088   if (!OK)
1089     return False;
1090   LongDist = ShortDist - 1;
1091 
1092   if (OpSize == eSymbolSizeUnknown)
1093     OpSize = ((ShortDist <= 63) && (ShortDist >= -64)) ? eSymbolSizeFloat32Bit : eSymbolSize32Bit;
1094   switch (OpSize)
1095   {
1096     case eSymbolSize32Bit:
1097       if (!mSymbolQuestionable(Flags) && !RangeCheck(LongDist, SInt15))
1098       {
1099         WrError(ErrNum_JmpDistTooBig);
1100         return False;
1101       }
1102       else
1103       {
1104         BAsmCode[CodeLen++] = 0x80 | ((LongDist >> 7) & 0x7f);
1105         BAsmCode[CodeLen++] = LongDist & 0xff;
1106       }
1107       break;
1108     case eSymbolSizeFloat32Bit:
1109       if (!mSymbolQuestionable(Flags) && !RangeCheck(ShortDist, SInt7))
1110       {
1111         WrError(ErrNum_JmpDistTooBig);
1112         return False;
1113       }
1114       else
1115       {
1116         BAsmCode[CodeLen++] = ShortDist & 0x7f;
1117       }
1118       break;
1119     default:
1120       WrStrErrorPos(ErrNum_InvOpSize, &AttrPart);
1121       return False;
1122   }
1123   return True;
1124 }
1125 
DecodeBranch(Word Code)1126 static void DecodeBranch(Word Code)
1127 {
1128   if (!ChkArgCnt(1, 1))
1129     return;
1130 
1131   PutCode(Code);
1132   if (!DecodeBranchCore(1))
1133     CodeLen = 0;
1134 }
1135 
DecodeReg(Word Code)1136 static void DecodeReg(Word Code)
1137 {
1138   Byte Reg;
1139 
1140   if (ChkArgCnt(1, 1)
1141    && DecodeRegArg(1, &Reg, 0xff)
1142    && SetOpSize(RegSizes[Reg]))
1143     PutCode(Code | Reg);
1144 }
1145 
DecodeTwoReg(Word Code)1146 static void DecodeTwoReg(Word Code)
1147 {
1148   Byte SrcReg, DestReg;
1149 
1150   /* TODO: what is the operand order (source/dest)? The manual is
1151      unclear about this.  Assuming source is first argument, similar to TFR: */
1152 
1153   if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1154   else if (ChkArgCnt(2, 2)
1155         && DecodeRegArg(2, &DestReg, 0xff)
1156         && DecodeRegArg(1, &SrcReg, 0xff))
1157   {
1158     PutCode(Code);
1159     BAsmCode[CodeLen++] = DestReg | (SrcReg << 4);
1160   }
1161 }
1162 
DecodeRegMemImm(Word Code)1163 static void DecodeRegMemImm(Word Code)
1164 {
1165   Byte Reg;
1166   tAdrVals AdrVals;
1167 
1168   if (ChkArgCnt(2, 2)
1169    && DecodeRegArg(1, &Reg, 0xff)
1170    && SetOpSize(RegSizes[Reg])
1171    && DecodeAdr(2, MModeImm | MModeMemReg, &AdrVals))
1172   {
1173     if (AdrVals.Mode == AdrModeImm)
1174       PutCode(Code | Reg);
1175     else
1176     {
1177       PutCode((Code + 0x10) | Reg);
1178       BAsmCode[CodeLen++] = AdrVals.Arg;
1179     }
1180     AppendAdrVals(&AdrVals);
1181   }
1182 }
1183 
DecodeSUB(Word Code)1184 static void DecodeSUB(Word Code)
1185 {
1186   Byte Reg;
1187   tAdrVals AdrVals;
1188 
1189   if (ArgCnt == 3)
1190   {
1191     if (DecodeRegArg(1, &Reg, 1 << 6)
1192      && DecodeAdrRegArg(2, &Reg, 3)
1193      && DecodeAdrRegArg(3, &Reg, 1 << (1 - Reg)))
1194     {
1195       BAsmCode[CodeLen++] = 0xfe - Reg;
1196     }
1197   }
1198   else if (ChkArgCnt(2, 3)
1199    && DecodeRegArg(1, &Reg, 0xff)
1200    && SetOpSize(RegSizes[Reg])
1201    && DecodeAdr(2, MModeImm | MModeMemReg, &AdrVals))
1202   {
1203     if (AdrVals.Mode == AdrModeImm)
1204       PutCode(Code | Reg);
1205     else
1206     {
1207       PutCode((Code + 0x10) | Reg);
1208       BAsmCode[CodeLen++] = AdrVals.Arg;
1209     }
1210     AppendAdrVals(&AdrVals);
1211   }
1212 }
1213 
DecodeCMP(Word Code)1214 static void DecodeCMP(Word Code)
1215 {
1216   if (ChkArgCnt(2, 2))
1217   {
1218     Byte Reg;
1219     tAdrVals AdrVals;
1220 
1221     DecodeAdr(1, MModeReg | MModeAReg, &AdrVals);
1222     Reg = AdrVals.Arg;
1223     switch (AdrVals.Mode)
1224     {
1225       case AdrModeReg:
1226         if (SetOpSize(RegSizes[Reg])
1227          && DecodeAdr(2, MModeImm | MModeMemReg, &AdrVals))
1228         {
1229           if (AdrVals.Mode == AdrModeImm)
1230             PutCode(Code | Reg);
1231           else
1232           {
1233             PutCode((Code + 0x10) | Reg);
1234             BAsmCode[CodeLen++] = AdrVals.Arg;
1235           }
1236           AppendAdrVals(&AdrVals);
1237         }
1238         break;
1239       case AdrModeAReg:
1240         if (Reg == 3) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
1241         else if (SetOpSize(eSymbolSize24Bit))
1242         {
1243           DecodeAdr(2, MModeImm | MModeMemReg | MModeAReg, &AdrVals);
1244           switch (AdrVals.Mode)
1245           {
1246             case AdrModeImm:
1247               PutCode((Reg == 2) ? 0x1b04 : (0xe8 | Reg));
1248               AppendAdrVals(&AdrVals);
1249               break;
1250             case AdrModeMemReg:
1251               PutCode((Reg == 2) ? 0x1b02 : (0xf8 | Reg));
1252               BAsmCode[CodeLen++] = AdrVals.Arg;
1253               AppendAdrVals(&AdrVals);
1254               break;
1255             case AdrModeAReg:
1256               if (Reg != 0) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
1257               else if (AdrVals.Arg != 1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
1258               else
1259                 PutCode(0xfc);
1260               break;
1261             default:
1262               break;
1263           }
1264         }
1265         break;
1266       default:
1267         break;
1268     }
1269   }
1270 }
1271 
DecodeImm8(Word Code)1272 static void DecodeImm8(Word Code)
1273 {
1274   tAdrVals AdrVals;
1275 
1276   if (ChkArgCnt(1, 1) && SetOpSize(eSymbolSize8Bit) && DecodeAdr(1, MModeImm, &AdrVals))
1277   {
1278     PutCode(Code);
1279     AppendAdrVals(&AdrVals);
1280   }
1281 }
1282 
DecodeShift(Word Code)1283 static void DecodeShift(Word Code)
1284 {
1285   if (ChkArgCnt(2,3))
1286   {
1287     tAdrVals CntAdrVals, OpAdrVals;
1288     tSymbolSize SaveOpSize;
1289     Boolean IsASL = (Code == 0xc0),
1290             IsASR = (Code == 0x80);
1291     Boolean ImmediateCnt, DestIsReg;
1292     Byte ImmCnt, SizeCode, OpReg, DestReg;
1293 
1294     /* force operand size to 5 bits for count */
1295 
1296     SaveOpSize = OpSize;
1297     OpSize = OpSizeShiftCount;
1298     if (!DecodeAdr(ArgCnt, MModeImm | MModeMemReg | MModeReg, &CntAdrVals))
1299       return;
1300     ImmediateCnt = IsImmediate(&CntAdrVals, OpSize, &ImmCnt);
1301     OpSize = SaveOpSize;
1302 
1303     /* source or source-and-dest operand */
1304 
1305     if (!DecodeAdr(ArgCnt - 1, MModeMemReg | MModeReg, &OpAdrVals))
1306       return;
1307 
1308     /* operand size not yet set - then set from source */
1309 
1310     if (IsReg(&OpAdrVals, &OpReg))
1311       SetOpSize(RegSizes[OpReg]);
1312     if (OpSize < 0)
1313     {
1314       WrError(ErrNum_UndefOpSizes);
1315       return;
1316     }
1317     else if (!SizeCode2(OpSize, &SizeCode))
1318     {
1319       WrError(ErrNum_InvOpSize);
1320       return;
1321     }
1322 
1323     /* for three args, destination is always a register */
1324 
1325     if (ArgCnt == 3)
1326     {
1327       /* dest reg does not set operand size - opsize is from src
1328          operand which may be memory */
1329 
1330       if (!DecodeRegArg(1, &DestReg, 0xff))
1331         return;
1332       DestIsReg = True;
1333     }
1334     else
1335       DestIsReg = IsReg(&OpAdrVals, &DestReg);
1336 
1337     /* REG-REG-OPR1/2/3 only allowed with ASL: convert to (REG-)OPR1/2/3-OPR1/2/3 for other instructions,
1338        unless count is immediate: */
1339 
1340     if (!IsASL && DestIsReg && (OpAdrVals.Mode == AdrModeReg) && !ImmediateCnt && (CntAdrVals.Mode == AdrModeMemReg))
1341     {
1342       OpAdrVals.Mode = AdrModeMemReg;
1343       OpAdrVals.Arg |= 0xb8;
1344     }
1345 
1346     /* REG-REG */
1347 
1348     if (DestIsReg && (OpAdrVals.Mode == AdrModeReg) && (CntAdrVals.Mode == AdrModeReg))
1349     {
1350       BAsmCode[CodeLen++] = 0x10 | DestReg;
1351       BAsmCode[CodeLen++] = Code | (IsASL ? 0x10 : 0x20) | OpAdrVals.Arg;
1352       BAsmCode[CodeLen++] = 0xb8 | CntAdrVals.Arg;
1353     }
1354 
1355     /* REG-IMM with n=1..2 */
1356 
1357     else if (DestIsReg && (OpAdrVals.Mode == AdrModeReg) && ImmediateCnt && (ImmCnt >= 1) && (ImmCnt <= 2))
1358     {
1359       BAsmCode[CodeLen++] = (IsASR ? 0x00 : 0x10) | DestReg;
1360       BAsmCode[CodeLen++] = Code | (IsASR ? 0x10 : 0x00) | ((ImmCnt - 1) << 3) | OpAdrVals.Arg;
1361     }
1362 
1363     /* REG-IMM with arbitrary n */
1364 
1365     else if (DestIsReg && (OpAdrVals.Mode == AdrModeReg) && ImmediateCnt)
1366     {
1367       BAsmCode[CodeLen++] = 0x10 | DestReg;
1368       BAsmCode[CodeLen++] = Code | (IsASL ? 0x00 : 0x10) | ((ImmCnt & 1) << 3) | OpAdrVals.Arg;
1369       BAsmCode[CodeLen++] = 0x70 | ((ImmCnt >> 1) & 7);
1370     }
1371 
1372     /* REG-OPR1/2/3 - ASL only */
1373 
1374     else if (IsASL && DestIsReg && (OpAdrVals.Mode == AdrModeReg) && (CntAdrVals.Mode == AdrModeMemReg))
1375     {
1376       BAsmCode[CodeLen++] = 0x10 | DestReg;
1377       BAsmCode[CodeLen++] = Code | (CntAdrVals.ShiftLSB << 3) | OpAdrVals.Arg;
1378       BAsmCode[CodeLen++] = CntAdrVals.Arg;
1379       AppendAdrVals(&CntAdrVals);
1380     }
1381 
1382     /* (REG-)OPR1/2/3-IMM with n=1..2 */
1383 
1384     else if (DestIsReg && ImmediateCnt && (ImmCnt >= 1) && (ImmCnt <= 2))
1385     {
1386       BAsmCode[CodeLen++] = 0x10 | DestReg;
1387       BAsmCode[CodeLen++] = Code | 0x20 | ((ImmCnt - 1) << 3) | SizeCode;
1388       BAsmCode[CodeLen++] = OpAdrVals.Arg;
1389       AppendAdrVals(&OpAdrVals);
1390     }
1391 
1392     /* (REG-)OPR1/2/3-IMM with arbitrary n */
1393 
1394     else if (DestIsReg && ImmediateCnt && (OpAdrVals.Mode == AdrModeMemReg))
1395     {
1396       BAsmCode[CodeLen++] = 0x10 | DestReg;
1397       BAsmCode[CodeLen++] = Code | 0x30 | ((ImmCnt & 1) << 3) | SizeCode;
1398       BAsmCode[CodeLen++] = OpAdrVals.Arg;
1399       AppendAdrVals(&OpAdrVals);
1400       BAsmCode[CodeLen++] = 0x70 | ((ImmCnt >> 1) & 0x0f);
1401     }
1402 
1403     /* (REG-)OPR1/2/3-OPR1/2/3 */
1404 
1405     else if (DestIsReg && (OpAdrVals.Mode == AdrModeMemReg) && (CntAdrVals.Mode == AdrModeMemReg))
1406     {
1407       BAsmCode[CodeLen++] = 0x10 | DestReg;
1408       BAsmCode[CodeLen++] = Code | 0x30 | (CntAdrVals.ShiftLSB << 3) | SizeCode;
1409       BAsmCode[CodeLen++] = OpAdrVals.Arg;
1410       AppendAdrVals(&OpAdrVals);
1411       BAsmCode[CodeLen++] = CntAdrVals.Arg;
1412       AppendAdrVals(&CntAdrVals);
1413     }
1414 
1415     /* (src-)OPR/1/2/3-IMM (n=1..2) */
1416 
1417     else if ((OpAdrVals.Mode == AdrModeMemReg) && ImmediateCnt && (ImmCnt >= 1) && (ImmCnt <= 2))
1418     {
1419       BAsmCode[CodeLen++] = 0x10;
1420       BAsmCode[CodeLen++] = Code | 0x34 | ((ImmCnt - 1) << 3) | SizeCode;
1421       BAsmCode[CodeLen++] = OpAdrVals.Arg;
1422       AppendAdrVals(&OpAdrVals);
1423     }
1424 
1425     else
1426       WrError(ErrNum_InvAddrMode);
1427   }
1428 }
1429 
DecodeBit(Word Code)1430 static void DecodeBit(Word Code)
1431 {
1432   tSymbolSize SaveOpSize;
1433   tAdrVals PosAdrVals, OpAdrVals;
1434   Byte ImmPos, ImmWidth, SizeCode, OpReg;
1435   Boolean ImmediatePos;
1436 
1437   if (!ChkArgCnt(1, 2))
1438     return;
1439 
1440   /* bit operand: */
1441 
1442   if (1 == ArgCnt)
1443   {
1444     LongWord BitArg;
1445     tSymbolSize ThisOpSize;
1446     Word Address;
1447 
1448     if (DecodeBitArg(&BitArg, 1, 1, OpSize)
1449      && DissectBitSymbol(BitArg, &Address, &ImmPos, &ImmWidth, &ThisOpSize)
1450      && SetOpSize(ThisOpSize))
1451     {
1452       /* TODO: warn if ImmWidth != 1 */
1453       if (!SizeCode2(OpSize, &SizeCode) || (SizeCode == 2))
1454       {
1455         WrError(ErrNum_InvOpSize);
1456         return;
1457       }
1458       ImmediatePos = True;
1459       OpAdrVals.Mode = AdrModeMemReg;
1460       OpAdrVals.Arg = Hi(Address);
1461       OpAdrVals.Vals[0] = Lo(Address);
1462       OpAdrVals.ValCnt = 1;
1463     }
1464     else
1465       return;
1466     OpReg = 0;
1467   }
1468 
1469   /* other operand */
1470 
1471   else
1472   {
1473     if (!DecodeAdr(1, MModeMemReg | MModeReg, &OpAdrVals))
1474       return;
1475 
1476     /* operand size not yet set - then set from source */
1477 
1478     if (IsReg(&OpAdrVals, &OpReg))
1479       SetOpSize(RegSizes[OpReg]);
1480     if (OpSize < 0)
1481     {
1482       WrError(ErrNum_UndefOpSizes);
1483       return;
1484     }
1485 
1486     else if (!SizeCode2(OpSize, &SizeCode) || (SizeCode == 2))
1487     {
1488       WrError(ErrNum_InvOpSize);
1489       return;
1490     }
1491 
1492     /* force operand size to 3/4/5 bits for bit position */
1493 
1494     SaveOpSize = OpSize;
1495     OpSize = OpSizeBitPos8 + OpSize;
1496     if (!DecodeAdr(2, MModeImm | MModeReg, &PosAdrVals))
1497       return;
1498     ImmediatePos = IsImmediate(&PosAdrVals, OpSize, &ImmPos);
1499     OpSize = SaveOpSize;
1500   }
1501 
1502   switch (OpAdrVals.Mode)
1503   {
1504     case AdrModeReg:
1505       BAsmCode[CodeLen++] = Code;
1506       if (ImmediatePos)
1507         BAsmCode[CodeLen++] = (ImmPos << 3) | OpReg;
1508       else
1509       {
1510         BAsmCode[CodeLen++] = 0x81 | (PosAdrVals.Arg << 4);
1511         BAsmCode[CodeLen++] = 0xb8 | OpReg;
1512       }
1513       break;
1514     case AdrModeMemReg:
1515       BAsmCode[CodeLen++] = Code;
1516       if (ImmediatePos)
1517       {
1518         BAsmCode[CodeLen] = 0x80 | ((ImmPos & 7) << 4);
1519         if (OpSize >= eSymbolSize16Bit)
1520           BAsmCode[CodeLen] |= (1 << SizeCode) | ((ImmPos >> 3) & SizeCode);
1521         CodeLen++;
1522       }
1523       else
1524         BAsmCode[CodeLen++] = 0x81 | (PosAdrVals.Arg << 4) | (SizeCode << 2);
1525       BAsmCode[CodeLen++] = OpAdrVals.Arg;
1526       AppendAdrVals(&OpAdrVals);
1527       break;
1528     default:
1529       break;
1530   }
1531 }
1532 
DecodeBitField(Word Code)1533 static void DecodeBitField(Word Code)
1534 {
1535   if (!ChkArgCnt(2, 3))
1536     return;
1537 
1538   /* if two arguments, bit field is symbolic and is
1539      - the destination (first arg) for BFINS
1540      - the source (second arg) for BFEXT */
1541 
1542   if (2 == ArgCnt)
1543   {
1544     LongWord BitfieldArg;
1545     Byte Reg, ImmPos, ImmWidth, SizeCode;
1546     Word FieldSpec, Address;
1547     tSymbolSize ThisOpSize;
1548     int RegArg = (Code == 0x80) ? 2 : 1;
1549 
1550     if (DecodeRegArg(RegArg, &Reg, 0xff)
1551      && DecodeBitfieldArg(&BitfieldArg, 3 - RegArg, 3 - RegArg, OpSize)
1552      && DissectBitSymbol(BitfieldArg, &Address, &ImmPos, &ImmWidth, &ThisOpSize)
1553      && SetOpSize(ThisOpSize)
1554      && SizeCode2(OpSize, &SizeCode))
1555     {
1556       FieldSpec = ImmPos | ((ImmWidth < 32) ? ((Word)ImmWidth << 5) : 0);
1557       BAsmCode[CodeLen++] = 0x1b;
1558       BAsmCode[CodeLen++] = 0x08 | Reg;
1559       BAsmCode[CodeLen++] = (Code ? 0xf0: 0x60) | (SizeCode << 2) | Hi(FieldSpec);
1560       BAsmCode[CodeLen++] = Lo(FieldSpec);
1561       BAsmCode[CodeLen++] = Hi(Address);
1562       BAsmCode[CodeLen++] = Lo(Address);
1563     }
1564   }
1565   else
1566   {
1567     Boolean ImmParam;
1568     Byte ParamReg, SizeCode;
1569     Word ParamImm;
1570     tAdrVals SrcAdrVals, DestAdrVals;
1571 
1572     if (*ArgStr[3].Str == '#')
1573     {
1574       tStrComp Field;
1575 
1576       ImmParam = True;
1577       StrCompRefRight(&Field, &ArgStr[3], 1);
1578       if (!DecodeImmBitField(&Field, &ParamImm))
1579         return;
1580     }
1581 
1582     /* only D2...D5 allowed as parameter */
1583 
1584     else if (!DecodeRegStr(ArgStr[3].Str, &ParamReg) || (ParamReg >= 4))
1585     {
1586       WrStrErrorPos(ErrNum_InvReg, &ArgStr[3]);
1587       return;
1588     }
1589     else
1590       ImmParam = False;
1591 
1592     DecodeAdr(2, MModeReg | MModeImm | MModeMemReg, &SrcAdrVals);
1593     switch (SrcAdrVals.Mode)
1594     {
1595       case AdrModeReg:
1596         DecodeAdr(1, MModeReg | MModeMemReg, &DestAdrVals);
1597         switch (DestAdrVals.Mode)
1598         {
1599           case AdrModeReg:
1600             BAsmCode[CodeLen++] = 0x1b;
1601             BAsmCode[CodeLen++] = 0x08 | DestAdrVals.Arg;
1602             if (ImmParam)
1603             {
1604               BAsmCode[CodeLen++] = Code | 0x20 | (SrcAdrVals.Arg << 2) | Hi(ParamImm);
1605               BAsmCode[CodeLen++] = Lo(ParamImm);
1606             }
1607             else
1608               BAsmCode[CodeLen++] = Code | (SrcAdrVals.Arg << 2) | ParamReg;
1609             break;
1610           case AdrModeMemReg:
1611             if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1612             else if (!SizeCode2(OpSize, &SizeCode)) WrError(ErrNum_InvOpSize);
1613             else
1614             {
1615               BAsmCode[CodeLen++] = 0x1b;
1616               BAsmCode[CodeLen++] = 0x08 | SrcAdrVals.Arg;
1617               if (ImmParam)
1618               {
1619                 BAsmCode[CodeLen++] = Code | 0x70 | (SizeCode << 2) | Hi(ParamImm);
1620                 BAsmCode[CodeLen++] = Lo(ParamImm);
1621               }
1622               else
1623                 BAsmCode[CodeLen++] = Code | 0x50 | (SizeCode << 2) | ParamReg;
1624               BAsmCode[CodeLen++] = DestAdrVals.Arg;
1625               AppendAdrVals(&DestAdrVals);
1626             }
1627             break;
1628           default:
1629             break;
1630         }
1631         break;
1632       case AdrModeMemReg:
1633         DecodeAdr(1, MModeReg, &DestAdrVals);
1634         switch (DestAdrVals.Mode)
1635         {
1636           case AdrModeReg:
1637             if (OpSize  == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1638             else if (!SizeCode2(OpSize, &SizeCode)) WrError(ErrNum_InvOpSize);
1639             else
1640             {
1641               BAsmCode[CodeLen++] = 0x1b;
1642               BAsmCode[CodeLen++] = 0x08 | DestAdrVals.Arg;
1643               if (ImmParam)
1644               {
1645                 BAsmCode[CodeLen++] = Code | 0x60 | (SizeCode << 2) | Hi(ParamImm);
1646                 BAsmCode[CodeLen++] = Lo(ParamImm);
1647               }
1648               else
1649                 BAsmCode[CodeLen++] = Code | 0x40 | (SizeCode << 2) | ParamReg;
1650               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
1651               AppendAdrVals(&SrcAdrVals);
1652             }
1653             break;
1654           default:
1655             break;
1656         }
1657         break;
1658       case AdrModeImm: /* immediate only allowed for short immediate in MemReg op */
1659         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
1660         break;
1661       default:
1662         break;
1663     }
1664   }
1665 }
1666 
DecodeBitRel(Word Code)1667 static void DecodeBitRel(Word Code)
1668 {
1669   if (!ChkArgCnt(3, 3))
1670     return;
1671 
1672   ArgCnt--;
1673   DecodeBit(Code);
1674   if (!CodeLen)
1675     return;
1676 
1677   /* operand size attribute is consumed by bit operand */
1678 
1679   OpSize = eSymbolSizeUnknown;
1680   if (!DecodeBranchCore(3))
1681     CodeLen = 0;
1682 }
1683 
DecodeCLR(Word Code)1684 static void DecodeCLR(Word Code)
1685 {
1686   tAdrVals AdrVals;
1687 
1688   UNUSED(Code);
1689 
1690   if (ChkArgCnt(1, 1) && DecodeAdr(1, MModeReg | MModeAReg | MModeMemReg, &AdrVals))
1691   {
1692     switch (AdrVals.Mode)
1693     {
1694       case AdrModeReg:
1695         if (SetOpSize(RegSizes[AdrVals.Arg]))
1696           PutCode(0x0038 | AdrVals.Arg);
1697         break;
1698       case AdrModeAReg:
1699         if (!SetOpSize(eSymbolSize24Bit));
1700         else if (AdrVals.Arg > 1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
1701         else
1702           PutCode(0x009a | AdrVals.Arg);
1703         break;
1704       case AdrModeMemReg:
1705       {
1706         Byte SizeCode;
1707 
1708         if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1709         else if (!SizeCode2(OpSize, &SizeCode)) WrError(ErrNum_InvOpSize);
1710         else
1711         {
1712           BAsmCode[CodeLen++] = 0xbc | SizeCode;
1713           BAsmCode[CodeLen++] = AdrVals.Arg;
1714           AppendAdrVals(&AdrVals);
1715         }
1716         break;
1717       }
1718       default:
1719         break;
1720     }
1721   }
1722 }
1723 
DecodeCOM_NEG(Word Code)1724 static void DecodeCOM_NEG(Word Code)
1725 {
1726   tAdrVals AdrVals;
1727   Byte OpReg, SizeCode;
1728 
1729   if (!ChkArgCnt(1, 1))
1730     return;
1731   DecodeAdr(1, MModeMemReg, &AdrVals);
1732 
1733   /* operand size not yet set - then set from (register) op */
1734 
1735   if (IsReg(&AdrVals, &OpReg))
1736   {
1737     if (!SetOpSize(RegSizes[OpReg]))
1738       return;
1739   }
1740   if (OpSize == eSymbolSizeUnknown)
1741   {
1742     WrError(ErrNum_UndefOpSizes);
1743     return;
1744   }
1745   if (!SizeCode2(OpSize, &SizeCode) || (OpSize == eSymbolSize24Bit))
1746   {
1747     WrError(ErrNum_InvOpSize);
1748     return;
1749   }
1750   PutCode(Code | SizeCode);
1751   BAsmCode[CodeLen++] = AdrVals.Arg;
1752   AppendAdrVals(&AdrVals);
1753 }
1754 
DecodeDBcc(Word Code)1755 static void DecodeDBcc(Word Code)
1756 {
1757   tAdrVals AdrVals;
1758   Byte OpReg, SizeCode;
1759 
1760   if (!ChkArgCnt(2, 2))
1761     return;
1762   DecodeAdr(1, MModeReg | MModeAReg | MModeMemReg, &AdrVals);
1763 
1764   if (IsReg(&AdrVals, &OpReg))
1765   {
1766     if (!SetOpSize(RegSizes[OpReg]))
1767       return;
1768   }
1769   else if (AdrVals.Mode == AdrModeAReg)
1770   {
1771     if (!SetOpSize(eSymbolSize24Bit))
1772       return;
1773   }
1774   if (OpSize == eSymbolSizeUnknown)
1775   {
1776     WrError(ErrNum_UndefOpSizes);
1777     return;
1778   }
1779   if (!SizeCode2(OpSize, &SizeCode))
1780   {
1781     WrError(ErrNum_InvOpSize);
1782     return;
1783   }
1784   switch (AdrVals.Mode)
1785   {
1786     case AdrModeReg:
1787       PutCode(Code | AdrVals.Arg);
1788       break;
1789     case AdrModeAReg:
1790       if (AdrVals.Arg > 1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
1791       else
1792         PutCode(Code | 0x0008 | AdrVals.Arg);
1793       break;
1794     case AdrModeMemReg:
1795       PutCode(Code | 0x000c | SizeCode);
1796       BAsmCode[CodeLen++] = AdrVals.Arg;
1797       AppendAdrVals(&AdrVals);
1798       break;
1799     default:
1800       break;
1801   }
1802 
1803   if (CodeLen > 0)
1804   {
1805     /* operand size attribute consumed by operand */
1806 
1807     OpSize = eSymbolSizeUnknown;
1808 
1809     if (!DecodeBranchCore(2))
1810       CodeLen = 0;
1811   }
1812 }
1813 
DecodeINC_DEC(Word Code)1814 static void DecodeINC_DEC(Word Code)
1815 {
1816   tAdrVals AdrVals;
1817 
1818   if (ChkArgCnt(1, 1) && DecodeAdr(1, MModeReg | MModeMemReg, &AdrVals))
1819   {
1820     switch (AdrVals.Mode)
1821     {
1822       case AdrModeReg:
1823         if (SetOpSize(RegSizes[AdrVals.Arg]))
1824           PutCode(Code + AdrVals.Arg);
1825         break;
1826       case AdrModeMemReg:
1827       {
1828         Byte SizeCode;
1829 
1830         if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1831         else if (!SizeCode2(OpSize, &SizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
1832         else
1833         {
1834           BAsmCode[CodeLen++] = (Code + 0x6c) | SizeCode;
1835           BAsmCode[CodeLen++] = AdrVals.Arg;
1836           AppendAdrVals(&AdrVals);
1837         }
1838         break;
1839       }
1840       default:
1841         break;
1842     }
1843   }
1844 }
1845 
DecodeDIV_MOD(Word Code)1846 static void DecodeDIV_MOD(Word Code)
1847 {
1848   tAdrVals DividentAdrVals, DivisorAdrVals;
1849   Byte DividentSizeCode, DivisorSizeCode, DestReg, DivisorReg;
1850   Word EffCode, LoCode;
1851 
1852   EffCode = Hi(Code) | ((Lo(Code) & 0x01) ? 0x1b00 : 0x0000);
1853   LoCode = Lo(Code) & 0x80;
1854 
1855   /* destination is always a register */
1856 
1857   if (!ChkArgCnt(3, 3) || !DecodeRegArg(1, &DestReg, 0xff))
1858     return;
1859 
1860   DecodeAdr(2, MModeImm | MModeReg | MModeMemReg, &DividentAdrVals);
1861   switch (DividentAdrVals.Mode)
1862   {
1863     case AdrModeReg:
1864       DecodeAdr(3, MModeImm | MModeReg | MModeMemReg, &DivisorAdrVals);
1865       switch (DivisorAdrVals.Mode)
1866       {
1867         case AdrModeReg:
1868           PutCode(EffCode | DestReg);
1869           BAsmCode[CodeLen++] = LoCode | (DividentAdrVals.Arg << 3) | DivisorAdrVals.Arg;
1870           break;
1871         case AdrModeImm:
1872           if (!SizeCode2(OpSize, &DivisorSizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
1873           else
1874           {
1875             PutCode(EffCode | DestReg);
1876             BAsmCode[CodeLen++] = LoCode | 0x44 | (DividentAdrVals.Arg << 3) | DivisorSizeCode;
1877             AppendAdrVals(&DivisorAdrVals);
1878           }
1879           break;
1880         case AdrModeMemReg:
1881           if (!SizeCode2(OpSize, &DivisorSizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
1882           else
1883           {
1884             PutCode(EffCode | DestReg);
1885             BAsmCode[CodeLen++] = LoCode | 0x40 | (DividentAdrVals.Arg << 3) | DivisorSizeCode;
1886             BAsmCode[CodeLen++] = DivisorAdrVals.Arg;
1887             AppendAdrVals(&DivisorAdrVals);
1888           }
1889           break;
1890         default:
1891           break;
1892       }
1893       break;
1894     case AdrModeMemReg:
1895       /* divident==register is filtered out before, so divident size cannot be set from register */
1896       if (!SizeCode2(OpSize, &DividentSizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
1897       else
1898       {
1899         OpSize = OpSize2;
1900         DecodeAdr(3, MModeImm | MModeMemReg, &DivisorAdrVals);
1901         switch (DivisorAdrVals.Mode)
1902         {
1903           case AdrModeMemReg:
1904             if ((OpSize == eSymbolSizeUnknown) && IsReg(&DivisorAdrVals, &DivisorReg))
1905               SetOpSize(RegSizes[DivisorReg]);
1906             if (!SizeCode2(OpSize, &DivisorSizeCode) || (OpSize == eSymbolSize24Bit)) WrError(ErrNum_UndefOpSizes);
1907             else
1908             {
1909               PutCode(EffCode | DestReg);
1910               BAsmCode[CodeLen++] = LoCode | 0x42 | (DividentSizeCode << 4) | (DivisorSizeCode << 2);
1911               BAsmCode[CodeLen++] = DividentAdrVals.Arg;
1912               AppendAdrVals(&DividentAdrVals);
1913               BAsmCode[CodeLen++] = DivisorAdrVals.Arg;
1914               AppendAdrVals(&DivisorAdrVals);
1915             }
1916             break;
1917           case AdrModeImm: /* was only allowed for short imm in MemReg */
1918             WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[3]);
1919             break;
1920           default:
1921             break;
1922         }
1923       }
1924       break;
1925     case AdrModeImm: /* was only allowed for short imm in MemReg */
1926       WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
1927       break;
1928     default:
1929       break;
1930   }
1931 }
1932 
DecodeEXG_TFR(Word Code)1933 static void DecodeEXG_TFR(Word Code)
1934 {
1935   Byte SrcReg, DestReg;
1936 
1937   if (ChkArgCnt(2, 2)
1938    && DecodeGenRegArg(1, &SrcReg)
1939    && DecodeGenRegArg(2, &DestReg))
1940   {
1941     if ((OpSizeByteLen(RegSizes[SrcReg]) >= OpSizeByteLen(RegSizes[DestReg])) && Hi(Code))
1942       WrError(ErrNum_SrcLEThanDest);
1943     BAsmCode[CodeLen++] = Lo(Code);
1944     BAsmCode[CodeLen++] = (SrcReg << 4) | DestReg;
1945   }
1946 }
1947 
DecodeJMP_JSR(Word Code)1948 static void DecodeJMP_JSR(Word Code)
1949 {
1950   tAdrVals AdrVals;
1951 
1952   if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1953   else if (ChkArgCnt(1, 1) && DecodeAdr(1, MModeMemReg, &AdrVals))
1954   {
1955     Byte Dummy;
1956 
1957     if (IsReg(&AdrVals, &Dummy)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
1958     else
1959     {
1960       if (AdrVals.Arg == 0xfa)
1961         PutCode(Code | 0x10);
1962       else
1963       {
1964         PutCode(Code);
1965         BAsmCode[CodeLen++] = AdrVals.Arg;
1966       }
1967       AppendAdrVals(&AdrVals);
1968     }
1969   }
1970 }
1971 
DecodeLD_ST(Word Code)1972 static void DecodeLD_ST(Word Code)
1973 {
1974   tAdrVals SrcAdrVals, DestAdrVals;
1975 
1976   if (ChkArgCnt(2, 2) && DecodeAdr(1, MModeReg | MModeAReg, &DestAdrVals))
1977   {
1978     switch (DestAdrVals.Mode)
1979     {
1980       case AdrModeReg:
1981         if (!SetOpSize(RegSizes[DestAdrVals.Arg]))
1982           return;
1983         DecodeAdr(2, (Code ? 0 : MModeImm) | MModeMemReg, &SrcAdrVals);
1984         switch (SrcAdrVals.Mode)
1985         {
1986           case AdrModeMemReg:
1987           {
1988             Byte ImmVal;
1989 
1990             if ((OpSize == eSymbolSize8Bit) && IsImmediate(&SrcAdrVals, OpSize, &ImmVal)) /* same instr length for byte, but what people expect? */
1991             {
1992               ChangeImmediate(&SrcAdrVals, OpSize, ImmVal);
1993               goto immediate;
1994             }
1995             if (SrcAdrVals.Arg == 0xfa)
1996               BAsmCode[CodeLen++] = (0xb0 + Code) | DestAdrVals.Arg;
1997             else
1998             {
1999               BAsmCode[CodeLen++] = (0xa0 + Code) | DestAdrVals.Arg;
2000               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
2001             }
2002             AppendAdrVals(&SrcAdrVals);
2003             break;
2004           }
2005           case AdrModeImm:
2006           immediate:
2007             BAsmCode[CodeLen++] = 0x90 | DestAdrVals.Arg;
2008             AppendAdrVals(&SrcAdrVals);
2009             break;
2010           default:
2011             break;
2012         }
2013         break;
2014       case AdrModeAReg:
2015         if (DestAdrVals.Arg > 2)
2016         {
2017           WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2018         }
2019         if (!SetOpSize(eSymbolSize24Bit))
2020           return;
2021         DecodeAdr(2, (Code ? 0 : MModeImm) | MModeMemReg, &SrcAdrVals);
2022         switch (SrcAdrVals.Mode)
2023         {
2024           case AdrModeMemReg:
2025             if ((DestAdrVals.Arg < 2) && (SrcAdrVals.Arg == 0xfa))
2026               BAsmCode[CodeLen++] = (0xb8 + Code) | DestAdrVals.Arg;
2027             else if (2 == DestAdrVals.Arg)
2028             {
2029               BAsmCode[CodeLen++] = 0x1b;
2030               BAsmCode[CodeLen++] = 0x00 + !!Code;
2031               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
2032             }
2033             else
2034             {
2035               BAsmCode[CodeLen++] = (0xa8 + Code) | DestAdrVals.Arg;
2036               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
2037             }
2038             AppendAdrVals(&SrcAdrVals);
2039             break;
2040           case AdrModeImm:
2041             /* SrcAdrVals.Cnt must be 3 */
2042             if ((DestAdrVals.Arg < 2) && (SrcAdrVals.Vals[0] < 0x04))
2043             {
2044               BAsmCode[CodeLen++] = 0xca | DestAdrVals.Arg | (SrcAdrVals.Vals[0] << 4);
2045               BAsmCode[CodeLen++] = SrcAdrVals.Vals[1];
2046               BAsmCode[CodeLen++] = SrcAdrVals.Vals[2];
2047             }
2048             else
2049             {
2050               PutCode((DestAdrVals.Arg == 2) ? 0x1b03 : (0x98 | DestAdrVals.Arg));
2051               AppendAdrVals(&SrcAdrVals);
2052             }
2053             break;
2054           default:
2055             break;
2056         }
2057         break;
2058       default:
2059         break;
2060     }
2061   }
2062 }
2063 
DecodeLEA(Word Code)2064 static void DecodeLEA(Word Code)
2065 {
2066   tAdrVals DestAdrVals, SrcAdrVals;
2067   Byte Reg;
2068 
2069   UNUSED(Code);
2070 
2071   if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2072   else if (ChkArgCnt(2, 2) && DecodeAdr(1, MModeReg | MModeAReg, &DestAdrVals))
2073   {
2074     switch (DestAdrVals.Mode)
2075     {
2076       case AdrModeReg:
2077         if (DestAdrVals.Arg < 6) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2078         else if (DecodeAdr(2, MModeMemReg, &SrcAdrVals))
2079         {
2080           if (IsReg(&SrcAdrVals, &Reg)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
2081           else
2082           {
2083             BAsmCode[CodeLen++] = 0x00 | DestAdrVals.Arg;
2084             BAsmCode[CodeLen++] = SrcAdrVals.Arg;
2085             AppendAdrVals(&SrcAdrVals);
2086           }
2087         }
2088         break;
2089       case AdrModeAReg:
2090         if (DestAdrVals.Arg > 2) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2091         else if (DecodeAdr(2, MModeMemReg, &SrcAdrVals))
2092         {
2093           if (IsReg(&SrcAdrVals, &Reg)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
2094           else
2095           {
2096             /* XYS,(i8,XYS) */
2097 
2098             if (((SrcAdrVals.Arg & 0xce) == 0xc0) /* ...,(XYS,i9) */
2099              && ((SrcAdrVals.Arg & 0x01) == ((SrcAdrVals.Vals[0] >> 7) & 1)) /* i9 is i8 */
2100              && (DestAdrVals.Arg == ((SrcAdrVals.Arg >> 4) & 3))) /* destreg==srcreg */
2101             {
2102               BAsmCode[CodeLen++] = 0x18 | DestAdrVals.Arg;
2103               BAsmCode[CodeLen++] = SrcAdrVals.Vals[0];
2104             }
2105             else
2106             {
2107               BAsmCode[CodeLen++] = 0x08 | DestAdrVals.Arg;
2108               BAsmCode[CodeLen++] = SrcAdrVals.Arg;
2109               AppendAdrVals(&SrcAdrVals);
2110             }
2111           }
2112         }
2113         break;
2114       default:
2115         break;
2116     }
2117   }
2118 }
2119 
DecodeMIN_MAX(Word Code)2120 static void DecodeMIN_MAX(Word Code)
2121 {
2122   tAdrVals AdrVals;
2123   Byte Reg;
2124 
2125   if (ChkArgCnt(2, 2)
2126    && DecodeRegArg(1, &Reg, 0xff)
2127    && SetOpSize(RegSizes[Reg])
2128    && DecodeAdr(2, MModeMemReg | MModeImm, &AdrVals))
2129   {
2130     switch (AdrVals.Mode)
2131     {
2132       case AdrModeMemReg:
2133         PutCode(Code | Reg);
2134         BAsmCode[CodeLen++] = AdrVals.Arg;
2135         AppendAdrVals(&AdrVals);
2136         break;
2137       case AdrModeImm: /* was only allowed for short immediate in MemReg */
2138         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
2139         break;
2140       default:
2141         break;
2142     }
2143   }
2144 }
2145 
DecodeMOV(Word Code)2146 static void DecodeMOV(Word Code)
2147 {
2148   tAdrVals SrcAdrVals, DestAdrVals;
2149   Byte Reg, SizeCode;
2150 
2151   UNUSED(Code);
2152 
2153   if (ChkArgCnt(2, 2)
2154    && DecodeAdr(2, MModeMemReg, &DestAdrVals))
2155   {
2156     /* prefer attribute to destination... */
2157 
2158     if (IsReg(&DestAdrVals, &Reg) && (OpSize == eSymbolSizeUnknown))
2159       SetOpSize(RegSizes[Reg]);
2160 
2161     if (!DecodeAdr(1, MModeMemReg | MModeImm, &SrcAdrVals))
2162       return;
2163 
2164     /* ...to source operand size */
2165 
2166     if (IsReg(&SrcAdrVals, &Reg) && (OpSize == eSymbolSizeUnknown))
2167       SetOpSize(RegSizes[Reg]);
2168 
2169     if (!SizeCode2(OpSize, &SizeCode))
2170     {
2171       WrError(ErrNum_InvOpSize);
2172       return;
2173     }
2174 
2175     switch (SrcAdrVals.Mode)
2176     {
2177       case AdrModeImm:
2178         PutCode(0x0c + SizeCode);
2179         AppendAdrVals(&SrcAdrVals);
2180         BAsmCode[CodeLen++] = DestAdrVals.Arg;
2181         AppendAdrVals(&DestAdrVals);
2182         break;
2183       case AdrModeMemReg:
2184         PutCode(0x1c | SizeCode);
2185         BAsmCode[CodeLen++] = SrcAdrVals.Arg;
2186         AppendAdrVals(&SrcAdrVals);
2187         BAsmCode[CodeLen++] = DestAdrVals.Arg;
2188         AppendAdrVals(&DestAdrVals);
2189         break;
2190       default:
2191         break;
2192     }
2193   }
2194 }
2195 
DecodePSH_PUL(Word Code)2196 static void DecodePSH_PUL(Word Code)
2197 {
2198   Word RegMask = 0, ThisRegMask;
2199   int z;
2200   Byte Reg;
2201   static const Word RegMasks[8] = { 0x0002, 0x0001, 0x2000, 0x1000, 0x0008, 0x004, 0x0800, 0x0400 };
2202 
2203   if (!ChkArgCnt(1, ArgCntMax))
2204     return;
2205   for (z = 1; z <= ArgCnt; z++)
2206   {
2207     if (!as_strcasecmp(ArgStr[z].Str, "ALL"))
2208       ThisRegMask = 0x3f3f;
2209     else if (!as_strcasecmp(ArgStr[z].Str, "ALL16b"))
2210       ThisRegMask = 0x3003;
2211     else if (DecodeRegStr(ArgStr[z].Str, &Reg))
2212       ThisRegMask = RegMasks[Reg];
2213     else if (!as_strcasecmp(ArgStr[z].Str, "CCH"))
2214       ThisRegMask = 0x0020;
2215     else if (!as_strcasecmp(ArgStr[z].Str, "CCL"))
2216       ThisRegMask = 0x0010;
2217     else if (DecodeAdrRegStr(ArgStr[z].Str, &Reg) && (Reg < 2))
2218       ThisRegMask = 0x0200 >> Reg;
2219     else
2220     {
2221       WrStrErrorPos(ErrNum_InvReg, &ArgStr[z]);
2222       return;
2223     }
2224     if (ThisRegMask & RegMask)
2225     {
2226       WrStrErrorPos(ErrNum_DoubleReg, &ArgStr[z]);
2227       return;
2228     }
2229     RegMask |= ThisRegMask;
2230   }
2231   if (RegMask == 0x3f3f)
2232     PutCode(Code | 0x00);
2233   else if (RegMask == 0x3003)
2234     PutCode(Code | 0x40);
2235   else if (Hi(RegMask) && !Lo(RegMask))
2236     PutCode(Code | 0x40 | Hi(RegMask));
2237   else if (Lo(RegMask) && !Hi(RegMask))
2238     PutCode(Code | 0x00 | Lo(RegMask));
2239   else
2240     WrError(ErrNum_InvRegList);
2241 }
2242 
DecodeROL_ROR(Word Code)2243 static void DecodeROL_ROR(Word Code)
2244 {
2245   tAdrVals AdrVals;
2246   Byte Reg, SizeCode;
2247 
2248   if (ChkArgCnt(1, 1) && DecodeAdr(1, MModeMemReg, &AdrVals))
2249   {
2250     if (IsReg(&AdrVals, &Reg) && !SetOpSize(RegSizes[Reg]))
2251       return;
2252     if (OpSize == eSymbolSizeUnknown)
2253     {
2254       WrError(ErrNum_UndefOpSizes);
2255       return;
2256     }
2257     if (!SizeCode2(OpSize, &SizeCode))
2258     {
2259       WrError(ErrNum_InvOpSize);
2260       return;
2261     }
2262     PutCode(Code | SizeCode);
2263     BAsmCode[CodeLen++] = AdrVals.Arg;
2264     AppendAdrVals(&AdrVals);
2265   }
2266 }
2267 
DecodeTBcc(Word Code)2268 static void DecodeTBcc(Word Code)
2269 {
2270   tAdrVals AdrVals;
2271 
2272   if (!ChkArgCnt(2, 2) || !DecodeAdr(1, MModeReg | MModeAReg | MModeMemReg | MModeImm, &AdrVals))
2273     return;
2274 
2275   switch (AdrVals.Mode)
2276   {
2277     case AdrModeReg:
2278       if (!SetOpSize(RegSizes[AdrVals.Arg]))
2279         return;
2280       PutCode(Code | AdrVals.Arg);
2281       break;
2282     case AdrModeAReg:
2283       if (AdrVals.Arg >= 2)
2284       {
2285         WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2286         return;
2287       }
2288       if (!SetOpSize(eSymbolSize24Bit))
2289         return;
2290       PutCode(Code | 0x0008 | AdrVals.Arg);
2291       break;
2292     case AdrModeMemReg:
2293     {
2294       Byte SizeCode;
2295 
2296       if (OpSize == eSymbolSizeUnknown)
2297       {
2298         WrError(ErrNum_UndefOpSizes);
2299         return;
2300       }
2301       if (!SizeCode2(OpSize, &SizeCode))
2302       {
2303         WrError(ErrNum_InvOpSize);
2304         return;
2305       }
2306       PutCode(Code | 0x000c | SizeCode);
2307       BAsmCode[CodeLen++] = AdrVals.Arg;
2308       AppendAdrVals(&AdrVals);
2309       break;
2310     }
2311     case AdrModeImm: /* was only allowed for short immediate */
2312       WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
2313       return;
2314     default:
2315       return;
2316   }
2317 
2318   OpSize = OpSize2;
2319   if (!DecodeBranchCore(2))
2320     CodeLen = 0;
2321 }
2322 
DecodeTRAP(Word Code)2323 static void DecodeTRAP(Word Code)
2324 {
2325   tAdrVals AdrVals;
2326 
2327   UNUSED(Code);
2328 
2329   if (ChkArgCnt(1, 1) && SetOpSize(eSymbolSize8Bit) && DecodeAdr(1, MModeImm, &AdrVals))
2330   {
2331     BAsmCode[CodeLen++] = 0x1b;
2332     BAsmCode[CodeLen++] = AdrVals.Vals[0];
2333     switch ((AdrVals.Vals[0] >> 4) & 0x0f)
2334     {
2335       case 12: case 13: case 14: case 15:
2336         break;
2337       case 10: case 11:
2338         if ((AdrVals.Vals[0] & 0x0f) >= 8)
2339           break;
2340         else
2341           goto warn;
2342       case 9:
2343         if ((AdrVals.Vals[0] & 0x0f) >= 2)
2344           break;
2345         /* else fall-through */
2346       default:
2347       warn:
2348         WrError(ErrNum_TrapValidInstruction);
2349     }
2350   }
2351 }
2352 
DecodeDEFBIT(Word Code)2353 static void DecodeDEFBIT(Word Code)
2354 {
2355   LongWord BitSpec;
2356 
2357   UNUSED(Code);
2358 
2359   /* if in structure definition, add special element to structure */
2360 
2361   if (ActPC == StructSeg)
2362   {
2363     Boolean OK;
2364     Byte BitPos;
2365     PStructElem pElement;
2366 
2367     if (!ChkArgCnt(2, 2))
2368       return;
2369     BitPos = EvalBitPosition(&ArgStr[2], &OK, (OpSize == eSymbolSizeUnknown) ? eSymbolSize32Bit : OpSize);
2370     if (!OK)
2371       return;
2372     pElement = CreateStructElem(LabPart.Str);
2373     pElement->pRefElemName = as_strdup(ArgStr[1].Str);
2374     pElement->OpSize = OpSize;
2375     pElement->BitPos = BitPos;
2376     pElement->ExpandFnc = ExpandS12ZBit;
2377     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
2378   }
2379   else
2380   {
2381     if (OpSize == eSymbolSizeUnknown)
2382       OpSize = eSymbolSize8Bit;
2383     if (OpSize > eSymbolSize32Bit)
2384     {
2385       WrError(ErrNum_InvOpSize);
2386       return;
2387     }
2388 
2389     if (DecodeBitArg(&BitSpec, 1, ArgCnt, OpSize))
2390     {
2391       *ListLine = '=';
2392       DissectBit_S12Z(ListLine + 1, STRINGSIZE - 3, BitSpec);
2393       PushLocHandle(-1);
2394       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
2395       PopLocHandle();
2396       /* TODO: MakeUseList? */
2397     }
2398   }
2399 }
2400 
DecodeDEFBITFIELD(Word Code)2401 static void DecodeDEFBITFIELD(Word Code)
2402 {
2403   UNUSED(Code);
2404 
2405   /* if in structure definition, add special element to structure */
2406 
2407   if (ActPC == StructSeg)
2408   {
2409     Word BitField;
2410     PStructElem pElement;
2411 
2412     if (!ChkArgCnt(2, 2))
2413       return;
2414     if (!DecodeImmBitField(&ArgStr[2], &BitField))
2415       return;
2416     pElement = CreateStructElem(LabPart.Str);
2417     pElement->pRefElemName = as_strdup(ArgStr[1].Str);
2418     pElement->OpSize = OpSize;
2419     pElement->BitPos = BitField & 31;
2420     pElement->BitWidthM1 = (BitField >> 5) - 1;
2421     pElement->ExpandFnc = ExpandS12ZBitfield;
2422     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
2423   }
2424   else
2425   {
2426     LongWord BitfieldSpec;
2427 
2428     /* opposed to bit operations, bit field operations also work
2429         24 bit operands: */
2430 
2431     if (OpSize == eSymbolSizeUnknown)
2432       OpSize = eSymbolSize8Bit;
2433     if ((OpSize > eSymbolSize32Bit) && (OpSize != eSymbolSize24Bit))
2434     {
2435       WrError(ErrNum_InvOpSize);
2436       return;
2437     }
2438 
2439     if (DecodeBitfieldArg(&BitfieldSpec, 1, ArgCnt, OpSize))
2440     {
2441       *ListLine = '=';
2442       DissectBit_S12Z(ListLine + 1, STRINGSIZE - 3, BitfieldSpec);
2443       PushLocHandle(-1);
2444       EnterIntSymbol(&LabPart, BitfieldSpec, SegBData, False);
2445       PopLocHandle();
2446       /* TODO: MakeUseList? */
2447     }
2448   }
2449 }
2450 
2451 /*--------------------------------------------------------------------------*/
2452 /* Code Table Handling */
2453 
AddFixed(const char * pName,Word Code)2454 static void AddFixed(const char *pName, Word Code)
2455 {
2456   AddInstTable(InstTable, pName, Code, DecodeFixed);
2457 }
2458 
AddBranch(const char * pName,Word Code)2459 static void AddBranch(const char *pName, Word Code)
2460 {
2461   AddInstTable(InstTable, pName, Code, DecodeBranch);
2462 }
2463 
AddReg(const char * pName,Word Code)2464 static void AddReg(const char *pName, Word Code)
2465 {
2466   AddInstTable(InstTable, pName, Code, DecodeReg);
2467 }
2468 
AddRegMemImm(const char * pName,Word Code)2469 static void AddRegMemImm(const char *pName, Word Code)
2470 {
2471   AddInstTable(InstTable, pName, Code, DecodeRegMemImm);
2472 }
2473 
AddCondition(const char * pName,Word Code,InstProc Proc)2474 static void AddCondition(const char *pName, Word Code, InstProc Proc)
2475 {
2476   char InstrName[20];
2477 
2478   as_snprintf(InstrName, sizeof(InstrName), pName, "NE"); AddInstTable(InstTable, InstrName, Code | (0 << 4), Proc);
2479   as_snprintf(InstrName, sizeof(InstrName), pName, "EQ"); AddInstTable(InstTable, InstrName, Code | (1 << 4), Proc);
2480   as_snprintf(InstrName, sizeof(InstrName), pName, "PL"); AddInstTable(InstTable, InstrName, Code | (2 << 4), Proc);
2481   as_snprintf(InstrName, sizeof(InstrName), pName, "MI"); AddInstTable(InstTable, InstrName, Code | (3 << 4), Proc);
2482   as_snprintf(InstrName, sizeof(InstrName), pName, "GT"); AddInstTable(InstTable, InstrName, Code | (4 << 4), Proc);
2483   as_snprintf(InstrName, sizeof(InstrName), pName, "LE"); AddInstTable(InstTable, InstrName, Code | (5 << 4), Proc);
2484 }
2485 
InitFields(void)2486 static void InitFields(void)
2487 {
2488   InstTable = CreateInstTable(405);
2489   SetDynamicInstTable(InstTable);
2490 
2491   AddFixed("NOP",  NOPCode);
2492   AddFixed("BGND", 0x0000);
2493   AddFixed("CLC",  0xcefe);
2494   AddFixed("CLI",  0xceef);
2495   AddFixed("CLV",  0xcefd);
2496   AddFixed("RTI",  0x1b90);
2497   AddFixed("RTS",  0x0005);
2498   AddFixed("SEC",  0xde01);
2499   AddFixed("SEI",  0xde10);
2500   AddFixed("SEV",  0xde02);
2501   AddFixed("STOP", 0x1b05);
2502   AddFixed("SWI",  0x00ff);
2503   AddFixed("SYS",  0x1b07);
2504   AddFixed("WAI",  0x1b06);
2505   AddFixed("SPARE", 0x00ef);
2506 
2507   AddBranch("BCC", 0x0024);
2508   AddBranch("BCS", 0x0025);
2509   AddBranch("BEQ", 0x0027);
2510   AddBranch("BGE", 0x002c);
2511   AddBranch("BGT", 0x002e);
2512   AddBranch("BHI", 0x0022);
2513   AddBranch("BHS", 0x0024);
2514   AddBranch("BLE", 0x002f);
2515   AddBranch("BLO", 0x0025);
2516   AddBranch("BLS", 0x0023);
2517   AddBranch("BLT", 0x002d);
2518   AddBranch("BMI", 0x002b);
2519   AddBranch("BNE", 0x0026);
2520   AddBranch("BPL", 0x002a);
2521   AddBranch("BRA", 0x0020);
2522   AddBranch("BSR", 0x0021);
2523   AddBranch("BVC", 0x0028);
2524   AddBranch("BVS", 0x0029);
2525 
2526   AddReg("ABS", 0x1b40);
2527   AddReg("SAT", 0x1ba0);
2528 
2529   AddRegMemImm("ADC",  0x1b50);
2530   AddRegMemImm("ADD",  0x0050);
2531   AddRegMemImm("AND",  0x0058);
2532   AddRegMemImm("BIT",  0x1b58);
2533   AddRegMemImm("EOR",  0x1b78);
2534   AddRegMemImm("OR",   0x0078);
2535   AddRegMemImm("SBC",  0x1b70);
2536 
2537   AddInstTable(InstTable, "SUB", 0x0070, DecodeSUB);
2538   AddInstTable(InstTable, "CMP", 0x00e0, DecodeCMP);
2539 
2540   AddInstTable(InstTable, "ANDCC", 0x00ce, DecodeImm8);
2541   AddInstTable(InstTable, "ORCC" , 0x00de, DecodeImm8);
2542   AddInstTable(InstTable, "TRAP" , 0, DecodeTRAP);
2543 
2544   AddInstTable(InstTable, "ASL", 0xc0, DecodeShift);
2545   AddInstTable(InstTable, "ASR", 0x80, DecodeShift);
2546   AddInstTable(InstTable, "LSL", 0x40, DecodeShift);
2547   AddInstTable(InstTable, "LSR", 0x00, DecodeShift);
2548 
2549   AddInstTable(InstTable, "BCLR", 0xec, DecodeBit);
2550   AddInstTable(InstTable, "BSET", 0xed, DecodeBit);
2551   AddInstTable(InstTable, "BTGL", 0xee, DecodeBit);
2552 
2553   AddInstTable(InstTable, "BFEXT", 0x00, DecodeBitField);
2554   AddInstTable(InstTable, "BFINS", 0x80, DecodeBitField);
2555 
2556   AddInstTable(InstTable, "BRCLR", 0x02, DecodeBitRel);
2557   AddInstTable(InstTable, "BRSET", 0x03, DecodeBitRel);
2558 
2559   AddInstTable(InstTable, "CLB", 0x1b91, DecodeTwoReg);
2560 
2561   AddInstTable(InstTable, "CLR", 0x0000, DecodeCLR);
2562   AddInstTable(InstTable, "COM", 0x00cc, DecodeCOM_NEG);
2563   AddInstTable(InstTable, "NEG", 0x00dc, DecodeCOM_NEG);
2564   AddCondition("DB%s", 0x0d80, DecodeDBcc);
2565   AddInstTable(InstTable, "DEC", 0x0040, DecodeINC_DEC);
2566   AddInstTable(InstTable, "INC", 0x0030, DecodeINC_DEC);
2567 
2568   AddInstTable(InstTable, "DIVS", 0x3081, DecodeDIV_MOD);
2569   AddInstTable(InstTable, "DIVU", 0x3001, DecodeDIV_MOD);
2570   AddInstTable(InstTable, "MODS", 0x3881, DecodeDIV_MOD);
2571   AddInstTable(InstTable, "MODU", 0x3801, DecodeDIV_MOD);
2572   AddInstTable(InstTable, "MACS", 0x4881, DecodeDIV_MOD);
2573   AddInstTable(InstTable, "MACU", 0x4801, DecodeDIV_MOD);
2574   AddInstTable(InstTable, "MULS", 0x4880, DecodeDIV_MOD);
2575   AddInstTable(InstTable, "MULU", 0x4800, DecodeDIV_MOD);
2576   AddInstTable(InstTable,"QMULS", 0xb081, DecodeDIV_MOD);
2577   AddInstTable(InstTable,"QMULU", 0xb001, DecodeDIV_MOD);
2578 
2579   AddInstTable(InstTable, "EXG", 0x00ae, DecodeEXG_TFR);
2580   AddInstTable(InstTable, "TFR", 0x009e, DecodeEXG_TFR);
2581   AddInstTable(InstTable, "SEX", 0x01ae, DecodeEXG_TFR);
2582   AddInstTable(InstTable, "ZEX", 0x019e, DecodeEXG_TFR);
2583 
2584   AddInstTable(InstTable, "JMP", 0x00aa, DecodeJMP_JSR);
2585   AddInstTable(InstTable, "JSR", 0x00ab, DecodeJMP_JSR);
2586 
2587   AddInstTable(InstTable, "LD" , 0x0000, DecodeLD_ST);
2588   AddInstTable(InstTable, "ST" , 0x0020, DecodeLD_ST);
2589   AddInstTable(InstTable, "MOV" , 0x0000, DecodeMOV);
2590   AddInstTable(InstTable, "LEA" , 0x0000, DecodeLEA);
2591 
2592   AddInstTable(InstTable, "MAXS", 0x1b28, DecodeMIN_MAX);
2593   AddInstTable(InstTable, "MAXU", 0x1b18, DecodeMIN_MAX);
2594   AddInstTable(InstTable, "MINS", 0x1b20, DecodeMIN_MAX);
2595   AddInstTable(InstTable, "MINU", 0x1b10, DecodeMIN_MAX);
2596 
2597   AddInstTable(InstTable, "PSH", 0x0400, DecodePSH_PUL);
2598   AddInstTable(InstTable, "PUL", 0x0480, DecodePSH_PUL);
2599 
2600   AddInstTable(InstTable, "ROL", 0x1064, DecodeROL_ROR);
2601   AddInstTable(InstTable, "ROR", 0x1024, DecodeROL_ROR);
2602 
2603   AddCondition("TB%s", 0x0b00, DecodeTBcc);
2604 
2605   AddInstTable(InstTable, "DEFBIT", 0, DecodeDEFBIT);
2606   AddInstTable(InstTable, "DEFBITFIELD", 0, DecodeDEFBITFIELD);
2607 
2608   AddInstTable(InstTable, "DB", 0, DecodeMotoBYT);
2609   AddInstTable(InstTable, "DW", 0, DecodeMotoADR);
2610 }
2611 
DeinitFields(void)2612 static void DeinitFields(void)
2613 {
2614   DestroyInstTable(InstTable);
2615 }
2616 
2617 /*--------------------------------------------------------------------------*/
2618 /* Semiglobal Functions */
2619 
DecodeAttrPart_S12Z(void)2620 static Boolean DecodeAttrPart_S12Z(void)
2621 {
2622   int z;
2623 
2624   OpSize2 = eSymbolSizeUnknown;
2625   for (z = 0; z < 2; z++)
2626   {
2627     if (AttrPart.Str[z] == '\0')
2628       break;
2629     if (!DecodeMoto16AttrSize(AttrPart.Str[z], z ? &OpSize2 : &AttrPartOpSize, True))
2630       return False;
2631   }
2632   return True;
2633 }
2634 
MakeCode_S12Z(void)2635 static void MakeCode_S12Z(void)
2636 {
2637   CodeLen = 0;
2638   DontPrint = False;
2639 
2640   /* OpSize2 has been set in DecodeAttrPart() */
2641 
2642   OpSize = (AttrPartOpSize != eSymbolSizeUnknown) ? AttrPartOpSize : eSymbolSizeUnknown;
2643 
2644   /* zu ignorierendes */
2645 
2646   if (Memo(""))
2647     return;
2648 
2649   /* Pseudoanweisungen */
2650 
2651   /* TODO: handle eSymbolSize24Bit in DC/DS */
2652 
2653   if (DecodeMotoPseudo(True)) return;
2654   if (DecodeMoto16Pseudo(OpSize, True)) return;
2655 
2656   if (!LookupInstTable(InstTable, OpPart.Str))
2657     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2658 }
2659 
IsDef_S12Z(void)2660 static Boolean IsDef_S12Z(void)
2661 {
2662   return Memo("DEFBIT") || Memo("DEFBITFIELD");
2663 }
2664 
SwitchFrom_S12Z(void)2665 static void SwitchFrom_S12Z(void)
2666 {
2667   DeinitFields();
2668   ClearONOFF();
2669 }
2670 
SwitchTo_S12Z(void)2671 static void SwitchTo_S12Z(void)
2672 {
2673   const PFamilyDescr pDescr = FindFamilyByName("S12Z");
2674   TurnWords = False;
2675   ConstMode = ConstModeMoto;
2676 
2677   PCSymbol = "*";
2678   HeaderID = pDescr->Id;
2679   NOPCode = 0x01;
2680   DivideChars = ",";
2681   HasAttrs = True;
2682   AttrChars = ".";
2683 
2684   ValidSegs = (1 << SegCode);
2685   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
2686   SegLimits[SegCode] = 0xffffff;
2687   DecodeAttrPart = DecodeAttrPart_S12Z;
2688   MakeCode = MakeCode_S12Z;
2689   IsDef = IsDef_S12Z;
2690   SwitchFrom = SwitchFrom_S12Z;
2691   DissectBit = DissectBit_S12Z;
2692   InitFields();
2693   AddMoto16PseudoONOFF();
2694 }
2695 
codes12z_init(void)2696 void codes12z_init(void)
2697 {
2698   (void)AddCPU("S912ZVC19F0MKH" , SwitchTo_S12Z);
2699   (void)AddCPU("S912ZVC19F0MLF" , SwitchTo_S12Z);
2700   (void)AddCPU("S912ZVCA19F0MKH", SwitchTo_S12Z);
2701   (void)AddCPU("S912ZVCA19F0MLF", SwitchTo_S12Z);
2702   (void)AddCPU("S912ZVCA19F0WKH", SwitchTo_S12Z);
2703   (void)AddCPU("S912ZVH128F2CLQ", SwitchTo_S12Z);
2704   (void)AddCPU("S912ZVH128F2CLL", SwitchTo_S12Z);
2705   (void)AddCPU("S912ZVH64F2CLQ" , SwitchTo_S12Z);
2706   (void)AddCPU("S912ZVHY64F1CLQ", SwitchTo_S12Z);
2707   (void)AddCPU("S912ZVHY32F1CLQ", SwitchTo_S12Z);
2708   (void)AddCPU("S912ZVHY64F1CLL", SwitchTo_S12Z);
2709   (void)AddCPU("S912ZVHY32F1CLL", SwitchTo_S12Z);
2710   (void)AddCPU("S912ZVHL64F1CLQ", SwitchTo_S12Z);
2711   (void)AddCPU("S912ZVHL32F1CLQ", SwitchTo_S12Z);
2712   (void)AddCPU("S912ZVHL64F1CLL", SwitchTo_S12Z);
2713   (void)AddCPU("S912ZVHL32F1CLL", SwitchTo_S12Z);
2714   (void)AddCPU("S912ZVFP64F1CLQ", SwitchTo_S12Z);
2715   (void)AddCPU("S912ZVFP64F1CLL", SwitchTo_S12Z);
2716   (void)AddCPU("S912ZVH128F2VLQ", SwitchTo_S12Z);
2717   (void)AddCPU("S912ZVH128F2VLL", SwitchTo_S12Z);
2718   (void)AddCPU("S912ZVH64F2VLQ" , SwitchTo_S12Z);
2719   (void)AddCPU("S912ZVHY64F1VLQ", SwitchTo_S12Z);
2720   (void)AddCPU("S912ZVHY32F1VLQ", SwitchTo_S12Z);
2721   (void)AddCPU("S912ZVHY64F1VL" , SwitchTo_S12Z);
2722   (void)AddCPU("S912ZVHY32F1VLL", SwitchTo_S12Z);
2723   (void)AddCPU("S912ZVHL64F1VLQ", SwitchTo_S12Z);
2724 }
2725