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