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