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