Subversion Repositories pentevo

Rev

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

  1. /* tipseudo.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS                                                                        */
  6. /*                                                                           */
  7. /* Commonly Used TI-Style Pseudo Instructions-Befehle                        */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. /*****************************************************************************
  12.  * Includes
  13.  *****************************************************************************/
  14.  
  15. #include "stdinc.h"
  16. #include <ctype.h>
  17. #include <string.h>
  18. #include <math.h>
  19.  
  20. #include "strutil.h"
  21. #include "be_le.h"
  22. #include "ieeefloat.h"
  23. #include "asmdef.h"
  24. #include "asmsub.h"
  25. #include "asmpars.h"
  26. #include "asmitree.h"
  27. #include "onoff_common.h"
  28. #include "errmsg.h"
  29. #include "chartrans.h"
  30.  
  31. #include "codepseudo.h"
  32. #include "fourpseudo.h"
  33. #include "tipseudo.h"
  34.  
  35. #define LEAVE goto func_exit
  36.  
  37. /*****************************************************************************
  38.  * Local Functions
  39.  *****************************************************************************/
  40.  
  41. static void define_untyped_label(void)
  42. {
  43.   if (LabPart.str.p_str[0])
  44.   {
  45.     PushLocHandle(-1);
  46.     EnterIntSymbol(&LabPart, EProgCounter(), SegNone, False);
  47.     PopLocHandle();
  48.   }
  49. }
  50.  
  51. static void pseudo_qxx(Integer num)
  52. {
  53.   tStrComp *pArg;
  54.   Boolean ok = True;
  55.   double res;
  56.  
  57.   if (!ChkArgCnt(1, ArgCntMax))
  58.     return;
  59.  
  60.   forallargs (pArg, True)
  61.   {
  62.     if (!*pArg->str.p_str)
  63.     {
  64.       ok = False;
  65.       break;
  66.     }
  67.  
  68.     res = ldexp(EvalStrFloatExpression(pArg, Float64, &ok), num);
  69.     if (!ok)
  70.       break;
  71.  
  72.     if ((res > 32767.49) || (res < -32768.49))
  73.     {
  74.       ok = False;
  75.       WrError(ErrNum_OverRange);
  76.       break;
  77.     }
  78.     WAsmCode[CodeLen++] = res;
  79.   }
  80.  
  81.   if (!ok)
  82.     CodeLen = 0;
  83. }
  84.  
  85. static void pseudo_lqxx(Integer num)
  86. {
  87.   tStrComp *pArg;
  88.   Boolean ok = True;
  89.   double res;
  90.   LongInt resli;
  91.  
  92.   if (!ChkArgCnt(1, ArgCntMax))
  93.     return;
  94.  
  95.   forallargs (pArg, True)
  96.   {
  97.     if (!*pArg->str.p_str)
  98.     {
  99.       ok = False;
  100.       break;
  101.     }
  102.  
  103.     res = ldexp(EvalStrFloatExpression(pArg, Float64, &ok), num);
  104.     if (!ok)
  105.       break;
  106.  
  107.     if ((res > 2147483647.49) || (res < -2147483647.49))
  108.     {
  109.       ok = False;
  110.       WrError(ErrNum_OverRange);
  111.       break;
  112.     }
  113.     resli = res;
  114.     WAsmCode[CodeLen++] = resli & 0xffff;
  115.     WAsmCode[CodeLen++] = resli >> 16;
  116.   }
  117.  
  118.   if (!ok)
  119.     CodeLen = 0;
  120. }
  121.  
  122. typedef void (*tcallback)(
  123. #ifdef __PROTOS__
  124. Boolean *, int *, LongInt, tSymbolFlags
  125. #endif
  126. );
  127.  
  128. static void pseudo_store(tcallback callback, Word MaxMultCharLen)
  129. {
  130.   Boolean ok = True;
  131.   int adr = 0;
  132.   tStrComp *pArg;
  133.   TempResult t;
  134.  
  135.   as_tempres_ini(&t);
  136.  
  137.   if (!ChkArgCnt(1, ArgCntMax))
  138.     LEAVE;
  139.  
  140.   define_untyped_label();
  141.  
  142.   forallargs (pArg, ok)
  143.   {
  144.     if (!*pArg->str.p_str)
  145.     {
  146.       ok = False;
  147.       break;
  148.     }
  149.  
  150.     EvalStrExpression(pArg, &t);
  151.     switch (t.Typ)
  152.     {
  153.       case TempFloat:
  154.         WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
  155.         LEAVE;
  156.       case TempString:
  157.       {
  158.         unsigned char *cp, *cend;
  159.  
  160.         if (MultiCharToInt(&t, MaxMultCharLen))
  161.           goto ToInt;
  162.  
  163.         if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
  164.           ok = False;
  165.         else
  166.         {
  167.           cp = (unsigned char *)t.Contents.str.p_str;
  168.           cend = cp + t.Contents.str.len;
  169.           while (cp < cend)
  170.             callback(&ok, &adr, *cp++ & 0xff, t.Flags);
  171.         }
  172.         break;
  173.       }
  174.       case TempInt:
  175.       ToInt:
  176.         callback(&ok, &adr, t.Contents.Int, t.Flags);
  177.         break;
  178.       default:
  179.         ok = False;
  180.         break;
  181.     }
  182.     if (!ok)
  183.       break;
  184.   }
  185.  
  186.   if (!ok)
  187.     CodeLen = 0;
  188.  
  189. func_exit:
  190.   as_tempres_free(&t);
  191. }
  192.  
  193. static void wr_code_byte(Boolean *ok, int *adr, LongInt val, tSymbolFlags Flags)
  194. {
  195.   if (!mFirstPassUnknownOrQuestionable(Flags) && !RangeCheck(val, Int8))
  196.   {
  197.     WrError(ErrNum_OverRange);
  198.     *ok = False;
  199.     return;
  200.   }
  201.   WAsmCode[(*adr)++] = val & 0xff;
  202.   CodeLen = *adr;
  203. }
  204.  
  205. static void wr_code_word(Boolean *ok, int *adr, LongInt val, tSymbolFlags Flags)
  206. {
  207.   if (!mFirstPassUnknownOrQuestionable(Flags) && !RangeCheck(val, Int16))
  208.   {
  209.     WrError(ErrNum_OverRange);
  210.     *ok = False;
  211.     return;
  212.   }
  213.   WAsmCode[(*adr)++] = val;
  214.   CodeLen = *adr;
  215. }
  216.  
  217. static void wr_code_long(Boolean *ok, int *adr, LongInt val, tSymbolFlags Flags)
  218. {
  219.   UNUSED(ok);
  220.   UNUSED(Flags);
  221.  
  222.   WAsmCode[(*adr)++] = val & 0xffff;
  223.   WAsmCode[(*adr)++] = val >> 16;
  224.   CodeLen = *adr;
  225. }
  226.  
  227. static void wr_code_byte_hilo(Boolean *ok, int *adr, LongInt val, tSymbolFlags Flags)
  228. {
  229.   if (!mFirstPassUnknownOrQuestionable(Flags) && !RangeCheck(val, Int8))
  230.   {
  231.     WrError(ErrNum_OverRange);
  232.     *ok = False;
  233.     return;
  234.   }
  235.   if ((*adr) & 1)
  236.     WAsmCode[((*adr)++) / 2] |= val & 0xff;
  237.   else
  238.     WAsmCode[((*adr)++) / 2] = val << 8;
  239.   CodeLen = ((*adr) + 1) / 2;
  240. }
  241.  
  242. static void wr_code_byte_lohi(Boolean *ok, int *adr, LongInt val, tSymbolFlags Flags)
  243. {
  244.   if (!mFirstPassUnknownOrQuestionable(Flags) && !RangeCheck(val, Int8))
  245.   {
  246.     WrError(ErrNum_OverRange);
  247.     *ok = False;
  248.     return;
  249.   }
  250.   if ((*adr) & 1)
  251.     WAsmCode[((*adr)++) / 2] |= val << 8;
  252.   else
  253.     WAsmCode[((*adr)++) / 2] = val & 0xff;
  254.   CodeLen = ((*adr) + 1) / 2;
  255. }
  256.  
  257. /*!------------------------------------------------------------------------
  258.  * \fn     DecodeFLOAT(Word Code)
  259.  * \brief  decode FLOAT instruction
  260.  * ------------------------------------------------------------------------ */
  261.  
  262. static void DecodeFLOAT(Word Code)
  263. {
  264.   Boolean ok;
  265.   tStrComp *pArg;
  266.   Byte Dest[4];
  267.  
  268.   UNUSED(Code);
  269.  
  270.   if (!ChkArgCnt(1, ArgCntMax))
  271.     return;
  272.   define_untyped_label();
  273.   ok = True;
  274.   if (SetMaxCodeLen(ArgCnt * 4))
  275.     return;
  276.   forallargs (pArg, ok)
  277.   {
  278.     if (!*pArg->str.p_str)
  279.     {
  280.       ok = False;
  281.       break;
  282.     }
  283.     Double_2_ieee4(EvalStrFloatExpression(pArg, Float32, &ok), Dest, False);
  284.     WAsmCode[CodeLen++] = (Word)Dest[0] | ((Word)Dest[1]) << 8;
  285.     WAsmCode[CodeLen++] = (Word)Dest[2] | ((Word)Dest[3]) << 8;
  286.   }
  287.   if (!ok)
  288.     CodeLen = 0;
  289. }
  290.  
  291. /*!------------------------------------------------------------------------
  292.  * \fn     DecodeDOUBLE(Word Code)
  293.  * \brief  decode DOUBLE instruction
  294.  * ------------------------------------------------------------------------ */
  295.  
  296. static void DecodeDOUBLE(Word Code)
  297. {
  298.   Boolean ok;
  299.   tStrComp *pArg;
  300.   Byte Dest[8];
  301.  
  302.   UNUSED(Code);
  303.  
  304.   if (!ChkArgCnt(1, ArgCntMax))
  305.     return;
  306.   define_untyped_label();
  307.   ok = True;
  308.   if (SetMaxCodeLen(ArgCnt * 8))
  309.     return;
  310.   forallargs (pArg, ok)
  311.   {
  312.     if (!*pArg->str.p_str)
  313.     {
  314.       ok = False;
  315.       break;
  316.     }
  317.     Double_2_ieee8(EvalStrFloatExpression(pArg, Float64, &ok), Dest, False);
  318.     WAsmCode[CodeLen++] = (Word)Dest[0] | ((Word)Dest[1]) << 8;
  319.     WAsmCode[CodeLen++] = (Word)Dest[2] | ((Word)Dest[3]) << 8;
  320.     WAsmCode[CodeLen++] = (Word)Dest[4] | ((Word)Dest[5]) << 8;
  321.     WAsmCode[CodeLen++] = (Word)Dest[6] | ((Word)Dest[7]) << 8;
  322.   }
  323.   if (!ok)
  324.     CodeLen = 0;
  325. }
  326.  
  327. /*!------------------------------------------------------------------------
  328.  * \fn     DecodeEFLOAT(Word Code)
  329.  * \brief  decode EFLOAT instruction
  330.  * ------------------------------------------------------------------------ */
  331.  
  332. static void DecodeEFLOAT(Word Code)
  333. {
  334.   Boolean ok;
  335.   tStrComp *pArg;
  336.   double dbl, mant;
  337.   int exp;
  338.  
  339.   UNUSED(Code);
  340.  
  341.   if (!ChkArgCnt(1, ArgCntMax))
  342.     return;
  343.   define_untyped_label();
  344.   ok = True;
  345.   if (SetMaxCodeLen(ArgCnt * 4))
  346.     return;
  347.   forallargs (pArg, ok)
  348.   {
  349.     if (!*pArg->str.p_str)
  350.     {
  351.       ok = False;
  352.       break;
  353.     }
  354.     dbl = EvalStrFloatExpression(pArg, Float64, &ok);
  355.     mant = frexp(dbl, &exp);
  356.     WAsmCode[CodeLen++] = ldexp(mant, 15);
  357.     WAsmCode[CodeLen++] = exp - 1;
  358.   }
  359.   if (!ok)
  360.     CodeLen = 0;
  361. }
  362.  
  363. /*!------------------------------------------------------------------------
  364.  * \fn     DecodeBFLOAT(Word Code)
  365.  * \brief  decode BFLOAT instruction
  366.  * ------------------------------------------------------------------------ */
  367.  
  368. static void DecodeBFLOAT(Word Code)
  369. {
  370.   Boolean ok;
  371.   tStrComp *pArg;
  372.   double dbl, mant;
  373.   long lmant;
  374.   int exp;
  375.  
  376.   UNUSED(Code);
  377.  
  378.   if (!ChkArgCnt(1, ArgCntMax))
  379.     return;
  380.   define_untyped_label();
  381.   ok = True;
  382.   if (SetMaxCodeLen(ArgCnt * 6))
  383.     return;
  384.   forallargs (pArg, ok)
  385.   {
  386.     if (!*pArg->str.p_str)
  387.     {
  388.       ok = False;
  389.       break;
  390.     }
  391.     dbl = EvalStrFloatExpression(pArg, Float64, &ok);
  392.     mant = frexp(dbl, &exp);
  393.     lmant = ldexp(mant, 31);
  394.     WAsmCode[CodeLen++] = (lmant & 0xffff);
  395.     WAsmCode[CodeLen++] = (lmant >> 16);
  396.     WAsmCode[CodeLen++] = exp - 1;
  397.   }
  398.   if (!ok)
  399.     CodeLen = 0;
  400. }
  401.  
  402. /*!------------------------------------------------------------------------
  403.  * \fn     DecodeTFLOAT(Word Code)
  404.  * \brief  decode TFLOAT instruction
  405.  * ------------------------------------------------------------------------ */
  406.  
  407. static void DecodeTFLOAT(Word Code)
  408. {
  409.   Boolean ok;
  410.   tStrComp *pArg;
  411.   double dbl, mant;
  412.   int exp;
  413.  
  414.   UNUSED(Code);
  415.  
  416.   if (!ChkArgCnt(1, ArgCntMax))
  417.     return;
  418.   define_untyped_label();
  419.   ok = True;
  420.   if (SetMaxCodeLen(ArgCnt * 12))
  421.     return;
  422.   forallargs (pArg, ok)
  423.   {
  424.     if (!*pArg->str.p_str)
  425.     {
  426.       ok = False;
  427.       break;
  428.     }
  429.     dbl = EvalStrFloatExpression(pArg, Float64, &ok);
  430.     mant = frexp(dbl, &exp);
  431.     mant = modf(ldexp(mant, 15), &dbl);
  432.     WAsmCode[CodeLen + 3] = dbl;
  433.     mant = modf(ldexp(mant, 16), &dbl);
  434.     WAsmCode[CodeLen + 2] = dbl;
  435.     mant = modf(ldexp(mant, 16), &dbl);
  436.     WAsmCode[CodeLen + 1] = dbl;
  437.     mant = modf(ldexp(mant, 16), &dbl);
  438.     WAsmCode[CodeLen] = dbl;
  439.     CodeLen += 4;
  440.     WAsmCode[CodeLen++] = ((exp - 1) & 0xffff);
  441.     WAsmCode[CodeLen++] = ((exp - 1) >> 16);
  442.   }
  443.   if (!ok)
  444.     CodeLen = 0;
  445. }
  446.  
  447. /*!------------------------------------------------------------------------
  448.  * \fn     DecodeSTRING(Word Code)
  449.  * \brief  decode STRING instruction
  450.  * ------------------------------------------------------------------------ */
  451.  
  452. static void DecodeSTRING(Word Code)
  453. {
  454.   UNUSED(Code);
  455.  
  456.   pseudo_store(wr_code_byte_hilo, 1);
  457. }
  458.  
  459. /*!------------------------------------------------------------------------
  460.  * \fn     DecodeRSTRING(Word Code)
  461.  * \brief  decode RSTRING instruction
  462.  * ------------------------------------------------------------------------ */
  463.  
  464. static void DecodeRSTRING(Word Code)
  465. {
  466.   UNUSED(Code);
  467.  
  468.   pseudo_store(wr_code_byte_lohi, 1);
  469. }
  470.  
  471. /*!------------------------------------------------------------------------
  472.  * \fn     DecodeBYTE(Word Code)
  473.  * \brief  decode BYTE instruction
  474.  * ------------------------------------------------------------------------ */
  475.  
  476. static void DecodeBYTE(Word Code)
  477. {
  478.   UNUSED(Code);
  479.  
  480.   pseudo_store(wr_code_byte, 1);
  481. }
  482.  
  483. /*!------------------------------------------------------------------------
  484.  * \fn     DecodeWORD(Word Code)
  485.  * \brief  decode WORD instruction
  486.  * ------------------------------------------------------------------------ */
  487.  
  488. static void DecodeWORD(Word Code)
  489. {
  490.   UNUSED(Code);
  491.  
  492.   pseudo_store(wr_code_word, 2);
  493. }
  494.  
  495. /*!------------------------------------------------------------------------
  496.  * \fn     DecodeLONG(Word Code)
  497.  * \brief  decode LONG instruction
  498.  * ------------------------------------------------------------------------ */
  499.  
  500. static void DecodeLONG(Word Code)
  501. {
  502.   UNUSED(Code);
  503.  
  504.   pseudo_store(wr_code_long, 4);
  505. }
  506.  
  507. /*!------------------------------------------------------------------------
  508.  * \fn     DecodeBSS(Word Code)
  509.  * \brief  decode BSS instruction
  510.  * ------------------------------------------------------------------------ */
  511.  
  512. static void DecodeBSS_TI(Word Code)
  513. {
  514.   UNUSED(Code);
  515.  
  516.   define_untyped_label();
  517.   DecodeRES(Code);
  518. }
  519.  
  520. /*!------------------------------------------------------------------------
  521.  * \fn     DecodeDATA_TI(Word Code)
  522.  * \brief  decode TI-specific DATA instruction
  523.  * ------------------------------------------------------------------------ */
  524.  
  525. static void DecodeDATA_TI(Word Code)
  526. {
  527.   UNUSED(Code);
  528.   DecodeDATA(Int16, Int16);
  529. }
  530.  
  531. /*!------------------------------------------------------------------------
  532.  * \fn     Boolean Is99(const char *pStr, Integer *pNum)
  533.  * \brief  does string end with number 00...99?
  534.  * \param  pStr string to check
  535.  * \param  pNum appended number if yes
  536.  * \return True if yes
  537.  * ------------------------------------------------------------------------ */
  538.  
  539. static Boolean Is99(const char *pStr, Integer *pNum)
  540. {
  541.   int l = strlen(pStr);
  542.  
  543.   if ((l >= 3)
  544.    && as_isdigit(pStr[l - 2])
  545.    && as_isdigit(pStr[l - 1]))
  546.   {
  547.     *pNum = 10 * (pStr[l - 2] - '0') + (pStr[l - 1] - '0');
  548.     return True;
  549.   }
  550.   return False;
  551. }
  552.  
  553. /*****************************************************************************
  554.  * Global Functions
  555.  *****************************************************************************/
  556.  
  557. Boolean DecodeTIPseudo(void)
  558. {
  559.   static PInstTable InstTable;
  560.   Integer Num;
  561.  
  562.   /* Qxx */
  563.  
  564.   if (!as_strncasecmp(OpPart.str.p_str, "Q", 1)
  565.    && Is99(OpPart.str.p_str, &Num))
  566.   {
  567.     pseudo_qxx(Num);
  568.     return True;
  569.   }
  570.  
  571.   /* LQxx */
  572.  
  573.   if (!as_strncasecmp(OpPart.str.p_str, "LQ", 2)
  574.    && Is99(OpPart.str.p_str, &Num))
  575.   {
  576.     pseudo_lqxx(Num);
  577.     return True;
  578.   }
  579.  
  580.   if (!InstTable)
  581.   {
  582.     InstTable = CreateInstTable(23);
  583.     AddInstTable(InstTable, "RES"    , 0, DecodeRES);
  584.     AddInstTable(InstTable, "BSS"    , 0, DecodeBSS_TI);
  585.     AddInstTable(InstTable, "DATA"   , 0, DecodeDATA_TI);
  586.     AddInstTable(InstTable, "STRING" , 0, DecodeSTRING);
  587.     AddInstTable(InstTable, "RSTRING", 0, DecodeRSTRING);
  588.     AddInstTable(InstTable, "BYTE"   , 0, DecodeBYTE);
  589.     AddInstTable(InstTable, "WORD"   , 0, DecodeWORD);
  590.     AddInstTable(InstTable, "LONG"   , 0, DecodeLONG);
  591.     AddInstTable(InstTable, "FLOAT"  , 0, DecodeFLOAT);
  592.     AddInstTable(InstTable, "DOUBLE" , 0, DecodeDOUBLE);
  593.     AddInstTable(InstTable, "EFLOAT" , 0, DecodeEFLOAT);
  594.     AddInstTable(InstTable, "BFLOAT" , 0, DecodeBFLOAT);
  595.     AddInstTable(InstTable, "TFLOAT" , 0, DecodeTFLOAT);
  596.   }
  597.  
  598.   return LookupInstTable(InstTable, OpPart.str.p_str);
  599. }
  600.  
  601. Boolean IsTIDef(void)
  602. {
  603.   static const char *defs[] =
  604.   {
  605.     "BSS", "STRING", "RSTRING",
  606.     "BYTE", "WORD", "LONG", "FLOAT",
  607.     "DOUBLE", "EFLOAT", "BFLOAT",
  608.     "TFLOAT", NULL
  609.   };
  610.   const char **cp = defs;
  611.  
  612.   while (*cp)
  613.   {
  614.     if (Memo(*cp))
  615.       return True;
  616.     cp++;
  617.   }
  618.   return False;
  619. }
  620.  
  621. /*-------------------------------------------------------------------------*/
  622. /* Convert IEEE to C3x/C4x floating point format */
  623.  
  624. static void SplitExt(Double Inp, LongInt *Expo, LongWord *Mant)
  625. {
  626.   Byte Field[8];
  627.   Boolean Sign;
  628.   int z;
  629.  
  630.   Double_2_ieee8(Inp, Field, False);
  631.   Sign = (Field[7] > 0x7f);
  632.   *Expo = (((LongWord) Field[7] & 0x7f) << 4) + (Field[6] >> 4);
  633.   *Mant = Field[6] & 0x0f;
  634.   if (*Expo != 0)
  635.     *Mant |= 0x10;
  636.   for (z = 5; z > 2; z--)
  637.     *Mant = ((*Mant) << 8) | Field[z];
  638.   *Mant = ((*Mant) << 3) + (Field[2] >> 5);
  639.   *Expo -= 0x3ff;
  640.   if (Sign)
  641.     *Mant = (0xffffffff - *Mant) + 1;
  642.   *Mant = (*Mant) ^ 0x80000000;
  643. }
  644.  
  645. Boolean ExtToTIC34xShort(Double Inp, Word *Erg)
  646. {
  647.   LongInt Expo;
  648.   LongWord Mant;
  649.  
  650.   if (Inp == 0)
  651.     *Erg = 0x8000;
  652.   else
  653.   {
  654.     SplitExt(Inp, &Expo, &Mant);
  655.     if (!ChkRange(Expo, -7, 7))
  656.       return False;
  657.     *Erg = ((Expo << 12) & 0xf000) | ((Mant >> 20) & 0xfff);
  658.   }
  659.   return True;
  660. }
  661.  
  662. Boolean ExtToTIC34xSingle(Double Inp, LongWord *Erg)
  663. {
  664.   LongInt Expo;
  665.   LongWord Mant;
  666.  
  667.   if (Inp == 0)
  668.     *Erg = 0x80000000;
  669.   else
  670.   {
  671.     SplitExt(Inp, &Expo, &Mant);
  672.     if (!ChkRange(Expo, -127, 127))
  673.       return False;
  674.     *Erg = ((Expo << 24) & 0xff000000) + (Mant >> 8);
  675.   }
  676.   return True;
  677. }
  678.  
  679. Boolean ExtToTIC34xExt(Double Inp, LongWord *ErgL, LongWord *ErgH)
  680. {
  681.   LongInt Exp;
  682.  
  683.   if (Inp == 0)
  684.   {
  685.     *ErgH = 0x80;
  686.     *ErgL = 0x00000000;
  687.   }
  688.   else
  689.   {
  690.     SplitExt(Inp, &Exp, ErgL);
  691.     if (!ChkRange(Exp, -127, 127))
  692.       return False;
  693.     *ErgH = Exp & 0xff;
  694.   }
  695.   return True;
  696. }
  697.  
  698. /*-------------------------------------------------------------------------*/
  699. /* Pseudo Instructions common to C3x/C4x */
  700.  
  701. static void DecodeSINGLE(Word Code)
  702. {
  703.   Double f;
  704.   tStrComp *pArg;
  705.   Boolean OK;
  706.  
  707.   UNUSED(Code);
  708.  
  709.   if (ChkArgCnt(1, ArgCntMax))
  710.   {
  711.     OK = True;
  712.     forallargs (pArg, True)
  713.       if (OK)
  714.       {
  715.         f = EvalStrFloatExpression(pArg, Float64, &OK);
  716.         if (OK)
  717.           OK = OK && ExtToTIC34xSingle(f, DAsmCode + (CodeLen++));
  718.       }
  719.     if (!OK)
  720.       CodeLen = 0;
  721.   }
  722. }
  723.  
  724. static void DecodeEXTENDED(Word Code)
  725. {
  726.   Double f;
  727.   tStrComp *pArg;
  728.   Boolean OK;
  729.  
  730.   UNUSED(Code);
  731.  
  732.   if (ChkArgCnt(1, ArgCntMax))
  733.   {
  734.     OK = True;
  735.     forallargs (pArg, True)
  736.       if (OK)
  737.       {
  738.         f = EvalStrFloatExpression(pArg, Float64, &OK);
  739.         if (OK)
  740.           OK = OK && ExtToTIC34xExt(f, DAsmCode + CodeLen + 1, DAsmCode + CodeLen);
  741.         CodeLen += 2;
  742.       }
  743.     if (!OK)
  744.       CodeLen = 0;
  745.   }
  746. }
  747.  
  748. static void DecodeWORD_TI34x(Word Code)
  749. {
  750.   Boolean OK;
  751.   tStrComp *pArg;
  752.  
  753.   UNUSED(Code);
  754.  
  755.   if (ChkArgCnt(1, ArgCntMax))
  756.   {
  757.     OK = True;
  758.     forallargs (pArg, True)
  759.       if (OK) DAsmCode[CodeLen++] = EvalStrIntExpression(pArg, Int32, &OK);
  760.     if (!OK)
  761.       CodeLen = 0;
  762.   }
  763. }
  764.  
  765. static void DecodeDATA_TI34x(Word Code)
  766. {
  767.   Boolean OK;
  768.   TempResult t;
  769.   tStrComp *pArg;
  770.  
  771.   UNUSED(Code);
  772.   as_tempres_ini(&t);
  773.  
  774.   if (ChkArgCnt(1, ArgCntMax))
  775.   {
  776.     OK = True;
  777.     forallargs (pArg, OK)
  778.       if (OK)
  779.       {
  780.         EvalStrExpression(pArg, &t);
  781.         switch (t.Typ)
  782.         {
  783.           case TempInt:
  784.           ToInt:
  785. #ifdef HAS64
  786.             if (!RangeCheck(t.Contents.Int, Int32))
  787.             {
  788.               OK = False;
  789.               WrError(ErrNum_OverRange);
  790.             }
  791.             else
  792. #endif
  793.               DAsmCode[CodeLen++] = t.Contents.Int;
  794.             break;
  795.           case TempFloat:
  796.             if (!ExtToTIC34xSingle(t.Contents.Float, DAsmCode + (CodeLen++)))
  797.               OK = False;
  798.             break;
  799.           case TempString:
  800.           {
  801.             if (MultiCharToInt(&t, 4))
  802.               goto ToInt;
  803.  
  804.             if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
  805.               OK = False;
  806.             else
  807.               string_2_dasm_code(&t.Contents.str, Packing ? 4 : 1, True);
  808.             break;
  809.           }
  810.           default:
  811.             OK = False;
  812.         }
  813.       }
  814.     if (!OK)
  815.       CodeLen = 0;
  816.   }
  817.   as_tempres_free(&t);
  818. }
  819.  
  820. static void DecodeBSS_TI34x(Word Code)
  821. {
  822.   Boolean OK;
  823.   tSymbolFlags Flags;
  824.   LongInt Size;
  825.  
  826.   UNUSED(Code);
  827.  
  828.   if (ChkArgCnt(1, 1))
  829.   {
  830.     Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags);
  831.     if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  832.     if (OK && !mFirstPassUnknown(Flags))
  833.     {
  834.       DontPrint = True;
  835.       if (!Size)
  836.         WrError(ErrNum_NullResMem);
  837.       CodeLen = Size;
  838.       BookKeeping();
  839.     }
  840.   }
  841. }
  842.  
  843. void AddTI34xPseudo(TInstTable *pInstTable)
  844. {
  845.   AddInstTable(pInstTable, "SINGLE", 0, DecodeSINGLE);
  846.   AddInstTable(pInstTable, "EXTENDED", 0, DecodeEXTENDED);
  847.   AddInstTable(pInstTable, "WORD", 0, DecodeWORD_TI34x);
  848.   AddInstTable(pInstTable, "DATA", 0, DecodeDATA_TI34x);
  849.   AddInstTable(pInstTable, "BSS", 0, DecodeBSS_TI34x);
  850. }
  851.