Home | History | Annotate | Line # | Download | only in m32c
reg.c revision 1.3.2.1
      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 (void)
    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   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
    234 
    235   if (trace > ((id != pc) ? 0 : 1))
    236     printf ("put_reg (%s) = %0*x\n", reg_names[id], reg_bytes[id] * 2, v);
    237 
    238   switch (id)
    239     {
    240     case r0:
    241       b->r_r0 = v;
    242       break;
    243     case r0h:
    244       b->r_r0 = (b->r_r0 & 0xff) | (v << 8);
    245       break;
    246     case r0l:
    247       b->r_r0 = (b->r_r0 & 0xff00) | (v & 0xff);
    248       break;
    249     case r1:
    250       b->r_r1 = v;
    251       break;
    252     case r1h:
    253       b->r_r1 = (b->r_r1 & 0xff) | (v << 8);
    254       break;
    255     case r1l:
    256       b->r_r1 = (b->r_r1 & 0xff00) | (v & 0xff);
    257       break;
    258     case r2:
    259       b->r_r2 = v;
    260       break;
    261     case r2r0:
    262       b->r_r0 = v & 0xffff;
    263       b->r_r2 = v >> 16;
    264       break;
    265     case r3:
    266       b->r_r3 = v;
    267       break;
    268     case r3r1:
    269       b->r_r1 = v & 0xffff;
    270       b->r_r3 = v >> 16;
    271       break;
    272 
    273     case a0:
    274       b->r_a0 = v & addr_mask;
    275       break;
    276     case a1:
    277       b->r_a1 = v & addr_mask;
    278       break;
    279     case a1a0:
    280       b->r_a0 = v & 0xffff;
    281       b->r_a1 = v >> 16;
    282       break;
    283 
    284     case sb:
    285       b->r_sb = v & addr_mask;
    286       break;
    287     case fb:
    288       b->r_fb = v & addr_mask;
    289       break;
    290 
    291     case intb:
    292       regs.r_intbl = v & 0xffff;
    293       regs.r_intbh = v >> 16;
    294       break;
    295     case intbl:
    296       regs.r_intbl = v & 0xffff;
    297       break;
    298     case intbh:
    299       regs.r_intbh = v & 0xff;
    300       break;
    301 
    302     case sp:
    303       {
    304 	SI *spp;
    305 	if (regs.r_flags & FLAGBIT_U)
    306 	  spp = &regs.r_usp;
    307 	else
    308 	  spp = &regs.r_isp;
    309 	*spp = v & addr_mask;
    310 	if (*spp < heaptop)
    311 	  {
    312 	    printf ("collision: pc %08lx heap %08x stack %08lx\n", regs.r_pc,
    313 		    heaptop, *spp);
    314 	    exit (1);
    315 	  }
    316 	if (*spp < lowest_sp)
    317 	  lowest_sp = *spp;
    318 	if (*spp > highest_sp)
    319 	  highest_sp = *spp;
    320 	break;
    321       }
    322     case usp:
    323       regs.r_usp = v & addr_mask;
    324       break;
    325     case isp:
    326       regs.r_isp = v & addr_mask;
    327       break;
    328 
    329     case pc:
    330       regs.r_pc = v & membus_mask;
    331       break;
    332     case flags:
    333       regs.r_flags = v;
    334       break;
    335     default:
    336       abort ();
    337     }
    338 }
    339 
    340 int
    341 condition_true (int cond_id)
    342 {
    343   int f;
    344   if (A16)
    345     {
    346       static const char *cond_name[] = {
    347 	"C", "C&!Z", "Z", "S",
    348 	"!C", "!(C&!Z)", "!Z", "!S",
    349 	"(S^O)|Z", "O", "!(S^O)", "unk",
    350 	"!((S^O)|Z)", "!O", "S^O", "unk"
    351       };
    352       switch (cond_id & 15)
    353 	{
    354 	case 0:
    355 	  f = FLAG_C;
    356 	  break;		/* GEU/C */
    357 	case 1:
    358 	  f = FLAG_C & !FLAG_Z;
    359 	  break;		/* GTU */
    360 	case 2:
    361 	  f = FLAG_Z;
    362 	  break;		/* EQ/Z */
    363 	case 3:
    364 	  f = FLAG_S;
    365 	  break;		/* N */
    366 	case 4:
    367 	  f = !FLAG_C;
    368 	  break;		/* LTU/NC */
    369 	case 5:
    370 	  f = !(FLAG_C & !FLAG_Z);
    371 	  break;		/* LEU */
    372 	case 6:
    373 	  f = !FLAG_Z;
    374 	  break;		/* NE/NZ */
    375 	case 7:
    376 	  f = !FLAG_S;
    377 	  break;		/* PZ */
    378 
    379 	case 8:
    380 	  f = (FLAG_S ^ FLAG_O) | FLAG_Z;
    381 	  break;		/* LE */
    382 	case 9:
    383 	  f = FLAG_O;
    384 	  break;		/* O */
    385 	case 10:
    386 	  f = !(FLAG_S ^ FLAG_O);
    387 	  break;		/* GE */
    388 	case 12:
    389 	  f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
    390 	  break;		/* GT */
    391 	case 13:
    392 	  f = !FLAG_O;
    393 	  break;		/* NO */
    394 	case 14:
    395 	  f = FLAG_S ^ FLAG_O;
    396 	  break;		/* LT */
    397 
    398 	default:
    399 	  f = 0;
    400 	  break;
    401 	}
    402       if (trace)
    403 	printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
    404 		f ? "true" : "false");
    405     }
    406   else
    407     {
    408       static const char *cond_name[] = {
    409 	"!C", "LEU", "!Z", "PZ",
    410 	"!O", "GT", "GE", "?",
    411 	"C", "GTU", "Z", "N",
    412 	"O", "LE", "LT", "!?"
    413       };
    414       switch (cond_id & 15)
    415 	{
    416 	case 0:
    417 	  f = !FLAG_C;
    418 	  break;		/* LTU/NC */
    419 	case 1:
    420 	  f = !(FLAG_C & !FLAG_Z);
    421 	  break;		/* LEU */
    422 	case 2:
    423 	  f = !FLAG_Z;
    424 	  break;		/* NE/NZ */
    425 	case 3:
    426 	  f = !FLAG_S;
    427 	  break;		/* PZ */
    428 
    429 	case 4:
    430 	  f = !FLAG_O;
    431 	  break;		/* NO */
    432 	case 5:
    433 	  f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
    434 	  break;		/* GT */
    435 	case 6:
    436 	  f = !(FLAG_S ^ FLAG_O);
    437 	  break;		/* GE */
    438 
    439 	case 8:
    440 	  f = FLAG_C;
    441 	  break;		/* GEU/C */
    442 	case 9:
    443 	  f = FLAG_C & !FLAG_Z;
    444 	  break;		/* GTU */
    445 	case 10:
    446 	  f = FLAG_Z;
    447 	  break;		/* EQ/Z */
    448 	case 11:
    449 	  f = FLAG_S;
    450 	  break;		/* N */
    451 
    452 	case 12:
    453 	  f = FLAG_O;
    454 	  break;		/* O */
    455 	case 13:
    456 	  f = (FLAG_S ^ FLAG_O) | FLAG_Z;
    457 	  break;		/* LE */
    458 	case 14:
    459 	  f = FLAG_S ^ FLAG_O;
    460 	  break;		/* LT */
    461 
    462 	default:
    463 	  f = 0;
    464 	  break;
    465 	}
    466       if (trace)
    467 	printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
    468 		f ? "true" : "false");
    469     }
    470   return f;
    471 }
    472 
    473 void
    474 set_flags (int mask, int newbits)
    475 {
    476   int i;
    477   regs.r_flags &= ~mask;
    478   regs.r_flags |= newbits & mask;
    479   if (trace)
    480     {
    481       printf ("flags now \033[32m %d", (regs.r_flags >> (A16 ? 8 : 12)) & 7);
    482       for (i = 7; i >= 0; i--)
    483 	if (regs.r_flags & (1 << i))
    484 	  putchar ("CDZSBOIU"[i]);
    485 	else
    486 	  putchar ('-');
    487       printf ("\033[0m\n");
    488     }
    489 }
    490 
    491 void
    492 set_oszc (int value, int b, int c)
    493 {
    494   int mask = b2mask[b];
    495   int f = 0;
    496 
    497   if (c)
    498     f |= FLAGBIT_C;
    499   if ((value & mask) == 0)
    500     f |= FLAGBIT_Z;
    501   if (value & b2signbit[b])
    502     f |= FLAGBIT_S;
    503   if ((value > b2maxsigned[b]) || (value < b2minsigned[b]))
    504     f |= FLAGBIT_O;
    505   set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
    506 }
    507 
    508 void
    509 set_szc (int value, int b, int c)
    510 {
    511   int mask = b2mask[b];
    512   int f = 0;
    513 
    514   if (c)
    515     f |= FLAGBIT_C;
    516   if ((value & mask) == 0)
    517     f |= FLAGBIT_Z;
    518   if (value & b2signbit[b])
    519     f |= FLAGBIT_S;
    520   set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_C, f);
    521 }
    522 
    523 void
    524 set_osz (int value, int b)
    525 {
    526   int mask = b2mask[b];
    527   int f = 0;
    528 
    529   if ((value & mask) == 0)
    530     f |= FLAGBIT_Z;
    531   if (value & b2signbit[b])
    532     f |= FLAGBIT_S;
    533   if (value & ~mask && (value & ~mask) != ~mask)
    534     f |= FLAGBIT_O;
    535   set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O, f);
    536 }
    537 
    538 void
    539 set_sz (int value, int b)
    540 {
    541   int mask = b2mask[b];
    542   int f = 0;
    543 
    544   if ((value & mask) == 0)
    545     f |= FLAGBIT_Z;
    546   if (value & b2signbit[b])
    547     f |= FLAGBIT_S;
    548   set_flags (FLAGBIT_Z | FLAGBIT_S, f);
    549 }
    550 
    551 void
    552 set_zc (int z, int c)
    553 {
    554   set_flags (FLAGBIT_C | FLAGBIT_Z,
    555 	     (c ? FLAGBIT_C : 0) | (z ? FLAGBIT_Z : 0));
    556 }
    557 
    558 void
    559 set_c (int c)
    560 {
    561   set_flags (FLAGBIT_C, c ? FLAGBIT_C : 0);
    562 }
    563 
    564 void
    565 put_reg_ll (reg_id id, DI v)
    566 {
    567   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
    568 
    569   switch (id)
    570     {
    571     case r3r1r2r0:
    572       b->r_r3 = v >> 48;
    573       b->r_r1 = v >> 32;
    574       b->r_r2 = v >> 16;
    575       b->r_r0 = v;
    576       break;
    577     case r3r2r1r0:
    578       b->r_r3 = v >> 48;
    579       b->r_r2 = v >> 32;
    580       b->r_r1 = v >> 16;
    581       b->r_r0 = v;
    582       break;
    583     default:
    584       put_reg (id, v);
    585     }
    586 }
    587 
    588 static void
    589 print_flags (int f)
    590 {
    591   int i;
    592   static char fn[] = "CDZSBOIU";
    593   printf ("%d.", (f >> 12) & 7);
    594   for (i = 7; i >= 0; i--)
    595     if (f & (1 << i))
    596       putchar (fn[i]);
    597 }
    598 
    599 #define TRC(f,n, id) \
    600   if (oldregs.f != regs.f) \
    601     { \
    602       printf("  %s %0*x:%0*x", n, \
    603 	     reg_bytes[id]*2, (unsigned int)oldregs.f, \
    604 	     reg_bytes[id]*2, (unsigned int)regs.f); \
    605       oldregs.f = regs.f; \
    606     }
    607 
    608 void
    609 trace_register_changes (void)
    610 {
    611   if (!trace)
    612     return;
    613   printf ("\033[36mREGS:");
    614   TRC (r[0].r_r0, "r0", r0);
    615   TRC (r[0].r_r1, "r1", r1);
    616   TRC (r[0].r_r2, "r2", r2);
    617   TRC (r[0].r_r3, "r3", r3);
    618   TRC (r[0].r_a0, "a0", a0);
    619   TRC (r[0].r_a1, "a1", a1);
    620   TRC (r[0].r_sb, "sb", sb);
    621   TRC (r[0].r_fb, "fb", fb);
    622   TRC (r[1].r_r0, "r0'", r0);
    623   TRC (r[1].r_r1, "r1'", r1);
    624   TRC (r[1].r_r2, "r2'", r2);
    625   TRC (r[1].r_r3, "r3'", r3);
    626   TRC (r[1].r_a0, "a0'", a0);
    627   TRC (r[1].r_a1, "a1'", a1);
    628   TRC (r[1].r_sb, "sb'", sb);
    629   TRC (r[1].r_fb, "fb'", fb);
    630   TRC (r_intbh, "intbh", intbh);
    631   TRC (r_intbl, "intbl", intbl);
    632   TRC (r_usp, "usp", usp);
    633   TRC (r_isp, "isp", isp);
    634   TRC (r_pc, "pc", pc);
    635   if (oldregs.r_flags != regs.r_flags)
    636     {
    637       printf ("  flags ");
    638       print_flags (oldregs.r_flags);
    639       printf (":");
    640       print_flags (regs.r_flags);
    641     }
    642   printf ("\033[0m\n");
    643 }
    644 
    645 #define DRC(f, n, id) \
    646   printf("  %-3s %0*x", n,			       \
    647 	 reg_bytes[id]*2, (unsigned int)regs.f);       \
    648 
    649 void
    650 m32c_dump_all_registers (void)
    651 {
    652   printf ("\033[36mREGS:");
    653   DRC (r[0].r_r0, "r0", r0);
    654   DRC (r[0].r_r1, "r1", r1);
    655   DRC (r[0].r_r2, "r2", r2);
    656   DRC (r[0].r_r3, "r3", r3);
    657   DRC (r[0].r_a0, "a0", a0);
    658   DRC (r[0].r_a1, "a1", a1);
    659   DRC (r[0].r_sb, "sb", sb);
    660   DRC (r[0].r_fb, "fb", fb);
    661   printf ("\n     ");
    662   DRC (r[1].r_r0, "r0'", r0);
    663   DRC (r[1].r_r1, "r1'", r1);
    664   DRC (r[1].r_r2, "r2'", r2);
    665   DRC (r[1].r_r3, "r3'", r3);
    666   DRC (r[1].r_a0, "a0'", a0);
    667   DRC (r[1].r_a1, "a1'", a1);
    668   DRC (r[1].r_sb, "sb'", sb);
    669   DRC (r[1].r_fb, "fb'", fb);
    670   printf ("     \n");
    671   DRC (r_intbh, "intbh", intbh);
    672   DRC (r_intbl, "intbl", intbl);
    673   DRC (r_usp, "usp", usp);
    674   DRC (r_isp, "isp", isp);
    675   DRC (r_pc, "pc", pc);
    676   printf ("  flags ");
    677   print_flags (regs.r_flags);
    678   printf ("\033[0m\n");
    679   /*sim_disasm_one (); */
    680 }
    681