Home | History | Annotate | Line # | Download | only in m32c
reg.c revision 1.6
      1  1.1  christos /* reg.c --- register set model for M32C simulator.
      2  1.1  christos 
      3  1.6  christos Copyright (C) 2005-2016 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 #include <string.h>
     25  1.1  christos 
     26  1.1  christos #include "cpu.h"
     27  1.1  christos 
     28  1.1  christos int verbose = 0;
     29  1.1  christos int trace = 0;
     30  1.1  christos int enable_counting = 0;
     31  1.1  christos int in_gdb = 1;
     32  1.1  christos 
     33  1.1  christos regs_type regs;
     34  1.1  christos int addr_mask = 0xffff;
     35  1.1  christos int membus_mask = 0xfffff;
     36  1.1  christos int m32c_cpu = 0;
     37  1.1  christos int step_result;
     38  1.1  christos unsigned int heapbottom = 0;
     39  1.1  christos unsigned int heaptop = 0;
     40  1.1  christos 
     41  1.1  christos char *reg_names[] = {
     42  1.1  christos   "mem",
     43  1.1  christos   "r0", "r0h", "r0l",
     44  1.1  christos   "r1", "r1h", "r1l",
     45  1.1  christos   "r2", "r2r0",
     46  1.1  christos   "r3", "r3r1",
     47  1.1  christos   "r3r1r2r0",
     48  1.1  christos   "r3r2r1r0",
     49  1.1  christos   "a0",
     50  1.1  christos   "a1", "a1a0",
     51  1.1  christos   "sb", "fb",
     52  1.1  christos   "intb", "intbl", "intbh",
     53  1.1  christos   "sp", "usp", "isp", "pc", "flags"
     54  1.1  christos };
     55  1.1  christos 
     56  1.1  christos int reg_bytes[] = {
     57  1.1  christos   0,
     58  1.1  christos   2, 1, 1,
     59  1.1  christos   2, 1, 1,
     60  1.1  christos   2, 4,
     61  1.1  christos   2, 4,
     62  1.1  christos   8,
     63  1.1  christos   8,
     64  1.1  christos   2,
     65  1.1  christos   2, 4,
     66  1.1  christos   2, 2,
     67  1.1  christos   2, 1, 3,
     68  1.1  christos   2, 2, 2, 3, 2
     69  1.1  christos };
     70  1.1  christos 
     71  1.1  christos 
     72  1.1  christos unsigned int b2mask[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
     73  1.1  christos unsigned int b2signbit[] = { 0, (1 << 7), (1 << 15), (1 << 24), (1 << 31) };
     74  1.1  christos int b2maxsigned[] = { 0, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff };
     75  1.1  christos int b2minsigned[] = { 0, -128, -32768, -8388608, -2147483647 - 1 };
     76  1.1  christos 
     77  1.1  christos static regs_type oldregs;
     78  1.1  christos 
     79  1.1  christos int m32c_opcode_pc;
     80  1.1  christos 
     81  1.1  christos void
     82  1.1  christos init_regs (void)
     83  1.1  christos {
     84  1.1  christos   memset (&regs, 0, sizeof (regs));
     85  1.1  christos   memset (&oldregs, 0, sizeof (oldregs));
     86  1.1  christos }
     87  1.1  christos 
     88  1.1  christos void
     89  1.1  christos set_pointer_width (int bytes)
     90  1.1  christos {
     91  1.1  christos   if (bytes == 2)
     92  1.1  christos     {
     93  1.1  christos       addr_mask = 0xffff;
     94  1.1  christos       membus_mask = 0x000fffff;
     95  1.1  christos       reg_bytes[a0] = reg_bytes[a1] = reg_bytes[sb] = reg_bytes[fb] =
     96  1.1  christos 	reg_bytes[sp] = reg_bytes[usp] = reg_bytes[isp] = 2;
     97  1.1  christos     }
     98  1.1  christos   else
     99  1.1  christos     {
    100  1.1  christos       addr_mask = 0xffffff;
    101  1.1  christos       membus_mask = 0x00ffffff;
    102  1.1  christos       reg_bytes[a0] = reg_bytes[a1] = reg_bytes[sb] = reg_bytes[fb] =
    103  1.1  christos 	reg_bytes[sp] = reg_bytes[usp] = reg_bytes[isp] = 3;
    104  1.1  christos     }
    105  1.1  christos }
    106  1.1  christos 
    107  1.1  christos void
    108  1.1  christos m32c_set_cpu (int cpu)
    109  1.1  christos {
    110  1.1  christos   switch (cpu)
    111  1.1  christos     {
    112  1.1  christos     case CPU_R8C:
    113  1.1  christos     case CPU_M16C:
    114  1.1  christos       set_pointer_width (2);
    115  1.1  christos       decode_opcode = decode_r8c;
    116  1.1  christos       break;
    117  1.1  christos     case CPU_M32CM:
    118  1.1  christos     case CPU_M32C:
    119  1.1  christos       set_pointer_width (3);
    120  1.1  christos       decode_opcode = decode_m32c;
    121  1.1  christos       break;
    122  1.1  christos     default:
    123  1.1  christos       abort ();
    124  1.1  christos     }
    125  1.1  christos   m32c_cpu = cpu;
    126  1.1  christos }
    127  1.1  christos 
    128  1.1  christos static unsigned int
    129  1.1  christos get_reg_i (reg_id id)
    130  1.1  christos {
    131  1.1  christos   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
    132  1.1  christos 
    133  1.1  christos   switch (id)
    134  1.1  christos     {
    135  1.1  christos     case r0:
    136  1.1  christos       return b->r_r0;
    137  1.1  christos     case r0h:
    138  1.1  christos       return b->r_r0 >> 8;
    139  1.1  christos     case r0l:
    140  1.1  christos       return b->r_r0 & 0xff;
    141  1.1  christos     case r1:
    142  1.1  christos       return b->r_r1;
    143  1.1  christos     case r1h:
    144  1.1  christos       return b->r_r1 >> 8;
    145  1.1  christos     case r1l:
    146  1.1  christos       return b->r_r1 & 0xff;
    147  1.1  christos     case r2:
    148  1.1  christos       return b->r_r2;
    149  1.1  christos     case r2r0:
    150  1.1  christos       return b->r_r2 * 65536 + b->r_r0;
    151  1.1  christos     case r3:
    152  1.1  christos       return b->r_r3;
    153  1.1  christos     case r3r1:
    154  1.1  christos       return b->r_r3 * 65536 + b->r_r1;
    155  1.1  christos 
    156  1.1  christos     case a0:
    157  1.1  christos       return b->r_a0 & addr_mask;
    158  1.1  christos     case a1:
    159  1.1  christos       return b->r_a1 & addr_mask;
    160  1.1  christos     case a1a0:
    161  1.1  christos       return (b->r_a1 & 0xffff) * 65536 | (b->r_a0 & 0xffff);
    162  1.1  christos 
    163  1.1  christos     case sb:
    164  1.1  christos       return b->r_sb & addr_mask;
    165  1.1  christos     case fb:
    166  1.1  christos       return b->r_fb & addr_mask;
    167  1.1  christos 
    168  1.1  christos     case intb:
    169  1.1  christos       return regs.r_intbh * 65536 + regs.r_intbl;
    170  1.1  christos     case intbl:
    171  1.1  christos       return regs.r_intbl;
    172  1.1  christos     case intbh:
    173  1.1  christos       return regs.r_intbh;
    174  1.1  christos 
    175  1.1  christos     case sp:
    176  1.1  christos       return ((regs.r_flags & FLAGBIT_U) ? regs.r_usp : regs.
    177  1.1  christos 	      r_isp) & addr_mask;
    178  1.1  christos     case usp:
    179  1.1  christos       return regs.r_usp & addr_mask;
    180  1.1  christos     case isp:
    181  1.1  christos       return regs.r_isp & addr_mask;
    182  1.1  christos 
    183  1.1  christos     case pc:
    184  1.1  christos       return regs.r_pc & membus_mask;
    185  1.1  christos     case flags:
    186  1.1  christos       return regs.r_flags;
    187  1.1  christos     default:
    188  1.1  christos       abort ();
    189  1.1  christos     }
    190  1.1  christos }
    191  1.1  christos 
    192  1.1  christos unsigned int
    193  1.1  christos get_reg (reg_id id)
    194  1.1  christos {
    195  1.1  christos   unsigned int rv = get_reg_i (id);
    196  1.1  christos   if (trace > ((id != pc && id != fb && id != sp) ? 0 : 1))
    197  1.1  christos     printf ("get_reg (%s) = %0*x\n", reg_names[id], reg_bytes[id] * 2, rv);
    198  1.1  christos   return rv;
    199  1.1  christos }
    200  1.1  christos 
    201  1.1  christos DI
    202  1.1  christos get_reg_ll (reg_id id)
    203  1.1  christos {
    204  1.1  christos   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
    205  1.1  christos 
    206  1.1  christos   switch (id)
    207  1.1  christos     {
    208  1.1  christos     case r3r1r2r0:
    209  1.1  christos       return ((DI) b->r_r3 << 48
    210  1.1  christos 	      | (DI) b->r_r1 << 32 | (DI) b->r_r2 << 16 | (DI) b->r_r0);
    211  1.1  christos     case r3r2r1r0:
    212  1.1  christos       return ((DI) b->r_r3 << 48
    213  1.1  christos 	      | (DI) b->r_r2 << 32 | (DI) b->r_r1 << 16 | (DI) b->r_r0);
    214  1.1  christos     default:
    215  1.1  christos       return get_reg (id);
    216  1.1  christos     }
    217  1.1  christos }
    218  1.1  christos 
    219  1.1  christos static int highest_sp = 0, lowest_sp = 0xffffff;
    220  1.1  christos 
    221  1.1  christos void
    222  1.5  christos stack_heap_stats (void)
    223  1.1  christos {
    224  1.1  christos   printf ("heap:  %08x - %08x (%d bytes)\n", heapbottom, heaptop,
    225  1.1  christos 	  heaptop - heapbottom);
    226  1.1  christos   printf ("stack: %08x - %08x (%d bytes)\n", lowest_sp, highest_sp,
    227  1.1  christos 	  highest_sp - lowest_sp);
    228  1.1  christos }
    229  1.1  christos 
    230  1.1  christos void
    231  1.1  christos put_reg (reg_id id, unsigned int v)
    232  1.1  christos {
    233  1.5  christos   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
    234  1.5  christos 
    235  1.1  christos   if (trace > ((id != pc) ? 0 : 1))
    236  1.1  christos     printf ("put_reg (%s) = %0*x\n", reg_names[id], reg_bytes[id] * 2, v);
    237  1.1  christos 
    238  1.1  christos   switch (id)
    239  1.1  christos     {
    240  1.1  christos     case r0:
    241  1.1  christos       b->r_r0 = v;
    242  1.1  christos       break;
    243  1.1  christos     case r0h:
    244  1.1  christos       b->r_r0 = (b->r_r0 & 0xff) | (v << 8);
    245  1.1  christos       break;
    246  1.1  christos     case r0l:
    247  1.1  christos       b->r_r0 = (b->r_r0 & 0xff00) | (v & 0xff);
    248  1.1  christos       break;
    249  1.1  christos     case r1:
    250  1.1  christos       b->r_r1 = v;
    251  1.1  christos       break;
    252  1.1  christos     case r1h:
    253  1.1  christos       b->r_r1 = (b->r_r1 & 0xff) | (v << 8);
    254  1.1  christos       break;
    255  1.1  christos     case r1l:
    256  1.1  christos       b->r_r1 = (b->r_r1 & 0xff00) | (v & 0xff);
    257  1.1  christos       break;
    258  1.1  christos     case r2:
    259  1.1  christos       b->r_r2 = v;
    260  1.1  christos       break;
    261  1.1  christos     case r2r0:
    262  1.1  christos       b->r_r0 = v & 0xffff;
    263  1.1  christos       b->r_r2 = v >> 16;
    264  1.1  christos       break;
    265  1.1  christos     case r3:
    266  1.1  christos       b->r_r3 = v;
    267  1.1  christos       break;
    268  1.1  christos     case r3r1:
    269  1.1  christos       b->r_r1 = v & 0xffff;
    270  1.1  christos       b->r_r3 = v >> 16;
    271  1.1  christos       break;
    272  1.1  christos 
    273  1.1  christos     case a0:
    274  1.1  christos       b->r_a0 = v & addr_mask;
    275  1.1  christos       break;
    276  1.1  christos     case a1:
    277  1.1  christos       b->r_a1 = v & addr_mask;
    278  1.1  christos       break;
    279  1.1  christos     case a1a0:
    280  1.1  christos       b->r_a0 = v & 0xffff;
    281  1.1  christos       b->r_a1 = v >> 16;
    282  1.1  christos       break;
    283  1.1  christos 
    284  1.1  christos     case sb:
    285  1.1  christos       b->r_sb = v & addr_mask;
    286  1.1  christos       break;
    287  1.1  christos     case fb:
    288  1.1  christos       b->r_fb = v & addr_mask;
    289  1.1  christos       break;
    290  1.1  christos 
    291  1.1  christos     case intb:
    292  1.1  christos       regs.r_intbl = v & 0xffff;
    293  1.1  christos       regs.r_intbh = v >> 16;
    294  1.1  christos       break;
    295  1.1  christos     case intbl:
    296  1.1  christos       regs.r_intbl = v & 0xffff;
    297  1.1  christos       break;
    298  1.1  christos     case intbh:
    299  1.1  christos       regs.r_intbh = v & 0xff;
    300  1.1  christos       break;
    301  1.1  christos 
    302  1.1  christos     case sp:
    303  1.1  christos       {
    304  1.1  christos 	SI *spp;
    305  1.1  christos 	if (regs.r_flags & FLAGBIT_U)
    306  1.1  christos 	  spp = &regs.r_usp;
    307  1.1  christos 	else
    308  1.1  christos 	  spp = &regs.r_isp;
    309  1.1  christos 	*spp = v & addr_mask;
    310  1.1  christos 	if (*spp < heaptop)
    311  1.1  christos 	  {
    312  1.1  christos 	    printf ("collision: pc %08lx heap %08x stack %08lx\n", regs.r_pc,
    313  1.1  christos 		    heaptop, *spp);
    314  1.1  christos 	    exit (1);
    315  1.1  christos 	  }
    316  1.1  christos 	if (*spp < lowest_sp)
    317  1.1  christos 	  lowest_sp = *spp;
    318  1.1  christos 	if (*spp > highest_sp)
    319  1.1  christos 	  highest_sp = *spp;
    320  1.1  christos 	break;
    321  1.1  christos       }
    322  1.1  christos     case usp:
    323  1.1  christos       regs.r_usp = v & addr_mask;
    324  1.1  christos       break;
    325  1.1  christos     case isp:
    326  1.1  christos       regs.r_isp = v & addr_mask;
    327  1.1  christos       break;
    328  1.1  christos 
    329  1.1  christos     case pc:
    330  1.1  christos       regs.r_pc = v & membus_mask;
    331  1.1  christos       break;
    332  1.1  christos     case flags:
    333  1.1  christos       regs.r_flags = v;
    334  1.1  christos       break;
    335  1.1  christos     default:
    336  1.1  christos       abort ();
    337  1.1  christos     }
    338  1.1  christos }
    339  1.1  christos 
    340  1.1  christos int
    341  1.1  christos condition_true (int cond_id)
    342  1.1  christos {
    343  1.1  christos   int f;
    344  1.1  christos   if (A16)
    345  1.1  christos     {
    346  1.1  christos       static const char *cond_name[] = {
    347  1.1  christos 	"C", "C&!Z", "Z", "S",
    348  1.1  christos 	"!C", "!(C&!Z)", "!Z", "!S",
    349  1.1  christos 	"(S^O)|Z", "O", "!(S^O)", "unk",
    350  1.1  christos 	"!((S^O)|Z)", "!O", "S^O", "unk"
    351  1.1  christos       };
    352  1.1  christos       switch (cond_id & 15)
    353  1.1  christos 	{
    354  1.1  christos 	case 0:
    355  1.1  christos 	  f = FLAG_C;
    356  1.1  christos 	  break;		/* GEU/C */
    357  1.1  christos 	case 1:
    358  1.1  christos 	  f = FLAG_C & !FLAG_Z;
    359  1.1  christos 	  break;		/* GTU */
    360  1.1  christos 	case 2:
    361  1.1  christos 	  f = FLAG_Z;
    362  1.1  christos 	  break;		/* EQ/Z */
    363  1.1  christos 	case 3:
    364  1.1  christos 	  f = FLAG_S;
    365  1.1  christos 	  break;		/* N */
    366  1.1  christos 	case 4:
    367  1.1  christos 	  f = !FLAG_C;
    368  1.1  christos 	  break;		/* LTU/NC */
    369  1.1  christos 	case 5:
    370  1.1  christos 	  f = !(FLAG_C & !FLAG_Z);
    371  1.1  christos 	  break;		/* LEU */
    372  1.1  christos 	case 6:
    373  1.1  christos 	  f = !FLAG_Z;
    374  1.1  christos 	  break;		/* NE/NZ */
    375  1.1  christos 	case 7:
    376  1.1  christos 	  f = !FLAG_S;
    377  1.1  christos 	  break;		/* PZ */
    378  1.1  christos 
    379  1.1  christos 	case 8:
    380  1.1  christos 	  f = (FLAG_S ^ FLAG_O) | FLAG_Z;
    381  1.1  christos 	  break;		/* LE */
    382  1.1  christos 	case 9:
    383  1.1  christos 	  f = FLAG_O;
    384  1.1  christos 	  break;		/* O */
    385  1.1  christos 	case 10:
    386  1.1  christos 	  f = !(FLAG_S ^ FLAG_O);
    387  1.1  christos 	  break;		/* GE */
    388  1.1  christos 	case 12:
    389  1.1  christos 	  f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
    390  1.1  christos 	  break;		/* GT */
    391  1.1  christos 	case 13:
    392  1.1  christos 	  f = !FLAG_O;
    393  1.1  christos 	  break;		/* NO */
    394  1.1  christos 	case 14:
    395  1.1  christos 	  f = FLAG_S ^ FLAG_O;
    396  1.1  christos 	  break;		/* LT */
    397  1.1  christos 
    398  1.1  christos 	default:
    399  1.1  christos 	  f = 0;
    400  1.1  christos 	  break;
    401  1.1  christos 	}
    402  1.1  christos       if (trace)
    403  1.1  christos 	printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
    404  1.1  christos 		f ? "true" : "false");
    405  1.1  christos     }
    406  1.1  christos   else
    407  1.1  christos     {
    408  1.1  christos       static const char *cond_name[] = {
    409  1.1  christos 	"!C", "LEU", "!Z", "PZ",
    410  1.1  christos 	"!O", "GT", "GE", "?",
    411  1.1  christos 	"C", "GTU", "Z", "N",
    412  1.1  christos 	"O", "LE", "LT", "!?"
    413  1.1  christos       };
    414  1.1  christos       switch (cond_id & 15)
    415  1.1  christos 	{
    416  1.1  christos 	case 0:
    417  1.1  christos 	  f = !FLAG_C;
    418  1.1  christos 	  break;		/* LTU/NC */
    419  1.1  christos 	case 1:
    420  1.1  christos 	  f = !(FLAG_C & !FLAG_Z);
    421  1.1  christos 	  break;		/* LEU */
    422  1.1  christos 	case 2:
    423  1.1  christos 	  f = !FLAG_Z;
    424  1.1  christos 	  break;		/* NE/NZ */
    425  1.1  christos 	case 3:
    426  1.1  christos 	  f = !FLAG_S;
    427  1.1  christos 	  break;		/* PZ */
    428  1.1  christos 
    429  1.1  christos 	case 4:
    430  1.1  christos 	  f = !FLAG_O;
    431  1.1  christos 	  break;		/* NO */
    432  1.1  christos 	case 5:
    433  1.1  christos 	  f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
    434  1.1  christos 	  break;		/* GT */
    435  1.1  christos 	case 6:
    436  1.1  christos 	  f = !(FLAG_S ^ FLAG_O);
    437  1.1  christos 	  break;		/* GE */
    438  1.1  christos 
    439  1.1  christos 	case 8:
    440  1.1  christos 	  f = FLAG_C;
    441  1.1  christos 	  break;		/* GEU/C */
    442  1.1  christos 	case 9:
    443  1.1  christos 	  f = FLAG_C & !FLAG_Z;
    444  1.1  christos 	  break;		/* GTU */
    445  1.1  christos 	case 10:
    446  1.1  christos 	  f = FLAG_Z;
    447  1.1  christos 	  break;		/* EQ/Z */
    448  1.1  christos 	case 11:
    449  1.1  christos 	  f = FLAG_S;
    450  1.1  christos 	  break;		/* N */
    451  1.1  christos 
    452  1.1  christos 	case 12:
    453  1.1  christos 	  f = FLAG_O;
    454  1.1  christos 	  break;		/* O */
    455  1.1  christos 	case 13:
    456  1.1  christos 	  f = (FLAG_S ^ FLAG_O) | FLAG_Z;
    457  1.1  christos 	  break;		/* LE */
    458  1.1  christos 	case 14:
    459  1.1  christos 	  f = FLAG_S ^ FLAG_O;
    460  1.1  christos 	  break;		/* LT */
    461  1.1  christos 
    462  1.1  christos 	default:
    463  1.1  christos 	  f = 0;
    464  1.1  christos 	  break;
    465  1.1  christos 	}
    466  1.1  christos       if (trace)
    467  1.1  christos 	printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
    468  1.1  christos 		f ? "true" : "false");
    469  1.1  christos     }
    470  1.1  christos   return f;
    471  1.1  christos }
    472  1.1  christos 
    473  1.1  christos void
    474  1.1  christos set_flags (int mask, int newbits)
    475  1.1  christos {
    476  1.1  christos   int i;
    477  1.1  christos   regs.r_flags &= ~mask;
    478  1.1  christos   regs.r_flags |= newbits & mask;
    479  1.1  christos   if (trace)
    480  1.1  christos     {
    481  1.1  christos       printf ("flags now \033[32m %d", (regs.r_flags >> (A16 ? 8 : 12)) & 7);
    482  1.1  christos       for (i = 7; i >= 0; i--)
    483  1.1  christos 	if (regs.r_flags & (1 << i))
    484  1.1  christos 	  putchar ("CDZSBOIU"[i]);
    485  1.1  christos 	else
    486  1.1  christos 	  putchar ('-');
    487  1.1  christos       printf ("\033[0m\n");
    488  1.1  christos     }
    489  1.1  christos }
    490  1.1  christos 
    491  1.1  christos void
    492  1.1  christos set_oszc (int value, int b, int c)
    493  1.1  christos {
    494  1.1  christos   int mask = b2mask[b];
    495  1.1  christos   int f = 0;
    496  1.1  christos 
    497  1.1  christos   if (c)
    498  1.1  christos     f |= FLAGBIT_C;
    499  1.1  christos   if ((value & mask) == 0)
    500  1.1  christos     f |= FLAGBIT_Z;
    501  1.1  christos   if (value & b2signbit[b])
    502  1.1  christos     f |= FLAGBIT_S;
    503  1.1  christos   if ((value > b2maxsigned[b]) || (value < b2minsigned[b]))
    504  1.1  christos     f |= FLAGBIT_O;
    505  1.1  christos   set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
    506  1.1  christos }
    507  1.1  christos 
    508  1.1  christos void
    509  1.1  christos set_szc (int value, int b, int c)
    510  1.1  christos {
    511  1.1  christos   int mask = b2mask[b];
    512  1.1  christos   int f = 0;
    513  1.1  christos 
    514  1.1  christos   if (c)
    515  1.1  christos     f |= FLAGBIT_C;
    516  1.1  christos   if ((value & mask) == 0)
    517  1.1  christos     f |= FLAGBIT_Z;
    518  1.1  christos   if (value & b2signbit[b])
    519  1.1  christos     f |= FLAGBIT_S;
    520  1.1  christos   set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_C, f);
    521  1.1  christos }
    522  1.1  christos 
    523  1.1  christos void
    524  1.1  christos set_osz (int value, int b)
    525  1.1  christos {
    526  1.1  christos   int mask = b2mask[b];
    527  1.1  christos   int f = 0;
    528  1.1  christos 
    529  1.1  christos   if ((value & mask) == 0)
    530  1.1  christos     f |= FLAGBIT_Z;
    531  1.1  christos   if (value & b2signbit[b])
    532  1.1  christos     f |= FLAGBIT_S;
    533  1.1  christos   if (value & ~mask && (value & ~mask) != ~mask)
    534  1.1  christos     f |= FLAGBIT_O;
    535  1.1  christos   set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O, f);
    536  1.1  christos }
    537  1.1  christos 
    538  1.1  christos void
    539  1.1  christos set_sz (int value, int b)
    540  1.1  christos {
    541  1.1  christos   int mask = b2mask[b];
    542  1.1  christos   int f = 0;
    543  1.1  christos 
    544  1.1  christos   if ((value & mask) == 0)
    545  1.1  christos     f |= FLAGBIT_Z;
    546  1.1  christos   if (value & b2signbit[b])
    547  1.1  christos     f |= FLAGBIT_S;
    548  1.1  christos   set_flags (FLAGBIT_Z | FLAGBIT_S, f);
    549  1.1  christos }
    550  1.1  christos 
    551  1.1  christos void
    552  1.1  christos set_zc (int z, int c)
    553  1.1  christos {
    554  1.1  christos   set_flags (FLAGBIT_C | FLAGBIT_Z,
    555  1.1  christos 	     (c ? FLAGBIT_C : 0) | (z ? FLAGBIT_Z : 0));
    556  1.1  christos }
    557  1.1  christos 
    558  1.1  christos void
    559  1.1  christos set_c (int c)
    560  1.1  christos {
    561  1.1  christos   set_flags (FLAGBIT_C, c ? FLAGBIT_C : 0);
    562  1.1  christos }
    563  1.1  christos 
    564  1.1  christos void
    565  1.1  christos put_reg_ll (reg_id id, DI v)
    566  1.1  christos {
    567  1.1  christos   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
    568  1.1  christos 
    569  1.1  christos   switch (id)
    570  1.1  christos     {
    571  1.1  christos     case r3r1r2r0:
    572  1.1  christos       b->r_r3 = v >> 48;
    573  1.1  christos       b->r_r1 = v >> 32;
    574  1.1  christos       b->r_r2 = v >> 16;
    575  1.1  christos       b->r_r0 = v;
    576  1.1  christos       break;
    577  1.1  christos     case r3r2r1r0:
    578  1.1  christos       b->r_r3 = v >> 48;
    579  1.1  christos       b->r_r2 = v >> 32;
    580  1.1  christos       b->r_r1 = v >> 16;
    581  1.1  christos       b->r_r0 = v;
    582  1.1  christos       break;
    583  1.1  christos     default:
    584  1.1  christos       put_reg (id, v);
    585  1.1  christos     }
    586  1.1  christos }
    587  1.1  christos 
    588  1.1  christos static void
    589  1.1  christos print_flags (int f)
    590  1.1  christos {
    591  1.1  christos   int i;
    592  1.1  christos   static char fn[] = "CDZSBOIU";
    593  1.1  christos   printf ("%d.", (f >> 12) & 7);
    594  1.1  christos   for (i = 7; i >= 0; i--)
    595  1.1  christos     if (f & (1 << i))
    596  1.1  christos       putchar (fn[i]);
    597  1.1  christos }
    598  1.1  christos 
    599  1.1  christos #define TRC(f,n, id) \
    600  1.1  christos   if (oldregs.f != regs.f) \
    601  1.1  christos     { \
    602  1.1  christos       printf("  %s %0*x:%0*x", n, \
    603  1.1  christos 	     reg_bytes[id]*2, (unsigned int)oldregs.f, \
    604  1.1  christos 	     reg_bytes[id]*2, (unsigned int)regs.f); \
    605  1.1  christos       oldregs.f = regs.f; \
    606  1.1  christos     }
    607  1.1  christos 
    608  1.1  christos void
    609  1.5  christos trace_register_changes (void)
    610  1.1  christos {
    611  1.1  christos   if (!trace)
    612  1.1  christos     return;
    613  1.1  christos   printf ("\033[36mREGS:");
    614  1.1  christos   TRC (r[0].r_r0, "r0", r0);
    615  1.1  christos   TRC (r[0].r_r1, "r1", r1);
    616  1.1  christos   TRC (r[0].r_r2, "r2", r2);
    617  1.1  christos   TRC (r[0].r_r3, "r3", r3);
    618  1.1  christos   TRC (r[0].r_a0, "a0", a0);
    619  1.1  christos   TRC (r[0].r_a1, "a1", a1);
    620  1.1  christos   TRC (r[0].r_sb, "sb", sb);
    621  1.1  christos   TRC (r[0].r_fb, "fb", fb);
    622  1.1  christos   TRC (r[1].r_r0, "r0'", r0);
    623  1.1  christos   TRC (r[1].r_r1, "r1'", r1);
    624  1.1  christos   TRC (r[1].r_r2, "r2'", r2);
    625  1.1  christos   TRC (r[1].r_r3, "r3'", r3);
    626  1.1  christos   TRC (r[1].r_a0, "a0'", a0);
    627  1.1  christos   TRC (r[1].r_a1, "a1'", a1);
    628  1.1  christos   TRC (r[1].r_sb, "sb'", sb);
    629  1.1  christos   TRC (r[1].r_fb, "fb'", fb);
    630  1.1  christos   TRC (r_intbh, "intbh", intbh);
    631  1.1  christos   TRC (r_intbl, "intbl", intbl);
    632  1.1  christos   TRC (r_usp, "usp", usp);
    633  1.1  christos   TRC (r_isp, "isp", isp);
    634  1.1  christos   TRC (r_pc, "pc", pc);
    635  1.1  christos   if (oldregs.r_flags != regs.r_flags)
    636  1.1  christos     {
    637  1.1  christos       printf ("  flags ");
    638  1.1  christos       print_flags (oldregs.r_flags);
    639  1.1  christos       printf (":");
    640  1.1  christos       print_flags (regs.r_flags);
    641  1.1  christos     }
    642  1.1  christos   printf ("\033[0m\n");
    643  1.1  christos }
    644  1.1  christos 
    645  1.1  christos #define DRC(f, n, id) \
    646  1.1  christos   printf("  %-3s %0*x", n,			       \
    647  1.1  christos 	 reg_bytes[id]*2, (unsigned int)regs.f);       \
    648  1.1  christos 
    649  1.1  christos void
    650  1.5  christos m32c_dump_all_registers (void)
    651  1.1  christos {
    652  1.1  christos   printf ("\033[36mREGS:");
    653  1.1  christos   DRC (r[0].r_r0, "r0", r0);
    654  1.1  christos   DRC (r[0].r_r1, "r1", r1);
    655  1.1  christos   DRC (r[0].r_r2, "r2", r2);
    656  1.1  christos   DRC (r[0].r_r3, "r3", r3);
    657  1.1  christos   DRC (r[0].r_a0, "a0", a0);
    658  1.1  christos   DRC (r[0].r_a1, "a1", a1);
    659  1.1  christos   DRC (r[0].r_sb, "sb", sb);
    660  1.1  christos   DRC (r[0].r_fb, "fb", fb);
    661  1.1  christos   printf ("\n     ");
    662  1.1  christos   DRC (r[1].r_r0, "r0'", r0);
    663  1.1  christos   DRC (r[1].r_r1, "r1'", r1);
    664  1.1  christos   DRC (r[1].r_r2, "r2'", r2);
    665  1.1  christos   DRC (r[1].r_r3, "r3'", r3);
    666  1.1  christos   DRC (r[1].r_a0, "a0'", a0);
    667  1.1  christos   DRC (r[1].r_a1, "a1'", a1);
    668  1.1  christos   DRC (r[1].r_sb, "sb'", sb);
    669  1.1  christos   DRC (r[1].r_fb, "fb'", fb);
    670  1.1  christos   printf ("     \n");
    671  1.1  christos   DRC (r_intbh, "intbh", intbh);
    672  1.1  christos   DRC (r_intbl, "intbl", intbl);
    673  1.1  christos   DRC (r_usp, "usp", usp);
    674  1.1  christos   DRC (r_isp, "isp", isp);
    675  1.1  christos   DRC (r_pc, "pc", pc);
    676  1.1  christos   printf ("  flags ");
    677  1.1  christos   print_flags (regs.r_flags);
    678  1.1  christos   printf ("\033[0m\n");
    679  1.1  christos   /*sim_disasm_one (); */
    680  1.1  christos }
    681