1 /* codemcore.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator MCORE-Familie */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <ctype.h>
13 #include <string.h>
14
15 #include "nls.h"
16 #include "endian.h"
17 #include "strutil.h"
18 #include "bpemu.h"
19 #include "asmdef.h"
20 #include "asmsub.h"
21 #include "asmpars.h"
22 #include "asmallg.h"
23 #include "codepseudo.h"
24 #include "motpseudo.h"
25 #include "asmitree.h"
26 #include "codevars.h"
27 #include "errmsg.h"
28
29 #include "codemcore.h"
30
31 /*--------------------------------------------------------------------------*/
32 /* Variablen */
33
34 #define REG_SP 0
35 #define REG_LR 15
36 #define REG_MARK 16 /* internal mark to differentiate SP<->R0 and LR<->R15 */
37
38 #define FixedOrderCnt 7
39 #define OneRegOrderCnt 32
40 #define TwoRegOrderCnt 23
41 #define UImm5OrderCnt 13
42 #define LJmpOrderCnt 4
43 #define CRegCnt 13
44
45 typedef struct
46 {
47 Word Code;
48 Boolean Priv;
49 } FixedOrder;
50
51 typedef struct
52 {
53 Word Code;
54 Word Min,Ofs;
55 } ImmOrder;
56
57 typedef struct
58 {
59 const char *Name;
60 Word Code;
61 } CReg;
62
63 static CPUVar CPUMCORE;
64 static tSymbolSize OpSize;
65
66 static FixedOrder *FixedOrders;
67 static FixedOrder *OneRegOrders;
68 static FixedOrder *TwoRegOrders;
69 static ImmOrder *UImm5Orders;
70 static FixedOrder *LJmpOrders;
71 static CReg *CRegs;
72
73 /*--------------------------------------------------------------------------*/
74 /* Hilfsdekoder */
75
76 static const Word AllRegMask = 0xffff;
77
78 /*!------------------------------------------------------------------------
79 * \fn DecodeRegCore(const char *pArg, Word *pResult)
80 * \brief check whether argument is a register
81 * \param pArg argument
82 * \param pResult register number if it is
83 * \return True if it is
84 * ------------------------------------------------------------------------ */
85
DecodeRegCore(const char * pArg,Word * pResult)86 static Boolean DecodeRegCore(const char *pArg, Word *pResult)
87 {
88 if (!as_strcasecmp(pArg, "SP"))
89 *pResult = REG_MARK | REG_SP;
90 else if (!as_strcasecmp(pArg, "LR"))
91 *pResult = REG_MARK | REG_LR;
92 else if (as_toupper(*pArg) != 'R')
93 return False;
94 else
95 {
96 char *endptr;
97
98 *pResult = strtol(pArg + 1, &endptr, 10);
99 if (*endptr || (*pResult > 15))
100 return False;
101 }
102 return True;
103 }
104
105 /*!------------------------------------------------------------------------
106 * \fn DissectReg_MCORE(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
107 * \brief dissect register symbols - M-CORE variant
108 * \param pDest destination buffer
109 * \param DestSize destination buffer size
110 * \param Value numeric register value
111 * \param InpSize register size
112 * ------------------------------------------------------------------------ */
113
DissectReg_MCORE(char * pDest,size_t DestSize,tRegInt Value,tSymbolSize InpSize)114 static void DissectReg_MCORE(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
115 {
116 switch (InpSize)
117 {
118 case eSymbolSize32Bit:
119 switch (Value)
120 {
121 case REG_MARK | REG_SP:
122 as_snprintf(pDest, DestSize, "SP");
123 break;
124 case REG_MARK | REG_LR:
125 as_snprintf(pDest, DestSize, "LR");
126 break;
127 default:
128 as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
129 }
130 break;
131 default:
132 as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
133 }
134 }
135
136 /*!------------------------------------------------------------------------
137 * \fn DecodeReg(const tStrComp *pArg, Word *pResult, Word Mask, Boolean MustBeReg)
138 * \brief check whether argument is a CPU register or register alias
139 * \param pArg argument
140 * \param pResult register number if it is
141 * \param Mask bit mask of allowed registers
142 * \param MustBeReg operand is expected to be a register
143 * \return True if it is an allowed register
144 * ------------------------------------------------------------------------ */
145
DecodeReg(const tStrComp * pArg,Word * pResult,Word Mask,Boolean MustBeReg)146 static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pResult, Word Mask, Boolean MustBeReg)
147 {
148 tRegEvalResult RegEvalResult;
149
150 if (DecodeRegCore(pArg->Str, pResult))
151 RegEvalResult = eIsReg;
152 else
153 {
154 tRegDescr RegDescr;
155 tEvalResult EvalResult;
156
157 RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize32Bit, MustBeReg);
158 *pResult = RegDescr.Reg;
159 }
160 *pResult &= ~REG_MARK;
161 if ((RegEvalResult == eIsReg) && !(Mask & (1 << *pResult)))
162 {
163 RegEvalResult = MustBeReg ? eRegAbort : eIsNoReg;
164 WrStrErrorPos(ErrNum_InvReg, pArg);
165 }
166 return RegEvalResult;
167 }
168
DecodeArgReg(int Index,Word * pErg,Word Mask)169 static Boolean DecodeArgReg(int Index, Word *pErg, Word Mask)
170 {
171 return (DecodeReg(&ArgStr[Index], pErg, Mask, True) == eIsReg);
172 }
173
DecodeArgIReg(int Index,Word * pErg,Word Mask)174 static Boolean DecodeArgIReg(int Index, Word *pErg, Word Mask)
175 {
176 tStrComp RegComp;
177 const char *pArg = ArgStr[Index].Str;
178 int l = strlen(pArg);
179
180 if ((l <= 3) || (pArg[0] != '(') || (pArg[l - 1] != ')'))
181 {
182 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[Index]);
183 return False;
184 }
185 StrCompRefRight(&RegComp, &ArgStr[Index], 1);
186 StrCompShorten(&RegComp, 1);
187 return (DecodeReg(&RegComp, pErg, Mask, True) == eIsReg);
188 }
189
DecodeArgRegPair(int Index,Word * pFrom,Word FromMask,Word * pTo,Word ToMask)190 static Boolean DecodeArgRegPair(int Index, Word *pFrom, Word FromMask, Word *pTo, Word ToMask)
191 {
192 tStrComp FromComp, ToComp;
193 char *pSep = strchr(ArgStr[Index].Str, '-');
194
195 if (!pSep)
196 {
197 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[Index]);
198 return False;
199 }
200
201 StrCompSplitRef(&FromComp, &ToComp, &ArgStr[Index], pSep);
202 return (DecodeReg(&FromComp, pFrom, FromMask, True) == eIsReg)
203 && (DecodeReg(&ToComp, pTo, ToMask, True) == eIsReg);
204 }
205
DecodeCReg(char * Asc,Word * Erg)206 static Boolean DecodeCReg(char *Asc, Word *Erg)
207 {
208 char *endptr;
209 int z;
210
211 for (z = 0; z < CRegCnt; z++)
212 if (!as_strcasecmp(Asc, CRegs[z].Name))
213 {
214 *Erg = CRegs[z].Code;
215 return True;
216 }
217
218 if ((as_toupper(*Asc) != 'C') || (as_toupper(Asc[1]) != 'R'))
219 return False;
220 else
221 {
222 *Erg = strtol(Asc + 2, &endptr, 10);
223 return ((*endptr == '\0') && (*Erg <= 31));
224 }
225 }
226
DecodeArgCReg(int Index,Word * pErg)227 static Boolean DecodeArgCReg(int Index, Word *pErg)
228 {
229 Boolean Result = DecodeCReg(ArgStr[Index].Str, pErg);
230
231 if (!Result)
232 WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[Index]);
233 return Result;
234 }
235
DecodeAdr(const tStrComp * pArg,Word * Erg)236 static Boolean DecodeAdr(const tStrComp *pArg, Word *Erg)
237 {
238 Word Base = 0xff, Tmp;
239 LongInt DispAcc = 0, DMask = (1 << OpSize) - 1, DMax = 15 << OpSize;
240 Boolean OK, FirstFlag = False;
241 tSymbolFlags Flags;
242 char *Pos;
243 tStrComp Arg, Remainder;
244
245 if (!IsIndirect(pArg->Str))
246 {
247 WrError(ErrNum_InvAddrMode);
248 return False;
249 }
250
251 StrCompRefRight(&Arg,pArg, 1);
252 StrCompShorten(&Arg, 1);
253 do
254 {
255 Pos = QuotPos(Arg.Str,',');
256 if (Pos)
257 StrCompSplitRef(&Arg, &Remainder, &Arg, Pos);
258 switch (DecodeReg(&Arg, &Tmp, AllRegMask, False))
259 {
260 case eIsReg:
261 if (Base == 0xff) Base = Tmp;
262 else
263 {
264 WrError(ErrNum_InvAddrMode);
265 return False;
266 }
267 break;
268 case eIsNoReg:
269 DispAcc += EvalStrIntExpressionWithFlags(&Arg, Int32, &OK, &Flags);
270 if (mFirstPassUnknown(Flags)) FirstFlag = True;
271 if (!OK)
272 return False;
273 break;
274 default:
275 return False;
276 }
277 if (Pos)
278 Arg = Remainder;
279 }
280 while (Pos);
281
282 if (Base == 0xff)
283 {
284 WrError(ErrNum_InvAddrMode);
285 return False;
286 }
287
288 if (FirstFlag)
289 {
290 DispAcc -= DispAcc & DMask;
291 if (DispAcc < 0) DispAcc = 0;
292 if (DispAcc > DMax) DispAcc = DMax;
293 }
294
295 if ((DispAcc & DMask) != 0)
296 {
297 WrError(ErrNum_NotAligned);
298 return False;
299 }
300 if (!ChkRange(DispAcc, 0, DMax))
301 return False;
302 *Erg = Base + ((DispAcc >> OpSize) << 4);
303 return True;
304 }
305
DecodeFixed(Word Index)306 static void DecodeFixed(Word Index)
307 {
308 FixedOrder *Instr = FixedOrders + Index;
309
310 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
311 else if (ChkArgCnt(0, 0))
312 {
313 if ((Instr->Priv) && (!SupAllowed)) WrError(ErrNum_PrivOrder);
314 WAsmCode[0] = Instr->Code;
315 CodeLen = 2;
316 }
317 }
318
DecodeOneReg(Word Index)319 static void DecodeOneReg(Word Index)
320 {
321 FixedOrder *Instr = OneRegOrders + Index;
322 Word RegX;
323
324 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
325 else if (ChkArgCnt(1, 1) && DecodeArgReg(1, &RegX, AllRegMask))
326 {
327 if ((Instr->Priv) && (!SupAllowed)) WrError(ErrNum_PrivOrder);
328 WAsmCode[0] = Instr->Code + RegX;
329 CodeLen = 2;
330 }
331 }
332
DecodeTwoReg(Word Index)333 static void DecodeTwoReg(Word Index)
334 {
335 FixedOrder *Instr = TwoRegOrders + Index;
336 Word RegX, RegY;
337
338 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
339 else if (ChkArgCnt(2, 2)
340 && DecodeArgReg(1, &RegX, AllRegMask)
341 && DecodeArgReg(2, &RegY, AllRegMask))
342 {
343 if ((Instr->Priv) && (!SupAllowed)) WrError(ErrNum_PrivOrder);
344 WAsmCode[0] = Instr->Code + (RegY << 4) + RegX;
345 CodeLen = 2;
346 }
347 }
348
DecodeUImm5(Word Index)349 static void DecodeUImm5(Word Index)
350 {
351 ImmOrder *Instr = UImm5Orders + Index;
352 Word RegX, ImmV;
353 Boolean OK;
354 tSymbolFlags Flags;
355
356 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
357 else if (ChkArgCnt(2, 2) && DecodeArgReg(1, &RegX, AllRegMask))
358 {
359 ImmV = EvalStrIntExpressionWithFlags(&ArgStr[2], (Instr->Ofs > 0) ? UInt6 : UInt5, &OK, &Flags);
360 if ((Instr->Min > 0) && (ImmV < Instr->Min))
361 {
362 if (mFirstPassUnknown(Flags)) ImmV = Instr->Min;
363 else
364 {
365 WrError(ErrNum_UnderRange); OK = False;
366 }
367 }
368 if ((Instr->Ofs > 0) && ((ImmV < Instr->Ofs) || (ImmV > 31 + Instr->Ofs)))
369 {
370 if (mFirstPassUnknown(Flags)) ImmV = Instr->Ofs;
371 else
372 {
373 WrError((ImmV < Instr->Ofs) ? ErrNum_UnderRange : ErrNum_OverRange);
374 OK = False;
375 }
376 }
377 if (OK)
378 {
379 WAsmCode[0] = Instr->Code + ((ImmV - Instr->Ofs) << 4) + RegX;
380 CodeLen = 2;
381 }
382 }
383 }
384
DecodeLJmp(Word Index)385 static void DecodeLJmp(Word Index)
386 {
387 FixedOrder *Instr = LJmpOrders + Index;
388 LongInt Dest;
389 Boolean OK;
390 tSymbolFlags Flags;
391
392 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
393 else if (ChkArgCnt(1, 1))
394 {
395 Dest = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt32, &OK, &Flags) - (EProgCounter() + 2);
396 if (OK)
397 {
398 if (!mSymbolQuestionable(Flags) && (Dest & 1)) WrError(ErrNum_DistIsOdd);
399 else if (!mSymbolQuestionable(Flags) && ((Dest > 2046) || (Dest < -2048))) WrError(ErrNum_JmpDistTooBig);
400 else
401 {
402 if ((Instr->Priv) && (!SupAllowed)) WrError(ErrNum_PrivOrder);
403 WAsmCode[0] = Instr->Code + ((Dest >> 1) & 0x7ff);
404 CodeLen = 2;
405 }
406 }
407 }
408 }
409
DecodeSJmp(Word Index)410 static void DecodeSJmp(Word Index)
411 {
412 LongInt Dest;
413 Boolean OK;
414 tSymbolFlags Flags;
415 int l = 0;
416
417 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
418 else if (!ChkArgCnt(1, 1));
419 else if ((*ArgStr[1].Str != '[') || (ArgStr[1].Str[l = strlen(ArgStr[1].Str) - 1] != ']')) WrError(ErrNum_InvAddrMode);
420 else
421 {
422 ArgStr[1].Str[l] = '\0';
423 Dest = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], 1, UInt32, &OK, &Flags);
424 if (OK)
425 {
426 if (!mSymbolQuestionable(Flags) && (Dest & 3)) WrError(ErrNum_NotAligned);
427 else
428 {
429 Dest = (Dest - (EProgCounter() + 2)) >> 2;
430 if ((EProgCounter() & 3) < 2) Dest++;
431 if (!mSymbolQuestionable(Flags) && ((Dest < 0) || (Dest > 255))) WrError(ErrNum_JmpDistTooBig);
432 else
433 {
434 WAsmCode[0] = 0x7000 + (Index << 8) + (Dest & 0xff);
435 CodeLen = 2;
436 }
437 }
438 }
439 }
440 }
441
DecodeBGENI(Word Index)442 static void DecodeBGENI(Word Index)
443 {
444 Word RegX, ImmV;
445 Boolean OK;
446 UNUSED(Index);
447
448 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
449 else if (ChkArgCnt(2, 2) && DecodeArgReg(1, &RegX, AllRegMask))
450 {
451 ImmV = EvalStrIntExpression(&ArgStr[2], UInt5, &OK);
452 if (OK)
453 {
454 if (ImmV > 6)
455 WAsmCode[0] = 0x3200 + (ImmV << 4) + RegX;
456 else
457 WAsmCode[0] = 0x6000 + (1 << (4 + ImmV)) + RegX;
458 CodeLen = 2;
459 }
460 }
461 }
462
DecodeBMASKI(Word Index)463 static void DecodeBMASKI(Word Index)
464 {
465 Word RegX, ImmV;
466 Boolean OK;
467 tSymbolFlags Flags;
468
469 UNUSED(Index);
470
471 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
472 else if (ChkArgCnt(2, 2) && DecodeArgReg(1, &RegX, AllRegMask))
473 {
474 ImmV = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt6, &OK, &Flags);
475 if (mFirstPassUnknown(Flags) && ((ImmV < 1) || (ImmV > 32))) ImmV = 8;
476 if (OK)
477 {
478 if (ChkRange(ImmV, 1, 32))
479 {
480 ImmV &= 31;
481 if ((ImmV < 1) || (ImmV > 7))
482 WAsmCode[0] = 0x2c00 + (ImmV << 4) + RegX;
483 else
484 WAsmCode[0] = 0x6000 + (((1 << ImmV) - 1) << 4) + RegX;
485 CodeLen = 2;
486 }
487 }
488 }
489 }
490
DecodeLdSt(Word Index)491 static void DecodeLdSt(Word Index)
492 {
493 Word RegX, RegZ, NSize;
494
495 if (*AttrPart.Str && (Lo(Index) != 0xff)) WrError(ErrNum_UseLessAttr);
496 else if (!ChkArgCnt(2, 2));
497 else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
498 else
499 {
500 if (Lo(Index) != 0xff) OpSize = (tSymbolSize)Lo(Index);
501 if (DecodeArgReg(1, &RegZ, AllRegMask) && DecodeAdr(&ArgStr[2], &RegX))
502 {
503 NSize = (OpSize == eSymbolSize32Bit) ? 0 : OpSize + 1;
504 WAsmCode[0] = 0x8000 + (NSize << 13) + (Hi(Index) << 12) + (RegZ << 8) + RegX;
505 CodeLen = 2;
506 }
507 }
508 }
509
DecodeLdStm(Word Index)510 static void DecodeLdStm(Word Index)
511 {
512 Word RegF, RegL, RegI;
513
514 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
515 else if (ChkArgCnt(2, 2)
516 && DecodeArgIReg(2, &RegI, 0x0001)
517 && DecodeArgRegPair(1, &RegF, 0x7ffe, &RegL, 0x8000))
518 {
519 WAsmCode[0] = 0x0060 + (Index << 4) + RegF;
520 CodeLen = 2;
521 }
522 }
523
DecodeLdStq(Word Index)524 static void DecodeLdStq(Word Index)
525 {
526 Word RegF, RegL, RegX;
527
528 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
529 else if (ChkArgCnt(2, 2)
530 && DecodeArgIReg(2, &RegX, 0xff0f)
531 && DecodeArgRegPair(1, &RegF, 0x0010, &RegL, 0x0080))
532 {
533 WAsmCode[0] = 0x0040 + (Index << 4) + RegX;
534 CodeLen = 2;
535 }
536 }
537
DecodeLoopt(Word Index)538 static void DecodeLoopt(Word Index)
539 {
540 Word RegY;
541 LongInt Dest;
542 Boolean OK;
543 tSymbolFlags Flags;
544 UNUSED(Index);
545
546 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
547 else if (ChkArgCnt(2, 2) && DecodeArgReg(1, &RegY, AllRegMask))
548 {
549 Dest = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt32, &OK, &Flags) - (EProgCounter() + 2);
550 if (OK)
551 {
552 if (!mSymbolQuestionable(Flags) && (Dest & 1)) WrError(ErrNum_DistIsOdd);
553 else if (!mSymbolQuestionable(Flags) && ((Dest > -2) || (Dest <- 32))) WrError(ErrNum_JmpDistTooBig);
554 else
555 {
556 WAsmCode[0] = 0x0400 + (RegY << 4) + ((Dest >> 1) & 15);
557 CodeLen = 2;
558 }
559 }
560 }
561 }
562
DecodeLrm(Word Index)563 static void DecodeLrm(Word Index)
564 {
565 LongInt Dest;
566 Word RegZ;
567 Boolean OK;
568 tSymbolFlags Flags;
569 int l = 0;
570 UNUSED(Index);
571
572 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
573 else if (!ChkArgCnt(2, 2));
574 else if (!DecodeArgReg(1, &RegZ, 0x7ffe));
575 else if ((*ArgStr[2].Str != '[') || (ArgStr[2].Str[l = strlen(ArgStr[2].Str) - 1] != ']')) WrError(ErrNum_InvAddrMode);
576 else
577 {
578 ArgStr[2].Str[l] = '\0';
579 Dest = EvalStrIntExpressionOffsWithFlags(&ArgStr[2], 1, UInt32, &OK, &Flags);
580 if (OK)
581 {
582 if (!mSymbolQuestionable(Flags) && (Dest & 3)) WrError(ErrNum_NotAligned);
583 else
584 {
585 Dest = (Dest - (EProgCounter() + 2)) >> 2;
586 if ((EProgCounter() & 3) < 2) Dest++;
587 if (!mSymbolQuestionable(Flags) && ((Dest < 0) || (Dest > 255))) WrError(ErrNum_JmpDistTooBig);
588 else
589 {
590 WAsmCode[0] = 0x7000 + (RegZ << 8) + (Dest & 0xff);
591 CodeLen = 2;
592 }
593 }
594 }
595 }
596 }
597
DecodeMcr(Word Index)598 static void DecodeMcr(Word Index)
599 {
600 Word RegX,CRegY;
601
602 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
603 else if (ChkArgCnt(2, 2)
604 && DecodeArgReg(1, &RegX, AllRegMask)
605 && DecodeArgCReg(2, &CRegY))
606 {
607 if (!SupAllowed) WrError(ErrNum_PrivOrder);
608 WAsmCode[0] = 0x1000 + (Index << 11) + (CRegY << 4) + RegX;
609 CodeLen = 2;
610 }
611 }
612
DecodeMovi(Word Index)613 static void DecodeMovi(Word Index)
614 {
615 Word RegX, ImmV;
616 Boolean OK;
617 UNUSED(Index);
618
619 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
620 else if (ChkArgCnt(2, 2) && DecodeArgReg(1, &RegX, AllRegMask))
621 {
622 ImmV = EvalStrIntExpression(&ArgStr[2], UInt7, &OK);
623 if (OK)
624 {
625 WAsmCode[0] = 0x6000 + ((ImmV & 127) << 4) + RegX;
626 CodeLen = 2;
627 }
628 }
629 }
630
DecodeTrap(Word Index)631 static void DecodeTrap(Word Index)
632 {
633 Word ImmV;
634 Boolean OK;
635 UNUSED(Index);
636
637 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
638 else if (!ChkArgCnt(1, 1));
639 else if (*ArgStr[1].Str != '#') WrError(ErrNum_OnlyImmAddr);
640 else
641 {
642 ImmV = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt2, &OK);
643 if (OK)
644 {
645 WAsmCode[0] = 0x0008 + ImmV;
646 CodeLen = 2;
647 }
648 }
649 }
650
651 /*--------------------------------------------------------------------------*/
652 /* Codetabellenverwaltung */
653
AddFixed(const char * NName,Word NCode,Boolean NPriv)654 static void AddFixed(const char *NName, Word NCode, Boolean NPriv)
655 {
656 if (InstrZ >= FixedOrderCnt) exit(255);
657 FixedOrders[InstrZ].Code = NCode;
658 FixedOrders[InstrZ].Priv = NPriv;
659 AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
660 }
661
AddOneReg(const char * NName,Word NCode,Boolean NPriv)662 static void AddOneReg(const char *NName, Word NCode, Boolean NPriv)
663 {
664 if (InstrZ >= OneRegOrderCnt) exit(255);
665 OneRegOrders[InstrZ].Code = NCode;
666 OneRegOrders[InstrZ].Priv = NPriv;
667 AddInstTable(InstTable, NName, InstrZ++, DecodeOneReg);
668 }
669
AddTwoReg(const char * NName,Word NCode,Boolean NPriv)670 static void AddTwoReg(const char *NName, Word NCode, Boolean NPriv)
671 {
672 if (InstrZ >= TwoRegOrderCnt) exit(255);
673 TwoRegOrders[InstrZ].Code = NCode;
674 TwoRegOrders[InstrZ].Priv = NPriv;
675 AddInstTable(InstTable, NName, InstrZ++, DecodeTwoReg);
676 }
677
AddUImm5(const char * NName,Word NCode,Word NMin,Word NOfs)678 static void AddUImm5(const char *NName, Word NCode, Word NMin, Word NOfs)
679 {
680 if (InstrZ >= UImm5OrderCnt) exit(255);
681 UImm5Orders[InstrZ].Code = NCode;
682 UImm5Orders[InstrZ].Min = NMin;
683 UImm5Orders[InstrZ].Ofs = NOfs;
684 AddInstTable(InstTable, NName, InstrZ++, DecodeUImm5);
685 }
686
AddLJmp(const char * NName,Word NCode,Boolean NPriv)687 static void AddLJmp(const char *NName, Word NCode, Boolean NPriv)
688 {
689 if (InstrZ >= LJmpOrderCnt) exit(255);
690 LJmpOrders[InstrZ].Code = NCode;
691 LJmpOrders[InstrZ].Priv = NPriv;
692 AddInstTable(InstTable, NName, InstrZ++, DecodeLJmp);
693 }
694
AddCReg(const char * NName,Word NCode)695 static void AddCReg(const char *NName, Word NCode)
696 {
697 if (InstrZ >= CRegCnt) exit(255);
698 CRegs[InstrZ].Name = NName;
699 CRegs[InstrZ++].Code = NCode;
700 }
701
InitFields(void)702 static void InitFields(void)
703 {
704 InstTable = CreateInstTable(201);
705
706 AddInstTable(InstTable, "REG", 0, CodeREG);
707
708 InstrZ = 0; FixedOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * FixedOrderCnt);
709 AddFixed("BKPT" , 0x0000, False);
710 AddFixed("DOZE" , 0x0006, True );
711 AddFixed("RFI" , 0x0003, True );
712 AddFixed("RTE" , 0x0002, True );
713 AddFixed("STOP" , 0x0004, True );
714 AddFixed("SYNC" , 0x0001, False);
715 AddFixed("WAIT" , 0x0005, True );
716
717 InstrZ = 0; OneRegOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * OneRegOrderCnt);
718 AddOneReg("ABS" , 0x01e0, False); AddOneReg("ASRC" , 0x3a00, False);
719 AddOneReg("BREV" , 0x00f0, False); AddOneReg("CLRF" , 0x01d0, False);
720 AddOneReg("CLRT" , 0x01c0, False); AddOneReg("DECF" , 0x0090, False);
721 AddOneReg("DECGT" , 0x01a0, False); AddOneReg("DECLT", 0x0180, False);
722 AddOneReg("DECNE" , 0x01b0, False); AddOneReg("DECT" , 0x0080, False);
723 AddOneReg("DIVS" , 0x3210, False); AddOneReg("DIVU" , 0x2c10, False);
724 AddOneReg("FF1" , 0x00e0, False); AddOneReg("INCF" , 0x00b0, False);
725 AddOneReg("INCT" , 0x00a0, False); AddOneReg("JMP" , 0x00c0, False);
726 AddOneReg("JSR" , 0x00d0, False); AddOneReg("LSLC" , 0x3c00, False);
727 AddOneReg("LSRC" , 0x3e00, False); AddOneReg("MVC" , 0x0020, False);
728 AddOneReg("MVCV" , 0x0030, False); AddOneReg("NOT" , 0x01f0, False);
729 AddOneReg("SEXTB" , 0x0150, False); AddOneReg("SEXTH", 0x0170, False);
730 AddOneReg("TSTNBZ", 0x0190, False); AddOneReg("XSR" , 0x3800, False);
731 AddOneReg("XTRB0" , 0x0130, False); AddOneReg("XTRB1", 0x0120, False);
732 AddOneReg("XTRB2" , 0x0110, False); AddOneReg("XTRB3", 0x0100, False);
733 AddOneReg("ZEXTB" , 0x0140, False); AddOneReg("ZEXTH", 0x0160, False);
734
735 InstrZ = 0; TwoRegOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * TwoRegOrderCnt);
736 AddTwoReg("ADDC" , 0x0600, False); AddTwoReg("ADDU" , 0x1c00, False);
737 AddTwoReg("AND" , 0x1600, False); AddTwoReg("ANDN" , 0x1f00, False);
738 AddTwoReg("ASR" , 0x1a00, False); AddTwoReg("BGENR", 0x1300, False);
739 AddTwoReg("CMPHS", 0x0c00, False); AddTwoReg("CMPLT", 0x0d00, False);
740 AddTwoReg("CMPNE", 0x0f00, False); AddTwoReg("IXH" , 0x1d00, False);
741 AddTwoReg("IXW" , 0x1500, False); AddTwoReg("LSL" , 0x1b00, False);
742 AddTwoReg("LSR" , 0x0b00, False); AddTwoReg("MOV" , 0x1200, False);
743 AddTwoReg("MOVF" , 0x0a00, False); AddTwoReg("MOVT" , 0x0200, False);
744 AddTwoReg("MULT" , 0x0300, False); AddTwoReg("OR" , 0x1e00, False);
745 AddTwoReg("RSUB" , 0x1400, False); AddTwoReg("SUBC" , 0x0700, False);
746 AddTwoReg("SUBU" , 0x0500, False); AddTwoReg("TST" , 0x0e00, False);
747 AddTwoReg("XOR" , 0x1700, False);
748
749 InstrZ = 0; UImm5Orders = (ImmOrder *) malloc(sizeof(ImmOrder) * UImm5OrderCnt);
750 AddUImm5("ADDI" , 0x2000, 0, 1); AddUImm5("ANDI" , 0x2e00, 0, 0);
751 AddUImm5("ASRI" , 0x3a00, 1, 0); AddUImm5("BCLRI" , 0x3000, 0, 0);
752 AddUImm5("BSETI" , 0x3400, 0, 0); AddUImm5("BTSTI" , 0x3600, 0, 0);
753 AddUImm5("CMPLTI", 0x2200, 0, 1); AddUImm5("CMPNEI", 0x2a00, 0, 0);
754 AddUImm5("LSLI" , 0x3c00, 1, 0); AddUImm5("LSRI" , 0x3e00, 1, 0);
755 AddUImm5("ROTLI" , 0x3800, 1, 0); AddUImm5("RSUBI" , 0x2800, 0, 0);
756 AddUImm5("SUBI" , 0x2400, 0, 1);
757
758 InstrZ = 0; LJmpOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * LJmpOrderCnt);
759 AddLJmp("BF" , 0xe800, False); AddLJmp("BR" , 0xf000, False);
760 AddLJmp("BSR" , 0xf800, False); AddLJmp("BT" , 0xe000, False);
761
762 InstrZ = 0; CRegs = (CReg *) malloc(sizeof(CReg) * CRegCnt);
763 AddCReg("PSR" , 0); AddCReg("VBR" , 1);
764 AddCReg("EPSR", 2); AddCReg("FPSR", 3);
765 AddCReg("EPC" , 4); AddCReg("FPC", 5);
766 AddCReg("SS0", 6); AddCReg("SS1", 7);
767 AddCReg("SS2", 8); AddCReg("SS3", 9);
768 AddCReg("SS4", 10); AddCReg("GCR", 11);
769 AddCReg("GSR", 12);
770
771 AddInstTable(InstTable, "BGENI" , 0, DecodeBGENI);
772 AddInstTable(InstTable, "BMASKI", 0, DecodeBMASKI);
773 AddInstTable(InstTable, "JMPI" , 0, DecodeSJmp);
774 AddInstTable(InstTable, "JSRI" , 0, DecodeSJmp);
775 AddInstTable(InstTable, "LD" , 0x0ff, DecodeLdSt);
776 AddInstTable(InstTable, "LDB" , 0x000, DecodeLdSt);
777 AddInstTable(InstTable, "LDH" , 0x001, DecodeLdSt);
778 AddInstTable(InstTable, "LDW" , 0x002, DecodeLdSt);
779 AddInstTable(InstTable, "ST" , 0x1ff, DecodeLdSt);
780 AddInstTable(InstTable, "STB" , 0x100, DecodeLdSt);
781 AddInstTable(InstTable, "STH" , 0x101, DecodeLdSt);
782 AddInstTable(InstTable, "STW" , 0x102, DecodeLdSt);
783 AddInstTable(InstTable, "LDM" , 0, DecodeLdStm);
784 AddInstTable(InstTable, "STM" , 1, DecodeLdStm);
785 AddInstTable(InstTable, "LDQ" , 0, DecodeLdStq);
786 AddInstTable(InstTable, "STQ" , 1, DecodeLdStq);
787 AddInstTable(InstTable, "LOOPT" , 0, DecodeLoopt);
788 AddInstTable(InstTable, "LRM" , 0, DecodeLrm);
789 AddInstTable(InstTable, "MFCR" , 0, DecodeMcr);
790 AddInstTable(InstTable, "MTCR" , 1, DecodeMcr);
791 AddInstTable(InstTable, "MOVI" , 0, DecodeMovi);
792 AddInstTable(InstTable, "TRAP" , 0, DecodeTrap);
793 }
794
DeinitFields(void)795 static void DeinitFields(void)
796 {
797 DestroyInstTable(InstTable);
798 free(FixedOrders);
799 free(OneRegOrders);
800 free(TwoRegOrders);
801 free(UImm5Orders);
802 free(LJmpOrders);
803 free(CRegs);
804 }
805
806 /*--------------------------------------------------------------------------*/
807 /* Callbacks */
808
809 /*!------------------------------------------------------------------------
810 * \fn InternSymbol_MCORE(char *pArg, TempResult *pResult)
811 * \brief handle built-in (register) symbols for M-CORE
812 * \param pArg source argument
813 * \param pResult buffer for possible result
814 * ------------------------------------------------------------------------ */
815
InternSymbol_MCORE(char * pArg,TempResult * pResult)816 static void InternSymbol_MCORE(char *pArg, TempResult *pResult)
817 {
818 Word RegNum;
819
820 if (DecodeRegCore(pArg, &RegNum))
821 {
822 pResult->Typ = TempReg;
823 pResult->DataSize = eSymbolSize32Bit;
824 pResult->Contents.RegDescr.Dissect = DissectReg_MCORE;
825 pResult->Contents.RegDescr.Reg = RegNum;
826 }
827 }
828
DecodeAttrPart_MCORE(void)829 static Boolean DecodeAttrPart_MCORE(void)
830 {
831 /* operand size identifiers slightly differ from '68K Standard': */
832
833 switch (as_toupper(*AttrPart.Str))
834 {
835 case 'H': AttrPartOpSize = eSymbolSize16Bit; break;
836 case 'W': AttrPartOpSize = eSymbolSize32Bit; break;
837 case 'L': WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); return False;
838 default:
839 return DecodeMoto16AttrSize(*AttrPart.Str, &AttrPartOpSize, False);
840 }
841 return True;
842 }
843
MakeCode_MCORE(void)844 static void MakeCode_MCORE(void)
845 {
846 CodeLen = 0;
847
848 OpSize = (AttrPartOpSize != eSymbolSizeUnknown) ? AttrPartOpSize : eSymbolSize32Bit;
849 DontPrint = False;
850
851 /* Nullanweisung */
852
853 if ((*OpPart.Str == '\0') && !*AttrPart.Str && (ArgCnt == 0)) return;
854
855 /* Pseudoanweisungen */
856
857 if (DecodeMoto16Pseudo(OpSize,True)) return;
858
859 /* Befehlszaehler ungerade ? */
860
861 if (Odd(EProgCounter())) WrError(ErrNum_AddrNotAligned);
862
863 /* alles aus der Tabelle */
864
865 if (!LookupInstTable(InstTable, OpPart.Str))
866 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
867 }
868
IsDef_MCORE(void)869 static Boolean IsDef_MCORE(void)
870 {
871 return Memo("REG");
872 }
873
SwitchFrom_MCORE(void)874 static void SwitchFrom_MCORE(void)
875 {
876 DeinitFields();
877 ClearONOFF();
878 }
879
SwitchTo_MCORE(void)880 static void SwitchTo_MCORE(void)
881 {
882 TurnWords = True; ConstMode = ConstModeMoto;
883
884 PCSymbol = "*"; HeaderID = 0x03; NOPCode = 0x1200; /* ==MOV r0,r0 */
885 DivideChars = ","; HasAttrs = True; AttrChars = ".";
886
887 ValidSegs = (1 << SegCode);
888 Grans[SegCode] = 1; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
889 SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
890
891 DecodeAttrPart = DecodeAttrPart_MCORE;
892 MakeCode = MakeCode_MCORE;
893 IsDef = IsDef_MCORE;
894 InternSymbol = InternSymbol_MCORE;
895 DissectReg = DissectReg_MCORE;
896
897 SwitchFrom = SwitchFrom_MCORE; InitFields();
898 AddONOFF("SUPMODE" , &SupAllowed, SupAllowedName, False);
899 AddMoto16PseudoONOFF();
900
901 SetFlag(&DoPadding, DoPaddingName, True);
902 }
903
904 /*--------------------------------------------------------------------------*/
905 /* Initialisierung */
906
codemcore_init(void)907 void codemcore_init(void)
908 {
909 CPUMCORE = AddCPU("MCORE", SwitchTo_MCORE);
910 }
911