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