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