Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

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