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