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