1 /* codeavr.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Codegenerator Atmel AVR                                                   */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 
13 #include <ctype.h>
14 #include <string.h>
15 
16 #include "bpemu.h"
17 #include "nls.h"
18 #include "strutil.h"
19 #include "asmdef.h"
20 #include "asmsub.h"
21 #include "asmpars.h"
22 #include "asmallg.h"
23 #include "asmitree.h"
24 #include "asmcode.h"
25 #include "codepseudo.h"
26 #include "intpseudo.h"
27 #include "codevars.h"
28 #include "errmsg.h"
29 
30 #include "codeavr.h"
31 
32 #define FixedOrderCnt 27
33 #define Reg1OrderCnt 10
34 #define Reg2OrderCnt 12
35 
36 #define RegBankSize 32
37 #define IOAreaStdSize 64
38 #define IOAreaExtSize (IOAreaStdSize + 160)
39 #define IOAreaExt2Size (IOAreaExtSize + 256)
40 
41 #define BitFlag_Data 0x800000ul
42 #define BitFlag_IO 0x400000ul
43 
44 typedef enum
45 {
46   eCoreNone,
47   eCoreMinTiny,
48   eCore90S1200,
49   eCoreClassic, /* AT90Sxxxx */
50   eCoreTiny, /* ATtiny up to 8KB flash */
51   eCoreTiny16K,
52   eCoreMega
53 } tCPUCore;
54 
55 #define MinCoreMask(c) ((Word)(0xffffu << (c)))
56 
57 typedef struct
58 {
59   Word Code;
60   Word CoreMask;
61 } FixedOrder;
62 
63 /* Data types are a bit squeezed to make struct fit into fewer bytes:
64    lower four bits of FlashEnd are always 0xf and are not stored: */
65 
66 typedef struct
67 {
68   const char *pName;
69   Word FlashEndD16, RAMSize, EESize, IOAreaSize;
70   Boolean RegistersMapped;
71   Byte Core;
72 } tCPUProps;
73 
74 static FixedOrder *FixedOrders, *Reg1Orders, *Reg2Orders;
75 
76 static Boolean WrapFlag;
77 static LongInt ORMask, SignMask, CodeSegSize;
78 static const tCPUProps *pCurrCPUProps;
79 
80 static IntType CodeAdrIntType,
81                DataAdrIntType;
82 
83 static const char WrapFlagName[] = "WRAPMODE";
84 
85 /*---------------------------------------------------------------------------*/
86 
CutAdr(LongInt Adr)87 static LongInt CutAdr(LongInt Adr)
88 {
89   if ((Adr & SignMask) != 0)
90     return (Adr | ORMask);
91   else
92     return (Adr & SegLimits[SegCode]);
93 }
94 
ChkMinCore(tCPUCore MinCore)95 static Boolean ChkMinCore(tCPUCore MinCore)
96 {
97   if (pCurrCPUProps->Core < MinCore)
98   {
99     WrError(ErrNum_InstructionNotSupported);
100     return False;
101   }
102   return True;
103 }
104 
ChkCoreMask(Word CoreMask)105 static Boolean ChkCoreMask(Word CoreMask)
106 {
107   if ((1 << pCurrCPUProps->Core) & CoreMask)
108     return True;
109   WrError(ErrNum_InstructionNotSupported);
110   return False;
111 }
112 
DissectBit_AVR(char * pDest,size_t DestSize,LargeWord Inp)113 static void DissectBit_AVR(char *pDest, size_t DestSize, LargeWord Inp)
114 {
115   LongWord BitSpec = Inp;
116 
117   as_snprintf(pDest, DestSize, "0x%0*x(%c).%d",
118               (BitSpec & BitFlag_IO) ? 2 : 3,
119               (unsigned)((BitSpec >> 3) & 0xffff),
120               (BitSpec & BitFlag_Data) ? SegShorts[SegData]
121                                    : ((BitSpec & BitFlag_IO) ? SegShorts[SegIO] : SegShorts[SegNone]),
122               (int)(BitSpec & 7));
123 }
124 
125 /*---------------------------------------------------------------------------*/
126 /* Argument Decoders                                                         */
127 
128 /*!------------------------------------------------------------------------
129  * \fn     DecodeRegCore(const char *pArg, Word *pResult)
130  * \brief  check wether argument is CPU register
131  * \param  pArg source code argument
132  * \param  pResult register # if it's a register
133  * \return True if it's a register
134  * ------------------------------------------------------------------------ */
135 
DecodeRegCore(const char * pArg,Word * pResult)136 static Boolean DecodeRegCore(const char *pArg, Word *pResult)
137 {
138   Boolean OK;
139   int l = strlen(pArg);
140 
141   if ((l < 2) || (l > 3) || (as_toupper(*pArg) != 'R'))
142     return False;
143 
144   *pResult = ConstLongInt(pArg + 1, &OK, 10);
145   return (OK
146        && ((*pResult >= 16) || (pCurrCPUProps->Core != eCoreMinTiny))
147        && (*pResult < 32));
148 }
149 
150 /*!------------------------------------------------------------------------
151  * \fn     DissectReg_AVR(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
152  * \brief  dissect register symbols - AVR variant
153  * \param  pDest destination buffer
154  * \param  DestSize destination buffer size
155  * \param  Value numeric register value
156  * \param  InpSize register size
157  * ------------------------------------------------------------------------ */
158 
DissectReg_AVR(char * pDest,size_t DestSize,tRegInt Value,tSymbolSize InpSize)159 static void DissectReg_AVR(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
160 {
161   switch (InpSize)
162   {
163     case eSymbolSize8Bit:
164       as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
165       break;
166     default:
167       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
168   }
169 }
170 
171 /*!------------------------------------------------------------------------
172  * \fn     DecodeReg(const tStrComp *pArg, Word *pResult)
173  * \brief  check wether argument is CPU register, including register aliases
174  * \param  pArg source code argument
175  * \param  pResult register # if it's a register
176  * \return True if it's a register
177  * ------------------------------------------------------------------------ */
178 
DecodeReg(const tStrComp * pArg,Word * pResult)179 static Boolean DecodeReg(const tStrComp *pArg, Word *pResult)
180 {
181   tRegDescr RegDescr;
182   tEvalResult EvalResult;
183   tRegEvalResult RegEvalResult;
184 
185   if (DecodeRegCore(pArg->Str, pResult))
186     return True;
187 
188   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize8Bit, True);
189   *pResult = RegDescr.Reg;
190   return (RegEvalResult == eIsReg);
191 }
192 
DecodeMem(char * Asc,Word * Erg)193 static Boolean DecodeMem(char * Asc, Word *Erg)
194 {
195   if (as_strcasecmp(Asc, "X") == 0) *Erg = 0x1c;
196   else if (as_strcasecmp(Asc, "X+") == 0) *Erg = 0x1d;
197   else if (as_strcasecmp(Asc, "-X") == 0) *Erg = 0x1e;
198   else if (as_strcasecmp(Asc, "Y" ) == 0) *Erg = 0x08;
199   else if (as_strcasecmp(Asc, "Y+") == 0) *Erg = 0x19;
200   else if (as_strcasecmp(Asc, "-Y") == 0) *Erg = 0x1a;
201   else if (as_strcasecmp(Asc, "Z" ) == 0) *Erg = 0x00;
202   else if (as_strcasecmp(Asc, "Z+") == 0) *Erg = 0x11;
203   else if (as_strcasecmp(Asc, "-Z") == 0) *Erg = 0x12;
204   else return False;
205   return True;
206 }
207 
DecodeBitArg2(const tStrComp * pRegArg,const tStrComp * pBitArg,LongWord * pResult)208 static Boolean DecodeBitArg2(const tStrComp *pRegArg, const tStrComp *pBitArg, LongWord *pResult)
209 {
210   tEvalResult EvalResult;
211   LongWord Addr;
212 
213   *pResult = EvalStrIntExpressionWithResult(pBitArg, UInt3, &EvalResult);
214   if (!EvalResult.OK)
215     return False;
216 
217   Addr = EvalStrIntExpressionWithResult(pRegArg, DataAdrIntType, &EvalResult);
218   if (!EvalResult.OK)
219     return False;
220 
221   if (EvalResult.AddrSpaceMask & (1 << SegIO))
222   {
223     if (!mFirstPassUnknown(EvalResult.Flags) && !ChkRange(Addr, 0, IOAreaStdSize - 1))
224       return False;
225     *pResult |= BitFlag_IO | (Addr & 0x3f) << 3;
226     return True;
227   }
228   else
229   {
230     ChkSpace(SegData, EvalResult.AddrSpaceMask);
231 
232     if (!mFirstPassUnknown(EvalResult.Flags) && !ChkRange(Addr, 0, SegLimits[SegData]))
233       return False;
234     *pResult |= ((EvalResult.AddrSpaceMask & (1 << SegData)) ? BitFlag_Data : 0) | (Addr & 0x1ff) << 3;
235     return True;
236   }
237 }
238 
DecodeBitArg(int Start,int Stop,LongWord * pResult)239 static Boolean DecodeBitArg(int Start, int Stop, LongWord *pResult)
240 {
241   if (Start == Stop)
242   {
243     char *pPos = QuotPos(ArgStr[Start].Str, '.');
244     tEvalResult EvalResult;
245 
246     if (pPos)
247     {
248       tStrComp RegArg, BitArg;
249 
250       StrCompSplitRef(&RegArg, &BitArg, &ArgStr[Start], pPos);
251       return DecodeBitArg2(&RegArg, &BitArg, pResult);
252     }
253     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt16, &EvalResult);
254     if (EvalResult.OK)
255       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
256     return EvalResult.OK;
257   }
258   else if (Stop == Start + 1)
259     return DecodeBitArg2(&ArgStr[Start], &ArgStr[Stop], pResult);
260   else
261   {
262     WrError(ErrNum_WrongArgCnt);
263     return False;
264   }
265 }
266 
267 static const LongWord
268        AllRegMask = 0xfffffffful,
269        UpperHalfRegMask = 0xffff0000ul,
270        Reg16_23Mask = 0x00ff0000ul,
271        EvenRegMask = 0x55555555ul,
272        UpperEightEvenRegMask = 0x55000000ul;
273 
DecodeArgReg(unsigned ArgIndex,Word * pReg,LongWord RegMask)274 static Boolean DecodeArgReg(unsigned ArgIndex, Word *pReg, LongWord RegMask)
275 {
276   Boolean Result;
277 
278   Result = DecodeReg(&ArgStr[ArgIndex], pReg);
279   if (Result && !((RegMask >> *pReg) & 1))
280   {
281     WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgIndex]);
282     return False;
283   }
284   return Result;
285 }
286 
287 /*!------------------------------------------------------------------------
288  * \fn     GetWordCodeAddress(tStrComp *pArg, tEvalResult *EvalResult)
289  * \brief  decode argument as code address and divide by two if in byte mode
290  * \param  pArg address argument
291  * \param  pEvalResult returns OK/failure
292  * \return (word) address
293  * ------------------------------------------------------------------------ */
294 
GetWordCodeAddress(tStrComp * pArg,tEvalResult * pEvalResult)295 static LongInt GetWordCodeAddress(tStrComp *pArg, tEvalResult *pEvalResult)
296 {
297   LongInt Result;
298 
299   Result = EvalStrIntExpressionWithResult(pArg, CodeAdrIntType, pEvalResult);
300   if (pEvalResult->OK)
301   {
302     ChkSpace(SegCode, pEvalResult->AddrSpaceMask);
303     if (!CodeSegSize)
304     {
305       if (mFirstPassUnknown(pEvalResult->Flags))
306         Result &= ~1ul;
307       if (Result & 1)
308       {
309         WrStrErrorPos(ErrNum_NotAligned, pArg);
310         pEvalResult->OK = False;
311       }
312       else
313         Result >>= 1;
314     }
315   }
316   return Result;
317 }
318 
319 /*!------------------------------------------------------------------------
320  * \fn     GetNextCodeAddress(void)
321  * \brief  retrieve (word) address of next instruction
322  * \return (word) address
323  * ------------------------------------------------------------------------ */
324 
GetNextCodeAddress(void)325 static LongInt GetNextCodeAddress(void)
326 {
327   LongInt Result = EProgCounter();
328 
329   if (!CodeSegSize)
330     Result >>= 1;
331   return Result + 1;
332 }
333 
334 /*---------------------------------------------------------------------------*/
335 /* Individual Decoders                                                       */
336 
337 /* Pseudo Instructions */
338 
DecodePORT(Word Index)339 static void DecodePORT(Word Index)
340 {
341   UNUSED(Index);
342 
343   CodeEquate(SegIO, 0, 0x3f);
344 }
345 
DecodeSFR(Word Index)346 static void DecodeSFR(Word Index)
347 {
348   LargeWord Start = (pCurrCPUProps->RegistersMapped ? RegBankSize : 0);
349   UNUSED(Index);
350 
351   CodeEquate(SegData, Start, Start + pCurrCPUProps->IOAreaSize);
352 }
353 
AppendCode(Word Code)354 static void AppendCode(Word Code)
355 {
356   if (CodeSegSize)
357     WAsmCode[CodeLen++] = Code;
358   else
359   {
360     BAsmCode[CodeLen++] = Lo(Code);
361     BAsmCode[CodeLen++] = Hi(Code);
362   }
363 }
364 
365 /* No Argument */
366 
DecodeFixed(Word Index)367 static void DecodeFixed(Word Index)
368 {
369   const FixedOrder *pOrder = FixedOrders + Index;
370 
371   if (ChkArgCnt(0, 0) && ChkCoreMask(pOrder->CoreMask))
372     AppendCode(pOrder->Code);
373 }
374 
DecodeRES(Word Index)375 static void DecodeRES(Word Index)
376 {
377   Boolean OK;
378   Integer Size;
379   tSymbolFlags Flags;
380 
381   UNUSED(Index);
382 
383   Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
384   if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
385   if (OK && !mFirstPassUnknown(Flags))
386   {
387     DontPrint = True;
388     if (!Size) WrError(ErrNum_NullResMem);
389     CodeLen = Size;
390     BookKeeping();
391   }
392 }
393 
394 static Word WordAcc;
395 static Boolean WordAccFull;
396 
PlaceValue(Word Value,Boolean IsByte)397 static void PlaceValue(Word Value, Boolean IsByte)
398 {
399   if (ActPC != SegCode)
400   {
401     BAsmCode[CodeLen++] = Value;
402     WordAccFull = False;
403   }
404   else if (IsByte)
405   {
406     if (CodeSegSize)
407     {
408       Value &= 0xff;
409       if (WordAccFull)
410         AppendCode(WordAcc |= (Value << 8));
411       else
412         WordAcc = Value;
413       WordAccFull = !WordAccFull;
414     }
415     else
416     {
417       BAsmCode[CodeLen++] = Value;
418       WordAccFull = False;
419     }
420   }
421   else
422   {
423     if (CodeSegSize)
424       AppendCode(Value);
425     else
426     {
427       BAsmCode[CodeLen++] = Lo(Value);
428       BAsmCode[CodeLen++] = Hi(Value);
429     }
430     WordAccFull = False;
431   }
432 }
433 
DecodeDATA_AVR(Word Index)434 static void DecodeDATA_AVR(Word Index)
435 {
436   Integer Trans;
437   int z;
438   Boolean OK;
439   TempResult t;
440   LongInt MinV, MaxV;
441 
442   UNUSED(Index);
443 
444   MaxV = ((ActPC == SegCode) && (!Packing)) ? 65535 : 255;
445   MinV = (-((MaxV + 1) >> 1));
446   WordAccFull = FALSE;
447   if (ChkArgCnt(1, ArgCntMax))
448   {
449     OK = True;
450     for (z = 1; z <= ArgCnt; z++)
451      if (OK)
452      {
453        EvalStrExpression(&ArgStr[z], &t);
454        if (mFirstPassUnknown(t.Flags) && (t.Typ == TempInt)) t.Contents.Int &= MaxV;
455        switch (t.Typ)
456        {
457          case TempString:
458          {
459            int z2;
460 
461            if (MultiCharToInt(&t, 2))
462              goto ToInt;
463 
464            for (z2 = 0; z2 < (int)t.Contents.Ascii.Length; z2++)
465            {
466              Trans = CharTransTable[((usint) t.Contents.Ascii.Contents[z2]) & 0xff];
467              PlaceValue(Trans, True);
468            }
469            break;
470          }
471          ToInt:
472          case TempInt:
473            if (ChkRange(t.Contents.Int, MinV, MaxV))
474              PlaceValue(t.Contents.Int, Packing);
475            break;
476          case TempFloat:
477            WrStrErrorPos(ErrNum_StringOrIntButFloat, &ArgStr[z]);
478            /* fall-through */
479          default:
480            OK = False;
481        }
482      }
483     if (!OK)
484       CodeLen = 0;
485     else if (WordAccFull)
486     {
487       WrError(ErrNum_PaddingAdded);
488       AppendCode(WordAcc);
489     }
490   }
491 }
492 
493 /* one register 0..31 */
494 
DecodeReg1(Word Index)495 static void DecodeReg1(Word Index)
496 {
497   const FixedOrder *pOrder = Reg1Orders + Index;
498   Word Reg;
499 
500   if (ChkArgCnt(1, 1)
501    && ChkCoreMask(pOrder->CoreMask)
502    && DecodeArgReg(1, &Reg, AllRegMask))
503     AppendCode(pOrder->Code | (Reg << 4));
504 }
505 
506 /* two registers 0..31 */
507 
DecodeReg2(Word Index)508 static void DecodeReg2(Word Index)
509 {
510   const FixedOrder *pOrder = Reg2Orders + Index;
511   Word Reg1, Reg2;
512 
513   if (ChkArgCnt(2, 2)
514    && ChkCoreMask(pOrder->CoreMask)
515    && DecodeArgReg(1, &Reg1, AllRegMask)
516    && DecodeArgReg(2, &Reg2, AllRegMask))
517     AppendCode(pOrder->Code | (Reg2 & 15) | (Reg1 << 4) | ((Reg2 & 16) << 5));
518 }
519 
520 /* one register 0..31 with itself */
521 
DecodeReg3(Word Code)522 static void DecodeReg3(Word Code)
523 {
524   Word Reg;
525 
526   if (ChkArgCnt(1, 1) && DecodeArgReg(1, &Reg, AllRegMask))
527     AppendCode(Code | (Reg & 15) | (Reg << 4) | ((Reg & 16) << 5));
528 }
529 
530 /* immediate with register */
531 
DecodeImm(Word Code)532 static void DecodeImm(Word Code)
533 {
534   Word Reg, Const;
535   Boolean OK;
536 
537   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Reg, UpperHalfRegMask))
538   {
539     Const = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
540     if (OK)
541       AppendCode(Code | ((Const & 0xf0) << 4) | (Const & 0x0f) | ((Reg & 0x0f) << 4));
542   }
543 }
544 
DecodeADIW(Word Index)545 static void DecodeADIW(Word Index)
546 {
547   Word Reg, Const;
548   Boolean OK;
549 
550   if (ChkArgCnt(2, 2)
551    && ChkMinCore(eCoreClassic)
552    && DecodeArgReg(1, &Reg, UpperEightEvenRegMask))
553   {
554     Const = EvalStrIntExpression(&ArgStr[2], UInt6, &OK);
555     if (OK)
556       AppendCode(0x9600 | Index | ((Reg & 6) << 3) | (Const & 15) | ((Const & 0x30) << 2));
557   }
558 }
559 
560 /* transfer operations */
561 
DecodeLDST(Word Index)562 static void DecodeLDST(Word Index)
563 {
564   int RegI, MemI;
565   Word Reg, Mem;
566 
567   if (ChkArgCnt(2, 2))
568   {
569     RegI = Index ? 2 : 1; /* ST */
570     MemI = 3 - RegI;
571     if (!DecodeArgReg(RegI, &Reg, AllRegMask));
572     else if (!DecodeMem(ArgStr[MemI].Str, &Mem)) WrError(ErrNum_InvAddrMode);
573     else if ((pCurrCPUProps->Core == eCore90S1200) && (Mem != 0)) WrError(ErrNum_AddrMustBeAligned);
574     else
575     {
576       AppendCode(0x8000 | Index | (Reg << 4) | (Mem & 0x0f) | ((Mem & 0x10) << 8));
577       if (((Mem >= 0x1d) && (Mem <= 0x1e) && (Reg >= 26) && (Reg <= 27))  /* X+/-X with X */
578        || ((Mem >= 0x19) && (Mem <= 0x1a) && (Reg >= 28) && (Reg <= 29))  /* Y+/-Y with Y */
579        || ((Mem >= 0x11) && (Mem <= 0x12) && (Reg >= 30) && (Reg <= 31))) /* Z+/-Z with Z */
580         WrError(ErrNum_Unpredictable);
581     }
582   }
583 }
584 
DecodeLDDSTD(Word Index)585 static void DecodeLDDSTD(Word Index)
586 {
587   int RegI, MemI;
588   Word Reg, Disp;
589   Boolean OK;
590 
591   if (ChkArgCnt(2, 2)
592    && ChkMinCore(eCoreClassic))
593   {
594     char RegChar;
595 
596     RegI = Index ? 2 : 1; /* STD */
597     MemI = 3 - RegI;
598     RegChar = *ArgStr[MemI].Str;
599     OK = True;
600     if (as_toupper(RegChar) == 'Y') Index += 8;
601     else if (as_toupper(RegChar) == 'Z');
602     else OK = False;
603     if (!OK) WrError(ErrNum_InvAddrMode);
604     else if (DecodeArgReg(RegI, &Reg, AllRegMask))
605     {
606       *ArgStr[MemI].Str = '0';
607       Disp = EvalStrIntExpression(&ArgStr[MemI], UInt6, &OK);
608       *ArgStr[MemI].Str = RegChar;
609       if (OK)
610         AppendCode(0x8000 | Index | (Reg << 4) | (Disp & 7) | ((Disp & 0x18) << 7) | ((Disp & 0x20) << 8));
611     }
612   }
613 }
614 
DecodeINOUT(Word Index)615 static void DecodeINOUT(Word Index)
616 {
617   int RegI, MemI;
618   Word Reg, Mem;
619 
620   if (ChkArgCnt(2, 2))
621   {
622     RegI = Index ? 2 : 1; /* OUT */
623     MemI = 3 - RegI;
624     if (DecodeArgReg(RegI, &Reg, AllRegMask))
625     {
626       tEvalResult EvalResult;
627 
628       Mem = EvalStrIntExpressionWithResult(&ArgStr[MemI], UInt6, &EvalResult);
629       if (EvalResult.OK)
630       {
631         ChkSpace(SegIO, EvalResult.AddrSpaceMask);
632         AppendCode(0xb000 | Index | (Reg << 4) | (Mem & 0x0f) | ((Mem & 0xf0) << 5));
633       }
634     }
635   }
636 }
637 
DecodeLDSSTS(Word Index)638 static void DecodeLDSSTS(Word Index)
639 {
640   int RegI, MemI;
641   Word Reg;
642 
643   if (ChkArgCnt(2, 2)
644    && ChkCoreMask(MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny)))
645   {
646     RegI = Index ? 2 : 1; /* STS */
647     MemI = 3 - RegI;
648     if (DecodeArgReg(RegI, &Reg, AllRegMask))
649     {
650       tEvalResult EvalResult;
651       Word Address = EvalStrIntExpressionWithResult(&ArgStr[MemI], UInt16, &EvalResult);
652       if (EvalResult.OK)
653       {
654         ChkSpace(SegData, EvalResult.AddrSpaceMask);
655         AppendCode(0x9000 | Index | (Reg << 4));
656         AppendCode(Address);
657       }
658     }
659   }
660 }
661 
662 /* bit operations */
663 
DecodeBCLRSET(Word Index)664 static void DecodeBCLRSET(Word Index)
665 {
666   Word Bit;
667   Boolean OK;
668 
669   if (ChkArgCnt(1, 1))
670   {
671     Bit = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
672     if (OK)
673       AppendCode(0x9408 | (Bit << 4) | Index);
674   }
675 }
676 
DecodeBit(Word Code)677 static void DecodeBit(Word Code)
678 {
679   Word Reg, Bit;
680   Boolean OK;
681 
682   if (!ChkArgCnt(2, 2));
683   else if (DecodeArgReg(1, &Reg, AllRegMask))
684   {
685     Bit = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
686     if (OK)
687       AppendCode(Code | (Reg << 4) | Bit);
688   }
689 }
690 
DecodeCBR(Word Index)691 static void DecodeCBR(Word Index)
692 {
693   Word Reg, Mask;
694   Boolean OK;
695 
696   UNUSED(Index);
697 
698   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Reg, UpperHalfRegMask))
699   {
700     Mask = EvalStrIntExpression(&ArgStr[2], Int8, &OK) ^ 0xff;
701     if (OK)
702       AppendCode(0x7000 | ((Mask & 0xf0) << 4) | (Mask & 0x0f) | ((Reg & 0x0f) << 4));
703   }
704 }
705 
DecodeSER(Word Index)706 static void DecodeSER(Word Index)
707 {
708   Word Reg;
709 
710   UNUSED(Index);
711 
712   if (ChkArgCnt(1, 1) && DecodeArgReg(1, &Reg, UpperHalfRegMask))
713     AppendCode(0xef0f | ((Reg & 0x0f) << 4));
714 }
715 
DecodePBit(Word Code)716 static void DecodePBit(Word Code)
717 {
718   LongWord BitSpec;
719 
720   if (DecodeBitArg(1, ArgCnt, &BitSpec))
721   {
722     Word Bit = BitSpec & 7,
723          Adr = (BitSpec >> 3) & 0xffff;
724 
725     if (BitSpec & BitFlag_Data) WrError(ErrNum_WrongSegment);
726     if (ChkRange(Adr, 0, 31))
727       AppendCode(Code | Bit | (Adr << 3));
728   }
729 }
730 
731 /* branches */
732 
DecodeRel(Word Code)733 static void DecodeRel(Word Code)
734 {
735   LongInt AdrInt;
736   tEvalResult EvalResult;
737 
738   if (ChkArgCnt(1, 1))
739   {
740     AdrInt = GetWordCodeAddress(&ArgStr[1], &EvalResult) - GetNextCodeAddress();
741     if (EvalResult.OK)
742     {
743       if (WrapFlag) AdrInt = CutAdr(AdrInt);
744       if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -64) || (AdrInt > 63))) WrError(ErrNum_JmpDistTooBig);
745       else
746         AppendCode(Code | ((AdrInt & 0x7f) << 3));
747     }
748   }
749 }
750 
DecodeBRBSBC(Word Index)751 static void DecodeBRBSBC(Word Index)
752 {
753   Word Bit;
754   LongInt AdrInt;
755   tEvalResult EvalResult;
756 
757   if (ChkArgCnt(2, 2))
758   {
759     Bit = EvalStrIntExpressionWithResult(&ArgStr[1], UInt3, &EvalResult);
760     if (EvalResult.OK)
761     {
762       AdrInt = GetWordCodeAddress(&ArgStr[2], &EvalResult) - GetNextCodeAddress();
763       if (EvalResult.OK)
764       {
765         if (WrapFlag) AdrInt = CutAdr(AdrInt);
766         if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -64) || (AdrInt > 63))) WrError(ErrNum_JmpDistTooBig);
767         else
768           AppendCode(0xf000 | Index | ((AdrInt & 0x7f) << 3) | Bit);
769       }
770     }
771   }
772 }
773 
DecodeJMPCALL(Word Index)774 static void DecodeJMPCALL(Word Index)
775 {
776   LongInt AdrInt;
777   tEvalResult EvalResult;
778 
779   if (ChkArgCnt(1, 1)
780    && ChkMinCore(eCoreTiny16K))
781   {
782     AdrInt = GetWordCodeAddress(&ArgStr[1], &EvalResult);
783     if (EvalResult.OK)
784     {
785       AppendCode(0x940c | Index | ((AdrInt & 0x3e0000) >> 13) | ((AdrInt & 0x10000) >> 16));
786       AppendCode(AdrInt & 0xffff);
787     }
788   }
789 }
790 
DecodeRJMPCALL(Word Index)791 static void DecodeRJMPCALL(Word Index)
792 {
793   LongInt AdrInt;
794   tEvalResult EvalResult;
795 
796   if (ChkArgCnt(1, 1))
797   {
798     AdrInt = GetWordCodeAddress(&ArgStr[1], &EvalResult) - GetNextCodeAddress();
799     if (EvalResult.OK)
800     {
801       if (WrapFlag) AdrInt = CutAdr(AdrInt);
802       if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -2048) || (AdrInt > 2047))) WrError(ErrNum_JmpDistTooBig);
803       else
804         AppendCode(0xc000 | Index | (AdrInt & 0xfff));
805     }
806   }
807 }
808 
DecodeMULS(Word Index)809 static void DecodeMULS(Word Index)
810 {
811   Word Reg1, Reg2;
812 
813   UNUSED(Index);
814 
815   if (ChkArgCnt(2, 2)
816    && ChkMinCore(eCoreMega)
817    && DecodeArgReg(1, &Reg1, UpperHalfRegMask)
818    && DecodeArgReg(2, &Reg2, UpperHalfRegMask))
819     AppendCode(0x0200 | ((Reg1 & 15) << 4) | (Reg2 & 15));
820 }
821 
DecodeMegaMUL(Word Index)822 static void DecodeMegaMUL(Word Index)
823 {
824   Word Reg1, Reg2;
825 
826   if (ChkArgCnt(2, 2)
827    && ChkMinCore(eCoreMega)
828    && DecodeArgReg(1, &Reg1, Reg16_23Mask)
829    && DecodeArgReg(2, &Reg2, Reg16_23Mask))
830     AppendCode(Index | ((Reg1 & 7) << 4) | (Reg2 & 7));
831 }
832 
DecodeMOVW(Word Index)833 static void DecodeMOVW(Word Index)
834 {
835   Word Reg1, Reg2;
836 
837   UNUSED(Index);
838 
839   if (ChkArgCnt(2, 2)
840    && ChkMinCore(eCoreTiny)
841    && DecodeArgReg(1, &Reg1, EvenRegMask)
842    && DecodeArgReg(2, &Reg2, EvenRegMask))
843     AppendCode(0x0100 | ((Reg1 >> 1) << 4) | (Reg2 >> 1));
844 }
845 
DecodeLPM(Word Index)846 static void DecodeLPM(Word Index)
847 {
848   Word Reg, Adr;
849 
850   UNUSED(Index);
851 
852   if (!ArgCnt)
853   {
854     if (ChkMinCore(eCoreClassic))
855       AppendCode(0x95c8);
856   }
857   else if (ArgCnt == 2)
858   {
859     if (!ChkMinCore(eCoreTiny));
860     else if (!DecodeArgReg(1, &Reg, AllRegMask));
861     else if (!DecodeMem(ArgStr[2].Str, &Adr)) WrError(ErrNum_InvAddrMode);
862     else if ((Adr != 0x00) && (Adr != 0x11)) WrError(ErrNum_InvAddrMode);
863     else
864     {
865       if (((Reg == 30) || (Reg == 31)) && (Adr == 0x11)) WrError(ErrNum_Unpredictable);
866       AppendCode(0x9004 | (Reg << 4) | (Adr & 1));
867     }
868   }
869   else
870     (void)ChkArgCnt(2, 2);
871 }
872 
DecodeELPM(Word Index)873 static void DecodeELPM(Word Index)
874 {
875   Word Reg, Adr;
876 
877   UNUSED(Index);
878 
879   if (!ChkMinCore(eCoreMega));
880   else if (!ArgCnt)
881     AppendCode(0x95d8);
882   else if (!ChkArgCnt(2, 2));
883   else if (!DecodeArgReg(1, &Reg, AllRegMask));
884   else if (!DecodeMem(ArgStr[2].Str, &Adr)) WrError(ErrNum_InvAddrMode);
885   else if ((Adr != 0x00) && (Adr != 0x11)) WrError(ErrNum_InvAddrMode);
886   else
887   {
888     if (((Reg == 30) || (Reg == 31)) && (Adr == 0x11)) WrError(ErrNum_Unpredictable);
889     AppendCode(0x9006 | (Reg << 4) | (Adr & 1));
890   }
891 }
892 
DecodeBIT(Word Code)893 static void DecodeBIT(Word Code)
894 {
895   LongWord BitSpec;
896 
897   UNUSED(Code);
898 
899   if (DecodeBitArg(1, ArgCnt, &BitSpec))
900   {
901     *ListLine = '=';
902     DissectBit_AVR(ListLine + 1, STRINGSIZE - 3, BitSpec);
903     PushLocHandle(-1);
904     EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
905     PopLocHandle();
906     if (MakeUseList)
907     {
908       if (AddChunk(SegChunks + SegBData, BitSpec, 1, False))
909         WrError(ErrNum_Overlap);
910     }
911   }
912 }
913 
914 /*---------------------------------------------------------------------------*/
915 /* Dynamic Code Table Handling                                               */
916 
AddFixed(const char * NName,Word NMin,Word NCode)917 static void AddFixed(const char *NName, Word NMin, Word NCode)
918 {
919   if (InstrZ >= FixedOrderCnt) exit(255);
920   FixedOrders[InstrZ].Code = NCode;
921   FixedOrders[InstrZ].CoreMask = NMin;
922   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
923 }
924 
AddReg1(const char * NName,Word NMin,Word NCode)925 static void AddReg1(const char *NName, Word NMin, Word NCode)
926 {
927   if (InstrZ >= Reg1OrderCnt) exit(255);
928   Reg1Orders[InstrZ].Code = NCode;
929   Reg1Orders[InstrZ].CoreMask = NMin;
930   AddInstTable(InstTable, NName, InstrZ++, DecodeReg1);
931 }
932 
AddReg2(const char * NName,Word NMin,Word NCode)933 static void AddReg2(const char *NName, Word NMin, Word NCode)
934 {
935   if (InstrZ >= Reg2OrderCnt) exit(255);
936   Reg2Orders[InstrZ].Code = NCode;
937   Reg2Orders[InstrZ].CoreMask = NMin;
938   AddInstTable(InstTable, NName, InstrZ++, DecodeReg2);
939 }
940 
AddReg3(const char * NName,Word NCode)941 static void AddReg3(const char *NName, Word NCode)
942 {
943   AddInstTable(InstTable, NName, NCode, DecodeReg3);
944 }
945 
AddImm(const char * NName,Word NCode)946 static void AddImm(const char *NName, Word NCode)
947 {
948   AddInstTable(InstTable, NName, NCode, DecodeImm);
949 }
950 
AddRel(const char * NName,Word NCode)951 static void AddRel(const char *NName, Word NCode)
952 {
953   AddInstTable(InstTable, NName, NCode, DecodeRel);
954 }
955 
AddBit(const char * NName,Word NCode)956 static void AddBit(const char *NName, Word NCode)
957 {
958   AddInstTable(InstTable, NName, NCode, DecodeBit);
959 }
960 
AddPBit(const char * NName,Word NCode)961 static void AddPBit(const char *NName, Word NCode)
962 {
963   AddInstTable(InstTable, NName, NCode, DecodePBit);
964 }
965 
InitFields(void)966 static void InitFields(void)
967 {
968   InstTable = CreateInstTable(203);
969 
970   FixedOrders = (FixedOrder*)malloc(sizeof(*FixedOrders) * FixedOrderCnt); InstrZ = 0;
971   AddFixed("IJMP" , MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x9409);
972   AddFixed("ICALL", MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x9509);
973   AddFixed("RET"  , MinCoreMask(eCoreMinTiny), 0x9508); AddFixed("RETI"  , MinCoreMask(eCoreMinTiny), 0x9518);
974   AddFixed("SEC"  , MinCoreMask(eCoreMinTiny), 0x9408);
975   AddFixed("CLC"  , MinCoreMask(eCoreMinTiny), 0x9488); AddFixed("SEN"   , MinCoreMask(eCoreMinTiny), 0x9428);
976   AddFixed("CLN"  , MinCoreMask(eCoreMinTiny), 0x94a8); AddFixed("SEZ"   , MinCoreMask(eCoreMinTiny), 0x9418);
977   AddFixed("CLZ"  , MinCoreMask(eCoreMinTiny), 0x9498); AddFixed("SEI"   , MinCoreMask(eCoreMinTiny), 0x9478);
978   AddFixed("CLI"  , MinCoreMask(eCoreMinTiny), 0x94f8); AddFixed("SES"   , MinCoreMask(eCoreMinTiny), 0x9448);
979   AddFixed("CLS"  , MinCoreMask(eCoreMinTiny), 0x94c8); AddFixed("SEV"   , MinCoreMask(eCoreMinTiny), 0x9438);
980   AddFixed("CLV"  , MinCoreMask(eCoreMinTiny), 0x94b8); AddFixed("SET"   , MinCoreMask(eCoreMinTiny), 0x9468);
981   AddFixed("CLT"  , MinCoreMask(eCoreMinTiny), 0x94e8); AddFixed("SEH"   , MinCoreMask(eCoreMinTiny), 0x9458);
982   AddFixed("CLH"  , MinCoreMask(eCoreMinTiny), 0x94d8); AddFixed("NOP"   , MinCoreMask(eCoreMinTiny), 0x0000);
983   AddFixed("SLEEP", MinCoreMask(eCoreMinTiny), 0x9588); AddFixed("WDR"   , MinCoreMask(eCoreMinTiny), 0x95a8);
984   AddFixed("EIJMP", MinCoreMask(eCoreMega   ), 0x9419); AddFixed("EICALL", MinCoreMask(eCoreMega   ), 0x9519);
985   AddFixed("SPM"  , MinCoreMask(eCoreTiny   ), 0x95e8);
986   AddFixed("BREAK" , MinCoreMask(eCoreTiny   ) | (1 << eCoreMinTiny), 0x9598);
987 
988   Reg1Orders = (FixedOrder*)malloc(sizeof(*Reg1Orders) * Reg1OrderCnt); InstrZ = 0;
989   AddReg1("COM"  , MinCoreMask(eCoreMinTiny), 0x9400); AddReg1("NEG"  , MinCoreMask(eCoreMinTiny), 0x9401);
990   AddReg1("INC"  , MinCoreMask(eCoreMinTiny), 0x9403); AddReg1("DEC"  , MinCoreMask(eCoreMinTiny), 0x940a);
991   AddReg1("PUSH" , MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x920f);
992   AddReg1("POP"  , MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x900f);
993   AddReg1("LSR"  , MinCoreMask(eCoreMinTiny), 0x9406); AddReg1("ROR"  , MinCoreMask(eCoreMinTiny), 0x9407);
994   AddReg1("ASR"  , MinCoreMask(eCoreMinTiny), 0x9405); AddReg1("SWAP" , MinCoreMask(eCoreMinTiny), 0x9402);
995 
996   Reg2Orders = (FixedOrder*)malloc(sizeof(*Reg2Orders) * Reg2OrderCnt); InstrZ = 0;
997   AddReg2("ADD"  , MinCoreMask(eCoreMinTiny), 0x0c00); AddReg2("ADC"  , MinCoreMask(eCoreMinTiny), 0x1c00);
998   AddReg2("SUB"  , MinCoreMask(eCoreMinTiny), 0x1800); AddReg2("SBC"  , MinCoreMask(eCoreMinTiny), 0x0800);
999   AddReg2("AND"  , MinCoreMask(eCoreMinTiny), 0x2000); AddReg2("OR"   , MinCoreMask(eCoreMinTiny), 0x2800);
1000   AddReg2("EOR"  , MinCoreMask(eCoreMinTiny), 0x2400); AddReg2("CPSE" , MinCoreMask(eCoreMinTiny), 0x1000);
1001   AddReg2("CP"   , MinCoreMask(eCoreMinTiny), 0x1400); AddReg2("CPC"  , MinCoreMask(eCoreMinTiny), 0x0400);
1002   AddReg2("MOV"  , MinCoreMask(eCoreMinTiny), 0x2c00); AddReg2("MUL"  , MinCoreMask(eCoreMega   ), 0x9c00);
1003 
1004   AddReg3("CLR"  , 0x2400); AddReg3("TST"  , 0x2000); AddReg3("LSL"  , 0x0c00);
1005   AddReg3("ROL"  , 0x1c00);
1006 
1007   AddImm("SUBI" , 0x5000); AddImm("SBCI" , 0x4000); AddImm("ANDI" , 0x7000);
1008   AddImm("ORI"  , 0x6000); AddImm("SBR"  , 0x6000); AddImm("CPI"  , 0x3000);
1009   AddImm("LDI"  , 0xe000);
1010 
1011   AddRel("BRCC" , 0xf400); AddRel("BRCS" , 0xf000); AddRel("BREQ" , 0xf001);
1012   AddRel("BRGE" , 0xf404); AddRel("BRSH" , 0xf400); AddRel("BRID" , 0xf407);
1013   AddRel("BRIE" , 0xf007); AddRel("BRLO" , 0xf000); AddRel("BRLT" , 0xf004);
1014   AddRel("BRMI" , 0xf002); AddRel("BRNE" , 0xf401); AddRel("BRHC" , 0xf405);
1015   AddRel("BRHS" , 0xf005); AddRel("BRPL" , 0xf402); AddRel("BRTC" , 0xf406);
1016   AddRel("BRTS" , 0xf006); AddRel("BRVC" , 0xf403); AddRel("BRVS" , 0xf003);
1017 
1018   AddBit("BLD"  , 0xf800); AddBit("BST"  , 0xfa00);
1019   AddBit("SBRC" , 0xfc00); AddBit("SBRS" , 0xfe00);
1020 
1021   AddPBit("CBI" , 0x9800); AddPBit("SBI" , 0x9a00);
1022   AddPBit("SBIC", 0x9900); AddPBit("SBIS", 0x9b00);
1023 
1024   AddInstTable(InstTable, "ADIW", 0x0000, DecodeADIW);
1025   AddInstTable(InstTable, "SBIW", 0x0100, DecodeADIW);
1026 
1027   AddInstTable(InstTable, "LD", 0x0000, DecodeLDST);
1028   AddInstTable(InstTable, "ST", 0x0200, DecodeLDST);
1029 
1030   AddInstTable(InstTable, "LDD", 0x0000, DecodeLDDSTD);
1031   AddInstTable(InstTable, "STD", 0x0200, DecodeLDDSTD);
1032 
1033   AddInstTable(InstTable, "IN" , 0x0000, DecodeINOUT);
1034   AddInstTable(InstTable, "OUT", 0x0800, DecodeINOUT);
1035 
1036   AddInstTable(InstTable, "LDS", 0x0000, DecodeLDSSTS);
1037   AddInstTable(InstTable, "STS", 0x0200, DecodeLDSSTS);
1038 
1039   AddInstTable(InstTable, "BCLR", 0x0080, DecodeBCLRSET);
1040   AddInstTable(InstTable, "BSET", 0x0000, DecodeBCLRSET);
1041 
1042   AddInstTable(InstTable, "CBR", 0, DecodeCBR);
1043   AddInstTable(InstTable, "SER", 0, DecodeSER);
1044 
1045   AddInstTable(InstTable, "BRBC", 0x0400, DecodeBRBSBC);
1046   AddInstTable(InstTable, "BRBS", 0x0000, DecodeBRBSBC);
1047 
1048   AddInstTable(InstTable, "JMP" , 0, DecodeJMPCALL);
1049   AddInstTable(InstTable, "CALL", 2, DecodeJMPCALL);
1050 
1051   AddInstTable(InstTable, "RJMP" , 0x0000, DecodeRJMPCALL);
1052   AddInstTable(InstTable, "RCALL", 0x1000, DecodeRJMPCALL);
1053 
1054   AddInstTable(InstTable, "PORT", 0, DecodePORT);
1055   AddInstTable(InstTable, "SFR" , 0, DecodeSFR);
1056   AddInstTable(InstTable, "RES" , 0, DecodeRES);
1057   AddInstTable(InstTable, "REG" , 0, CodeREG);
1058   AddInstTable(InstTable, "BIT" , 0, DecodeBIT);
1059 
1060   AddInstTable(InstTable, "MULS", 0, DecodeMULS);
1061 
1062   AddInstTable(InstTable, "MULSU" , 0x0300, DecodeMegaMUL);
1063   AddInstTable(InstTable, "FMUL"  , 0x0308, DecodeMegaMUL);
1064   AddInstTable(InstTable, "FMULS" , 0x0380, DecodeMegaMUL);
1065   AddInstTable(InstTable, "FMULSU", 0x0388, DecodeMegaMUL);
1066 
1067   AddInstTable(InstTable, "MOVW", 0, DecodeMOVW);
1068 
1069   AddInstTable(InstTable, "LPM" , 0, DecodeLPM);
1070   AddInstTable(InstTable, "ELPM", 0, DecodeELPM);
1071 }
1072 
DeinitFields(void)1073 static void DeinitFields(void)
1074 {
1075   DestroyInstTable(InstTable);
1076   free(FixedOrders);
1077   free(Reg1Orders);
1078   free(Reg2Orders);
1079 }
1080 
1081 /*---------------------------------------------------------------------------*/
1082 
MakeCode_AVR(void)1083 static void MakeCode_AVR(void)
1084 {
1085   CodeLen = 0; DontPrint = False;
1086 
1087   if (Memo("")) return;
1088 
1089   /* instructions that do not require word alignment in byte mode */
1090 
1091   if (Memo("DATA"))
1092   {
1093     DecodeDATA_AVR(0);
1094     return;
1095   }
1096 
1097   if (DecodeIntelPseudo(False))
1098     return;
1099 
1100   /* All other instructions must be on an even address in byte mode.
1101      In other words, they may not cross flash word boundaries: */
1102 
1103   if (!CodeSegSize)
1104   {
1105     if (Odd(EProgCounter()))
1106     {
1107       if (DoPadding)
1108         InsertPadding(1, False);
1109       else
1110         WrError(ErrNum_AddrNotAligned);
1111     }
1112   }
1113 
1114   if (!LookupInstTable(InstTable, OpPart.Str))
1115     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1116 }
1117 
InitCode_AVR(void)1118 static void InitCode_AVR(void)
1119 {
1120   SetFlag(&Packing, PackingName, False);
1121 }
1122 
IsDef_AVR(void)1123 static Boolean IsDef_AVR(void)
1124 {
1125   return (Memo("PORT")
1126        || Memo("REG")
1127        || Memo("SFR")
1128        || Memo("BIT"));
1129 }
1130 
1131 /*!------------------------------------------------------------------------
1132  * \fn     InternSymbol_AVR(char *pArg, TempResult *pResult)
1133  * \brief  parse for built-in symbols
1134  * \param  pArg source argument
1135  * \param  pResult possible result
1136  * ------------------------------------------------------------------------ */
1137 
InternSymbol_AVR(char * pArg,TempResult * pResult)1138 static void InternSymbol_AVR(char *pArg, TempResult *pResult)
1139 {
1140   Word RegValue;
1141 
1142   if (DecodeRegCore(pArg, &RegValue))
1143   {
1144     pResult->Typ = TempReg;
1145     pResult->DataSize = eSymbolSize8Bit;
1146     pResult->Contents.RegDescr.Reg = RegValue;
1147     pResult->Contents.RegDescr.Dissect = DissectReg_AVR;
1148   }
1149 }
1150 
SwitchFrom_AVR(void)1151 static void SwitchFrom_AVR(void)
1152 {
1153   DeinitFields();
1154   ClearONOFF();
1155 }
1156 
ChkZeroArg(void)1157 static Boolean ChkZeroArg(void)
1158 {
1159   return (0 == ArgCnt);
1160 }
1161 
SwitchTo_AVR(void * pUser)1162 static void SwitchTo_AVR(void *pUser)
1163 {
1164   pCurrCPUProps = (const tCPUProps*)pUser;
1165 
1166   TurnWords = False;
1167   ConstMode = ConstModeC;
1168   SetIsOccupiedFnc = ChkZeroArg;
1169 
1170   PCSymbol = "*";
1171   HeaderID = CodeSegSize ? 0x3b : 0x3d;
1172   NOPCode = 0x0000;
1173   DivideChars = ",";
1174   HasAttrs = False;
1175 
1176   ValidSegs = (1 << SegCode) | (1 << SegData) | (1 << SegIO);
1177   Grans[SegCode] = ListGrans[SegCode] = 1 << CodeSegSize; SegInits[SegCode] = 0;
1178   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 32;
1179   Grans[SegIO  ] = 1; ListGrans[SegIO  ] = 1; SegInits[SegIO  ] = 0;  SegLimits[SegIO] = 0x3f;
1180   if (pCurrCPUProps->EESize)
1181   {
1182     ValidSegs |= (1 << SegEEData);
1183     SegLimits[SegEEData] = pCurrCPUProps->EESize;
1184     Grans[SegEEData] = 1; ListGrans[SegEEData] = 1; SegInits[SegEEData] = 0;
1185   }
1186 
1187   SegLimits[SegCode] = ((LongWord)pCurrCPUProps->FlashEndD16) << 4 | 0xf;
1188   if (!CodeSegSize)
1189   {
1190     SegLimits[SegCode] = (SegLimits[SegCode] << 1) + 1;
1191     AddONOFF("PADDING", &DoPadding, DoPaddingName, False);
1192   }
1193   SegLimits[SegData] = (pCurrCPUProps->RegistersMapped ? RegBankSize : 0)
1194                      + pCurrCPUProps->IOAreaSize
1195                      + pCurrCPUProps->RAMSize
1196                      - 1;
1197 
1198   CodeAdrIntType = GetSmallestUIntType(SegLimits[SegCode]);
1199   DataAdrIntType = GetSmallestUIntType(SegLimits[SegData]);
1200 
1201   SignMask = (SegLimits[SegCode] + 1) >> 1;
1202   ORMask = ((LongInt) - 1) - SegLimits[SegCode];
1203 
1204   AddONOFF("WRAPMODE", &WrapFlag, WrapFlagName, False);
1205   AddONOFF("PACKING", &Packing, PackingName, False);
1206   SetFlag(&WrapFlag, WrapFlagName, False);
1207 
1208   MakeCode = MakeCode_AVR;
1209   IsDef = IsDef_AVR;
1210   InternSymbol = InternSymbol_AVR;
1211   DissectReg = DissectReg_AVR;
1212   SwitchFrom = SwitchFrom_AVR;
1213   DissectBit = DissectBit_AVR;
1214   InitFields();
1215 }
1216 
1217 static const tCPUProps CPUProps[] =
1218 {
1219   { "AT90S1200"      ,  0x01f, 0x0000, 0x003f, IOAreaStdSize , True , eCore90S1200   },
1220   { "AT90S2313"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   },
1221   { "AT90S2323"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   },
1222   { "AT90S2333"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   }, /* == ATtiny22 */
1223   { "AT90S2343"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   },
1224   { "AT90S4414"      ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreClassic   },
1225   { "AT90S4433"      ,  0x07f, 0x0080, 0x00ff, IOAreaStdSize , True , eCoreClassic   },
1226   { "AT90S4434"      ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreClassic   },
1227   { "AT90S8515"      ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreClassic   },
1228   { "AT90C8534"      ,  0x0ff, 0x0100, 0x01ff, IOAreaStdSize , True , eCoreClassic   },
1229   { "AT90S8535"      ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreClassic   },
1230   { "AT90USB646"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
1231   { "AT90USB647"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
1232   { "AT90USB1286"    ,  0xfff, 0x2000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
1233   { "AT90USB1287"    ,  0xfff, 0x2000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
1234 
1235   { "AT43USB355"     ,  0x2ff, 0x0400, 0x0000, 0x2000-RegBankSize, True , eCoreClassic   }, /* allow USB registers @ 0x1fxx */
1236 
1237   { "ATTINY4"        ,  0x00f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
1238   { "ATTINY5"        ,  0x00f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
1239   { "ATTINY9"        ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
1240   { "ATTINY10"       ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
1241   { "ATTINY11"       ,  0x01f, 0x0000, 0x0000, IOAreaStdSize , True , eCore90S1200   },
1242   { "ATTINY12"       ,  0x01f, 0x0000, 0x003f, IOAreaStdSize , True , eCore90S1200   },
1243   { "ATTINY13"       ,  0x01f, 0x0040, 0x003f, IOAreaStdSize , True , eCoreTiny      },
1244   { "ATTINY13A"      ,  0x01f, 0x0040, 0x003f, IOAreaStdSize , True , eCoreTiny      },
1245   { "ATTINY15"       ,  0x01f, 0x0000, 0x003f, IOAreaStdSize , True , eCore90S1200   },
1246   { "ATTINY20"       ,  0x03f, 0x0080, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
1247   { "ATTINY24"       ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1248   { "ATTINY24A"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1249   { "ATTINY25"       ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1250   { "ATTINY26"       ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1251   { "ATTINY28"       ,  0x03f, 0x0000, 0x0000, IOAreaStdSize , True , eCore90S1200   },
1252   { "ATTINY40"       ,  0x07f, 0x0100, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
1253   { "ATTINY44"       ,  0x07f, 0x0100, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1254   { "ATTINY44A"      ,  0x07f, 0x0100, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1255   { "ATTINY45"       ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
1256   { "ATTINY48"       ,  0x07f, 0x0100, 0x003f, IOAreaExtSize , True , eCoreTiny      },
1257   { "ATTINY84"       ,  0x0ff, 0x0200, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1258   { "ATTINY84A"      ,  0x0ff, 0x0200, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1259   { "ATTINY85"       ,  0x0ff, 0x0200, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
1260   { "ATTINY87"       ,  0x0ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreTiny16K   },
1261   { "ATTINY88"       ,  0x0ff, 0x0200, 0x003f, IOAreaExtSize , True , eCoreTiny      },
1262   { "ATTINY102"      ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
1263   { "ATTINY104"      ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
1264   { "ATTINY167"      ,  0x1ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreTiny16K   },
1265   { "ATTINY261"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1266   { "ATTINY261A"     ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1267   { "ATTINY43U"      ,  0x07f, 0x0100, 0x003f, IOAreaStdSize , True , eCoreTiny      },
1268   { "ATTINY441"      ,  0x07f, 0x0100, 0x00ff, IOAreaExtSize , True , eCoreTiny      },
1269   { "ATTINY461"      ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
1270   { "ATTINY461A"     ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
1271   { "ATTINY828"      ,  0x0ff, 0x0200, 0x00ff, IOAreaExtSize , True , eCoreTiny      },
1272   { "ATTINY841"      ,  0x0ff, 0x0200, 0x00ff, IOAreaExtSize , True , eCoreTiny      },
1273   { "ATTINY861"      ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreTiny      },
1274   { "ATTINY861A"     ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreTiny      },
1275   { "ATTINY1634"     ,  0x1ff, 0x0400, 0x00ff, IOAreaExtSize , True , eCoreTiny16K   },
1276   { "ATTINY2313"     ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1277   { "ATTINY2313A"    ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
1278   { "ATTINY4313"     ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
1279 
1280   { "ATMEGA48"       ,  0x07f, 0x0200, 0x00ff, IOAreaExtSize , True , eCoreMega      },
1281 
1282   { "ATMEGA8"        ,  0x0ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
1283   { "ATMEGA8515"     ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreMega      },
1284   { "ATMEGA8535"     ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreMega      },
1285   { "ATMEGA88"       ,  0x0ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1286   { "ATMEGA8U2"      ,  0x0ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1287 
1288   { "ATMEGA16"       ,  0x1ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
1289   { "ATMEGA161"      ,  0x1ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
1290   { "ATMEGA162"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1291   { "ATMEGA163"      ,  0x1ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
1292   { "ATMEGA164"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1293   { "ATMEGA165"      ,  0x1ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1294   { "ATMEGA168"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1295   { "ATMEGA169"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1296   { "ATMEGA16U2"     ,  0x1ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1297   { "ATMEGA16U4"     ,  0x1ff, 0x0500, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1298 
1299   { "ATMEGA32"       ,  0x3ff, 0x0800, 0x03ff, IOAreaStdSize , True , eCoreMega      },
1300   { "ATMEGA323"      ,  0x3ff, 0x0800, 0x03ff, IOAreaStdSize , True , eCoreMega      },
1301   { "ATMEGA324"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
1302   { "ATMEGA325"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
1303   { "ATMEGA3250"     ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
1304   { "ATMEGA328"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
1305   { "ATMEGA329"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
1306   { "ATMEGA3290"     ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
1307   { "ATMEGA32U2"     ,  0x3ff, 0x0400, 0x03ff, IOAreaExtSize , True , eCoreMega      },
1308   { "ATMEGA32U4"     ,  0x3ff, 0x0a00, 0x03ff, IOAreaExtSize , True , eCoreMega      },
1309   { "ATMEGA32U6"     ,  0x3ff, 0x0a00, 0x03ff, IOAreaExtSize , True , eCoreMega      },
1310 
1311   { "ATMEGA406"      ,  0x4ff, 0x0800, 0x01ff, IOAreaExtSize , True , eCoreMega      },
1312 
1313   { "ATMEGA64"       ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
1314   { "ATMEGA640"      ,  0x7ff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
1315   { "ATMEGA644"      ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
1316   { "ATMEGA644RFR2"  ,  0x7ff, 0x2000, 0x07ff, IOAreaExt2Size, True , eCoreMega      },
1317   { "ATMEGA645"      ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
1318   { "ATMEGA6450"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
1319   { "ATMEGA649"      ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
1320   { "ATMEGA6490"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
1321 
1322   { "ATMEGA103"      ,  0xfff, 0x1000, 0x0fff, IOAreaStdSize , True , eCoreMega      },
1323   { "ATMEGA128"      ,  0xfff, 0x1000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
1324   { "ATMEGA1280"     ,  0xfff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
1325   { "ATMEGA1281"     ,  0xfff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
1326   { "ATMEGA1284"     ,  0xfff, 0x4000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
1327   { "ATMEGA1284RFR2" ,  0xfff, 0x4000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
1328 
1329   { "ATMEGA2560"     , 0x1fff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
1330   { "ATMEGA2561"     , 0x1fff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
1331   { "ATMEGA2564RFR2" , 0x1fff, 0x8000, 0x1fff, IOAreaExt2Size, True , eCoreMega      },
1332   { NULL             ,    0x0, 0     , 0     , 0             , False, eCoreNone      },
1333 };
1334 
codeavr_init(void)1335 void codeavr_init(void)
1336 {
1337   const tCPUProps *pProp;
1338   static const tCPUArg AVRArgs[] =
1339   {
1340     { "CODESEGSIZE", 0, 1, 1, &CodeSegSize },
1341     { NULL         , 0, 0, 0, NULL         }
1342   };
1343 
1344   for (pProp = CPUProps; pProp->pName; pProp++)
1345     (void)AddCPUUserWithArgs(pProp->pName, SwitchTo_AVR, (void*)pProp, NULL, AVRArgs);
1346 
1347    AddInitPassProc(InitCode_AVR);
1348 }
1349