Subversion Repositories pentevo

Rev

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

  1. /* codepdp11.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS                                                                        */
  6. /*                                                                           */
  7. /* Code Generator VAX                                                        */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <assert.h>
  14.  
  15. #include "bpemu.h"
  16. #include "strutil.h"
  17. #include "headids.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmallg.h"
  22. #include "asmcode.h"
  23. #include "asmitree.h"
  24. #include "codevars.h"
  25. #include "codepseudo.h"
  26. #include "errmsg.h"
  27. #include "intpseudo.h"
  28. #include "decpseudo.h"
  29. #include "decfloat.h"
  30. #include "codepdp11.h"
  31.  
  32. typedef enum
  33. {
  34.   e_cpu_cap_none = 0,
  35.   e_cpu_cap_float_g = 1 << 0,
  36.   e_cpu_cap_float_h = 1 << 1,
  37.   /* MOVC3 MOVC5 mandatory */
  38.   /* CMPC3, LOCC, SCANC, SKPC, SPANC */
  39.   e_cpu_cap_string_mvax = 1 << 2,
  40.   e_cpu_cap_string_rest = 1 << 3,
  41.   e_cpu_cap_crc = 1 << 4,
  42.   e_cpu_cap_packed = 1 << 5,
  43.   e_cpu_cap_edit = 1 << 6,
  44.   e_cpu_cap_vector = 1 << 7
  45. } cpu_cap_t;
  46.  
  47. #define e_cpu_cap_string (e_cpu_cap_string_mvax | e_cpu_cap_string_rest)
  48. #define e_cpu_cap_all_no_vector (e_cpu_cap_float_g | e_cpu_cap_float_h | e_cpu_cap_string | e_cpu_cap_crc | e_cpu_cap_packed | e_cpu_cap_edit)
  49. #define e_cpu_cap_all_vector (e_cpu_cap_all_no_vector | e_cpu_cap_vector)
  50.  
  51. #ifdef __cplusplus
  52. # include "codevax.hpp"
  53. #endif
  54.  
  55. typedef struct
  56. {
  57.   char name[15];
  58.   cpu_cap_t caps;
  59. } cpu_props_t;
  60.  
  61. typedef struct
  62. {
  63.   int gen_indices[4];
  64. } var_arg_order_t;
  65.  
  66. typedef struct
  67. {
  68.   Word code;
  69.   ShortInt bit_field_arg_start;
  70.   Boolean bit_field_size_present;
  71.   Byte max_access_mode;
  72.   size_t arg_cnt;
  73.   cpu_cap_t required_caps;
  74.   unsigned adr_mode_mask[6];
  75.   tSymbolSize op_size[6];
  76. } gen_order_t;
  77.  
  78. typedef enum
  79. {
  80.   ModNone = -1,
  81.   ModReg = 0,
  82.   ModImm = 1,
  83.   ModMem = 2,
  84.   ModLit = 3,
  85.   ModBranch = 4
  86. } adr_mode_t;
  87.  
  88. #define MModReg (1 << ModReg)
  89. #define MModImm (1 << ModImm)
  90. #define MModMem (1 << ModMem)
  91. #define MModLit (1 << ModLit)
  92. #define MModBranch (1 << ModBranch)
  93.  
  94. typedef struct
  95. {
  96.   adr_mode_t mode;
  97.   unsigned count;
  98.   Byte vals[20];
  99.   LargeInt imm_value;
  100.   tSymbolFlags imm_flags;
  101. } adr_vals_t;
  102.  
  103. static const cpu_props_t *p_curr_cpu_props;
  104. static tSymbolSize op_size;
  105. static gen_order_t *gen_orders;
  106. static var_arg_order_t *var_arg_orders;
  107. static unsigned var_arg_op_cnt;
  108. static Boolean curr_access_mode_set;
  109. static unsigned curr_access_mode;
  110. static const char access_mode_name[] = "ACCMODE";
  111.  
  112. /*-------------------------------------------------------------------------*/
  113. /* Register Symbols */
  114.  
  115. /*!------------------------------------------------------------------------
  116.  * \fn     decode_reg_core(const char *p_arg, Word *p_result, tSymbolSize *p_size)
  117.  * \brief  check whether argument is a CPU register
  118.  * \param  p_arg argument to check
  119.  * \param  p_result numeric register value if yes
  120.  * \param  p_size returns register size
  121.  * \return True if yes
  122.  * ------------------------------------------------------------------------ */
  123.  
  124. #define REG_AP 12
  125. #define REG_FP 13
  126. #define REG_SP 14
  127. #define REG_PC 15
  128.  
  129. static const char xtra_reg_names[8] =
  130. {
  131.   'A','P',
  132.   'F','P',
  133.   'S','P',
  134.   'P','C'
  135. };
  136.  
  137. static Boolean decode_reg_core(const char *p_arg, Byte *p_result, tSymbolSize *p_size)
  138. {
  139.   switch (strlen(p_arg))
  140.   {
  141.     case 2:
  142.     {
  143.       int z;
  144.  
  145.       for (z = 0; z < 8; z += 2)
  146.         if ((as_toupper(p_arg[0]) == xtra_reg_names[z + 0])
  147.          && (as_toupper(p_arg[1]) == xtra_reg_names[z + 1]))
  148.       {
  149.         *p_result = ((z / 2) + REG_AP) | REGSYM_FLAG_ALIAS;
  150.         *p_size = eSymbolSize32Bit;
  151.         return True;
  152.       }
  153.       if ((as_toupper(*p_arg) == 'R')
  154.        && isdigit(p_arg[1]))
  155.       {
  156.         *p_result = p_arg[1] - '0';
  157.         *p_size = eSymbolSize32Bit;
  158.         return True;
  159.       }
  160.       break;
  161.     }
  162.     case 3:
  163.       if ((as_toupper(*p_arg) == 'R')
  164.        && (as_toupper(p_arg[1]) == '1')
  165.        && isdigit(p_arg[2])
  166.        && (p_arg[2] < '6'))
  167.       {
  168.         *p_result = 10 + p_arg[2] - '0';
  169.         *p_size = eSymbolSize32Bit;
  170.         return True;
  171.       }
  172.       break;
  173.     default:
  174.       break;
  175.   }
  176.   return False;
  177. }
  178.  
  179. /*!------------------------------------------------------------------------
  180.  * \fn     dissect_reg_vax(char *p_dest, size_t dest_size, tRegInt value, tSymbolSize inp_size)
  181.  * \brief  dissect register symbols - PDP-11 variant
  182.  * \param  p_dest destination buffer
  183.  * \param  dest_size destination buffer size
  184.  * \param  value numeric register value
  185.  * \param  inp_size register size
  186.  * ------------------------------------------------------------------------ */
  187.  
  188. static void dissect_reg_vax(char *p_dest, size_t dest_size, tRegInt value, tSymbolSize inp_size)
  189. {
  190.   switch (inp_size)
  191.   {
  192.     case eSymbolSize32Bit:
  193.     {
  194.       unsigned r_num = value & 15;
  195.  
  196.       if ((value & REGSYM_FLAG_ALIAS) && (r_num >= REG_AP))
  197.         as_snprintf(p_dest, dest_size, "%2.2s", &xtra_reg_names[(r_num - REG_AP) * 2]);
  198.       else
  199.         as_snprintf(p_dest, dest_size, "R%u", r_num);
  200.       break;
  201.     }
  202.     default:
  203.       as_snprintf(p_dest, dest_size, "%d-%u", (int)inp_size, (unsigned)value);
  204.   }
  205. }
  206.  
  207. /*--------------------------------------------------------------------------*/
  208. /* Address Decoding */
  209.  
  210. static tRegEvalResult decode_reg(const tStrComp *p_arg, Byte *p_result, Boolean must_be_reg)
  211. {
  212.   tRegDescr reg_descr;
  213.   tEvalResult eval_result;
  214.   tRegEvalResult reg_eval_result;
  215.  
  216.   if (decode_reg_core(p_arg->str.p_str, p_result, &eval_result.DataSize))
  217.   {
  218.     reg_descr.Reg = *p_result;
  219.     reg_eval_result = eIsReg;
  220.   }
  221.   else
  222.     reg_eval_result = EvalStrRegExpressionAsOperand(p_arg, &reg_descr, &eval_result, eSymbolSizeUnknown, must_be_reg);
  223.  
  224.   *p_result = reg_descr.Reg & ~REGSYM_FLAG_ALIAS;
  225.   return reg_eval_result;
  226. }
  227.  
  228. /*!------------------------------------------------------------------------
  229.  * \fn     reset_adr_vals(adr_vals_t *p_vals)
  230.  * \brief  reset encoded addressing
  231.  * \param  p_vals buffer to reset
  232.  * \return constant False for convenience
  233.  * ------------------------------------------------------------------------ */
  234.  
  235. static Boolean reset_adr_vals(adr_vals_t *p_vals)
  236. {
  237.   p_vals->mode = ModNone;
  238.   p_vals->count = 0;
  239.   p_vals->imm_value = 0;
  240.   p_vals->imm_flags = eSymbolFlag_None;
  241.   return False;
  242. }
  243.  
  244. /*!------------------------------------------------------------------------
  245.  * \fn     append_adr_vals_int(adr_vals_t *p_vals, LargeWord int_value, tSymbolSize size)
  246.  * \brief  append integer value to encoded address value
  247.  * \param  p_vals where to append
  248.  * \param  int_value value to append
  249.  * \param  size integer size
  250.  * \return
  251.  * ------------------------------------------------------------------------ */
  252.  
  253. static void append_adr_vals_int(adr_vals_t *p_vals, LargeWord int_value, tSymbolSize size)
  254. {
  255.   unsigned num_iter = GetSymbolSizeBytes(size), z;
  256.  
  257.   for (z = 0; z < num_iter; z++)
  258.   {
  259.     p_vals->vals[p_vals->count++] = int_value & 0xff;
  260.     int_value >>= 8;
  261.   }
  262. }
  263.  
  264. /*!------------------------------------------------------------------------
  265.  * \fn     decode_adr(tStrComp *p_arg, adr_vals_t *p_result, Word pc_value, unsigned mode_mask)
  266.  * \brief  parse address expression
  267.  * \param  p_arg source argument
  268.  * \param  p_result parsed result
  269.  * \param  pc_value value of PC to be used in PC-relative calculation
  270.  * \param  mode_mask bit mask of allowed addressing modes
  271.  * \return True if success
  272.  * ------------------------------------------------------------------------ */
  273.  
  274. static Boolean check_mode_mask(unsigned mode_mask, unsigned act_mask, tStrComp *p_arg, adr_vals_t *p_result)
  275. {
  276.   if (!(mode_mask & act_mask))
  277.   {
  278.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  279.     return reset_adr_vals(p_result);
  280.   }
  281.   else
  282.     return True;
  283. }
  284.  
  285. static Boolean is_pre_decrement(const tStrComp *p_arg, Byte *p_result, tRegEvalResult *p_reg_eval_result)
  286. {
  287.   String reg;
  288.   tStrComp reg_comp;
  289.   size_t arg_len = strlen(p_arg->str.p_str);
  290.  
  291.   if ((arg_len < 4)
  292.    || (p_arg->str.p_str[0] != '-')
  293.    || (p_arg->str.p_str[1] != '(')
  294.    || (p_arg->str.p_str[arg_len - 1] != ')'))
  295.     return False;
  296.   StrCompMkTemp(&reg_comp, reg, sizeof(reg));
  297.   StrCompCopySub(&reg_comp, p_arg, 2, arg_len - 3);
  298.   KillPrefBlanksStrComp(&reg_comp);
  299.   KillPostBlanksStrComp(&reg_comp);
  300.   *p_reg_eval_result = decode_reg(&reg_comp, p_result, False);
  301.   return (*p_reg_eval_result != eIsNoReg);
  302. }
  303.  
  304. static Boolean is_post_increment(const tStrComp *p_arg, Byte *p_result, tRegEvalResult *p_reg_eval_result)
  305. {
  306.   String reg;
  307.   tStrComp reg_comp;
  308.   size_t arg_len = strlen(p_arg->str.p_str);
  309.  
  310.   if ((arg_len < 4)
  311.    || (p_arg->str.p_str[0] != '(')
  312.    || (p_arg->str.p_str[arg_len - 2] != ')')
  313.    || (p_arg->str.p_str[arg_len - 1] != '+'))
  314.     return False;
  315.   StrCompMkTemp(&reg_comp, reg, sizeof(reg));
  316.   StrCompCopySub(&reg_comp, p_arg, 1, arg_len - 3);
  317.   KillPrefBlanksStrComp(&reg_comp);
  318.   KillPostBlanksStrComp(&reg_comp);
  319.   *p_reg_eval_result = decode_reg(&reg_comp, p_result, False);
  320.   return (*p_reg_eval_result != eIsNoReg);
  321. }
  322.  
  323. static Boolean decode_abs(const tStrComp *p_arg, adr_vals_t *p_result)
  324. {
  325.   Boolean ok;
  326.   LongWord address = EvalStrIntExpression(p_arg, UInt32, &ok);
  327.  
  328.   if (ok)
  329.     append_adr_vals_int(p_result, address, eSymbolSize32Bit);
  330.  
  331.   return ok;
  332. }
  333.  
  334. static int index_qualifier(const char *p_arg, int next_non_blank_pos, int split_pos)
  335. {
  336.   /* extra check for post increment: good enough? */
  337.  
  338.   int ret = ((next_non_blank_pos >= 4)
  339.        && (p_arg[0] == '(')
  340.        && (p_arg[next_non_blank_pos - 1] == ')')
  341.        && (p_arg[next_non_blank_pos] == '+'))
  342.    ? split_pos : -1;
  343.   return ret;
  344. }
  345.  
  346. static Boolean decode_adr(tStrComp *p_arg, adr_vals_t *p_result, LongWord pc_value, unsigned mode_mask)
  347. {
  348.   tStrComp arg, len_spec_arg;
  349.   Boolean deferred;
  350.   Byte reg, index_reg;
  351.   tEvalResult eval_result;
  352.   tRegEvalResult reg_eval_result;
  353.   int arg_len, split_pos;
  354.   char len_spec, ch;
  355.  
  356.   reset_adr_vals(p_result);
  357.  
  358.   /* split off deferred flag? */
  359.  
  360.   deferred = (p_arg->str.p_str[0] == '@');
  361.   StrCompRefRight(&arg, p_arg, deferred);
  362.   if (deferred)
  363.     KillPrefBlanksStrCompRef(&arg);
  364.  
  365.   /* Split off index register (which must not be PC): */
  366.  
  367.   split_pos = FindDispBaseSplitWithQualifier(arg.str.p_str, &arg_len, index_qualifier, "[]");
  368.   if (split_pos > 0)
  369.   {
  370.     String reg_str;
  371.     tStrComp reg_comp;
  372.  
  373.     StrCompMkTemp(&reg_comp, reg_str, sizeof(reg_str));
  374.     StrCompCopySub(&reg_comp, &arg, split_pos + 1, arg_len - split_pos - 2);
  375.     KillPostBlanksStrComp(&reg_comp);
  376.     KillPrefBlanksStrComp(&reg_comp);
  377.     switch (decode_reg(&reg_comp, &index_reg, False))
  378.     {
  379.       case eRegAbort:
  380.         return False;
  381.       case eIsReg:
  382.         StrCompShorten(&arg, arg_len - split_pos);
  383.         p_result->vals[p_result->count++] = (index_reg |= 0x40);
  384.         pc_value++;
  385.         break;
  386.       default:
  387.         break;
  388.     }
  389.   }
  390.   else
  391.     index_reg = 0;
  392.  
  393.   /* Plain register? */
  394.  
  395.   switch (decode_reg(&arg, &reg, False))
  396.   {
  397.     case eIsReg:
  398.       if (index_reg && !deferred)
  399.       {
  400.         WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  401.         return reset_adr_vals(p_result);
  402.       }
  403.       p_result->vals[p_result->count++] = reg | (deferred ? 0x60 : 0x50);
  404.       return check_mode_mask(mode_mask, deferred ? MModMem : MModReg, p_arg, p_result);
  405.     case eRegAbort:
  406.       return reset_adr_vals(p_result);
  407.     default:
  408.       break;
  409.   }
  410.  
  411.   /* Split off length specifier (BWLIS)^... */
  412.  
  413.   if ((strlen(arg.str.p_str) > 2)
  414.    && ('^' == arg.str.p_str[1])
  415.    && strchr("BWLIS", (ch = as_toupper(arg.str.p_str[0]))))
  416.   {
  417.     StrCompSplitRef(&len_spec_arg, &arg, &arg, &arg.str.p_str[1]);
  418.     len_spec = ch;
  419.     KillPrefBlanksStrCompRef(&arg);
  420.   }
  421.   else
  422.   {
  423.     len_spec = '\0';
  424.     LineCompReset(&len_spec_arg.Pos);
  425.   }
  426.  
  427.   /* #imm, @#abs */
  428.  
  429.   if (*arg.str.p_str == '#')
  430.   {
  431.     tStrComp imm_arg;
  432.  
  433.     StrCompRefRight(&imm_arg, &arg, 1);
  434.  
  435.     /* @#abs */
  436.  
  437.     if (deferred)
  438.     {
  439.       p_result->vals[p_result->count++] = 0x90 | REG_PC;
  440.       eval_result.OK = decode_abs(&imm_arg, p_result);
  441.       return eval_result.OK
  442.              ? check_mode_mask(mode_mask, MModMem, p_arg, p_result)
  443.              : reset_adr_vals(p_result);
  444.     }
  445.  
  446.     /* #imm */
  447.  
  448.     else
  449.     {
  450.       IntType eval_int_type;
  451.       int (*float_convert)(as_float_t inp, Word *p_dest);
  452.       Byte *p_specifier;
  453.  
  454.       if (index_reg)
  455.       {
  456.         WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  457.         return reset_adr_vals(p_result);
  458.       }
  459.  
  460.       p_specifier = &p_result->vals[p_result->count]; p_result->count++;
  461.  
  462.       if (len_spec && (len_spec != 'S') && (len_spec != 'I'))
  463.       {
  464.         WrStrErrorPos(ErrNum_UndefAttr, &len_spec_arg);
  465.         return reset_adr_vals(p_result);
  466.       }
  467.  
  468.       switch (op_size)
  469.       {
  470.         case eSymbolSize8Bit:
  471.           eval_int_type = Int8;
  472.           goto int_common;
  473.         case eSymbolSize16Bit:
  474.           eval_int_type = Int16;
  475.           goto int_common;
  476.         case eSymbolSize64Bit:
  477.         case eSymbolSize128Bit:
  478. #ifdef HAS64
  479.           eval_int_type = Int64;
  480.           goto int_common;
  481. #endif
  482.         case eSymbolSize32Bit:
  483.           eval_int_type = Int32;
  484.           goto int_common;
  485.  
  486.         case eSymbolSizeFloat32Bit:
  487.           float_convert = as_float_2_dec_f;
  488.           goto float_common;
  489.  
  490.         case eSymbolSizeFloat64Bit:
  491.           float_convert = as_float_2_dec_d;
  492.           goto float_common;
  493.  
  494.         case eSymbolSizeFloat64Bit_G:
  495.           float_convert = as_float_2_dec_g;
  496.           goto float_common;
  497.  
  498.         case eSymbolSizeFloat128Bit:
  499.           float_convert = as_float_2_dec_h;
  500.           goto float_common;
  501.  
  502.         int_common:
  503.         {
  504.           if (len_spec == 'S')
  505.             eval_int_type = UInt6;
  506.           p_result->imm_value = EvalStrIntExpressionWithFlags(&imm_arg, eval_int_type, &eval_result.OK, &p_result->imm_flags);
  507.           if (!eval_result.OK)
  508.             return reset_adr_vals(p_result);
  509.           if (!len_spec)
  510.             len_spec = (RangeCheck(p_result->imm_value, UInt6) && (mode_mask & MModLit)) ? 'S' : 'I';
  511.           if (len_spec == 'S')
  512.           {
  513.             *p_specifier = p_result->imm_value & 63;
  514.             return check_mode_mask(mode_mask, MModLit, p_arg, p_result);
  515.           }
  516.           else
  517.           {
  518.             *p_specifier = 0x80 | REG_PC;
  519.             append_adr_vals_int(p_result, (LargeWord)p_result->imm_value, op_size);
  520.             return check_mode_mask(mode_mask, MModImm, p_arg, p_result);
  521.           }
  522.         }
  523.  
  524.         float_common:
  525.         {
  526.           as_float_t value = EvalStrFloatExpressionWithResult(&imm_arg, &eval_result);
  527.  
  528.           if (!eval_result.OK)
  529.             return reset_adr_vals(p_result);
  530.           if (len_spec == 'S')
  531.           {
  532.             int ret = as_float_2_dec_lit(value, p_specifier);
  533.             if (ret <= 0)
  534.             {
  535.               asmerr_check_fp_dispose_result(ret, &imm_arg);
  536.               return reset_adr_vals(p_result);
  537.             }
  538.           }
  539.           else if (!len_spec && (mode_mask & MModLit) && (as_float_2_dec_lit(value, p_specifier) > 0)) { }
  540.           else
  541.           {
  542.             Word buf[8];
  543.             int z, ret = float_convert(value, buf);
  544.  
  545.             if (ret < 0)
  546.             {
  547.               asmerr_check_fp_dispose_result(ret, &imm_arg);
  548.               return reset_adr_vals(p_result);
  549.             }
  550.             *p_specifier = 0x80 | REG_PC;
  551.             for (z = 0; z < ret; z++)
  552.             {
  553.               p_result->vals[p_result->count++] = Lo(buf[z]);
  554.               p_result->vals[p_result->count++] = Hi(buf[z]);
  555.             }
  556.           }
  557.           return check_mode_mask(mode_mask, (p_result->count > 1) ? MModImm : MModLit, p_arg, p_result);
  558.         }
  559.  
  560.         default:
  561.           WrStrErrorPos(ErrNum_InvOpSize, &imm_arg);
  562.           return reset_adr_vals(p_result);
  563.       }
  564.     }
  565.   }
  566.  
  567.   /* (Rn)+, @(Rn)+ */
  568.  
  569.   if (is_post_increment(&arg, &reg, &reg_eval_result))
  570.   {
  571.     if (eRegAbort == reg_eval_result)
  572.       return reset_adr_vals(p_result);
  573.     else if (len_spec)
  574.     {
  575.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  576.       return reset_adr_vals(p_result);
  577.     }
  578.     if (index_reg && (reg == (index_reg & 0xf)))
  579.       WrStrErrorPos(ErrNum_Unpredictable,p_arg);
  580.     p_result->vals[p_result->count++] = reg | (deferred ? 0x90 : 0x80);
  581.     return check_mode_mask(mode_mask, MModMem, p_arg, p_result);
  582.   }
  583.  
  584.   /* -(Rn), @-(Rn) (not supported on VAX) */
  585.  
  586.   if (is_pre_decrement(&arg, &reg, &reg_eval_result))
  587.   {
  588.     if (eRegAbort == reg_eval_result)
  589.       return reset_adr_vals(p_result);
  590.     else if (deferred || len_spec)
  591.     {
  592.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  593.       return reset_adr_vals(p_result);
  594.     }
  595.     if (index_reg && (reg == (index_reg & 0xf)))
  596.       WrStrErrorPos(ErrNum_Unpredictable,p_arg);
  597.     p_result->vals[p_result->count++] = reg | 0x70;
  598.     return check_mode_mask(mode_mask, MModMem, p_arg, p_result);
  599.   }
  600.  
  601.   /* (Rn), X(Rn) */
  602.  
  603.   split_pos = FindDispBaseSplitWithQualifier(arg.str.p_str, &arg_len, NULL, "()");
  604.   if (split_pos >= 0)
  605.   {
  606.     tStrComp disp_arg, reg_arg;
  607.  
  608.     StrCompSplitRef(&disp_arg, &reg_arg, &arg, &arg.str.p_str[split_pos]);
  609.     KillPostBlanksStrComp(&disp_arg);
  610.     KillPrefBlanksStrCompRef(&reg_arg);
  611.     StrCompShorten(&reg_arg, 1);
  612.     KillPostBlanksStrComp(&reg_arg);
  613.  
  614.     if (decode_reg(&reg_arg, &reg, True) != eIsReg)
  615.     {
  616.       WrStrErrorPos(ErrNum_InvReg, &reg_arg);
  617.       return reset_adr_vals(p_result);
  618.     }
  619.  
  620.     /* (Rn) */
  621.  
  622.     if (!*disp_arg.str.p_str && !deferred)
  623.     {
  624.       if (len_spec)
  625.       {
  626.         WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  627.         return reset_adr_vals(p_result);
  628.       }
  629.       p_result->vals[p_result->count++] = reg | 0x60;
  630.     }
  631.  
  632.     /* X(Rn) */
  633.  
  634.     else
  635.     {
  636.       LongInt disp;
  637.       tSymbolSize size = eSymbolSizeUnknown;
  638.       IntType eval_int_type;
  639.  
  640.       switch (len_spec)
  641.       {
  642.         case 'B':
  643.           eval_int_type = SInt8;
  644.           size = eSymbolSize8Bit;
  645.           break;
  646.         case 'W':
  647.           eval_int_type = SInt16;
  648.           size = eSymbolSize16Bit;
  649.           break;
  650.         case 'L':
  651.           size = eSymbolSize32Bit;
  652.           /* FALL-THRU */
  653.         case '\0':
  654.           eval_int_type = SInt32;
  655.           break;
  656.         default: /* I,S not allowed here */
  657.           WrStrErrorPos(ErrNum_UndefAttr, &len_spec_arg);
  658.           return reset_adr_vals(p_result);
  659.       }
  660.       if (disp_arg.str.p_str[0])
  661.         disp = EvalStrIntExpressionWithResult(&disp_arg, eval_int_type, &eval_result);
  662.       else
  663.       {
  664.         disp = 0;
  665.         eval_result.OK = True;
  666.       }
  667.       if (!eval_result.OK)
  668.         return reset_adr_vals(p_result);
  669.  
  670.       /* deduce displacement size */
  671.  
  672.       if (eSymbolSizeUnknown == size)
  673.       {
  674.         if (RangeCheck(disp, SInt8))
  675.           size = eSymbolSize8Bit;
  676.         else if (RangeCheck(disp, SInt16))
  677.           size = eSymbolSize16Bit;
  678.         else
  679.           size = eSymbolSize32Bit;
  680.       }
  681.  
  682.       /* write out addressing mode */
  683.  
  684.       switch (size)
  685.       {
  686.         case eSymbolSize32Bit:
  687.           p_result->vals[p_result->count++] = reg | (deferred ? 0xf0 : 0xe0);
  688.           break;
  689.         case eSymbolSize16Bit:
  690.           p_result->vals[p_result->count++] = reg | (deferred ? 0xd0 : 0xc0);
  691.           break;
  692.         default:
  693.           p_result->vals[p_result->count++] = reg | (deferred ? 0xb0 : 0xa0);
  694.       }
  695.       append_adr_vals_int(p_result, disp, size);
  696.     }
  697.     return check_mode_mask(mode_mask, MModMem, p_arg, p_result);
  698.   }
  699.  
  700.   {
  701.     LongInt dist;
  702.     tSymbolSize dist_size;
  703.  
  704.     /* Remains: rel, @rel
  705.        PC value is the PC value after displacement was loaded,
  706.        which is the 'current PC' within the instruction we got as
  707.        argument, plus the specifier and optional index byte,
  708.        plus 1, 2, or 4 bytes for the displacement itself: */
  709.  
  710.     dist = EvalStrIntExpressionWithResult(&arg, UInt32, &eval_result) - pc_value;
  711.     if (!eval_result.OK)
  712.       return False;
  713.  
  714.     if (!len_spec)
  715.     {
  716.       if (RangeCheck(dist - 2, SInt8))
  717.         len_spec = 'B';
  718.       else if (RangeCheck(dist - 3, SInt16))
  719.         len_spec = 'W';
  720.       else
  721.         len_spec = 'L';
  722.     }
  723.     switch (len_spec)
  724.     {
  725.       case 'B':
  726.         p_result->vals[p_result->count++] = REG_PC | (deferred ? 0xb0 : 0xa0);
  727.         dist -= 2;
  728.         if (!mFirstPassUnknownOrQuestionable(eval_result.Flags) && !ChkRangeByType(dist, SInt8, &arg))
  729.           return reset_adr_vals(p_result);
  730.         dist_size = eSymbolSize8Bit;
  731.         break;
  732.       case 'W':
  733.         p_result->vals[p_result->count++] = REG_PC | (deferred ? 0xd0 : 0xc0);
  734.         dist -= 3;
  735.         if (!mFirstPassUnknownOrQuestionable(eval_result.Flags) && !ChkRangeByType(dist, SInt16, &arg))
  736.           return reset_adr_vals(p_result);
  737.         dist_size = eSymbolSize16Bit;
  738.         break;
  739.       case 'L':
  740.         p_result->vals[p_result->count++] = REG_PC | (deferred ? 0xf0 : 0xe0);
  741.         dist -= 5;
  742.         dist_size = eSymbolSize32Bit;
  743.         break;
  744.       default:
  745.         WrStrErrorPos(ErrNum_UndefAttr, &len_spec_arg);
  746.         return reset_adr_vals(p_result);
  747.     }
  748.     append_adr_vals_int(p_result, (LongWord)dist, dist_size);
  749.     return check_mode_mask(mode_mask, MModMem, p_arg, p_result);
  750.   }
  751. }
  752.  
  753. /*!------------------------------------------------------------------------
  754.  * \fn     is_register(const adr_vals_t *p_vals)
  755.  * \brief  checks whether encoded argument is a register
  756.  * \param  p_vals encoded argument
  757.  * \return True if yes
  758.  * ------------------------------------------------------------------------ */
  759.  
  760. static Boolean is_register(const adr_vals_t *p_vals)
  761. {
  762.   return (p_vals->count > 0)
  763.       && ((p_vals->vals[0] & 0xf0) == 0x50);
  764. }
  765.  
  766. /*!------------------------------------------------------------------------
  767.  * \fn     is_immediate(const adr_vals_t *p_vals)
  768.  * \brief  checks whether encoded argument is immediate
  769.  * \param  p_vals encoded argument
  770.  * \return True if yes
  771.  * ------------------------------------------------------------------------ */
  772.  
  773. static Boolean is_immediate(const adr_vals_t *p_vals)
  774. {
  775.   return (p_vals->count > 0)
  776.       && ((p_vals->vals[0] == (0x80 | REG_PC)) /* i^... */
  777.        || (p_vals->vals[0] <= 0x3f)); /* s^... */
  778. }
  779.  
  780. /*!------------------------------------------------------------------------
  781.  * \fn     decode_branch(tStrComp *p_arg, adr_vals_t *p_result, LongWord pc_value)
  782.  * \brief  handle branch addressing mode
  783.  * \param  p_arg source argument
  784.  * \param  p_result dest buffer
  785.  * \param  pc_value value of PC to use in calculation
  786.  * \return True if argument OK
  787.  * ------------------------------------------------------------------------ */
  788.  
  789. static Boolean decode_branch(tStrComp *p_arg, adr_vals_t *p_result, LongWord pc_value)
  790. {
  791.   tSymbolFlags flags;
  792.   Boolean ok;
  793.   LongWord dest;
  794.   LongInt dist;
  795.   IntType range_int;
  796.   tSymbolSize act_op_size;
  797.  
  798.   reset_adr_vals(p_result);
  799.   dest = EvalStrIntExpressionWithFlags(p_arg, UInt32, &ok, &flags);
  800.   if (!ok)
  801.     return False;
  802.   if (op_size == eSymbolSizeUnknown)
  803.   {
  804.     dist = dest - (pc_value + 1);
  805.     if (RangeCheck(dist, SInt8))
  806.       act_op_size = eSymbolSize8Bit;
  807.     else
  808.     {
  809.       act_op_size = eSymbolSize16Bit;
  810.       BAsmCode[CodeLen - 1] += 0x20;
  811.     }
  812.   }
  813.   else
  814.     act_op_size = op_size;
  815.   dist = dest - (pc_value + GetSymbolSizeBytes(act_op_size));
  816.   if (!mFirstPassUnknownOrQuestionable(flags))
  817.   {
  818.     switch (act_op_size)
  819.     {
  820.       case eSymbolSize8Bit:
  821.         range_int = SInt8;
  822.         goto check;
  823.       case eSymbolSize16Bit:
  824.         range_int = SInt16;
  825.         goto check;
  826.       default:
  827.         return False;
  828.       check:
  829.         if (!RangeCheck(dist, range_int))
  830.         {
  831.           WrStrErrorPos(ErrNum_JmpDistTooBig, p_arg);
  832.           return False;
  833.         }
  834.     }
  835.   }
  836.   append_adr_vals_int(p_result, dist, act_op_size);
  837.   return True;
  838. }
  839.  
  840. /*!------------------------------------------------------------------------
  841.  * \fn     append_adr_vals(const adr_vals_t *p_vals)
  842.  * \brief  append addressing mode values to instruction stream
  843.  * \param  p_vals values to append
  844.  * ------------------------------------------------------------------------ */
  845.  
  846. static void append_adr_vals(const adr_vals_t *p_vals)
  847. {
  848.   SetMaxCodeLen(CodeLen + p_vals->count);
  849.   memcpy(&BAsmCode[CodeLen], p_vals->vals, p_vals->count);
  850.   CodeLen += p_vals->count;
  851. }
  852.  
  853. /*!------------------------------------------------------------------------
  854.  * \fn     set_access_mode(unsigned new_access_mode)
  855.  * \brief  set assumed access mode incl. readable symbol
  856.  * \param  new_access_mode mode to set (0...3)
  857.  * ------------------------------------------------------------------------ */
  858.  
  859. static void set_access_mode(unsigned new_access_mode)
  860. {
  861.   tStrComp tmp_comp;
  862.  
  863.   curr_access_mode_set = True;
  864.   curr_access_mode = new_access_mode;
  865.   PushLocHandle(-1);
  866.   StrCompMkTemp(&tmp_comp, (char*)access_mode_name, 0);
  867.   EnterIntSymbol(&tmp_comp, curr_access_mode, SegNone, True);
  868.   PopLocHandle();
  869. }
  870.  
  871. /*--------------------------------------------------------------------------*/
  872. /* Instruction Handler Helpers */
  873.  
  874. /*!------------------------------------------------------------------------
  875.  * \fn     code_len(Word op_code)
  876.  * \brief  check whether opcode is one or two byte opcode
  877.  * \param  op_code opcode
  878.  * \return 1 or 2
  879.  * ------------------------------------------------------------------------ */
  880.  
  881. static int code_len(Word op_code)
  882. {
  883.   return 1 + !!Hi(op_code);
  884. }
  885.  
  886. /*!------------------------------------------------------------------------
  887.  * \fn     append_opcode(Word op_code)
  888.  * \brief  append opcode to instruction stream
  889.  * \param  op_code opcode to append
  890.  * ------------------------------------------------------------------------ */
  891.  
  892. static void append_opcode(Word op_code)
  893. {
  894.   SetMaxCodeLen(CodeLen + code_len(op_code));
  895.  
  896.   BAsmCode[CodeLen++] = Lo(op_code);
  897.   if (Hi(op_code))
  898.     BAsmCode[CodeLen++] = Hi(op_code);
  899. }
  900.  
  901. /*!------------------------------------------------------------------------
  902.  * \fn     chk_required_caps(Word required_caps)
  903.  * \brief  check whether current target supports all required capabilities
  904.  * \param  required_caps bit mask of required capabilities
  905.  * \return True if yes
  906.  * ------------------------------------------------------------------------ */
  907.  
  908. static Boolean chk_required_caps(Word required_caps)
  909. {
  910.   if ((p_curr_cpu_props->caps & required_caps) != required_caps)
  911.   {
  912.     WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  913.     return False;
  914.   }
  915.   else
  916.     return True;
  917. }
  918.  
  919. /*--------------------------------------------------------------------------*/
  920. /* Instruction Handlers */
  921.  
  922. /*!------------------------------------------------------------------------
  923.  * \fn     decode_gen(Word index)
  924.  * \brief  handle generic instruction
  925.  * \param  index index into instruction list
  926.  * ------------------------------------------------------------------------ */
  927.  
  928. static void decode_gen(Word index)
  929. {
  930.   const gen_order_t *p_order = &gen_orders[index];
  931.   adr_vals_t adr_vals;
  932.   unsigned tot_count;
  933.   size_t z;
  934.   Boolean bit_field_size_imm = False,
  935.           bit_field_pos_imm = False;
  936.   tSymbolFlags bit_field_pos_flags = eSymbolFlag_None,
  937.                bit_field_size_flags = eSymbolFlag_None;
  938.   LongWord bit_field_pos = 0;
  939.   Byte bit_field_size = 0;
  940.  
  941.   if (!ChkArgCnt(p_order->arg_cnt, p_order->arg_cnt)
  942.    || !chk_required_caps(p_order->required_caps))
  943.     return;
  944.  
  945.   if (curr_access_mode > p_order->max_access_mode)
  946.   {
  947.     WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
  948.     return;
  949.   }
  950.  
  951.   append_opcode(p_order->code);
  952.   tot_count = code_len(p_order->code);
  953.   for (z = 0; z < p_order->arg_cnt; z++)
  954.   {
  955.     Boolean ret;
  956.  
  957.     /* Decode n-th argument */
  958.  
  959.     op_size = p_order->op_size[z];
  960.     ret = (p_order->adr_mode_mask[z] == MModBranch)
  961.         ? decode_branch(&ArgStr[z + 1], &adr_vals, EProgCounter() + tot_count)
  962.         : decode_adr(&ArgStr[z + 1], &adr_vals, EProgCounter() + tot_count, p_order->adr_mode_mask[z]);
  963.     if (!ret)
  964.     {
  965.       CodeLen = 0;
  966.       return;
  967.     }
  968.  
  969.     /* Consistency checks for bit field size/position arguments.
  970.        Of course, we can only warn if the size/pos values are immediate.
  971.        The field size may be missing if it is implicitly one: */
  972.  
  973.     if (p_order->bit_field_arg_start >= 0)
  974.     {
  975.       int bfield_index = z - p_order->bit_field_arg_start;
  976.  
  977.       switch (bfield_index)
  978.       {
  979.         case 0: /* position argument, independent of presence of size argument: */
  980.           if (is_immediate(&adr_vals))
  981.           {
  982.             bit_field_pos_imm = True;
  983.             bit_field_pos = adr_vals.imm_value;
  984.             bit_field_pos_flags = adr_vals.imm_flags;  
  985.           }
  986.           break;
  987.         case 1: /* size argument or already location argument: */
  988.           if (!p_order->bit_field_size_present)
  989.           {
  990.             bit_field_size_imm = True;
  991.             bit_field_size = 1;
  992.             bit_field_size_flags = eSymbolFlag_None;
  993.             goto check_location;
  994.           }
  995.           else if (is_immediate(&adr_vals))
  996.           {
  997.             bit_field_size_imm = True;
  998.             bit_field_size = adr_vals.imm_value;
  999.             bit_field_size_flags = adr_vals.imm_flags;
  1000.             if (!mFirstPassUnknownOrQuestionable(bit_field_size_flags)
  1001.              && (bit_field_size > 32))
  1002.             {
  1003.               WrStrErrorPos(ErrNum_InvBitField, &ArgStr[z + 1]);
  1004.               CodeLen = 0;
  1005.               return;
  1006.             }
  1007.           }
  1008.           break;
  1009.         case 2: /* location argument if size argument was present */
  1010.           if (p_order->bit_field_size_present)
  1011.             goto check_location;
  1012.           break;
  1013.         check_location:
  1014.           if (is_register(&adr_vals))
  1015.           {
  1016.             if (bit_field_size_imm
  1017.              && bit_field_pos_imm
  1018.              && !mFirstPassUnknownOrQuestionable(bit_field_size_flags)
  1019.              && !mFirstPassUnknownOrQuestionable(bit_field_pos_flags)
  1020.              && (bit_field_size != 0)
  1021.              && (bit_field_pos > 31))
  1022.             {
  1023.               WrStrErrorPos(ErrNum_InvBitField, &ArgStr[z + 1]);
  1024.               CodeLen = 0;
  1025.               return;
  1026.             }
  1027.           }
  1028.           break;
  1029.       }
  1030.     }
  1031.  
  1032.     /* Append to instruction stream: */
  1033.  
  1034.     append_adr_vals(&adr_vals);
  1035.     tot_count += adr_vals.count;
  1036.   }
  1037. }
  1038.  
  1039. /*!------------------------------------------------------------------------
  1040.  * \fn     decode_case(Word code)
  1041.  * \brief  Handle CASEx instructions
  1042.  * \param  code machine code & operand size
  1043.  * ------------------------------------------------------------------------ */
  1044.  
  1045. static void decode_case(Word code)
  1046. {
  1047.   int z;
  1048.   adr_vals_t adr_vals;
  1049.   unsigned tot_count;
  1050.  
  1051.   /* Selector, base & limit are mandatory: */
  1052.  
  1053.   if (!ChkArgCnt(3, ArgCntMax))
  1054.     return;
  1055.  
  1056.   /* Opcode first: */
  1057.  
  1058.   op_size = (tSymbolSize)Hi(code);
  1059.   append_opcode(Lo(code));
  1060.   tot_count = 1;
  1061.  
  1062.   /* Decode the fixed arguments: */
  1063.  
  1064.   for (z = 1; z <= 3; z++)
  1065.   {
  1066.     if (!decode_adr(&ArgStr[z], &adr_vals, EProgCounter() + tot_count, MModReg | MModMem | MModLit | MModImm))
  1067.     {
  1068.       CodeLen = 0;
  1069.       return;
  1070.     }
  1071.  
  1072.     /* Consistency check: */
  1073.  
  1074.     if ((3 == z)
  1075.      && is_immediate(&adr_vals)
  1076.      && (adr_vals.imm_value + 4 != ArgCnt))
  1077.       WrStrErrorPos(ErrNum_CaseWrongArgCnt, &ArgStr[z]);
  1078.  
  1079.     append_adr_vals(&adr_vals);
  1080.     tot_count += adr_vals.count;
  1081.   }
  1082.  
  1083.   /* Do not increment tot_count for branch arguments, since all displacements
  1084.      are relative to disp[0].  Further, we have to compensate for decode_branch()
  1085.      adding the displacement's size: */
  1086.  
  1087.   op_size = eSymbolSize16Bit;
  1088.   for (; z <= ArgCnt; z++)
  1089.   {
  1090.     if (!decode_branch(&ArgStr[z], &adr_vals, EProgCounter() + tot_count - 2))
  1091.     {
  1092.       CodeLen = 0;
  1093.       return;
  1094.     }
  1095.     append_adr_vals(&adr_vals);
  1096.   }
  1097. }
  1098.  
  1099. /*!------------------------------------------------------------------------
  1100.  * \fn     decode_var_arg(Word index)
  1101.  * \brief  handle instructions with a variable number of generic operands
  1102.  * \param  index index into instruction table
  1103.  * ------------------------------------------------------------------------ */
  1104.  
  1105. static void decode_var_arg(Word index)
  1106. {
  1107.   const var_arg_order_t *p_var_arg_order = &var_arg_orders[index];
  1108.   size_t z;
  1109.  
  1110.   for (z = 0; z < as_array_size(p_var_arg_order->gen_indices); z++)
  1111.     if (p_var_arg_order->gen_indices[z] < 0)
  1112.       break;
  1113.     else if (ArgCnt == (int)gen_orders[p_var_arg_order->gen_indices[z]].arg_cnt)
  1114.     {
  1115.       decode_gen(p_var_arg_order->gen_indices[z]);
  1116.       return;
  1117.     }
  1118.   WrError(ErrNum_WrongArgCnt);
  1119. }
  1120.  
  1121. /*!------------------------------------------------------------------------
  1122.  * \fn     decode_accmode(Word index)
  1123.  * \brief  handle ACCMODE instruction
  1124.  * ------------------------------------------------------------------------ */
  1125.  
  1126. static void decode_accmode(Word index)
  1127. {
  1128.   static const char mode_names[][11] = { "kernel", "executive", "supervisor", "user" };
  1129.   unsigned mode;
  1130.   Boolean ok;
  1131.  
  1132.   UNUSED(index);
  1133.  
  1134.   if (!ChkArgCnt(1, 1))
  1135.     return;
  1136.   for (mode = 0; mode < as_array_size(mode_names); mode++)
  1137.     if (!as_strcasecmp(ArgStr[1].str.p_str, mode_names[mode]))
  1138.     {
  1139.       set_access_mode(mode);
  1140.       return;
  1141.     }
  1142.  
  1143.   mode = EvalStrIntExpression(&ArgStr[1], UInt2, &ok);
  1144.   if (ok)
  1145.     set_access_mode(mode);
  1146. }
  1147.  
  1148. /*--------------------------------------------------------------------------*/
  1149. /* Instruction Lookup Table */
  1150.  
  1151. /*!------------------------------------------------------------------------
  1152.  * \fn     init_fields(void)
  1153.  * \brief  create lookup table
  1154.  * ------------------------------------------------------------------------ */
  1155.  
  1156. static unsigned get_adr_mode_mask(char specifier)
  1157. {
  1158.   switch (as_toupper(specifier))
  1159.   {
  1160.     case 'R':
  1161.       return MModImm | MModLit | MModMem | MModReg;
  1162.     case 'W':
  1163.     case 'M':
  1164.       return MModMem | MModReg;
  1165.     case 'A':
  1166.       return MModMem | MModImm;
  1167.     case 'V':
  1168.       return MModMem | MModImm | MModReg;
  1169.     case 'B':
  1170.       return MModBranch;
  1171.     default:
  1172.       return 0;
  1173.   }
  1174. }
  1175.  
  1176. static gen_order_t *rsv_gen_order(Word code)
  1177. {
  1178.   gen_order_t *p_order;
  1179.  
  1180.   order_array_rsv_end(gen_orders, gen_order_t);
  1181.   p_order = &gen_orders[InstrZ];
  1182.   p_order->code = code;
  1183.   p_order->bit_field_arg_start = -1;
  1184.   p_order->bit_field_size_present = False;
  1185.   p_order->max_access_mode = 3;
  1186.   p_order->required_caps = e_cpu_cap_none;
  1187.   p_order->arg_cnt = 0;
  1188.   return p_order;
  1189. }
  1190.  
  1191. static var_arg_order_t *rsv_var_arg_order(void)
  1192. {
  1193.   var_arg_order_t *p_order;
  1194.   size_t z;
  1195.  
  1196.   dyn_array_rsv_end(var_arg_orders, var_arg_order_t, var_arg_op_cnt);
  1197.   p_order = &var_arg_orders[var_arg_op_cnt];
  1198.   for (z = 0; z < as_array_size(p_order->gen_indices); z++)
  1199.     p_order->gen_indices[z] = -1;
  1200.   return p_order;
  1201. }
  1202.  
  1203. static void add_fixed(const char *p_name, Word code)
  1204. {
  1205.   (void)rsv_gen_order(code);
  1206.  
  1207.   AddInstTable(InstTable, p_name, InstrZ++, decode_gen);
  1208. }
  1209.  
  1210. static void add_one_op(const char *p_name, tSymbolSize op_size, Boolean allow_dest_immediate, Word code)
  1211. {
  1212.   gen_order_t *p_order = rsv_gen_order(code);
  1213.  
  1214.   p_order->arg_cnt = 1;
  1215.   p_order->adr_mode_mask[0] = get_adr_mode_mask(allow_dest_immediate ? 'r' : 'w');
  1216.   p_order->op_size[0] = op_size;
  1217.   AddInstTable(InstTable, p_name, InstrZ++, decode_gen);
  1218. }
  1219.  
  1220. static int add_two_op_size(const char *p_name, tSymbolSize src_op_size, tSymbolSize dest_op_size, Boolean allow_dest_immediate, Word code)
  1221. {
  1222.   gen_order_t *p_order = rsv_gen_order(code);
  1223.  
  1224.   p_order->arg_cnt = 2;
  1225.   p_order->adr_mode_mask[0] = get_adr_mode_mask('r');
  1226.   p_order->adr_mode_mask[1] = get_adr_mode_mask(allow_dest_immediate ? 'r' : 'w');
  1227.   p_order->op_size[0] = src_op_size;
  1228.   p_order->op_size[1] = dest_op_size;
  1229.   AddInstTable(InstTable, p_name, InstrZ, decode_gen);
  1230.   return InstrZ++;
  1231. }
  1232.  
  1233. static int add_two_op(const char *p_name, tSymbolSize op_size, Boolean allow_dest_immediate, Word code)
  1234. {
  1235.   return add_two_op_size(p_name, op_size, op_size, allow_dest_immediate, code);
  1236. }
  1237.  
  1238. static int add_three_op(const char *p_name, tSymbolSize op_size, Word code)
  1239. {
  1240.   gen_order_t *p_order = rsv_gen_order(code);
  1241.  
  1242.   p_order->arg_cnt = 3;
  1243.   p_order->adr_mode_mask[0] =
  1244.   p_order->adr_mode_mask[1] = get_adr_mode_mask('r');
  1245.   p_order->adr_mode_mask[2] = get_adr_mode_mask('w');
  1246.   p_order->op_size[0] =
  1247.   p_order->op_size[1] =
  1248.   p_order->op_size[2] = op_size;
  1249.   AddInstTable(InstTable, p_name, InstrZ, decode_gen);
  1250.   return InstrZ++;
  1251. }
  1252.  
  1253. static void add_two_three_op(const char *p_name, tSymbolSize op_size, Word code)
  1254. {
  1255.   char name[20];
  1256.   var_arg_order_t *p_order = rsv_var_arg_order();
  1257.  
  1258.   as_snprintf(name, sizeof(name), "%s2", p_name);
  1259.   p_order->gen_indices[0] = add_two_op(name, op_size, False, code);
  1260.   as_snprintf(name, sizeof(name), "%s3", p_name);
  1261.   p_order->gen_indices[1] = add_three_op(name, op_size, Hi(code) ? (code + 0x100) : (code + 1));
  1262.   AddInstTable(InstTable, p_name, var_arg_op_cnt++, decode_var_arg);
  1263. }
  1264.  
  1265. static void add_byte_two_op(const char *p_name, tSymbolSize op_size, Word code)
  1266. {
  1267.   gen_order_t *p_order = rsv_gen_order(code);
  1268.  
  1269.   p_order->arg_cnt = 3;
  1270.   p_order->adr_mode_mask[0] =
  1271.   p_order->adr_mode_mask[1] = get_adr_mode_mask('r');
  1272.   p_order->adr_mode_mask[2] = get_adr_mode_mask('w');
  1273.   p_order->op_size[0] = eSymbolSize8Bit;
  1274.   p_order->op_size[1] =
  1275.   p_order->op_size[2] = op_size;
  1276.   AddInstTable(InstTable, p_name, InstrZ++, decode_gen);
  1277. }
  1278.  
  1279. static int add_gen_caps(const char *p_name, const char *p_format, Word code, cpu_cap_t required_caps)
  1280. {
  1281.   gen_order_t *p_order = rsv_gen_order(code);
  1282.  
  1283.   p_order->required_caps = required_caps;
  1284.   if (isdigit(*p_format))
  1285.   {
  1286.     p_order->max_access_mode = *p_format - '0';
  1287.     p_format++;
  1288.   }
  1289.   for (; p_format[0] && p_format[1]; p_format += 2)
  1290.   {
  1291.     assert(p_order->arg_cnt < as_array_size(p_order->adr_mode_mask));
  1292.     p_order->adr_mode_mask[p_order->arg_cnt] = get_adr_mode_mask(p_format[0]);
  1293.     if ('V' == as_toupper(p_format[0]))
  1294.     {
  1295.       if (p_order->arg_cnt >= 2)
  1296.       {
  1297.         p_order->bit_field_arg_start = p_order->arg_cnt - 2;
  1298.         p_order->bit_field_size_present = True;
  1299.       }
  1300.       else /* BBx operate on bit fields of implicit size one */
  1301.         p_order->bit_field_arg_start = p_order->arg_cnt - 1;
  1302.     }
  1303.     switch (as_toupper(p_format[1]))
  1304.     {
  1305.       case 'X':
  1306.         p_order->op_size[p_order->arg_cnt] = eSymbolSizeUnknown;
  1307.         break;
  1308.       case 'B':
  1309.         p_order->op_size[p_order->arg_cnt] = eSymbolSize8Bit;
  1310.         break;
  1311.       case 'W':
  1312.         p_order->op_size[p_order->arg_cnt] = eSymbolSize16Bit;
  1313.         break;
  1314.       case 'L':
  1315.         p_order->op_size[p_order->arg_cnt] = eSymbolSize32Bit;
  1316.         break;
  1317.       case 'F':
  1318.         p_order->op_size[p_order->arg_cnt] = eSymbolSizeFloat32Bit;
  1319.         break;
  1320.       case 'Q':
  1321.         p_order->op_size[p_order->arg_cnt] = eSymbolSize64Bit;
  1322.         break;
  1323.       case 'D':
  1324.         p_order->op_size[p_order->arg_cnt] = eSymbolSizeFloat64Bit;
  1325.         break;
  1326.       case 'G':
  1327.         p_order->op_size[p_order->arg_cnt] = eSymbolSizeFloat64Bit_G;
  1328.         p_order->required_caps |= e_cpu_cap_float_g;
  1329.         break;
  1330.       case 'O':
  1331.         p_order->op_size[p_order->arg_cnt] = eSymbolSize128Bit;
  1332.         break;
  1333.       case 'H':
  1334.         p_order->op_size[p_order->arg_cnt] = eSymbolSizeFloat128Bit;
  1335.         p_order->required_caps |= e_cpu_cap_float_h;
  1336.         break;
  1337.       default: assert(0);
  1338.     }
  1339.     p_order->arg_cnt++;
  1340.   }
  1341.   AddInstTable(InstTable, p_name, InstrZ, decode_gen);
  1342.   return InstrZ++;
  1343. }
  1344.  
  1345. #define add_gen(p_name, p_format, code) \
  1346.         add_gen_caps(p_name, p_format, code, e_cpu_cap_none)
  1347.  
  1348. static void init_fields(void)
  1349. {
  1350.   var_arg_order_t *p_var_arg_order;
  1351.   InstTable = CreateInstTable(403);
  1352.   SetDynamicInstTable(InstTable);
  1353.  
  1354.   add_null_pseudo(InstTable);
  1355.  
  1356.   var_arg_op_cnt =
  1357.   InstrZ = 0;
  1358.  
  1359.   add_gen("HALT", "0", 0x00);
  1360.   add_fixed("NOP",  NOPCode);
  1361.   add_fixed("RSB", 0x05);
  1362.   add_fixed("RET", 0x04);
  1363.   add_fixed("BPT", 0x03);
  1364.   add_fixed("BUGW", 0xfeff);
  1365.   add_fixed("BUGL", 0xfdff);
  1366.   add_fixed("XFC", 0xfc);
  1367.   add_fixed("REI", 0x02);
  1368.   add_gen("LDPCTX", "0", 0x06);
  1369.   add_gen("SVPCTX", "0", 0x07);
  1370.  
  1371.   add_one_op("CLRB" , eSymbolSize8Bit  , False, 0x94);
  1372.   add_one_op("CLRW" , eSymbolSize16Bit , False, 0xb4);
  1373.   add_one_op("CLRL" , eSymbolSize32Bit , False, 0xd4);
  1374.   add_one_op("CLRQ" , eSymbolSize64Bit , False, 0x7c);
  1375.   add_one_op("CLRO" , eSymbolSize128Bit, False, 0x7cfd);
  1376.   add_one_op("CLRF" , eSymbolSizeFloat32Bit, False, 0xd4);
  1377.   add_one_op("CLRD" , eSymbolSizeFloat64Bit, False, 0x7c);
  1378.   add_one_op("CLRG" , eSymbolSizeFloat64Bit_G, False, 0x7c);
  1379.   add_one_op("CLRH" , eSymbolSizeFloat128Bit, False, 0x7cfd);
  1380.   add_one_op("DECB" , eSymbolSize8Bit  , False, 0x97);
  1381.   add_one_op("DECW" , eSymbolSize16Bit , False, 0xb7);
  1382.   add_one_op("DECL" , eSymbolSize32Bit , False, 0xd7);
  1383.   add_one_op("INCB" , eSymbolSize8Bit  , False, 0x96);
  1384.   add_one_op("INCW" , eSymbolSize16Bit , False, 0xb6);
  1385.   add_one_op("INCL" , eSymbolSize32Bit , False, 0xd6);
  1386.   add_one_op("PUSHL", eSymbolSize32Bit , True , 0xdd);
  1387.   add_one_op("TSTB" , eSymbolSize8Bit  , True , 0x95);
  1388.   add_one_op("TSTW" , eSymbolSize16Bit , True , 0xb5);
  1389.   add_one_op("TSTL" , eSymbolSize32Bit , True , 0xd5);
  1390.   add_one_op("TSTF" , eSymbolSizeFloat32Bit, True , 0x53);
  1391.   add_one_op("TSTD" , eSymbolSizeFloat64Bit, True , 0x73);
  1392.   add_one_op("TSTG" , eSymbolSizeFloat64Bit_G, True , 0x53fd);
  1393.   add_one_op("TSTH" , eSymbolSizeFloat128Bit, True , 0x73fd);
  1394.   add_one_op("BICPSW",eSymbolSize16Bit , True , 0xb9);
  1395.   add_one_op("BISPSW",eSymbolSize16Bit , True , 0xb8);
  1396.   add_one_op("MOVPSL",eSymbolSize32Bit , False, 0xdc);
  1397.   add_one_op("POPR" , eSymbolSize16Bit , True , 0xba);
  1398.   add_one_op("PUSHR", eSymbolSize16Bit , True , 0xbb);
  1399.  
  1400.   add_two_op("ADAWI", eSymbolSize16Bit , False, 0x58);
  1401.   add_two_op("ADWC" , eSymbolSize32Bit , False, 0xd8);
  1402.   add_two_op("BITB" , eSymbolSize8Bit  , True , 0x93);
  1403.   add_two_op("BITW" , eSymbolSize16Bit , True , 0xb3);
  1404.   add_two_op("BITL" , eSymbolSize32Bit , True , 0xd3);
  1405.   add_two_op("CMPB" , eSymbolSize8Bit  , True , 0x91);
  1406.   add_two_op("CMPW" , eSymbolSize16Bit , True , 0xb1);
  1407.   add_two_op("CMPL" , eSymbolSize32Bit , True , 0xd1);
  1408.   add_two_op("CMPF" , eSymbolSizeFloat32Bit, True , 0x51);
  1409.   add_two_op("CMPD" , eSymbolSizeFloat64Bit, True , 0x71);
  1410.   add_two_op("CMPG" , eSymbolSizeFloat64Bit_G, True , 0x51fd);
  1411.   add_two_op("CMPH" , eSymbolSizeFloat128Bit, True , 0x71fd);
  1412.   add_two_op("MOVB" , eSymbolSize8Bit  , False, 0x90);
  1413.   add_two_op("MOVW" , eSymbolSize16Bit , False, 0xb0);
  1414.   add_two_op("MOVL" , eSymbolSize32Bit , False, 0xd0);
  1415.   add_two_op("MOVQ" , eSymbolSize64Bit , False, 0x7d);
  1416.   add_two_op("MOVO" , eSymbolSize128Bit, False, 0x7dfd);
  1417.   add_two_op("MOVF" , eSymbolSizeFloat32Bit, False, 0x50);
  1418.   add_two_op("MOVD" , eSymbolSizeFloat64Bit, False, 0x70);
  1419.   add_two_op("MOVG" , eSymbolSizeFloat64Bit_G, False, 0x50fd);
  1420.   add_two_op("MOVH" , eSymbolSizeFloat128Bit, False, 0x70fd);
  1421.   add_two_op("MCOMB", eSymbolSize8Bit  , False, 0x92);
  1422.   add_two_op("MCOMW", eSymbolSize16Bit , False, 0xb2);
  1423.   add_two_op("MCOML", eSymbolSize32Bit , False, 0xd2);
  1424.   add_two_op("MNEGB", eSymbolSize8Bit  , False, 0x8e);
  1425.   add_two_op("MNEGW", eSymbolSize16Bit , False, 0xae);
  1426.   add_two_op("MNEGL", eSymbolSize32Bit , False, 0xce);
  1427.   add_two_op("MNEGF", eSymbolSizeFloat32Bit, False, 0x52);
  1428.   add_two_op("MNEGD", eSymbolSizeFloat64Bit, False, 0x72);
  1429.   add_two_op("MNEGG", eSymbolSizeFloat64Bit_G, False, 0x52fd);
  1430.   add_two_op("MNEGH", eSymbolSizeFloat128Bit, False, 0x72fd);
  1431.   add_two_op("SBWC" , eSymbolSize32Bit , False, 0xd9);
  1432.  
  1433.   add_two_op_size("CVTBW" , eSymbolSize8Bit,  eSymbolSize16Bit, False, 0x99);
  1434.   add_two_op_size("CVTBL" , eSymbolSize8Bit,  eSymbolSize32Bit, False, 0x98);
  1435.   add_two_op_size("CVTWB" , eSymbolSize16Bit, eSymbolSize8Bit,  False, 0x33);
  1436.   add_two_op_size("CVTWL" , eSymbolSize16Bit, eSymbolSize32Bit, False, 0x32);
  1437.   add_two_op_size("CVTLB" , eSymbolSize32Bit, eSymbolSize8Bit,  False, 0xf6);
  1438.   add_two_op_size("CVTLW" , eSymbolSize32Bit, eSymbolSize16Bit, False, 0xf7);
  1439.   add_two_op_size("CVTFB" , eSymbolSizeFloat32Bit, eSymbolSize8Bit, False, 0x48);
  1440.   add_two_op_size("CVTFW" , eSymbolSizeFloat32Bit, eSymbolSize16Bit, False, 0x49);
  1441.   add_two_op_size("CVTFL" , eSymbolSizeFloat32Bit, eSymbolSize32Bit, False, 0x4a);
  1442.   add_two_op_size("CVTRFL", eSymbolSizeFloat32Bit, eSymbolSize32Bit, False, 0x4b);
  1443.   add_two_op_size("CVTBF" , eSymbolSize8Bit, eSymbolSizeFloat32Bit, False, 0x4c);
  1444.   add_two_op_size("CVTWF" , eSymbolSize16Bit, eSymbolSizeFloat32Bit, False, 0x4d);
  1445.   add_two_op_size("CVTLF" , eSymbolSize32Bit, eSymbolSizeFloat32Bit, False, 0x4e);
  1446.   add_two_op_size("CVTFD" , eSymbolSizeFloat32Bit, eSymbolSizeFloat64Bit, False, 0x56);
  1447.   add_two_op_size("CVTDB" , eSymbolSizeFloat64Bit, eSymbolSize8Bit, False, 0x68);
  1448.   add_two_op_size("CVTDW" , eSymbolSizeFloat64Bit, eSymbolSize16Bit, False, 0x69);
  1449.   add_two_op_size("CVTDL" , eSymbolSizeFloat64Bit, eSymbolSize32Bit, False, 0x6a);
  1450.   add_two_op_size("CVTRDL", eSymbolSizeFloat64Bit, eSymbolSize32Bit, False, 0x6b);
  1451.   add_two_op_size("CVTBD" , eSymbolSize8Bit, eSymbolSizeFloat64Bit, False, 0x6c);
  1452.   add_two_op_size("CVTWD" , eSymbolSize16Bit, eSymbolSizeFloat64Bit, False, 0x6d);
  1453.   add_two_op_size("CVTLD" , eSymbolSize32Bit, eSymbolSizeFloat64Bit, False, 0x6e);
  1454.   add_two_op_size("CVTDF" , eSymbolSizeFloat64Bit, eSymbolSize32Bit, False, 0x76);
  1455.   add_two_op_size("CVTDH" , eSymbolSizeFloat64Bit, eSymbolSizeFloat128Bit, False, 0x32fd);
  1456.   add_two_op_size("CVTGF" , eSymbolSizeFloat64Bit_G, eSymbolSizeFloat32Bit, False, 0x33fd);
  1457.   add_two_op_size("CVTGB" , eSymbolSizeFloat64Bit_G, eSymbolSize8Bit, False, 0x48fd);
  1458.   add_two_op_size("CVTGW" , eSymbolSizeFloat64Bit_G, eSymbolSize16Bit, False, 0x49fd);
  1459.   add_two_op_size("CVTGL" , eSymbolSizeFloat64Bit_G, eSymbolSize32Bit, False, 0x4afd);
  1460.   add_two_op_size("CVTRGL", eSymbolSizeFloat64Bit_G, eSymbolSize32Bit, False, 0x4bfd);
  1461.   add_two_op_size("CVTBG" , eSymbolSize8Bit, eSymbolSizeFloat64Bit_G, False, 0x4cfd);
  1462.   add_two_op_size("CVTWG" , eSymbolSize16Bit, eSymbolSizeFloat64Bit_G, False, 0x4dfd);
  1463.   add_two_op_size("CVTLG" , eSymbolSize32Bit, eSymbolSizeFloat64Bit_G, False, 0x4efd);
  1464.   add_two_op_size("CVTGH" , eSymbolSizeFloat64Bit_G, eSymbolSizeFloat128Bit, False, 0x56fd);
  1465.   add_two_op_size("CVTHB" , eSymbolSizeFloat128Bit, eSymbolSize8Bit, False, 0x68fd);
  1466.   add_two_op_size("CVTHW" , eSymbolSizeFloat128Bit, eSymbolSize16Bit, False, 0x69fd);
  1467.   add_two_op_size("CVTHL" , eSymbolSizeFloat128Bit, eSymbolSize32Bit, False, 0x6afd);
  1468.   add_two_op_size("CVTRHL", eSymbolSizeFloat128Bit, eSymbolSize32Bit, False, 0x6bfd);
  1469.   add_two_op_size("CVTBH" , eSymbolSize8Bit, eSymbolSizeFloat128Bit, False, 0x6cfd);
  1470.   add_two_op_size("CVTWH" , eSymbolSize16Bit, eSymbolSizeFloat128Bit, False, 0x6dfd);
  1471.   add_two_op_size("CVTLH" , eSymbolSize32Bit, eSymbolSizeFloat128Bit, False, 0x6efd);
  1472.   add_two_op_size("CVTHG" , eSymbolSizeFloat128Bit, eSymbolSizeFloat64Bit_G, False, 0x76fd);
  1473.   add_two_op_size("CVTFH" , eSymbolSizeFloat32Bit, eSymbolSizeFloat128Bit, False, 0x98fd);
  1474.   add_two_op_size("CVTFG" , eSymbolSizeFloat32Bit, eSymbolSizeFloat64Bit_G, False, 0x99fd);
  1475.   add_two_op_size("CVTHF" , eSymbolSizeFloat128Bit, eSymbolSizeFloat32Bit, False, 0xf6fd);
  1476.   add_two_op_size("CVTHD" , eSymbolSizeFloat128Bit, eSymbolSizeFloat64Bit, False, 0xf7fd);
  1477.   add_two_op_size("MOVZBW", eSymbolSize8Bit,  eSymbolSize16Bit, False, 0x9b);
  1478.   add_two_op_size("MOVZBL", eSymbolSize8Bit,  eSymbolSize32Bit, False, 0x9a);
  1479.   add_two_op_size("MOVZWL", eSymbolSize16Bit, eSymbolSize32Bit, False, 0x3c);
  1480.  
  1481.   add_two_three_op("ADDB", eSymbolSize8Bit,  0x80);
  1482.   add_two_three_op("ADDW", eSymbolSize16Bit, 0xa0);
  1483.   add_two_three_op("ADDL", eSymbolSize32Bit, 0xc0);
  1484.   add_two_three_op("ADDF", eSymbolSizeFloat32Bit, 0x40);
  1485.   add_two_three_op("ADDD", eSymbolSizeFloat64Bit, 0x60);
  1486.   add_two_three_op("ADDG", eSymbolSizeFloat64Bit_G, 0x40fd);
  1487.   add_two_three_op("ADDH", eSymbolSizeFloat128Bit, 0x60fd);
  1488.   add_two_three_op("BICB", eSymbolSize8Bit,  0x8a);
  1489.   add_two_three_op("BICW", eSymbolSize16Bit, 0xaa);
  1490.   add_two_three_op("BICL", eSymbolSize32Bit, 0xca);
  1491.   add_two_three_op("BISB", eSymbolSize8Bit,  0x88);
  1492.   add_two_three_op("BISW", eSymbolSize16Bit, 0xa8);
  1493.   add_two_three_op("BISL", eSymbolSize32Bit, 0xc8);
  1494.   add_two_three_op("DIVB", eSymbolSize8Bit,  0x86);
  1495.   add_two_three_op("DIVW", eSymbolSize16Bit, 0xa6);
  1496.   add_two_three_op("DIVL", eSymbolSize32Bit, 0xc6);
  1497.   add_two_three_op("DIVF", eSymbolSizeFloat32Bit, 0x46);
  1498.   add_two_three_op("DIVD", eSymbolSizeFloat64Bit, 0x66);
  1499.   add_two_three_op("DIVG", eSymbolSizeFloat64Bit_G, 0x46fd);
  1500.   add_two_three_op("DIVH", eSymbolSizeFloat128Bit, 0x66fd);
  1501.   add_two_three_op("MULB", eSymbolSize8Bit,  0x84);
  1502.   add_two_three_op("MULW", eSymbolSize16Bit, 0xa4);
  1503.   add_two_three_op("MULL", eSymbolSize32Bit, 0xc4);
  1504.   add_two_three_op("MULF", eSymbolSizeFloat32Bit, 0x44);
  1505.   add_two_three_op("MULD", eSymbolSizeFloat64Bit, 0x64);
  1506.   add_two_three_op("MULG", eSymbolSizeFloat64Bit_G, 0x44fd);
  1507.   add_two_three_op("MULH", eSymbolSizeFloat128Bit, 0x64fd);
  1508.   add_two_three_op("SUBB", eSymbolSize8Bit,  0x82);
  1509.   add_two_three_op("SUBW", eSymbolSize16Bit, 0xa2);
  1510.   add_two_three_op("SUBL", eSymbolSize32Bit, 0xc2);
  1511.   add_two_three_op("SUBF", eSymbolSizeFloat32Bit, 0x42);
  1512.   add_two_three_op("SUBD", eSymbolSizeFloat64Bit, 0x62);
  1513.   add_two_three_op("SUBG", eSymbolSizeFloat64Bit_G, 0x42fd);
  1514.   add_two_three_op("SUBH", eSymbolSizeFloat128Bit, 0x62fd);
  1515.   add_two_three_op("XORB", eSymbolSize8Bit,  0x8c);
  1516.   add_two_three_op("XORW", eSymbolSize16Bit, 0xac);
  1517.   add_two_three_op("XORL", eSymbolSize32Bit, 0xcc);
  1518.  
  1519.   add_byte_two_op("ASHL", eSymbolSize32Bit, 0x78);
  1520.   add_byte_two_op("ASHQ", eSymbolSize64Bit, 0x79);
  1521.   add_byte_two_op("ROTL", eSymbolSize32Bit, 0x9c);
  1522.  
  1523.   add_gen("EDIV"  , "rlrqwlwl", 0x7b);
  1524.   add_gen("EMUL"  , "rlrlrlwq", 0x7a);
  1525.   add_gen("MOVAB" , "abwl", 0x9e);
  1526.   add_gen("MOVAW" , "awwl", 0x3e);
  1527.   add_gen("MOVAL" , "alwl", 0xde);
  1528.   add_gen("MOVAF" , "afwl", 0xde);
  1529.   add_gen("MOVAQ" , "aqwl", 0x7e);
  1530.   add_gen("MOVAD" , "adwl", 0x7e);
  1531.   add_gen("MOVAG" , "agwl", 0x7e);
  1532.   add_gen("MOVAO" , "aowl", 0x7efd);
  1533.   add_gen("MOVAH" , "ahwl", 0x7efd);
  1534.   add_gen("PUSHAB", "ab", 0x9f);
  1535.   add_gen("PUSHAW", "aw", 0x3f);
  1536.   add_gen("PUSHAL", "al", 0xdf);
  1537.   add_gen("PUSHAF", "af", 0xdf);
  1538.   add_gen("PUSHAQ", "aq", 0x7f);
  1539.   add_gen("PUSHAD", "ad", 0x7f);
  1540.   add_gen("PUSHAG", "ag", 0x7f);
  1541.   add_gen("PUSHAO", "ao", 0x7ffd);
  1542.   add_gen("PUSHAH", "ah", 0x7ffd);
  1543.   add_gen("CMPV"  , "rlrbvbrl", 0xec);
  1544.   add_gen("CMPZV" , "rlrbvbrl", 0xed);
  1545.   add_gen("EXTV"  , "rlrbvbwl", 0xee);
  1546.   add_gen("EXTZV" , "rlrbvbwl", 0xef);
  1547.   add_gen("FFC"   , "rlrbvbwl", 0xeb);
  1548.   add_gen("FFS"   , "rlrbvbwl", 0xea);
  1549.   add_gen("INSV"  , "rlrlrbvb", 0xf0);
  1550.  
  1551.   add_gen("ACBB"  , "rbrbmbbw", 0x9d);
  1552.   add_gen("ACBW"  , "rwrwmwbw", 0x3d);
  1553.   add_gen("ACBL"  , "rlrlmlbw", 0xf1);
  1554.   add_gen("ACBF"  , "rfrfmfbw", 0x4f);
  1555.   add_gen("ACBD"  , "rdrdmdbw", 0x6f);
  1556.   add_gen("ACBG"  , "rgrgmgbw", 0x4ffd);
  1557.   add_gen("ACBH"  , "rhrhmhbw", 0x6ffd);
  1558.   add_gen("AOBLEQ", "rlmlbb", 0xf3);
  1559.   add_gen("AOBLSS", "rlmlbb", 0xf2);
  1560.   add_gen("BGTR"  , "bb", 0x14);
  1561.   add_gen("BLEQ"  , "bb", 0x15);
  1562.   add_gen("BNEQ"  , "bb", 0x12);
  1563.   add_gen("BNEQU" , "bb", 0x12);
  1564.   add_gen("BEQL"  , "bb", 0x13);
  1565.   add_gen("BEQLU" , "bb", 0x13);
  1566.   add_gen("BGEQ"  , "bb", 0x18);
  1567.   add_gen("BLSS"  , "bb", 0x19);
  1568.   add_gen("BGTRU" , "bb", 0x1a);
  1569.   add_gen("BLEQU" , "bb", 0x1b);
  1570.   add_gen("BVC"   , "bb", 0x1c);
  1571.   add_gen("BVS"   , "bb", 0x1d);
  1572.   add_gen("BGEQU" , "bb", 0x1e);
  1573.   add_gen("BCC"   , "bb", 0x1e);
  1574.   add_gen("BLSSU" , "bb", 0x1f);
  1575.   add_gen("BCS"   , "bb", 0x1f);
  1576.   add_gen("BBS"   , "rlvbbb", 0xe0);
  1577.   add_gen("BBC"   , "rlvbbb", 0xe1);
  1578.   add_gen("BBSS"  , "rlvbbb", 0xe2);
  1579.   add_gen("BBCS"  , "rlvbbb", 0xe3);
  1580.   add_gen("BBSC"  , "rlvbbb", 0xe4);
  1581.   add_gen("BBCC"  , "rlvbbb", 0xe5);
  1582.   add_gen("BBSSI" , "rlvbbb", 0xe6);
  1583.   add_gen("BBCCI" , "rlvbbb", 0xe7);
  1584.   add_gen("BLBS"  , "rlbb", 0xe8);
  1585.   add_gen("BLBC"  , "rlbb", 0xe9);
  1586.   add_gen("BRB"   , "bb", 0x11);
  1587.   add_gen("BRW"   , "bw", 0x31);
  1588.   add_gen("BR"    , "bx", 0x11);
  1589.   add_gen("BSBB"  , "bb", 0x10);
  1590.   add_gen("BSBW"  , "bw", 0x30);
  1591.   add_gen("BSB"   , "bx", 0x10);
  1592.   AddInstTable(InstTable, "CASEB", 0x8f | (eSymbolSize8Bit << 8), decode_case);
  1593.   AddInstTable(InstTable, "CASEW", 0xaf | (eSymbolSize16Bit << 8), decode_case);
  1594.   AddInstTable(InstTable, "CASEL", 0xcf | (eSymbolSize32Bit << 8), decode_case);
  1595.   add_gen("JMP"   , "ab", 0x17);
  1596.   add_gen("JSB"   , "ab", 0x16);
  1597.   add_gen("SOBGEQ", "mlbb", 0xf4);
  1598.   add_gen("SOBGTR", "mlbb", 0xf5);
  1599.   add_gen("CALLG" , "abab", 0xfa);
  1600.   add_gen("CALLS" , "rlab", 0xfb);
  1601.   add_gen("INDEX" , "rlrlrlrlrlwl", 0x0a);
  1602.  
  1603.   add_gen("INSQHI", "abaq", 0x5c);
  1604.   add_gen("INSQTI", "abaq", 0x5d);
  1605.   add_gen("INSQUE", "abab", 0x0e);
  1606.   add_gen("REMQHI", "aqwl", 0x5e);
  1607.   add_gen("REMQTI", "aqwl", 0x5f);
  1608.   add_gen("REMQUE", "abwl", 0x0f);
  1609.  
  1610.   add_gen("EMODF", "rfrbrfwlwf", 0x54);
  1611.   add_gen("EMODD", "rdrbrdwlwd", 0x74);
  1612.   add_gen("EMODG", "rgrwrgwlwg", 0x54fd);
  1613.   add_gen("EMODH", "rhrwrhwlwh", 0x74fd);
  1614.   add_gen("POLYF", "rfrwab", 0x55);
  1615.   add_gen("POLYD", "rdrwab", 0x75);
  1616.   add_gen("POLYG", "rgrwab", 0x55fd);
  1617.   add_gen("POLYH", "rhrwab", 0x75fd);
  1618.  
  1619.   p_var_arg_order = rsv_var_arg_order();
  1620.   p_var_arg_order->gen_indices[0] = add_gen_caps("CMPC3" , "rwabab"      , 0x29, e_cpu_cap_string_mvax);
  1621.   p_var_arg_order->gen_indices[1] = add_gen_caps("CMPC5" , "rwabrbrwab"  , 0x2d, e_cpu_cap_string_rest);
  1622.   AddInstTable(InstTable, "CMPC", var_arg_op_cnt++, decode_var_arg);
  1623.   add_gen_caps("LOCC"  , "rbrwab"      , 0x3a, e_cpu_cap_string_mvax);
  1624.   add_gen_caps("MATCHC", "rwabrwab"    , 0x39, e_cpu_cap_string_rest);
  1625.   p_var_arg_order = rsv_var_arg_order();
  1626.   p_var_arg_order->gen_indices[0] = add_gen("MOVC3" , "rwabab"      , 0x28);
  1627.   p_var_arg_order->gen_indices[1] = add_gen("MOVC5" , "rwabrbrwab"  , 0x2c);
  1628.   AddInstTable(InstTable, "MOVC", var_arg_op_cnt++, decode_var_arg);
  1629.   add_gen_caps("MOVTC" , "rwabrbabrwab", 0x2e, e_cpu_cap_string_rest);
  1630.   add_gen_caps("MOVTUC", "rwabrbabrwab", 0x2f, e_cpu_cap_string_rest);
  1631.   add_gen_caps("SCANC" , "rwababrb"    , 0x2a, e_cpu_cap_string_mvax);
  1632.   add_gen_caps("SKPC"  , "rbrwab"      , 0x3b, e_cpu_cap_string_mvax);
  1633.   add_gen_caps("SPANC" , "rwababrb"    , 0x2b, e_cpu_cap_string_mvax);
  1634.  
  1635.   add_gen_caps("CRC"   , "abrlrwab"    , 0x0b, e_cpu_cap_crc);
  1636.  
  1637.   p_var_arg_order = rsv_var_arg_order();
  1638.   p_var_arg_order->gen_indices[0] = add_gen_caps("ADDP4" , "rwabrwab"    , 0x20, e_cpu_cap_packed);
  1639.   p_var_arg_order->gen_indices[1] = add_gen_caps("ADDP6" , "rwabrwabrwab", 0x21, e_cpu_cap_packed);
  1640.   AddInstTable(InstTable, "ADDP", var_arg_op_cnt++, decode_var_arg);
  1641.   add_gen_caps("ASHP"  , "rbrwabrbrwab", 0xf8, e_cpu_cap_packed);
  1642.   p_var_arg_order = rsv_var_arg_order();
  1643.   p_var_arg_order->gen_indices[0] = add_gen_caps("CMPP3" , "rwabab"      , 0x35, e_cpu_cap_packed);
  1644.   p_var_arg_order->gen_indices[1] = add_gen_caps("CMPP4" , "rwabrwab"    , 0x37, e_cpu_cap_packed);
  1645.   AddInstTable(InstTable, "CMPP", var_arg_op_cnt++, decode_var_arg);
  1646.   add_gen_caps("CVTLP" , "rlrwab"      , 0xf9, e_cpu_cap_packed);
  1647.   add_gen_caps("CVTPL" , "rwabwl"      , 0x36, e_cpu_cap_packed);
  1648.   add_gen_caps("CVTPS" , "rwabrwab"    , 0x08, e_cpu_cap_packed);
  1649.   add_gen_caps("CVTPT" , "rwababrwab"  , 0x24, e_cpu_cap_packed);
  1650.   add_gen_caps("CVTSP" , "rwabrwab"    , 0x09, e_cpu_cap_packed);
  1651.   add_gen_caps("CVTTP" , "rwababrwab"  , 0x26, e_cpu_cap_packed);
  1652.   add_gen_caps("DIVP"  , "rwabrwabrwab", 0x27, e_cpu_cap_packed);
  1653.   add_gen_caps("MOVP"  , "rwabab"      , 0x34, e_cpu_cap_packed);
  1654.   add_gen_caps("MULP"  , "rwabrwabrwab", 0x25, e_cpu_cap_packed);
  1655.   p_var_arg_order = rsv_var_arg_order();
  1656.   p_var_arg_order->gen_indices[0] = add_gen_caps("SUBP4" , "rwabrwab"    , 0x22, e_cpu_cap_packed);
  1657.   p_var_arg_order->gen_indices[1] = add_gen_caps("SUBP6" , "rwabrwabrwab", 0x23, e_cpu_cap_packed);
  1658.   AddInstTable(InstTable, "SUBP", var_arg_op_cnt++, decode_var_arg);
  1659.   add_gen_caps("EDITPC", "rwababab"    , 0x38, e_cpu_cap_edit);
  1660.  
  1661.   add_gen("PROBER", "rbrwab"      , 0x0c);
  1662.   add_gen("PROBEW", "rbrwab"      , 0x0d);
  1663.   add_gen("CHMK"  , "rw"          , 0xbc);
  1664.   add_gen("CHME"  , "rw"          , 0xbd);
  1665.   add_gen("CHMS"  , "rw"          , 0xbe);
  1666.   add_gen("CHMU"  , "rw"          , 0xbf);
  1667.   add_gen("MTPR"  , "0rlrl"       , 0xda);
  1668.   add_gen("MFPR"  , "0rlwl"       , 0xdb);
  1669.  
  1670.   AddInstTable(InstTable, "BLKB",  1, DecodeIntelDS);
  1671.   AddInstTable(InstTable, "BLKW",  2, DecodeIntelDS);
  1672.   AddInstTable(InstTable, "BLKL",  4, DecodeIntelDS);
  1673.   AddInstTable(InstTable, "BLKQ",  8, DecodeIntelDS);
  1674.   AddInstTable(InstTable, "BLKO", 16, DecodeIntelDS);
  1675.   AddInstTable(InstTable, "BLKF",  4, DecodeIntelDS);
  1676.   AddInstTable(InstTable, "BLKD",  8, DecodeIntelDS);
  1677.   AddInstTable(InstTable, "BLKG",  8, DecodeIntelDS);
  1678.   AddInstTable(InstTable, "BLKH", 16, DecodeIntelDS);
  1679.  
  1680.   AddInstTable(InstTable, access_mode_name, 0, decode_accmode);
  1681.  
  1682.   /* TODO: ASCID */
  1683.  
  1684.   AddInstTable(InstTable, "ASCII"     , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowString | eIntPseudoFlag_DECFormat                       , DecodeIntelDB);
  1685.   AddInstTable(InstTable, "ASCIZ"     , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowString | eIntPseudoFlag_DECFormat | eIntPseudoFlag_ASCIZ, DecodeIntelDB);
  1686.   AddInstTable(InstTable, "ASCIC"     , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowString | eIntPseudoFlag_DECFormat | eIntPseudoFlag_ASCIC, DecodeIntelDB);
  1687. /*AddInstTable(InstTable, "ASCID"     , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowString | eIntPseudoFlag_DECFormat | eIntPseudoFlag_ASCID, DecodeIntelDB);*/
  1688.   AddInstTable(InstTable, "PACKED"    , 0, decode_dec_packed);
  1689.  
  1690.   AddInstTable(InstTable, "BYTE"      , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt                              , DecodeIntelDB);
  1691.   AddInstTable(InstTable, "WORD"      , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt                              , DecodeIntelDW);
  1692.   AddInstTable(InstTable, "LWORD"     , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt                              , DecodeIntelDD);
  1693.   AddInstTable(InstTable, "QUAD"      , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt                              , DecodeIntelDQ);
  1694.   AddInstTable(InstTable, "OCTA"      , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt                              , DecodeIntelDO);
  1695.   AddInstTable(InstTable, "FLOAT"     , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat , DecodeIntelDD);
  1696.   AddInstTable(InstTable, "F_FLOATING", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat , DecodeIntelDD);
  1697.   AddInstTable(InstTable, "DOUBLE"    , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat , DecodeIntelDQ);
  1698.   AddInstTable(InstTable, "D_FLOATING", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat , DecodeIntelDQ);
  1699.   AddInstTable(InstTable, "G_FLOATING", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECGFormat, DecodeIntelDQ);
  1700.   AddInstTable(InstTable, "H_FLOATING", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat , DecodeIntelDO);
  1701. }
  1702.  
  1703. /*!------------------------------------------------------------------------
  1704.  * \fn     deinit_fields(void)
  1705.  * \brief  destroy/cleanup lookup table
  1706.  * ------------------------------------------------------------------------ */
  1707.  
  1708. static void deinit_fields(void)
  1709. {
  1710.   order_array_free(var_arg_orders);
  1711.   order_array_free(gen_orders);
  1712.   DestroyInstTable(InstTable);
  1713. }
  1714.  
  1715. /*--------------------------------------------------------------------------*/
  1716. /* Interface Functions */
  1717.  
  1718. /*!------------------------------------------------------------------------
  1719.  * \fn     intern_symbol_vax(char *pArg, TempResult *pResult)
  1720.  * \brief  handle built-in (register) symbols for VAX
  1721.  * \param  p_arg source argument
  1722.  * \param  p_result result buffer
  1723.  * ------------------------------------------------------------------------ */
  1724.  
  1725. static void intern_symbol_vax(char *p_arg, TempResult *p_result)
  1726. {
  1727.   Byte reg_num;
  1728.   (void)p_arg; (void)p_result;
  1729.  
  1730.   if (decode_reg_core(p_arg, &reg_num, &p_result->DataSize))
  1731.   {
  1732.     p_result->Typ = TempReg;
  1733.     p_result->Contents.RegDescr.Reg = reg_num;
  1734.     p_result->Contents.RegDescr.Dissect = dissect_reg_vax;
  1735.     p_result->Contents.RegDescr.compare = NULL;
  1736.   }
  1737. }
  1738.  
  1739. /*!------------------------------------------------------------------------
  1740.  * \fn     make_code_vax(void)
  1741.  * \brief  encode machine instruction
  1742.  * ------------------------------------------------------------------------ */
  1743.  
  1744. static void make_code_vax(void)
  1745. {
  1746.   op_size = eSymbolSizeUnknown;
  1747.  
  1748.   /* Pseudo Instructions */
  1749.  
  1750.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1751.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1752. }
  1753.  
  1754. /*!------------------------------------------------------------------------
  1755.  * \fn     is_def_vax(void)
  1756.  * \brief  check whether insn makes own use of label
  1757.  * \return True if yes
  1758.  * ------------------------------------------------------------------------ */
  1759.  
  1760. static Boolean is_def_vax(void)
  1761. {
  1762.   return Memo("REG");
  1763. }
  1764.  
  1765. /*!------------------------------------------------------------------------
  1766.  * \fn     switch_from_vax(void)
  1767.  * \brief  deinitialize as target
  1768.  * ------------------------------------------------------------------------ */
  1769.  
  1770. static void switch_from_vax(void)
  1771. {
  1772.   deinit_fields();
  1773.   p_curr_cpu_props = NULL;
  1774. }
  1775.  
  1776. /*!------------------------------------------------------------------------
  1777.  * \fn     switch_to_vax(void *p_user)
  1778.  * \brief  prepare to assemble code for this target
  1779.  * ------------------------------------------------------------------------ */
  1780.  
  1781. static void switch_to_vax(void *p_user)
  1782. {
  1783.   const TFamilyDescr *p_descr;
  1784.  
  1785.   p_curr_cpu_props = (const cpu_props_t*)p_user;
  1786.   p_descr = FindFamilyByName("VAX");
  1787.   SetIntConstMode(eIntConstModeC);
  1788.  
  1789.   PCSymbol = "*";
  1790.   HeaderID = p_descr->Id;
  1791.   NOPCode = 0x01;
  1792.   DivideChars = ",";
  1793.  
  1794.   ValidSegs = 1 << SegCode;
  1795.   Grans[SegCode] = 1;
  1796.   ListGrans[SegCode] = 1;
  1797.   SegInits[SegCode] = 0;
  1798.   SegLimits[SegCode] = IntTypeDefs[UInt32].Max;
  1799.  
  1800.   MakeCode = make_code_vax;
  1801.   IsDef = is_def_vax;
  1802.   SwitchFrom = switch_from_vax;
  1803.   InternSymbol = intern_symbol_vax;
  1804. #if 0
  1805.   DissectReg = dissect_reg_vax;
  1806. #endif
  1807.   multi_char_le = True;
  1808.  
  1809.   init_fields();
  1810.  
  1811.   if (!curr_access_mode_set)
  1812.     set_access_mode(3);
  1813. }
  1814.  
  1815. /*!------------------------------------------------------------------------
  1816.  * \fn     initpass_vax(void)
  1817.  * \brief  initializations at beginning of pass
  1818.  * ------------------------------------------------------------------------ */
  1819.  
  1820. static void initpass_vax(void)
  1821. {
  1822.   /* Flag to introduce & initialize symbol at first switch to target */
  1823.  
  1824.   curr_access_mode_set = False;
  1825. }
  1826.  
  1827. /*!------------------------------------------------------------------------
  1828.  * \fn     codevax_init(void)
  1829.  * \brief  register VAX target
  1830.  * ------------------------------------------------------------------------ */
  1831.  
  1832. static const cpu_props_t cpu_props[] =
  1833. {
  1834.   { "MicroVAX-I"  , e_cpu_cap_float_g | e_cpu_cap_string_mvax },
  1835.   { "MicroVAX-II" , e_cpu_cap_float_g },
  1836.   { "VAX-11/725"  , e_cpu_cap_all_no_vector },
  1837.   { "VAX-11/730"  , e_cpu_cap_all_no_vector },
  1838.   { "VAX-11/750"  , e_cpu_cap_all_no_vector }, /* g/h optional */
  1839.   { "VAX-11/780"  , e_cpu_cap_all_no_vector }, /* g/h optional */
  1840.   { "VAX-11/782"  , e_cpu_cap_all_no_vector }, /* g/h optional */
  1841.   { "VAX-11/785"  , e_cpu_cap_all_no_vector }, /* g/h optional */
  1842.   { "VAX-8200"    , e_cpu_cap_all_no_vector },
  1843.   { "VAX-8300"    , e_cpu_cap_all_no_vector },
  1844.   { "VAX-8500"    , e_cpu_cap_all_no_vector },
  1845.   { "VAX-8600"    , e_cpu_cap_all_no_vector },
  1846.   { "VAX-8650"    , e_cpu_cap_all_no_vector },
  1847.   { "VAX-8800"    , e_cpu_cap_all_no_vector },
  1848. };
  1849.  
  1850. void codevax_init(void)
  1851. {
  1852.   const cpu_props_t *p_prop;
  1853.  
  1854.   for (p_prop = cpu_props; p_prop < cpu_props + as_array_size(cpu_props); p_prop++)
  1855.     (void)AddCPUUserWithArgs(p_prop->name, switch_to_vax, (void*)p_prop, NULL, NULL);
  1856.   AddInitPassProc(initpass_vax);
  1857. }
  1858.