1 /* reg.c --- register set model for M32C simulator. 2 3 Copyright (C) 2005-2020 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 (®s, 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 = ®s.r_usp; 307 else 308 spp = ®s.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