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