Home | History | Annotate | Line # | Download | only in m32c
      1   1.1  christos /* srcdest.c --- decoding M32C addressing modes.
      2   1.1  christos 
      3  1.11  christos Copyright (C) 2005-2024 Free Software Foundation, Inc.
      4   1.1  christos Contributed by Red Hat, Inc.
      5   1.1  christos 
      6   1.1  christos This file is part of the GNU simulators.
      7   1.1  christos 
      8   1.1  christos This program is free software; you can redistribute it and/or modify
      9   1.1  christos it under the terms of the GNU General Public License as published by
     10   1.1  christos the Free Software Foundation; either version 3 of the License, or
     11   1.1  christos (at your option) any later version.
     12   1.1  christos 
     13   1.1  christos This program is distributed in the hope that it will be useful,
     14   1.1  christos but WITHOUT ANY WARRANTY; without even the implied warranty of
     15   1.1  christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16   1.1  christos GNU General Public License for more details.
     17   1.1  christos 
     18   1.1  christos You should have received a copy of the GNU General Public License
     19   1.1  christos along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20   1.1  christos 
     21  1.10  christos /* This must come before any other includes.  */
     22  1.10  christos #include "defs.h"
     23   1.1  christos 
     24   1.1  christos #include <stdio.h>
     25   1.1  christos #include <stdlib.h>
     26   1.1  christos 
     27   1.7  christos #include "libiberty.h"
     28   1.1  christos #include "cpu.h"
     29   1.1  christos #include "mem.h"
     30   1.1  christos 
     31   1.1  christos static int src_indirect = 0;
     32   1.1  christos static int dest_indirect = 0;
     33   1.1  christos static int src_addend = 0;
     34   1.1  christos static int dest_addend = 0;
     35   1.1  christos 
     36   1.1  christos static int
     37   1.5  christos disp8 (void)
     38   1.1  christos {
     39   1.1  christos   int rv;
     40   1.1  christos   int tsave = trace;
     41   1.1  christos 
     42   1.1  christos   if (trace == 1)
     43   1.1  christos     trace = 0;
     44   1.1  christos   rv = mem_get_qi (get_reg (pc));
     45   1.1  christos   regs.r_pc++;
     46   1.1  christos   trace = tsave;
     47   1.1  christos   return rv;
     48   1.1  christos }
     49   1.1  christos 
     50   1.1  christos static int
     51   1.5  christos disp16 (void)
     52   1.1  christos {
     53   1.1  christos   int rv;
     54   1.1  christos   int tsave = trace;
     55   1.1  christos 
     56   1.1  christos   if (trace == 1)
     57   1.1  christos     trace = 0;
     58   1.1  christos   rv = mem_get_hi (get_reg (pc));
     59   1.1  christos   regs.r_pc += 2;
     60   1.1  christos   trace = tsave;
     61   1.1  christos   return rv;
     62   1.1  christos }
     63   1.1  christos 
     64   1.1  christos static int
     65   1.5  christos disp24 (void)
     66   1.1  christos {
     67   1.1  christos   int rv;
     68   1.1  christos   int tsave = trace;
     69   1.1  christos 
     70   1.1  christos   if (trace == 1)
     71   1.1  christos     trace = 0;
     72   1.1  christos   rv = mem_get_psi (get_reg (pc));
     73   1.1  christos   regs.r_pc += 3;
     74   1.1  christos   trace = tsave;
     75   1.1  christos   return rv;
     76   1.1  christos }
     77   1.1  christos 
     78   1.1  christos static int
     79   1.5  christos disp20 (void)
     80   1.1  christos {
     81   1.1  christos   return disp24 () & 0x000fffff;
     82   1.1  christos }
     83   1.1  christos 
     84   1.1  christos const char *
     85   1.1  christos bits (int v, int b)
     86   1.1  christos {
     87   1.1  christos   static char buf[17];
     88   1.1  christos   char *bp = buf + 16;
     89   1.1  christos   *bp = 0;
     90   1.1  christos   while (b)
     91   1.1  christos     {
     92   1.1  christos       *--bp = (v & 1) ? '1' : '0';
     93   1.1  christos       v >>= 1;
     94   1.1  christos       b--;
     95   1.1  christos     }
     96   1.1  christos   return bp;
     97   1.1  christos }
     98   1.1  christos 
     99   1.1  christos static const char *the_bits = 0;
    100   1.1  christos 
    101   1.1  christos void
    102   1.1  christos decode_indirect (int si, int di)
    103   1.1  christos {
    104   1.1  christos   src_indirect = si;
    105   1.1  christos   dest_indirect = di;
    106   1.1  christos   if (trace && (si || di))
    107   1.1  christos     printf ("indirect: s:%d d:%d\n", si, di);
    108   1.1  christos }
    109   1.1  christos 
    110   1.1  christos void
    111   1.1  christos decode_index (int sa, int da)
    112   1.1  christos {
    113   1.1  christos   src_addend = sa;
    114   1.1  christos   dest_addend = da;
    115   1.1  christos   if (trace && (sa || da))
    116   1.1  christos     printf ("index: s:%d d:%d\n", sa, da);
    117   1.1  christos }
    118   1.1  christos 
    119   1.1  christos srcdest
    120   1.1  christos decode_srcdest4 (int destcode, int bw)
    121   1.1  christos {
    122   1.1  christos   srcdest sd;
    123   1.1  christos   static const char *dc_wnames[16] = { "r0", "r1", "r2", "r3",
    124   1.1  christos     "a0", "a1", "[a0]", "[a1]",
    125   1.1  christos     "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
    126   1.1  christos     "disp16[a0]", "disp16[a1]", "disp16[sb]", "disp16"
    127   1.1  christos   };
    128   1.1  christos   static const char *dc_bnames[4] = { "r0l", "r0h", "r1l", "r1h" };;
    129   1.1  christos 
    130   1.5  christos   sd.bytes = bw ? 2 : 1;
    131   1.5  christos   sd.mem = (destcode >= 6) ? 1 : 0;
    132   1.5  christos 
    133   1.1  christos   if (trace)
    134   1.1  christos     {
    135   1.1  christos       const char *n = dc_wnames[destcode];
    136   1.1  christos       if (bw == 0 && destcode <= 3)
    137   1.1  christos 	n = dc_bnames[destcode];
    138   1.1  christos       if (!the_bits)
    139   1.1  christos 	the_bits = bits (destcode, 4);
    140   1.1  christos       printf ("decode: %s (%d) : %s\n", the_bits, destcode, n);
    141   1.1  christos       the_bits = 0;
    142   1.1  christos     }
    143   1.1  christos 
    144   1.1  christos   switch (destcode)
    145   1.1  christos     {
    146   1.1  christos     case 0x0:
    147   1.1  christos       sd.u.reg = bw ? r0 : r0l;
    148   1.1  christos       break;
    149   1.1  christos     case 0x1:
    150   1.1  christos       sd.u.reg = bw ? r1 : r0h;
    151   1.1  christos       break;
    152   1.1  christos     case 0x2:
    153   1.1  christos       sd.u.reg = bw ? r2 : r1l;
    154   1.1  christos       break;
    155   1.1  christos     case 0x3:
    156   1.1  christos       sd.u.reg = bw ? r3 : r1h;
    157   1.1  christos       break;
    158   1.1  christos     case 0x4:
    159   1.1  christos       sd.u.reg = a0;
    160   1.1  christos       break;
    161   1.1  christos     case 0x5:
    162   1.1  christos       sd.u.reg = a1;
    163   1.1  christos       break;
    164   1.1  christos     case 0x6:
    165   1.1  christos       sd.u.addr = get_reg (a0);
    166   1.1  christos       break;
    167   1.1  christos     case 0x7:
    168   1.1  christos       sd.u.addr = get_reg (a1);
    169   1.1  christos       break;
    170   1.1  christos     case 0x8:
    171   1.1  christos       sd.u.addr = get_reg (a0) + disp8 ();
    172   1.1  christos       break;
    173   1.1  christos     case 0x9:
    174   1.1  christos       sd.u.addr = get_reg (a1) + disp8 ();
    175   1.1  christos       break;
    176   1.1  christos     case 0xa:
    177   1.1  christos       sd.u.addr = get_reg (sb) + disp8 ();
    178   1.1  christos       break;
    179   1.1  christos     case 0xb:
    180   1.1  christos       sd.u.addr = get_reg (fb) + sign_ext (disp8 (), 8);
    181   1.1  christos       break;
    182   1.1  christos     case 0xc:
    183   1.1  christos       sd.u.addr = get_reg (a0) + disp16 ();
    184   1.1  christos       break;
    185   1.1  christos     case 0xd:
    186   1.1  christos       sd.u.addr = get_reg (a1) + disp16 ();
    187   1.1  christos       break;
    188   1.1  christos     case 0xe:
    189   1.1  christos       sd.u.addr = get_reg (sb) + disp16 ();
    190   1.1  christos       break;
    191   1.1  christos     case 0xf:
    192   1.1  christos       sd.u.addr = disp16 ();
    193   1.1  christos       break;
    194   1.1  christos     default:
    195   1.1  christos       abort ();
    196   1.1  christos     }
    197   1.1  christos   if (sd.mem)
    198   1.1  christos     sd.u.addr &= addr_mask;
    199   1.1  christos   return sd;
    200   1.1  christos }
    201   1.1  christos 
    202   1.1  christos srcdest
    203   1.1  christos decode_jumpdest (int destcode, int w)
    204   1.1  christos {
    205   1.1  christos   srcdest sd;
    206   1.1  christos   static const char *dc_wnames[16] = { "r0", "r1", "r2", "r3",
    207   1.1  christos     "a0", "a1", "[a0]", "[a1]",
    208   1.1  christos     "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
    209   1.1  christos     "disp20[a0]", "disp20[a1]", "disp16[sb]", "abs16"
    210   1.1  christos   };
    211   1.1  christos   static const char *dc_anames[4] = { "r0l", "r0h", "r1l", "r1h" };
    212   1.1  christos 
    213   1.5  christos   sd.bytes = w ? 2 : 3;
    214   1.5  christos   sd.mem = (destcode >= 6) ? 1 : 0;
    215   1.5  christos 
    216   1.1  christos   if (trace)
    217   1.1  christos     {
    218   1.1  christos       const char *n = dc_wnames[destcode];
    219   1.1  christos       if (w == 0 && destcode <= 3)
    220   1.1  christos 	n = dc_anames[destcode];
    221   1.1  christos       if (!the_bits)
    222   1.1  christos 	the_bits = bits (destcode, 4);
    223   1.1  christos       printf ("decode: %s : %s\n", the_bits, n);
    224   1.1  christos       the_bits = 0;
    225   1.1  christos     }
    226   1.1  christos 
    227   1.1  christos   switch (destcode)
    228   1.1  christos     {
    229   1.1  christos     case 0x0:
    230   1.1  christos       sd.u.reg = w ? r0 : r2r0;
    231   1.1  christos       break;
    232   1.1  christos     case 0x1:
    233   1.1  christos       sd.u.reg = w ? r1 : r2r0;
    234   1.1  christos       break;
    235   1.1  christos     case 0x2:
    236   1.1  christos       sd.u.reg = w ? r2 : r3r1;
    237   1.1  christos       break;
    238   1.1  christos     case 0x3:
    239   1.1  christos       sd.u.reg = w ? r3 : r3r1;
    240   1.1  christos       break;
    241   1.1  christos     case 0x4:
    242   1.1  christos       sd.u.reg = w ? a0 : a1a0;
    243   1.1  christos       break;
    244   1.1  christos     case 0x5:
    245   1.1  christos       sd.u.reg = w ? a1 : a1a0;
    246   1.1  christos       break;
    247   1.1  christos     case 0x6:
    248   1.1  christos       sd.u.addr = get_reg (a0);
    249   1.1  christos       break;
    250   1.1  christos     case 0x7:
    251   1.1  christos       sd.u.addr = get_reg (a1);
    252   1.1  christos       break;
    253   1.1  christos     case 0x8:
    254   1.1  christos       sd.u.addr = get_reg (a0) + disp8 ();
    255   1.1  christos       break;
    256   1.1  christos     case 0x9:
    257   1.1  christos       sd.u.addr = get_reg (a1) + disp8 ();
    258   1.1  christos       break;
    259   1.1  christos     case 0xa:
    260   1.1  christos       sd.u.addr = get_reg (sb) + disp8 ();
    261   1.1  christos       break;
    262   1.1  christos     case 0xb:
    263   1.1  christos       sd.u.addr = get_reg (fb) + sign_ext (disp8 (), 8);
    264   1.1  christos       break;
    265   1.1  christos     case 0xc:
    266   1.1  christos       sd.u.addr = get_reg (a0) + disp20 ();
    267   1.1  christos       break;
    268   1.1  christos     case 0xd:
    269   1.1  christos       sd.u.addr = get_reg (a1) + disp20 ();
    270   1.1  christos       break;
    271   1.1  christos     case 0xe:
    272   1.1  christos       sd.u.addr = get_reg (sb) + disp16 ();
    273   1.1  christos       break;
    274   1.1  christos     case 0xf:
    275   1.1  christos       sd.u.addr = disp16 ();
    276   1.1  christos       break;
    277   1.1  christos     default:
    278   1.1  christos       abort ();
    279   1.1  christos     }
    280   1.1  christos   if (sd.mem)
    281   1.1  christos     sd.u.addr &= addr_mask;
    282   1.1  christos   return sd;
    283   1.1  christos }
    284   1.1  christos 
    285   1.1  christos srcdest
    286   1.1  christos decode_dest3 (int destcode, int bw)
    287   1.1  christos {
    288   1.1  christos   static char map[8] = { -1, -1, -1, 1, 0, 10, 11, 15 };
    289   1.1  christos 
    290   1.1  christos   the_bits = bits (destcode, 3);
    291   1.1  christos   return decode_srcdest4 (map[destcode], bw);
    292   1.1  christos }
    293   1.1  christos 
    294   1.1  christos srcdest
    295   1.1  christos decode_src2 (int srccode, int bw, int d)
    296   1.1  christos {
    297   1.1  christos   static char map[4] = { 0, 10, 11, 15 };
    298   1.1  christos 
    299   1.1  christos   the_bits = bits (srccode, 2);
    300   1.1  christos   return decode_srcdest4 (srccode ? map[srccode] : 1 - d, bw);
    301   1.1  christos }
    302   1.1  christos 
    303   1.1  christos static struct
    304   1.1  christos {
    305   1.1  christos   reg_id b_regno;
    306   1.1  christos   reg_id w_regno;
    307   1.1  christos   int is_memory;
    308   1.1  christos   int disp_bytes;
    309   1.1  christos   char *name;
    310   1.1  christos } modes23[] =
    311   1.1  christos {
    312   1.1  christos   {
    313   1.1  christos   a0, a0, 1, 0, "[A0]"},	/* 0 0 0 0 0 */
    314   1.1  christos   {
    315   1.1  christos   a1, a1, 1, 0, "[A1]"},	/* 0 0 0 0 1 */
    316   1.1  christos   {
    317   1.1  christos   a0, a0, 0, 0, "A0"},		/* 0 0 0 1 0 */
    318   1.1  christos   {
    319   1.1  christos   a1, a1, 0, 0, "A1"},		/* 0 0 0 1 1 */
    320   1.1  christos   {
    321   1.1  christos   a0, a0, 1, 1, "dsp:8[A0]"},	/* 0 0 1 0 0 */
    322   1.1  christos   {
    323   1.1  christos   a1, a1, 1, 1, "dsp:8[A1]"},	/* 0 0 1 0 1 */
    324   1.1  christos   {
    325   1.1  christos   sb, sb, 1, 1, "dsp:8[SB]"},	/* 0 0 1 1 0 */
    326   1.1  christos   {
    327   1.1  christos   fb, fb, 1, -1, "dsp:8[FB]"},	/* 0 0 1 1 1 */
    328   1.1  christos   {
    329   1.1  christos   a0, a0, 1, 2, "dsp:16[A0]"},	/* 0 1 0 0 0 */
    330   1.1  christos   {
    331   1.1  christos   a1, a1, 1, 2, "dsp:16[A1]"},	/* 0 1 0 0 1 */
    332   1.1  christos   {
    333   1.1  christos   sb, sb, 1, 2, "dsp:16[SB]"},	/* 0 1 0 1 0 */
    334   1.1  christos   {
    335   1.1  christos   fb, fb, 1, -2, "dsp:16[FB]"},	/* 0 1 0 1 1 */
    336   1.1  christos   {
    337   1.1  christos   a0, a0, 1, 3, "dsp:24[A0]"},	/* 0 1 1 0 0 */
    338   1.1  christos   {
    339   1.1  christos   a1, a1, 1, 3, "dsp:24[A1]"},	/* 0 1 1 0 1 */
    340   1.1  christos   {
    341   1.1  christos   mem, mem, 1, 3, "abs24"},	/* 0 1 1 1 0 */
    342   1.1  christos   {
    343   1.1  christos   mem, mem, 1, 2, "abs16"},	/* 0 1 1 1 1 */
    344   1.1  christos   {
    345   1.1  christos   r0h, r2, 0, 0, "R0H/R2"},	/* 1 0 0 0 0 */
    346   1.1  christos   {
    347   1.1  christos   r1h, r3, 0, 0, "R1H/R3"},	/* 1 0 0 0 1 */
    348   1.1  christos   {
    349   1.1  christos   r0l, r0, 0, 0, "R0L/R0"},	/* 1 0 0 1 0 */
    350   1.1  christos   {
    351   1.1  christos   r1l, r1, 0, 0, "R1L/R1"},	/* 1 0 0 1 1 */
    352   1.1  christos };
    353   1.1  christos 
    354   1.1  christos static srcdest
    355   1.1  christos decode_sd23 (int bbb, int bb, int bytes, int ind, int add)
    356   1.1  christos {
    357   1.1  christos   srcdest sd;
    358   1.1  christos   int code = (bbb << 2) | bb;
    359   1.1  christos 
    360   1.7  christos   if (code >= ARRAY_SIZE (modes23))
    361   1.1  christos     abort ();
    362   1.1  christos 
    363   1.1  christos   if (trace)
    364   1.1  christos     {
    365   1.1  christos       char *b1 = "";
    366   1.1  christos       char *b2 = "";
    367   1.1  christos       char ad[30];
    368   1.1  christos       if (ind)
    369   1.1  christos 	{
    370   1.1  christos 	  b1 = "[";
    371   1.1  christos 	  b2 = "]";
    372   1.1  christos 	}
    373   1.1  christos       if (add)
    374   1.1  christos 	sprintf (ad, "%+d", add);
    375   1.1  christos       else
    376   1.1  christos 	ad[0] = 0;
    377   1.1  christos       if (!the_bits)
    378   1.1  christos 	the_bits = bits (code, 4);
    379   1.1  christos       printf ("decode: %s (%d) : %s%s%s%s\n", the_bits, code, b1,
    380   1.1  christos 	      modes23[code].name, ad, b2);
    381   1.1  christos       the_bits = 0;
    382   1.1  christos     }
    383   1.1  christos 
    384   1.1  christos   sd.bytes = bytes;
    385   1.1  christos   sd.mem = modes23[code].is_memory;
    386   1.1  christos   if (sd.mem)
    387   1.1  christos     {
    388   1.1  christos       if (modes23[code].w_regno == mem)
    389   1.1  christos 	sd.u.addr = 0;
    390   1.1  christos       else
    391   1.1  christos 	sd.u.addr = get_reg (modes23[code].w_regno);
    392   1.1  christos       switch (modes23[code].disp_bytes)
    393   1.1  christos 	{
    394   1.1  christos 	case 1:
    395   1.1  christos 	  sd.u.addr += disp8 ();
    396   1.1  christos 	  break;
    397   1.1  christos 	case 2:
    398   1.1  christos 	  sd.u.addr += disp16 ();
    399   1.1  christos 	  break;
    400   1.1  christos 	case -1:
    401   1.1  christos 	  sd.u.addr += sign_ext (disp8 (), 8);
    402   1.1  christos 	  break;
    403   1.1  christos 	case -2:
    404   1.1  christos 	  sd.u.addr += sign_ext (disp16 (), 16);
    405   1.1  christos 	  break;
    406   1.1  christos 	case 3:
    407   1.1  christos 	  sd.u.addr += disp24 ();
    408   1.1  christos 	  break;
    409   1.1  christos 	default:
    410   1.1  christos 	  break;
    411   1.1  christos 	}
    412   1.1  christos       if (add)
    413   1.1  christos 	sd.u.addr += add;
    414   1.1  christos       if (ind)
    415   1.1  christos 	sd.u.addr = mem_get_si (sd.u.addr & membus_mask);
    416   1.1  christos       sd.u.addr &= membus_mask;
    417   1.1  christos     }
    418   1.1  christos   else
    419   1.1  christos     {
    420   1.1  christos       sd.u.reg = (bytes > 1) ? modes23[code].w_regno : modes23[code].b_regno;
    421   1.1  christos       if (bytes == 3 || bytes == 4)
    422   1.1  christos 	{
    423   1.1  christos 	  switch (sd.u.reg)
    424   1.1  christos 	    {
    425   1.1  christos 	    case r0:
    426   1.1  christos 	      sd.u.reg = r2r0;
    427   1.1  christos 	      break;
    428   1.1  christos 	    case r1:
    429   1.1  christos 	      sd.u.reg = r3r1;
    430   1.1  christos 	      break;
    431   1.1  christos 	    case r2:
    432   1.1  christos 	      abort ();
    433   1.1  christos 	    case r3:
    434   1.1  christos 	      abort ();
    435   1.1  christos 	    default:;
    436   1.1  christos 	    }
    437   1.1  christos 	}
    438   1.1  christos 
    439   1.1  christos     }
    440   1.1  christos   return sd;
    441   1.1  christos }
    442   1.1  christos 
    443   1.1  christos srcdest
    444   1.1  christos decode_dest23 (int ddd, int dd, int bytes)
    445   1.1  christos {
    446   1.1  christos   return decode_sd23 (ddd, dd, bytes, dest_indirect, dest_addend);
    447   1.1  christos }
    448   1.1  christos 
    449   1.1  christos srcdest
    450   1.1  christos decode_src23 (int sss, int ss, int bytes)
    451   1.1  christos {
    452   1.1  christos   return decode_sd23 (sss, ss, bytes, src_indirect, src_addend);
    453   1.1  christos }
    454   1.1  christos 
    455   1.1  christos srcdest
    456   1.1  christos decode_dest2 (int dd, int bytes)
    457   1.1  christos {
    458   1.1  christos   /* r0l/r0, abs16, dsp:8[SB], dsp:8[FB] */
    459   1.1  christos   static char map[4] = { 0x12, 0x0f, 0x06, 0x07 };
    460   1.1  christos 
    461   1.1  christos   the_bits = bits (dd, 2);
    462   1.1  christos   return decode_sd23 (map[dd] >> 2, map[dd] & 3, bytes, dest_indirect,
    463   1.1  christos 		      dest_addend);
    464   1.1  christos }
    465   1.1  christos 
    466   1.1  christos srcdest
    467   1.1  christos decode_src3 (int sss, int bytes)
    468   1.1  christos {
    469   1.1  christos   /* r0, r1, a0, a1, r2, r3, N/A, N/A */
    470   1.1  christos   static char map[8] = { 0x12, 0x13, 0x02, 0x03, 0x10, 0x11, 0, 0 };
    471   1.1  christos 
    472   1.1  christos   the_bits = bits (sss, 3);
    473   1.1  christos   return decode_sd23 (map[sss] >> 2, map[sss] & 3, bytes, src_indirect,
    474   1.1  christos 		      src_addend);
    475   1.1  christos }
    476   1.1  christos 
    477   1.1  christos srcdest
    478   1.1  christos decode_dest1 (int destcode, int bw)
    479   1.1  christos {
    480   1.1  christos   the_bits = bits (destcode, 1);
    481   1.1  christos   return decode_srcdest4 (destcode, bw);
    482   1.1  christos }
    483   1.1  christos 
    484   1.1  christos srcdest
    485   1.1  christos decode_cr (int crcode)
    486   1.1  christos {
    487   1.1  christos   static int regcode[] = { 0, intbl, intbh, flags, isp, sp, sb, fb };
    488   1.1  christos   srcdest sd;
    489   1.1  christos   sd.mem = 0;
    490   1.1  christos   sd.bytes = 2;
    491   1.1  christos   sd.u.reg = regcode[crcode & 7];
    492   1.1  christos   return sd;
    493   1.1  christos }
    494   1.1  christos 
    495   1.1  christos srcdest
    496   1.1  christos decode_cr_b (int crcode, int bank)
    497   1.1  christos {
    498   1.1  christos   /* FIXME: intbl, intbh, isp */
    499   1.1  christos   static int regcode[3][8] = {
    500   1.1  christos     {0, 0, flags, 0, 0, 0, 0, 0},
    501   1.1  christos     {intb, sp, sb, fb, 0, 0, 0, isp},
    502   1.1  christos     {0, 0, 0, 0, 0, 0, 0, 0}
    503   1.1  christos   };
    504   1.1  christos   srcdest sd;
    505   1.1  christos   sd.mem = 0;
    506   1.1  christos   sd.bytes = bank ? 3 : 2;
    507   1.1  christos   sd.u.reg = regcode[bank][crcode & 7];
    508   1.1  christos   return sd;
    509   1.1  christos }
    510   1.1  christos 
    511   1.1  christos srcdest
    512   1.1  christos widen_sd (srcdest sd)
    513   1.1  christos {
    514   1.1  christos   sd.bytes *= 2;
    515   1.1  christos   if (!sd.mem)
    516   1.1  christos     switch (sd.u.reg)
    517   1.1  christos       {
    518   1.1  christos       case r0l:
    519   1.1  christos 	sd.u.reg = r0;
    520   1.1  christos 	break;
    521   1.1  christos       case r0:
    522   1.1  christos 	sd.u.reg = r2r0;
    523   1.1  christos 	break;
    524   1.1  christos       case r1l:
    525   1.1  christos 	sd.u.reg = r1;
    526   1.1  christos 	break;
    527   1.1  christos       case r1:
    528   1.1  christos 	sd.u.reg = r3r1;
    529   1.1  christos 	break;
    530   1.1  christos       case a0:
    531   1.1  christos 	if (A16)
    532   1.1  christos 	  sd.u.reg = a1a0;
    533   1.1  christos 	break;
    534   1.1  christos       default:
    535   1.1  christos 	break;
    536   1.1  christos       }
    537   1.1  christos   return sd;
    538   1.1  christos }
    539   1.1  christos 
    540   1.1  christos srcdest
    541   1.1  christos reg_sd (reg_id reg)
    542   1.1  christos {
    543   1.1  christos   srcdest rv;
    544   1.1  christos   rv.bytes = reg_bytes[reg];
    545   1.1  christos   rv.mem = 0;
    546   1.1  christos   rv.u.reg = reg;
    547   1.1  christos   return rv;
    548   1.1  christos }
    549   1.1  christos 
    550   1.1  christos int
    551   1.1  christos get_src (srcdest sd)
    552   1.1  christos {
    553   1.1  christos   int v;
    554   1.1  christos   if (sd.mem)
    555   1.1  christos     {
    556   1.1  christos       switch (sd.bytes)
    557   1.1  christos 	{
    558   1.1  christos 	case 1:
    559   1.1  christos 	  v = mem_get_qi (sd.u.addr);
    560   1.1  christos 	  break;
    561   1.1  christos 	case 2:
    562   1.1  christos 	  v = mem_get_hi (sd.u.addr);
    563   1.1  christos 	  break;
    564   1.1  christos 	case 3:
    565   1.1  christos 	  v = mem_get_psi (sd.u.addr);
    566   1.1  christos 	  break;
    567   1.1  christos 	case 4:
    568   1.1  christos 	  v = mem_get_si (sd.u.addr);
    569   1.1  christos 	  break;
    570   1.1  christos 	default:
    571   1.1  christos 	  abort ();
    572   1.1  christos 	}
    573   1.1  christos     }
    574   1.1  christos   else
    575   1.1  christos     {
    576   1.1  christos       v = get_reg (sd.u.reg);
    577   1.1  christos       switch (sd.bytes)
    578   1.1  christos 	{
    579   1.1  christos 	case 1:
    580   1.1  christos 	  v &= 0xff;
    581   1.1  christos 	  break;
    582   1.1  christos 	case 2:
    583   1.1  christos 	  v &= 0xffff;
    584   1.1  christos 	  break;
    585   1.1  christos 	case 3:
    586   1.1  christos 	  v &= 0xffffff;
    587   1.1  christos 	  break;
    588   1.1  christos 	}
    589   1.1  christos     }
    590   1.1  christos   return v;
    591   1.1  christos }
    592   1.1  christos 
    593   1.1  christos void
    594   1.1  christos put_dest (srcdest sd, int v)
    595   1.1  christos {
    596   1.1  christos   if (sd.mem)
    597   1.1  christos     {
    598   1.1  christos       switch (sd.bytes)
    599   1.1  christos 	{
    600   1.1  christos 	case 1:
    601   1.1  christos 	  mem_put_qi (sd.u.addr, v);
    602   1.1  christos 	  break;
    603   1.1  christos 	case 2:
    604   1.1  christos 	  mem_put_hi (sd.u.addr, v);
    605   1.1  christos 	  break;
    606   1.1  christos 	case 3:
    607   1.1  christos 	  mem_put_psi (sd.u.addr, v);
    608   1.1  christos 	  break;
    609   1.1  christos 	case 4:
    610   1.1  christos 	  mem_put_si (sd.u.addr, v);
    611   1.1  christos 	  break;
    612   1.1  christos 	}
    613   1.1  christos     }
    614   1.1  christos   else
    615   1.1  christos     {
    616   1.1  christos       switch (sd.bytes)
    617   1.1  christos 	{
    618   1.1  christos 	case 1:
    619   1.1  christos 	  v &= 0xff;
    620   1.1  christos 	  break;
    621   1.1  christos 	case 2:
    622   1.1  christos 	  v &= 0xffff;
    623   1.1  christos 	  break;
    624   1.1  christos 	case 3:
    625   1.1  christos 	  v &= 0xffffff;
    626   1.1  christos 	  break;
    627   1.1  christos 	}
    628   1.1  christos       put_reg (sd.u.reg, v);
    629   1.1  christos     }
    630   1.1  christos }
    631   1.1  christos 
    632   1.1  christos srcdest
    633   1.1  christos decode_bit (int destcode)
    634   1.1  christos {
    635   1.1  christos   srcdest sd;
    636   1.1  christos   int addr = 0;
    637   1.1  christos   static const char *dc_names[] = { "r0", "r1", "r2", "r3",
    638   1.1  christos     "a0", "a1", "[a0]", "[a1]",
    639   1.1  christos     "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
    640   1.1  christos     "disp16[a0]", "disp16[a1]", "disp16[sb]", "abs16"
    641   1.1  christos   };
    642   1.1  christos 
    643   1.1  christos   if (trace)
    644   1.1  christos     {
    645   1.1  christos       const char *the_bits = bits (destcode, 4);
    646   1.1  christos       printf ("decode: %s : %s\n", the_bits, dc_names[destcode]);
    647   1.1  christos     }
    648   1.1  christos 
    649   1.1  christos   switch (destcode)
    650   1.1  christos     {
    651   1.1  christos     case 0:
    652   1.1  christos       sd.u.reg = r0;
    653   1.1  christos       break;
    654   1.1  christos     case 1:
    655   1.1  christos       sd.u.reg = r1;
    656   1.1  christos       break;
    657   1.1  christos     case 2:
    658   1.1  christos       sd.u.reg = r2;
    659   1.1  christos       break;
    660   1.1  christos     case 3:
    661   1.1  christos       sd.u.reg = r3;
    662   1.1  christos       break;
    663   1.1  christos     case 4:
    664   1.1  christos       sd.u.reg = a0;
    665   1.1  christos       break;
    666   1.1  christos     case 5:
    667   1.1  christos       sd.u.reg = a1;
    668   1.1  christos       break;
    669   1.1  christos     case 6:
    670   1.1  christos       addr = get_reg (a0);
    671   1.1  christos       break;
    672   1.1  christos     case 7:
    673   1.1  christos       addr = get_reg (a1);
    674   1.1  christos       break;
    675   1.1  christos     case 8:
    676   1.1  christos       addr = get_reg (a0) + disp8 ();
    677   1.1  christos       break;
    678   1.1  christos     case 9:
    679   1.1  christos       addr = get_reg (a1) + disp8 ();
    680   1.1  christos       break;
    681   1.1  christos     case 10:
    682   1.1  christos       addr = get_reg (sb) * 8 + disp8 ();
    683   1.1  christos       break;
    684   1.1  christos     case 11:
    685   1.1  christos       addr = get_reg (fb) * 8 + sign_ext (disp8 (), 8);
    686   1.1  christos       break;
    687   1.1  christos     case 12:
    688   1.1  christos       addr = get_reg (a0) + disp16 ();
    689   1.1  christos       break;
    690   1.1  christos     case 13:
    691   1.1  christos       addr = get_reg (a1) + disp16 ();
    692   1.1  christos       break;
    693   1.1  christos     case 14:
    694   1.1  christos       addr = get_reg (sb) + disp16 ();
    695   1.1  christos       break;
    696   1.1  christos     case 15:
    697   1.1  christos       addr = disp16 ();
    698   1.1  christos       break;
    699   1.1  christos     }
    700   1.1  christos 
    701   1.1  christos   if (destcode < 6)
    702   1.1  christos     {
    703   1.1  christos       int d = disp8 ();
    704   1.1  christos       sd.mem = 0;
    705   1.1  christos       sd.mask = 1 << (d & 0x0f);
    706   1.1  christos     }
    707   1.1  christos   else
    708   1.1  christos     {
    709   1.1  christos       addr &= addr_mask;
    710   1.1  christos       sd.mem = 1;
    711   1.1  christos       sd.mask = 1 << (addr & 7);
    712   1.1  christos       sd.u.addr = addr >> 3;
    713   1.1  christos     }
    714   1.1  christos   return sd;
    715   1.1  christos }
    716   1.1  christos 
    717   1.1  christos srcdest
    718   1.1  christos decode_bit11 (int op0)
    719   1.1  christos {
    720   1.1  christos   srcdest sd;
    721   1.1  christos   sd.mask = 1 << (op0 & 7);
    722   1.1  christos   sd.mem = 1;
    723   1.1  christos   sd.u.addr = get_reg (sb) + disp8 ();
    724   1.1  christos   return sd;
    725   1.1  christos }
    726   1.1  christos 
    727   1.1  christos int
    728   1.1  christos get_bit (srcdest sd)
    729   1.1  christos {
    730   1.1  christos   int b;
    731   1.1  christos   if (sd.mem)
    732   1.1  christos     b = mem_get_qi (sd.u.addr) & sd.mask;
    733   1.1  christos   else
    734   1.1  christos     b = get_reg (sd.u.reg) & sd.mask;
    735   1.1  christos   return b ? 1 : 0;
    736   1.1  christos }
    737   1.1  christos 
    738   1.1  christos void
    739   1.1  christos put_bit (srcdest sd, int val)
    740   1.1  christos {
    741   1.1  christos   int b;
    742   1.1  christos   if (sd.mem)
    743   1.1  christos     b = mem_get_qi (sd.u.addr);
    744   1.1  christos   else
    745   1.1  christos     b = get_reg (sd.u.reg);
    746   1.1  christos   if (val)
    747   1.1  christos     b |= sd.mask;
    748   1.1  christos   else
    749   1.1  christos     b &= ~sd.mask;
    750   1.1  christos   if (sd.mem)
    751   1.1  christos     mem_put_qi (sd.u.addr, b);
    752   1.1  christos   else
    753   1.1  christos     put_reg (sd.u.reg, b);
    754   1.1  christos }
    755   1.1  christos 
    756   1.1  christos int
    757   1.1  christos get_bit2 (srcdest sd, int bit)
    758   1.1  christos {
    759   1.1  christos   int b;
    760   1.1  christos   if (sd.mem)
    761   1.1  christos     b = mem_get_qi (sd.u.addr + (bit >> 3)) & (1 << (bit & 7));
    762   1.1  christos   else
    763   1.1  christos     b = get_reg (sd.u.reg) & (1 << bit);
    764   1.1  christos   return b ? 1 : 0;
    765   1.1  christos }
    766   1.1  christos 
    767   1.1  christos void
    768   1.1  christos put_bit2 (srcdest sd, int bit, int val)
    769   1.1  christos {
    770   1.1  christos   int b;
    771   1.1  christos   if (sd.mem)
    772   1.1  christos     b = mem_get_qi (sd.u.addr + (bit >> 3));
    773   1.1  christos   else
    774   1.1  christos     b = get_reg (sd.u.reg);
    775   1.1  christos   if (val)
    776   1.1  christos     b |= (1 << (bit & 7));
    777   1.1  christos   else
    778   1.1  christos     b &= ~(1 << (bit & 7));
    779   1.1  christos   if (sd.mem)
    780   1.1  christos     mem_put_qi (sd.u.addr + (bit >> 3), b);
    781   1.1  christos   else
    782   1.1  christos     put_reg (sd.u.reg, b);
    783   1.1  christos }
    784