Subversion Repositories pentevo

Rev

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

  1. /* codexcore.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator XCore                                                       */
  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 "headids.h"
  24. #include "codepseudo.h"
  25. #include "intpseudo.h"
  26. #include "asmitree.h"
  27. #include "codevars.h"
  28. #include "errmsg.h"
  29.  
  30. #include "codexcore.h"
  31.  
  32. /*--------------------------------------------------------------------------*/
  33. /* Types */
  34.  
  35. typedef struct
  36. {
  37.   Word Opcode1, Opcode2;
  38. } lr2r_Order;
  39.  
  40. /*--------------------------------------------------------------------------*/
  41. /* Variables */
  42.  
  43. static CPUVar CPUXS1;
  44.  
  45. static lr2r_Order *lr2r_Orders;
  46.  
  47. /*--------------------------------------------------------------------------*/
  48. /* Common Decoder Subroutines */
  49.  
  50. static unsigned UpVal(unsigned Val1, unsigned Val3, unsigned Val9, unsigned Val27)
  51. {
  52.   return (((Val1 >> 2) & 3) * 1)
  53.        + (((Val3 >> 2) & 3) * 3)
  54.        + (((Val9 >> 2) & 3) * 9)
  55.        + (((Val27 >> 2) & 3) * 27);
  56. }
  57.  
  58. /*!------------------------------------------------------------------------
  59.  * \fn     ParseReg(const char *pArg, unsigned *pResult)
  60.  * \brief  check whether argument is a CPU register
  61.  * \param  pArg argument
  62.  * \param  pResult register number if yes
  63.  * \return True if yes
  64.  * ------------------------------------------------------------------------ */
  65.  
  66. static Boolean ParseReg(const char *pArg, unsigned *pResult)
  67. {
  68.   char *pEnd;
  69.  
  70.   if ((strlen(pArg) < 2) || (as_toupper(*pArg) != 'R'))
  71.     return False;
  72.  
  73.   *pResult = strtoul(pArg + 1, &pEnd, 10);
  74.   return (!*pEnd && (*pResult <= 11));
  75. }
  76.  
  77. /*!------------------------------------------------------------------------
  78.  * \fn     DissectReg_XCore(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  79.  * \brief  dissect register symbols - XCORE variant
  80.  * \param  pDest destination buffer
  81.  * \param  DestSize destination buffer size
  82.  * \param  Value numeric register value
  83.  * \param  InpSize register size
  84.  * ------------------------------------------------------------------------ */
  85.  
  86. static void DissectReg_XCore(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  87. {
  88.   switch (InpSize)
  89.   {
  90.     case eSymbolSize8Bit:
  91.       as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  92.       break;
  93.     default:
  94.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  95.   }
  96. }
  97.  
  98. /*!------------------------------------------------------------------------
  99.  * \fn     ParseArgReg(int Index, unsigned *pResult, Boolean MustBeReg)
  100.  * \brief  check whether argument is a CPU register or register alias
  101.  * \param  Index index of argument
  102.  * \param  register number if yes
  103.  * \param  MustBeReg expecting register as argument
  104.  * \return register eval result
  105.  * ------------------------------------------------------------------------ */
  106.  
  107. static tRegEvalResult ParseArgReg(int Index, unsigned *pResult, Boolean MustBeReg)
  108. {
  109.   tRegDescr RegDescr;
  110.   tEvalResult EvalResult;
  111.   tRegEvalResult RegEvalResult;
  112.  
  113.   if (ParseReg(ArgStr[Index].str.p_str, pResult))
  114.     return eIsReg;
  115.  
  116.   RegEvalResult = EvalStrRegExpressionAsOperand(&ArgStr[Index], &RegDescr, &EvalResult, eSymbolSize8Bit, MustBeReg);
  117.   *pResult = RegDescr.Reg;
  118.   return RegEvalResult;
  119. }
  120.  
  121. /*--------------------------------------------------------------------------*/
  122. /* Instruction Decoders */
  123.  
  124. static void Code_3r(Word Index)
  125. {
  126.   unsigned Op1, Op2, Op3;
  127.  
  128.   if (ChkArgCnt(3, 3)
  129.    && ParseArgReg(1, &Op1, True)
  130.    && ParseArgReg(2, &Op2, True)
  131.    && ParseArgReg(3, &Op3, True))
  132.   {
  133.     WAsmCode[0] = Index
  134.                 | ((Op3 & 3) << 0)
  135.                 | ((Op2 & 3) << 2)
  136.                 | ((Op1 & 3) << 4)
  137.                 | (UpVal(Op3, Op2, Op1, 0) << 6);
  138.     CodeLen = 2;
  139.   }
  140. }
  141.  
  142. static void Code_2rus(Word Index)
  143. {
  144.   unsigned Op1, Op2, Op3;
  145.   Boolean OK;
  146.  
  147.   if (ChkArgCnt(3, 3)
  148.    && ParseArgReg(1, &Op1, True)
  149.    && ParseArgReg(2, &Op2, True))
  150.   {
  151.     tSymbolFlags Flags;
  152.  
  153.     Op3 = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt4, &OK, &Flags);
  154.     if (mFirstPassUnknown(Flags))
  155.       Op3 &= 7;
  156.     if (OK)
  157.     {
  158.       if (Op3 > 11) WrStrErrorPos(ErrNum_OverRange, &ArgStr[3]);
  159.       else
  160.       {
  161.         WAsmCode[0] = Index
  162.                     | ((Op3 & 3) << 0)
  163.                     | ((Op2 & 3) << 2)
  164.                     | ((Op1 & 3) << 4)
  165.                     | (UpVal(Op3, Op2, Op1, 0) << 6);
  166.         CodeLen = 2;
  167.       }
  168.     }
  169.   }
  170. }
  171.  
  172. static void Code_2r(Word Index)
  173. {
  174.   unsigned Op1, Op2;
  175.  
  176.   if (ChkArgCnt(2, 2)
  177.    && ParseArgReg(1, &Op1, True)
  178.    && ParseArgReg(2, &Op2, True))
  179.   {
  180.     unsigned Up = UpVal(Op2, Op1, 0, 0) + 27;
  181.  
  182.     WAsmCode[0] = Index
  183.                 | ((Op2 & 3) << 0)
  184.                 | ((Op1 & 3) << 2)
  185.                 | ((Up & 0x1f) << 6)
  186.                 | (Up & 0x20);
  187.     CodeLen = 2;
  188.   }
  189. }
  190.  
  191. static void Code_l3r(Word Index)
  192. {
  193.   unsigned Op1, Op2, Op3;
  194.  
  195.   if (ChkArgCnt(3, 3)
  196.    && ParseArgReg(1, &Op1, True)
  197.    && ParseArgReg(2, &Op2, True)
  198.    && ParseArgReg(3, &Op3, True))
  199.   {
  200.     WAsmCode[0] = 0xf800
  201.                 | ((Op3 & 3) << 0)
  202.                 | ((Op2 & 3) << 2)
  203.                 | ((Op1 & 3) << 4)
  204.                 | (UpVal(Op3, Op2, Op1, 0) << 6);
  205.     WAsmCode[1] = Index;
  206.     CodeLen = 4;
  207.   }
  208. }
  209.  
  210. static void Code_l2rus(Word Index)
  211. {
  212.   unsigned Op1, Op2, Op3;
  213.   Boolean OK;
  214.  
  215.   if (ChkArgCnt(3, 3)
  216.    && ParseArgReg(1, &Op1, True)
  217.    && ParseArgReg(2, &Op2, True))
  218.   {
  219.     tSymbolFlags Flags;
  220.  
  221.     Op3 = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt4, &OK, &Flags);
  222.     if (mFirstPassUnknown(Flags))
  223.       Op3 &= 7;
  224.     if (OK)
  225.     {
  226.       if (Op3 > 11) WrStrErrorPos(ErrNum_OverRange, &ArgStr[3]);
  227.       else
  228.       {
  229.         WAsmCode[0] = 0xf800
  230.                     | ((Op3 & 3) << 0)
  231.                     | ((Op2 & 3) << 2)
  232.                     | ((Op1 & 3) << 4)
  233.                     | (UpVal(Op3, Op2, Op1, 0) << 6);
  234.         WAsmCode[1] = Index;
  235.         CodeLen = 4;
  236.       }
  237.     }
  238.   }
  239. }
  240.  
  241. static void Code_1r(Word Index)
  242. {
  243.   unsigned Op1;
  244.  
  245.   if (ChkArgCnt(1, 1) && ParseArgReg(1, &Op1, True))
  246.   {
  247.     WAsmCode[0] = Index | Op1;
  248.     CodeLen = 2;
  249.   }
  250. }
  251.  
  252. static void Code_l2r(Word Index)
  253. {
  254.   unsigned Op1, Op2;
  255.  
  256.   if (ChkArgCnt(2, 2)
  257.    && ParseArgReg(1, &Op1, True)
  258.    && ParseArgReg(2, &Op2, True))
  259.   {
  260.     unsigned Up = UpVal(Op2, Op1, 0, 0) + 27;
  261.  
  262.     WAsmCode[0] = 0xf800 | ((Index & 1) << 4)
  263.                 | ((Op2 & 3) << 0)
  264.                 | ((Op1 & 3) << 2)
  265.                 | ((Up & 0x1f) << 6)
  266.                 | (Up & 0x20);
  267.     WAsmCode[1] = Index & (~1);
  268.     CodeLen = 4;
  269.   }
  270. }
  271.  
  272. static void Code_u10(Word Index)
  273. {
  274.   if (ChkArgCnt(1, 1))
  275.   {
  276.     LongWord Op1;
  277.     Boolean OK;
  278.  
  279.     Op1 = EvalStrIntExpression(&ArgStr[1], UInt20, &OK);
  280.     if (OK)
  281.     {
  282.       if (Op1 > 0x3ff)
  283.       {
  284.         WAsmCode[CodeLen >> 1] = 0xf000 | ((Op1 >> 10) & 0x3ff);
  285.         CodeLen += 2;
  286.       }
  287.       WAsmCode[CodeLen >> 1] = Index | (Op1 & 0x3ff);
  288.       CodeLen += 2;
  289.     }
  290.   }
  291. }
  292.  
  293. static void Code_u6(Word Index)
  294. {
  295.   if (!ChkArgCnt(1, 1));
  296.   else
  297.   {
  298.     LongWord Op1;
  299.     Boolean OK;
  300.  
  301.     Op1 = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);
  302.     if (OK)
  303.     {
  304.       if (Op1 > 0x3f)
  305.       {
  306.         WAsmCode[CodeLen >> 1] = 0xf000 | ((Op1 >> 6) & 0x3ff);
  307.         CodeLen += 2;
  308.       }
  309.       WAsmCode[CodeLen >> 1] = Index | (Op1 & 0x3f);
  310.       CodeLen += 2;
  311.     }
  312.   }
  313. }
  314.  
  315. static void Code_ru6(Word Index)
  316. {
  317.   unsigned Op1;
  318.  
  319.   if (ChkArgCnt(2, 2) && ParseArgReg(1, &Op1, True))
  320.   {
  321.     LongWord Op2;
  322.     Boolean OK;
  323.  
  324.     Op2 = EvalStrIntExpression(&ArgStr[2], UInt16, &OK);
  325.     if (OK)
  326.     {
  327.       if (Op2 > 0x3f)
  328.       {
  329.         WAsmCode[CodeLen >> 1] = 0xf000 | ((Op2 >> 6) & 0x3ff);
  330.         CodeLen += 2;
  331.       }
  332.       WAsmCode[CodeLen >> 1] = Index | (Op1 << 6) | (Op2 & 0x3f);
  333.       CodeLen += 2;
  334.     }
  335.   }
  336. }
  337.  
  338. static void Code_rus(Word Index)
  339. {
  340.   unsigned Op1;
  341.  
  342.   if (ChkArgCnt(2, 2) && ParseArgReg(1, &Op1, True))
  343.   {
  344.     unsigned Op2;
  345.     Boolean OK;
  346.     tSymbolFlags Flags;
  347.  
  348.     Op2 = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt4, &OK, &Flags);
  349.     if (mFirstPassUnknown(Flags))
  350.       Op2 &= 7;
  351.     if (OK)
  352.     {
  353.       if (Op2 > 11) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  354.       else
  355.       {
  356.         unsigned Up = UpVal(Op2, Op1, 0, 0) + 27;
  357.  
  358.         WAsmCode[0] = Index
  359.                     | ((Op2 & 3) << 0)
  360.                     | ((Op1 & 3) << 2)
  361.                     | ((Up & 0x1f) << 6)
  362.                     | (Up & 0x20);
  363.         CodeLen = 2;
  364.       }
  365.     }
  366.   }
  367. }
  368.  
  369. static void Code_0r(Word Index)
  370. {
  371.   if (ChkArgCnt(0, 0))
  372.   {
  373.     WAsmCode[0] = Index;
  374.     CodeLen = 2;
  375.   }
  376. }
  377.  
  378. static void Code_l4r(Word Index)
  379. {
  380.   unsigned Op1, Op2, Op3, Op4;
  381.  
  382.   if (ChkArgCnt(4, 4)
  383.    && ParseArgReg(1, &Op1, True)
  384.    && ParseArgReg(2, &Op2, True)
  385.    && ParseArgReg(3, &Op3, True)
  386.    && ParseArgReg(4, &Op4, True))
  387.   {
  388.     WAsmCode[0] = 0xf800
  389.                 | ((Op3 & 3) << 0)
  390.                 | ((Op2 & 3) << 2)
  391.                 | ((Op1 & 3) << 4)
  392.                 | (UpVal(Op3, Op2, Op1, 0) << 6);
  393.     WAsmCode[1] = Index | Op4;
  394.     CodeLen = 4;
  395.   }
  396. }
  397.  
  398. static void Code_l5r(Word Index)
  399. {
  400.   unsigned Op1, Op2, Op3, Op4, Op5;
  401.  
  402.   if (ChkArgCnt(5, 5)
  403.    && ParseArgReg(1, &Op1, True)
  404.    && ParseArgReg(2, &Op4, True)
  405.    && ParseArgReg(3, &Op2, True)
  406.    && ParseArgReg(4, &Op3, True)
  407.    && ParseArgReg(5, &Op5, True))
  408.   {
  409.     unsigned Up = UpVal(Op5, Op4, 0, 0) + 27;
  410.     WAsmCode[0] = 0xf800
  411.                 | ((Op3 & 3) << 0)
  412.                 | ((Op2 & 3) << 2)
  413.                 | ((Op1 & 3) << 4)
  414.                 | (UpVal(Op3, Op2, Op1, 0) << 6);
  415.     WAsmCode[1] = Index
  416.                 | ((Op5 & 3) << 0)
  417.                 | ((Op4 & 3) << 2)
  418.                 | ((Up & 0x1f) << 6)
  419.                 | (Up & 0x20);
  420.     CodeLen = 4;
  421.   }
  422. }
  423.  
  424. static void Code_l6r(Word Index)
  425. {
  426.   unsigned Op1, Op2, Op3, Op4, Op5, Op6;
  427.  
  428.   if (ChkArgCnt(6, 6)
  429.    && ParseArgReg(1, &Op1, True)
  430.    && ParseArgReg(2, &Op4, True)
  431.    && ParseArgReg(3, &Op2, True)
  432.    && ParseArgReg(4, &Op3, True)
  433.    && ParseArgReg(5, &Op5, True)
  434.    && ParseArgReg(6, &Op6, True))
  435.   {
  436.     WAsmCode[0] = 0xf800
  437.                 | ((Op3 & 3) << 0)
  438.                 | ((Op2 & 3) << 2)
  439.                 | ((Op1 & 3) << 4)
  440.                 | (UpVal(Op3, Op2, Op1, 0) << 6);
  441.     WAsmCode[1] = Index
  442.                 | ((Op6 & 3) << 0)
  443.                 | ((Op5 & 3) << 2)
  444.                 | ((Op4 & 3) << 4)
  445.                 | (UpVal(Op6, Op5, Op4, 0) << 6);
  446.     CodeLen = 4;
  447.   }
  448. }
  449.  
  450. static void Code_branch_core(Word Code, int DistArgIndex)
  451. {
  452.   LongInt Delta;
  453.   Boolean OK;
  454.   tSymbolFlags Flags;
  455.  
  456.   /* assume short branch for distance computation */
  457.  
  458.   Delta = EvalStrIntExpressionWithFlags(&ArgStr[DistArgIndex], UInt32, &OK, &Flags) - (EProgCounter() + 2);
  459.   if (mFirstPassUnknown(Flags))
  460.     Delta &= 0x1fffe;
  461.  
  462.   /* distance must be even */
  463.  
  464.   if (Delta & 1) WrError(ErrNum_NotAligned);
  465.  
  466.   /* short branch possible? */
  467.  
  468.   else if ((Delta >= -126) && (Delta <= 126))
  469.   {
  470.     Delta /= 2;
  471.     WAsmCode[0] = Code;
  472.     if (Delta < 0)
  473.     {
  474.       WAsmCode[0] |= 0x0400;
  475.       Delta = -Delta;
  476.     }
  477.     WAsmCode[0] |= Delta & 0x3f;
  478.     CodeLen = 2;
  479.   }
  480.  
  481.   /* must use long: */
  482.  
  483.   else
  484.   {
  485.     /* correct delta for longer instruction */
  486.  
  487.     Delta -= 2;
  488.     if ((Delta < -131070) || (Delta >= 131070)) WrError(ErrNum_JmpDistTooBig);
  489.     else
  490.     {
  491.       Delta /= 2;
  492.       WAsmCode[1] = Code;
  493.       if (Delta < 0)
  494.       {
  495.         WAsmCode[1] |= 0x0400;
  496.         Delta = -Delta;
  497.       }
  498.       WAsmCode[1] |= Delta & 0x3f;
  499.       WAsmCode[0] = 0xf00 | ((Delta >> 6) & 0x3ff);
  500.       CodeLen = 4;
  501.     }
  502.   }
  503. }
  504.  
  505. static void Code_BRU(Word Index)
  506. {
  507.   unsigned Op1;
  508.  
  509.   UNUSED(Index);
  510.  
  511.   if (ChkArgCnt(1, 1))
  512.   {
  513.     switch (ParseArgReg(1, &Op1, False))
  514.     {
  515.       case eIsReg:
  516.         WAsmCode[0] = 0x2fe0 | Op1;
  517.         CodeLen = 2;
  518.         break;
  519.       case eIsNoReg:
  520.         Code_branch_core(0x7300, 1);
  521.         break;
  522.       case eRegAbort:
  523.         break;
  524.     }
  525.   }
  526. }
  527.  
  528. static void Code_cbranch(Word Index)
  529. {
  530.   unsigned Op1;
  531.  
  532.   if (ChkArgCnt(2, 2) && ParseArgReg(1, &Op1, True))
  533.     Code_branch_core(Index | (Op1 << 6), 2);
  534. }
  535.  
  536. static void Code_r2r(Word Index)
  537. {
  538.   unsigned Op1, Op2;
  539.  
  540.   if (ChkArgCnt(2, 2)
  541.    && ParseArgReg(1, &Op1, True)
  542.    && ParseArgReg(2, &Op2, True))
  543.   {
  544.     unsigned Up = UpVal(Op1, Op2, 0, 0) + 27;
  545.  
  546.     WAsmCode[0] = Index
  547.                 | ((Op1 & 3) << 0)
  548.                 | ((Op2 & 3) << 2)
  549.                 | ((Up & 0x1f) << 6)
  550.                 | (Up & 0x20);
  551.     CodeLen = 2;
  552.   }
  553. }
  554.  
  555. static void Code_lr2r(Word Index)
  556. {
  557.   unsigned Op1, Op2;
  558.   lr2r_Order *pOrder = lr2r_Orders + Index;
  559.  
  560.   if (ChkArgCnt(2, 2)
  561.    && ParseArgReg(1, &Op1, True)
  562.    && ParseArgReg(2, &Op2, True))
  563.   {
  564.     unsigned Up = UpVal(Op1, Op2, 0, 0) + 27;
  565.  
  566.     WAsmCode[0] = pOrder->Opcode1
  567.                 | ((Op1 & 3) << 0)
  568.                 | ((Op2 & 3) << 2)
  569.                 | ((Up & 0x1f) << 6)
  570.                 | (Up & 0x20);
  571.     WAsmCode[1] = pOrder->Opcode2;
  572.     CodeLen = 4;
  573.   }
  574. }
  575.  
  576. /*--------------------------------------------------------------------------*/
  577. /* Dynamic Code Table Handling */
  578.  
  579. static void Add_lr2r(const char *NName, Word NCode1, Word NCode2)
  580. {
  581.   order_array_rsv_end(lr2r_Orders, lr2r_Order);
  582.   lr2r_Orders[InstrZ].Opcode1 = NCode1;
  583.   lr2r_Orders[InstrZ].Opcode2 = NCode2;
  584.   AddInstTable(InstTable, NName, InstrZ++, Code_lr2r);
  585. }
  586.  
  587. static void InitFields(void)
  588. {
  589.   InstTable = CreateInstTable(207);
  590.  
  591.   AddInstTable(InstTable, "REG", 0, CodeREG);
  592.  
  593.   AddInstTable(InstTable, "ADD"    , 0x1000, Code_3r);
  594.   AddInstTable(InstTable, "AND"    , 0x3800, Code_3r);
  595.   AddInstTable(InstTable, "EQ"     , 0x3000, Code_3r);
  596.   AddInstTable(InstTable, "LD16S"  , 0x8000, Code_3r);
  597.   AddInstTable(InstTable, "LD8U"   , 0x8800, Code_3r);
  598.   AddInstTable(InstTable, "LDW"    , 0x4800, Code_3r);
  599.   AddInstTable(InstTable, "LSS"    , 0xc000, Code_3r);
  600.   AddInstTable(InstTable, "LSU"    , 0xc800, Code_3r);
  601.   AddInstTable(InstTable, "OR"     , 0x4000, Code_3r);
  602.   AddInstTable(InstTable, "SHL"    , 0x2000, Code_3r);
  603.   AddInstTable(InstTable, "SHR"    , 0x2800, Code_3r);
  604.   AddInstTable(InstTable, "SUB"    , 0x1800, Code_3r);
  605.   AddInstTable(InstTable, "TSETR"  , 0xb800, Code_3r);
  606.  
  607.   AddInstTable(InstTable, "ADDI"   , 0x9000, Code_2rus);
  608.   AddInstTable(InstTable, "EQI"    , 0xb000, Code_2rus);
  609.   AddInstTable(InstTable, "LDWI"   , 0x0800, Code_2rus);
  610.   AddInstTable(InstTable, "SHLI"   , 0xa000, Code_2rus);
  611.   AddInstTable(InstTable, "SHRI"   , 0xa800, Code_2rus);
  612.   AddInstTable(InstTable, "STWI"   , 0x0000, Code_2rus);
  613.   AddInstTable(InstTable, "SUBI"   , 0x9800, Code_2rus);
  614.  
  615.   AddInstTable(InstTable, "ANDNOT" , 0x2800, Code_2r);
  616.   AddInstTable(InstTable, "CHKCT"  , 0xc800, Code_2r);
  617.   AddInstTable(InstTable, "EEF"    , 0x2810, Code_2r);
  618.   AddInstTable(InstTable, "EET"    , 0x2010, Code_2r);
  619.   AddInstTable(InstTable, "ENDIN"  , 0x9010, Code_2r);
  620.   AddInstTable(InstTable, "GETST"  , 0x0010, Code_2r);
  621.   AddInstTable(InstTable, "GETTS"  , 0x3800, Code_2r);
  622.   AddInstTable(InstTable, "IN"     , 0xb000, Code_2r);
  623.   AddInstTable(InstTable, "INCT"   , 0x8010, Code_2r);
  624.   AddInstTable(InstTable, "INSHR"  , 0xb010, Code_2r);
  625.   AddInstTable(InstTable, "INT"    , 0x8810, Code_2r);
  626.   AddInstTable(InstTable, "MKMSK"  , 0xa000, Code_2r);
  627.   AddInstTable(InstTable, "NEG"    , 0x9000, Code_2r);
  628.   AddInstTable(InstTable, "NOT"    , 0x8800, Code_2r);
  629.   AddInstTable(InstTable, "OUTCT"  , 0x4800, Code_2r);
  630.   AddInstTable(InstTable, "PEEK"   , 0xb800, Code_2r);
  631.   AddInstTable(InstTable, "SEXT"   , 0x3000, Code_2r);
  632.   AddInstTable(InstTable, "TESTCT" , 0xb810, Code_2r);
  633.   AddInstTable(InstTable, "TESTWCT", 0xc010, Code_2r);
  634.   AddInstTable(InstTable, "TINITCP", 0x1800, Code_2r);
  635.   AddInstTable(InstTable, "TINITDP", 0x0800, Code_2r);
  636.   AddInstTable(InstTable, "TINITPC", 0x0000, Code_2r);
  637.   AddInstTable(InstTable, "TINITSP", 0x1000, Code_2r);
  638.   AddInstTable(InstTable, "TSETMR" , 0x1810, Code_2r);
  639.   AddInstTable(InstTable, "ZEXT"   , 0x4000, Code_2r);
  640.  
  641.   AddInstTable(InstTable, "ASHR"   , 0x17ec, Code_l3r);
  642.   AddInstTable(InstTable, "LDA16F" , 0x2fec, Code_l3r);
  643.   AddInstTable(InstTable, "REMU"   , 0xcfec, Code_l3r);
  644.   AddInstTable(InstTable, "CRC"    , 0xafec, Code_l3r);
  645.   AddInstTable(InstTable, "LDAWB"  , 0x27ec, Code_l3r);
  646.   AddInstTable(InstTable, "ST16"   , 0x87ec, Code_l3r);
  647.   AddInstTable(InstTable, "DIVS"   , 0x47ec, Code_l3r);
  648.   AddInstTable(InstTable, "LDAWF"  , 0x1fec, Code_l3r);
  649.   AddInstTable(InstTable, "ST8"    , 0x8fec, Code_l3r);
  650.   AddInstTable(InstTable, "DIVU"   , 0x4fec, Code_l3r);
  651.   AddInstTable(InstTable, "MUL"    , 0x3fec, Code_l3r);
  652.   AddInstTable(InstTable, "STW"    , 0x07ec, Code_l3r);
  653.   AddInstTable(InstTable, "LDA16B" , 0x37ec, Code_l3r);
  654.   AddInstTable(InstTable, "REMS"   , 0xc7ec, Code_l3r);
  655.   AddInstTable(InstTable, "XOR"    , 0x0fec, Code_l3r);
  656.  
  657.   AddInstTable(InstTable, "ASHRI"  , 0x97ec, Code_l2rus);
  658.   AddInstTable(InstTable, "LDAWBI" , 0xa7ec, Code_l2rus);
  659.   AddInstTable(InstTable, "OUTPW"  , 0x97ed, Code_l2rus);
  660.   AddInstTable(InstTable, "INPW"   , 0x97ee, Code_l2rus);
  661.   AddInstTable(InstTable, "LDAWFI" , 0x9fec, Code_l2rus);
  662.  
  663.   AddInstTable(InstTable, "BAU"    , 0x27f0, Code_1r);
  664.   AddInstTable(InstTable, "EEU"    , 0x07f0, Code_1r);
  665.   AddInstTable(InstTable, "SETSP"  , 0x2ff0, Code_1r);
  666.   AddInstTable(InstTable, "BLA"    , 0x27e0, Code_1r);
  667.   AddInstTable(InstTable, "FREER"  , 0x17e0, Code_1r);
  668.   AddInstTable(InstTable, "SETV"   , 0x47f0, Code_1r);
  669.   AddInstTable(InstTable, "KCALL"  , 0x27e0, Code_1r);
  670.   AddInstTable(InstTable, "SYNCR"  , 0x87f0, Code_1r);
  671.   AddInstTable(InstTable, "CLRPT"  , 0x87e0, Code_1r);
  672.   AddInstTable(InstTable, "MJOIN"  , 0x17f0, Code_1r);
  673.   AddInstTable(InstTable, "TSTART" , 0x1fe0, Code_1r);
  674.   AddInstTable(InstTable, "DGETREG", 0x3fe0, Code_1r);
  675.   AddInstTable(InstTable, "MSYNC"  , 0x1ff0, Code_1r);
  676.   AddInstTable(InstTable, "WAITEF" , 0x0ff0, Code_1r);
  677.   AddInstTable(InstTable, "ECALLF" , 0x4fe0, Code_1r);
  678.   AddInstTable(InstTable, "SETCP"  , 0x37f0, Code_1r);
  679.   AddInstTable(InstTable, "WAITET" , 0x0fe0, Code_1r);
  680.   AddInstTable(InstTable, "ECALLT" , 0x4ff0, Code_1r);
  681.   AddInstTable(InstTable, "SETDP"  , 0x37e0, Code_1r);
  682.   AddInstTable(InstTable, "EDU"    , 0x07e0, Code_1r);
  683.   AddInstTable(InstTable, "SETEV"  , 0x3ff0, Code_1r);
  684.  
  685.   AddInstTable(InstTable, "BITREV" , 0x07ec | 0, Code_l2r);
  686.   AddInstTable(InstTable, "GETD"   , 0x1fec | 1, Code_l2r);
  687.   AddInstTable(InstTable, "SETC"   , 0x2fec | 1, Code_l2r);
  688.   AddInstTable(InstTable, "BYTEREV", 0x07ec | 1, Code_l2r);
  689.   AddInstTable(InstTable, "GETN"   , 0x37ec | 1, Code_l2r);
  690.   AddInstTable(InstTable, "TESTLCL", 0x27ec | 0, Code_l2r);
  691.   AddInstTable(InstTable, "CLZ"    , 0x0fec | 0, Code_l2r);
  692.   AddInstTable(InstTable, "GETPS"  , 0x17ec | 1, Code_l2r);
  693.   AddInstTable(InstTable, "TINITLR", 0x17ec | 1, Code_l2r);
  694.  
  695.   AddInstTable(InstTable, "BLACP"  , 0xe000, Code_u10);
  696.   AddInstTable(InstTable, "BLRF"   , 0xd000, Code_u10);
  697.   AddInstTable(InstTable, "LDAPF"  , 0xd800, Code_u10);
  698.   AddInstTable(InstTable, "BLRB"   , 0xd400, Code_u10);
  699.   AddInstTable(InstTable, "LDAPB"  , 0xdc00, Code_u10);
  700.   AddInstTable(InstTable, "LDWCPL" , 0xe400, Code_u10);
  701.  
  702.   AddInstTable(InstTable, "BLAT"   , 0x7340, Code_u6);
  703.   AddInstTable(InstTable, "EXTDP"  , 0x7380, Code_u6);
  704.   AddInstTable(InstTable, "KRESTSP", 0x7bc0, Code_u6);
  705.   AddInstTable(InstTable, "BRBU"   , 0x7700, Code_u6);
  706.   AddInstTable(InstTable, "EXTSP"  , 0x7780, Code_u6);
  707.   AddInstTable(InstTable, "LDAWCP" , 0x7f40, Code_u6);
  708.   AddInstTable(InstTable, "BRFU"   , 0x7300, Code_u6);
  709.   AddInstTable(InstTable, "GETSR"  , 0x7f00, Code_u6);
  710.   AddInstTable(InstTable, "RETSP"  , 0x77c0, Code_u6);
  711.   AddInstTable(InstTable, "CLRSR"  , 0x7b00, Code_u6);
  712.   AddInstTable(InstTable, "KCALLI" , 0x73c0, Code_u6);
  713.   AddInstTable(InstTable, "SETSR"  , 0x7b40, Code_u6);
  714.   AddInstTable(InstTable, "ENTSP"  , 0x7740, Code_u6);
  715.   AddInstTable(InstTable, "KENTSP" , 0x7b80, Code_u6);
  716.  
  717.   AddInstTable(InstTable, "BRBF"   , 0x7c00, Code_ru6);
  718.   AddInstTable(InstTable, "LDAWSP" , 0x6400, Code_ru6);
  719.   AddInstTable(InstTable, "SETCI"  , 0xe800, Code_ru6);
  720.   AddInstTable(InstTable, "BRBT"   , 0x7400, Code_ru6);
  721.   AddInstTable(InstTable, "LDC"    , 0x6800, Code_ru6);
  722.   AddInstTable(InstTable, "STWDP"  , 0x5000, Code_ru6);
  723.   AddInstTable(InstTable, "BRFF"   , 0x7800, Code_ru6);
  724.   AddInstTable(InstTable, "LDWCP"  , 0x6c00, Code_ru6);
  725.   AddInstTable(InstTable, "STWSP"  , 0x5400, Code_ru6);
  726.   AddInstTable(InstTable, "BRFT"   , 0x7000, Code_ru6);
  727.   AddInstTable(InstTable, "LDWDP"  , 0x5800, Code_ru6);
  728.   AddInstTable(InstTable, "LDAWDP" , 0x6000, Code_ru6);
  729.   AddInstTable(InstTable, "LDWSP"  , 0x5c00, Code_ru6);
  730.  
  731.   AddInstTable(InstTable, "CHKCTI" , 0xc810, Code_rus);
  732.   AddInstTable(InstTable, "MKMSKI" , 0xa010, Code_rus);
  733.   AddInstTable(InstTable, "SEXTI"  , 0x3010, Code_rus);
  734.   AddInstTable(InstTable, "GETR"   , 0x8000, Code_rus);
  735.   AddInstTable(InstTable, "OUTCTI" , 0x4810, Code_rus);
  736.   AddInstTable(InstTable, "ZEXTI"  , 0x4010, Code_rus);
  737.  
  738.   AddInstTable(InstTable, "CLRE"   , 0x07ed, Code_0r);
  739.   AddInstTable(InstTable, "GETID"  , 0x17ee, Code_0r);
  740.   AddInstTable(InstTable, "SETKEP" , 0x07ff, Code_0r);
  741.   AddInstTable(InstTable, "DCALL"  , 0x07fc, Code_0r);
  742.   AddInstTable(InstTable, "GETKEP" , 0x17ef, Code_0r);
  743.   AddInstTable(InstTable, "SSYNC"  , 0x07ee, Code_0r);
  744.   AddInstTable(InstTable, "DENTSP" , 0x17ec, Code_0r);
  745.   AddInstTable(InstTable, "GETKSP" , 0x17fc, Code_0r);
  746.   AddInstTable(InstTable, "STET"   , 0x0ffd, Code_0r);
  747.   AddInstTable(InstTable, "DRESTSP", 0x17ed, Code_0r);
  748.   AddInstTable(InstTable, "KRET"   , 0x07fd, Code_0r);
  749.   AddInstTable(InstTable, "STSED"  , 0x0ffc, Code_0r);
  750.   AddInstTable(InstTable, "DRET"   , 0x07fe, Code_0r);
  751.   AddInstTable(InstTable, "LDET"   , 0x17fe, Code_0r);
  752.   AddInstTable(InstTable, "STSPC"  , 0x0fed, Code_0r);
  753.   AddInstTable(InstTable, "FREET"  , 0x07ef, Code_0r);
  754.   AddInstTable(InstTable, "LDSED"  , 0x17fd, Code_0r);
  755.   AddInstTable(InstTable, "STSSR"  , 0x0fef, Code_0r);
  756.   AddInstTable(InstTable, "GETED"  , 0x0ffe, Code_0r);
  757.   AddInstTable(InstTable, "LDSPC"  , 0x0fec, Code_0r);
  758.   AddInstTable(InstTable, "WAITEU" , 0x07ec, Code_0r);
  759.   AddInstTable(InstTable, "GETET"  , 0x0fff, Code_0r);
  760.   AddInstTable(InstTable, "LDSSR"  , 0x0fee, Code_0r);
  761.  
  762.   AddInstTable(InstTable, "CRC8"   , 0x07e0, Code_l4r);
  763.   AddInstTable(InstTable, "MACCS"  , 0x0fe0, Code_l4r);
  764.   AddInstTable(InstTable, "MACCU"  , 0x07f0, Code_l4r);
  765.  
  766.   AddInstTable(InstTable, "LADD"   , 0x0010, Code_l5r);
  767.   AddInstTable(InstTable, "LDIVU"  , 0x0000, Code_l5r);
  768.   AddInstTable(InstTable, "LSUB"   , 0x0100, Code_l5r);
  769.  
  770.   AddInstTable(InstTable, "LMUL"   , 0x0000, Code_l6r);
  771.  
  772.   AddInstTable(InstTable, "OUT"    , 0xa800, Code_r2r);
  773.   AddInstTable(InstTable, "OUTT"   , 0x0810, Code_r2r);
  774.   AddInstTable(InstTable, "SETPSC" , 0xc000, Code_r2r);
  775.   AddInstTable(InstTable, "OUTSHR" , 0xa810, Code_r2r);
  776.   AddInstTable(InstTable, "SETD"   , 0x1010, Code_r2r);
  777.   AddInstTable(InstTable, "SETPT"  , 0x3810, Code_r2r);
  778.  
  779.  
  780.   InstrZ = 0;
  781.   Add_lr2r("SETCLK"  , 0xf810, 0x0fec);
  782.   Add_lr2r("SETPS"   , 0xf800, 0x1fec);
  783.   Add_lr2r("SETTW"   , 0xf810, 0x27ec);
  784.   Add_lr2r("SETN"    , 0xf800, 0x37ec);
  785.   Add_lr2r("SETRDY"  , 0xf800, 0x2fec);
  786.  
  787.   AddInstTable(InstTable, "BRU"    , 0x7300, Code_BRU);
  788.   AddInstTable(InstTable, "BRF"    , 0x7800, Code_cbranch);
  789.   AddInstTable(InstTable, "BRT"    , 0x7000, Code_cbranch);
  790. }
  791.  
  792. static void DeinitFields(void)
  793. {
  794.   DestroyInstTable(InstTable);
  795.   order_array_free(lr2r_Orders);
  796. }
  797.  
  798. /*--------------------------------------------------------------------------*/
  799. /* Callbacks */
  800.  
  801. static void MakeCode_XCore(void)
  802. {
  803.   CodeLen = 0;
  804.  
  805.   DontPrint = False;
  806.  
  807.   /* Null Instruction */
  808.  
  809.   if ((*OpPart.str.p_str == '\0') && (ArgCnt == 0))
  810.     return;
  811.  
  812.   /* Pseudo Instructions */
  813.  
  814.   if (DecodeIntelPseudo(True))
  815.     return;
  816.  
  817.   /* Odd Program Counter ? */
  818.  
  819.   if (Odd(EProgCounter())) WrError(ErrNum_AddrNotAligned);
  820.  
  821.   /* everything from hash table */
  822.  
  823.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  824.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  825. }
  826.  
  827. /*!------------------------------------------------------------------------
  828.  * \fn     InternSymbol_XCore(char *pArg, TempResult *pResult)
  829.  * \brief  handle built-in (register) symbols for XCORE
  830.  * \param  pArg source argument
  831.  * \param  pResult result buffer
  832.  * ------------------------------------------------------------------------ */
  833.  
  834. static void InternSymbol_XCore(char *pArg, TempResult *pResult)
  835. {
  836.   unsigned RegNum;
  837.  
  838.   if (ParseReg(pArg, &RegNum))
  839.   {
  840.     pResult->Typ = TempReg;
  841.     pResult->DataSize = eSymbolSize8Bit;
  842.     pResult->Contents.RegDescr.Reg = RegNum;
  843.     pResult->Contents.RegDescr.Dissect = DissectReg_XCore;
  844.     pResult->Contents.RegDescr.compare = NULL;
  845.   }
  846. }
  847.  
  848. static Boolean IsDef_XCore(void)
  849. {
  850.   return Memo("REG");
  851. }
  852.  
  853. static void SwitchFrom_XCore(void)
  854. {
  855.   DeinitFields();
  856. }
  857.  
  858. static void SwitchTo_XCore(void)
  859. {
  860.   const TFamilyDescr *pDescr;
  861.  
  862.   TurnWords = False;
  863.   SetIntConstMode(eIntConstModeMoto);
  864.  
  865.   pDescr = FindFamilyByName("XCore");
  866.   PCSymbol = "$"; HeaderID = pDescr->Id; NOPCode = 0x0000;
  867.   DivideChars = ","; HasAttrs = False;
  868.  
  869.   ValidSegs = (1 << SegCode);
  870.   Grans[SegCode] = 1; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  871.   SegLimits[SegCode] = 0xffffffffl;
  872.  
  873.   MakeCode = MakeCode_XCore;
  874.   InternSymbol = InternSymbol_XCore;
  875.   DissectReg = DissectReg_XCore;
  876.   IsDef = IsDef_XCore;
  877.  
  878.   SwitchFrom = SwitchFrom_XCore; InitFields();
  879. }
  880.  
  881. /*--------------------------------------------------------------------------*/
  882. /* Initialisation */
  883.  
  884. void codexcore_init(void)
  885. {
  886.   CPUXS1 = AddCPU("XS1", SwitchTo_XCore);
  887. }
  888.