Subversion Repositories pentevo

Rev

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

  1. /* literals.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Literal Handling Functions                                                */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <assert.h>
  13.  
  14. #include "strutil.h"
  15. #include "errmsg.h"
  16. #include "asmdef.h"
  17. #include "asmsub.h"
  18. #include "asmpars.h"
  19. #include "asmerr.h"
  20. #include "literals.h"
  21.  
  22. /*---------------------------------------------------------------------------*/
  23.  
  24. as_literal_t *p_first_literal;
  25.  
  26. LongInt literal_forward_count;
  27.  
  28. /*---------------------------------------------------------------------------*/
  29.  
  30. /*!------------------------------------------------------------------------
  31.  * \fn     literals_chk_alldone(void)
  32.  * \brief  check whether all literals have been resolved
  33.  * ------------------------------------------------------------------------ */
  34.  
  35. void literals_chk_alldone(void)
  36. {
  37.   while (p_first_literal)
  38.   {
  39.     as_literal_t *p_run;
  40.     WrError(ErrNum_MsgMissingLTORG);
  41.  
  42.     p_run = p_first_literal;
  43.     p_first_literal = p_run->p_next;
  44.     literals_free(p_run);
  45.   }
  46. }
  47.  
  48. /*!------------------------------------------------------------------------
  49.  * \fn     literals_new(void)
  50.  * \brief  create new literal
  51.  * \return * to new instance or NULL
  52.  * ------------------------------------------------------------------------ */
  53.  
  54. as_literal_t *literals_new(void)
  55. {
  56.   as_literal_t *p_ret = (as_literal_t*)calloc(1, sizeof(*p_ret));
  57.   return p_ret;
  58. }
  59.  
  60. /*!------------------------------------------------------------------------
  61.  * \fn     literals_free(as_literal_t* p_literal)
  62.  * \brief  destroy literal
  63.  * \param   p_literalliteral to free
  64.  * ------------------------------------------------------------------------ */
  65.  
  66. void literals_free(as_literal_t* p_literal)
  67. {
  68.   free(p_literal);
  69. }
  70.  
  71. /*!------------------------------------------------------------------------
  72.  * \fn     literals_get_name(const as_literal_t *p_lit, char *p_result, size_t result_size)
  73.  * \brief  deduce name of literal
  74.  * \param  p_lit literal in question
  75.  * \param  p_result where to write result
  76.  * \param  result_size capacity of buffer
  77.  * \return * to b uffer
  78.  * ------------------------------------------------------------------------ */
  79.  
  80. const char *literals_get_name(const as_literal_t *p_lit, char *p_result, size_t result_size)
  81. {
  82.   as_snprintf(p_result, result_size, "LITERAL_");
  83.   if (p_lit->is_forward)
  84.     as_snprcatf(p_result, result_size, "F_%lllx", (LargeWord)p_lit->f_count);
  85.   else switch (p_lit->size)
  86.   {
  87.     case eSymbolSize32Bit:
  88.       as_snprcatf(p_result, result_size, "L_%08lllx", (LargeWord)p_lit->value);
  89.       break;
  90.     case eSymbolSize16Bit:
  91.       as_snprcatf(p_result, result_size, "W_%04x", (unsigned)p_lit->value);
  92.       break;
  93.     case eSymbolSize12Bit:
  94.       as_snprcatf(p_result, result_size, "W_%03x", (unsigned)p_lit->value);
  95.       break;
  96.     default:
  97.       assert(0);
  98.   }
  99.   as_snprcatf(p_result, result_size, "_%x", (unsigned)p_lit->pass_no);
  100.   return p_result;
  101. }
  102.  
  103. /*!------------------------------------------------------------------------
  104.  * \fn     literals_print(void)
  105.  * \brief  dump current list of literals
  106.  * ------------------------------------------------------------------------ */
  107.  
  108. void literals_print(void)
  109. {
  110.   as_literal_t *p_run;
  111.   String Name;
  112.  
  113.   WrLstLine("LiteralList");
  114.   p_run = p_first_literal;
  115.   while (p_run)
  116.   {
  117.     literals_get_name(p_run, Name, sizeof(Name));
  118.     WrLstLine(Name); p_run = p_run->p_next;
  119.   }
  120. }
  121.  
  122. /*!------------------------------------------------------------------------
  123.  * \fn     literal_make(tStrComp *p_comp, Byte *p_data_offset, LongInt value, tSymbolSize value_size, Boolean force_create)
  124.  * \brief  create/lookup literal, and return its symbolic name
  125.  * \param  p_comp destination buffer for symbol name
  126.  * \param  p_data_offset address offset into symbols's address (assuming big endian)
  127.  * \param  value value of literal
  128.  * \param  value_size operand size of literal
  129.  * \param  force_create do not re-use esisting literals
  130.  * ------------------------------------------------------------------------ */
  131.  
  132. void literal_make(tStrComp *p_comp, Byte *p_data_offset, LongInt value, tSymbolSize value_size, Boolean force_create)
  133. {
  134.   as_literal_t *p_run, *p_prev;
  135.   String name;
  136.  
  137.   switch (value_size)
  138.   {
  139.     case eSymbolSize32Bit:
  140.       break;
  141.     case eSymbolSize16Bit:
  142.       value &= 0xffff;
  143.       break;
  144.     case eSymbolSize12Bit:
  145.       value &= 07777;
  146.       break;
  147.     default:
  148.       assert(0);
  149.   }
  150.  
  151.   /* existing literal available? */
  152.  
  153.   if (p_data_offset) *p_data_offset = 0;
  154.   for (p_run = p_first_literal, p_prev = NULL; p_run; p_prev = p_run, p_run = p_run->p_next)
  155.   {
  156.     if (!force_create && !p_run->is_forward && (p_run->def_section == MomSectionHandle))
  157.     {
  158.       if (((p_run->size == value_size) && (value == p_run->value))
  159.        || ((p_run->size == eSymbolSize32Bit) && p_data_offset && (value_size == eSymbolSize16Bit) && (value == (p_run->value >> 16))))
  160.         break;
  161.       else if ((p_run->size == eSymbolSize32Bit) && p_data_offset && (value_size == eSymbolSize16Bit) && (value == (p_run->value & 0xffff)))
  162.       {
  163.         *p_data_offset = 2;
  164.         break;
  165.       }
  166.     }
  167.   }
  168.  
  169.   /* no - create new one */
  170.  
  171.   if (!p_run)
  172.   {
  173.     p_run = literals_new();
  174.     p_run->size = value_size;
  175.     p_run->value = value;
  176.     p_run->is_forward = force_create;
  177.     if (force_create)
  178.       p_run->f_count = literal_forward_count++;
  179.     p_run->def_section = MomSectionHandle;
  180.     for (p_run->pass_no = 1; ; p_run->pass_no++)
  181.     {
  182.       /* literals are section-specific */
  183.  
  184.       as_snprintf(p_comp->str.p_str, p_comp->str.capacity, "%s[PARENT0]",
  185.                   literals_get_name(p_run, name, sizeof(name)));
  186.       if (!IsSymbolDefined(p_comp))
  187.         break;
  188.     }
  189.     if (!p_prev)
  190.       p_first_literal = p_run;
  191.     else
  192.       p_prev->p_next = p_run;
  193.   }
  194.   else
  195.   {
  196.     as_snprintf(p_comp->str.p_str, p_comp->str.capacity, "%s[PARENT0]",
  197.                 literals_get_name(p_run, name, sizeof(name)));
  198.   }
  199. }
  200.  
  201. /*!------------------------------------------------------------------------
  202.  * \fn     literals_dump(literal_dump_fnc_t dump, tSymbolSize value_size, LongInt section_handle, Boolean compress)
  203.  * \brief  dump & free accumulated literals
  204.  * \param  dump callback to actually dispose value in memory
  205.  * \param  value_size only dump literals of given size
  206.  * \param  section_handle only dump literals out of given section
  207.  * \param  compress reference literals of same value to same address?
  208.  * ------------------------------------------------------------------------ */
  209.  
  210. void literals_dump(literal_dump_fnc_t dump, tSymbolSize value_size, LongInt section_handle, Boolean compress)
  211. {
  212.   as_literal_t *p_curr, *p_last, *p_tmp;
  213.   LargeInt address;
  214.   String name;
  215.   tStrComp tmp_comp;
  216.  
  217.   StrCompMkTemp(&tmp_comp, name, sizeof(name));
  218.   p_curr = p_first_literal;
  219.   p_last = NULL;
  220.   while (p_curr)
  221.   {
  222.     if ((p_curr->size == value_size) && (p_curr->def_section == section_handle))
  223.     {
  224.       literals_get_name(p_curr, name, sizeof(name));
  225.       address = dump(p_curr, &tmp_comp);
  226.       if (compress)
  227.       {
  228.         as_literal_t *p_eq_curr = p_curr->p_next, *p_eq_last = NULL;
  229.         while (p_eq_curr)
  230.         {
  231.           if ((p_eq_curr->size == value_size) && (p_eq_curr->def_section == section_handle) && (p_eq_curr->value == p_curr->value))
  232.           {
  233.             literals_get_name(p_eq_curr, name, sizeof(name));
  234.             EnterIntSymbol(&tmp_comp, address, ActPC, False);
  235.             p_tmp = p_eq_curr->p_next;
  236.             if (!p_eq_last)
  237.               p_curr->p_next = p_tmp;
  238.             else
  239.               p_eq_last->p_next = p_tmp;
  240.             literals_free(p_eq_curr);
  241.             p_eq_curr = p_tmp;
  242.           }
  243.           else
  244.           {
  245.             p_eq_last = p_eq_curr;
  246.             p_eq_curr = p_eq_curr->p_next;
  247.           }
  248.         }
  249.       }
  250.       p_tmp = p_curr->p_next;
  251.       if (!p_last)
  252.         p_first_literal = p_tmp;
  253.       else
  254.         p_last->p_next = p_tmp;
  255.       literals_free(p_curr);
  256.       p_curr = p_tmp;
  257.     }
  258.     else
  259.     {
  260.       p_last = p_curr;
  261.       p_curr = p_curr->p_next;
  262.     }
  263.   }
  264. }
  265.  
  266. /*!------------------------------------------------------------------------
  267.  * \fn     literals_init(void)
  268.  * \brief  module initialization
  269.  * ------------------------------------------------------------------------ */
  270.  
  271. static void init_pass_literals(void)
  272. {
  273.   literal_forward_count = 0;
  274. }
  275.  
  276. void literals_init(void)
  277. {
  278.   AddInitPassProc(init_pass_literals);
  279.   p_first_literal = NULL;
  280. }
  281.