1 /* rx.c --- opcode semantics for stand-alone RX simulator. 2 3 Copyright (C) 2008-2017 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 #include "config.h" 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <signal.h> 26 #include "libiberty.h" 27 28 #include "opcode/rx.h" 29 #include "cpu.h" 30 #include "mem.h" 31 #include "syscalls.h" 32 #include "fpu.h" 33 #include "err.h" 34 #include "misc.h" 35 36 #ifdef CYCLE_STATS 37 static const char * id_names[] = { 38 "RXO_unknown", 39 "RXO_mov", /* d = s (signed) */ 40 "RXO_movbi", /* d = [s,s2] (signed) */ 41 "RXO_movbir", /* [s,s2] = d (signed) */ 42 "RXO_pushm", /* s..s2 */ 43 "RXO_popm", /* s..s2 */ 44 "RXO_xchg", /* s <-> d */ 45 "RXO_stcc", /* d = s if cond(s2) */ 46 "RXO_rtsd", /* rtsd, 1=imm, 2-0 = reg if reg type */ 47 48 /* These are all either d OP= s or, if s2 is set, d = s OP s2. Note 49 that d may be "None". */ 50 "RXO_and", 51 "RXO_or", 52 "RXO_xor", 53 "RXO_add", 54 "RXO_sub", 55 "RXO_mul", 56 "RXO_div", 57 "RXO_divu", 58 "RXO_shll", 59 "RXO_shar", 60 "RXO_shlr", 61 62 "RXO_adc", /* d = d + s + carry */ 63 "RXO_sbb", /* d = d - s - ~carry */ 64 "RXO_abs", /* d = |s| */ 65 "RXO_max", /* d = max(d,s) */ 66 "RXO_min", /* d = min(d,s) */ 67 "RXO_emul", /* d:64 = d:32 * s */ 68 "RXO_emulu", /* d:64 = d:32 * s (unsigned) */ 69 70 "RXO_rolc", /* d <<= 1 through carry */ 71 "RXO_rorc", /* d >>= 1 through carry*/ 72 "RXO_rotl", /* d <<= #s without carry */ 73 "RXO_rotr", /* d >>= #s without carry*/ 74 "RXO_revw", /* d = revw(s) */ 75 "RXO_revl", /* d = revl(s) */ 76 "RXO_branch", /* pc = d if cond(s) */ 77 "RXO_branchrel",/* pc += d if cond(s) */ 78 "RXO_jsr", /* pc = d */ 79 "RXO_jsrrel", /* pc += d */ 80 "RXO_rts", 81 "RXO_nop", 82 "RXO_nop2", 83 "RXO_nop3", 84 "RXO_nop4", 85 "RXO_nop5", 86 "RXO_nop6", 87 "RXO_nop7", 88 89 "RXO_scmpu", 90 "RXO_smovu", 91 "RXO_smovb", 92 "RXO_suntil", 93 "RXO_swhile", 94 "RXO_smovf", 95 "RXO_sstr", 96 97 "RXO_rmpa", 98 "RXO_mulhi", 99 "RXO_mullo", 100 "RXO_machi", 101 "RXO_maclo", 102 "RXO_mvtachi", 103 "RXO_mvtaclo", 104 "RXO_mvfachi", 105 "RXO_mvfacmi", 106 "RXO_mvfaclo", 107 "RXO_racw", 108 109 "RXO_sat", /* sat(d) */ 110 "RXO_satr", 111 112 "RXO_fadd", /* d op= s */ 113 "RXO_fcmp", 114 "RXO_fsub", 115 "RXO_ftoi", 116 "RXO_fmul", 117 "RXO_fdiv", 118 "RXO_round", 119 "RXO_itof", 120 121 "RXO_bset", /* d |= (1<<s) */ 122 "RXO_bclr", /* d &= ~(1<<s) */ 123 "RXO_btst", /* s & (1<<s2) */ 124 "RXO_bnot", /* d ^= (1<<s) */ 125 "RXO_bmcc", /* d<s> = cond(s2) */ 126 127 "RXO_clrpsw", /* flag index in d */ 128 "RXO_setpsw", /* flag index in d */ 129 "RXO_mvtipl", /* new IPL in s */ 130 131 "RXO_rtfi", 132 "RXO_rte", 133 "RXO_rtd", /* undocumented */ 134 "RXO_brk", 135 "RXO_dbt", /* undocumented */ 136 "RXO_int", /* vector id in s */ 137 "RXO_stop", 138 "RXO_wait", 139 140 "RXO_sccnd", /* d = cond(s) ? 1 : 0 */ 141 }; 142 143 static const char * optype_names[] = { 144 " - ", 145 "#Imm", /* #addend */ 146 " Rn ", /* Rn */ 147 "[Rn]", /* [Rn + addend] */ 148 "Ps++", /* [Rn+] */ 149 "--Pr", /* [-Rn] */ 150 " cc ", /* eq, gtu, etc */ 151 "Flag", /* [UIOSZC] */ 152 "RbRi" /* [Rb + scale * Ri] */ 153 }; 154 155 #define N_RXO ARRAY_SIZE (id_names) 156 #define N_RXT ARRAY_SIZE (optype_names) 157 #define N_MAP 90 158 159 static unsigned long long benchmark_start_cycle; 160 static unsigned long long benchmark_end_cycle; 161 162 static int op_cache[N_RXT][N_RXT][N_RXT]; 163 static int op_cache_rev[N_MAP]; 164 static int op_cache_idx = 0; 165 166 static int 167 op_lookup (int a, int b, int c) 168 { 169 if (op_cache[a][b][c]) 170 return op_cache[a][b][c]; 171 op_cache_idx ++; 172 if (op_cache_idx >= N_MAP) 173 { 174 printf("op_cache_idx exceeds %d\n", N_MAP); 175 exit(1); 176 } 177 op_cache[a][b][c] = op_cache_idx; 178 op_cache_rev[op_cache_idx] = (a<<8) | (b<<4) | c; 179 return op_cache_idx; 180 } 181 182 static char * 183 op_cache_string (int map) 184 { 185 static int ci; 186 static char cb[5][20]; 187 int a, b, c; 188 189 map = op_cache_rev[map]; 190 a = (map >> 8) & 15; 191 b = (map >> 4) & 15; 192 c = (map >> 0) & 15; 193 ci = (ci + 1) % 5; 194 sprintf(cb[ci], "%s %s %s", optype_names[a], optype_names[b], optype_names[c]); 195 return cb[ci]; 196 } 197 198 static unsigned long long cycles_per_id[N_RXO][N_MAP]; 199 static unsigned long long times_per_id[N_RXO][N_MAP]; 200 static unsigned long long memory_stalls; 201 static unsigned long long register_stalls; 202 static unsigned long long branch_stalls; 203 static unsigned long long branch_alignment_stalls; 204 static unsigned long long fast_returns; 205 206 static unsigned long times_per_pair[N_RXO][N_MAP][N_RXO][N_MAP]; 207 static int prev_opcode_id = RXO_unknown; 208 static int po0; 209 210 #define STATS(x) x 211 212 #else 213 #define STATS(x) 214 #endif /* CYCLE_STATS */ 215 216 217 #ifdef CYCLE_ACCURATE 218 219 static int new_rt = -1; 220 221 /* Number of cycles to add if an insn spans an 8-byte boundary. */ 222 static int branch_alignment_penalty = 0; 223 224 #endif 225 226 static int running_benchmark = 1; 227 228 #define tprintf if (trace && running_benchmark) printf 229 230 jmp_buf decode_jmp_buf; 231 unsigned int rx_cycles = 0; 232 233 #ifdef CYCLE_ACCURATE 234 /* If nonzero, memory was read at some point and cycle latency might 235 take effect. */ 236 static int memory_source = 0; 237 /* If nonzero, memory was written and extra cycles might be 238 needed. */ 239 static int memory_dest = 0; 240 241 static void 242 cycles (int throughput) 243 { 244 tprintf("%d cycles\n", throughput); 245 regs.cycle_count += throughput; 246 } 247 248 /* Number of execution (E) cycles the op uses. For memory sources, we 249 include the load micro-op stall as two extra E cycles. */ 250 #define E(c) cycles (memory_source ? c + 2 : c) 251 #define E1 cycles (1) 252 #define E2 cycles (2) 253 #define EBIT cycles (memory_source ? 2 : 1) 254 255 /* Check to see if a read latency must be applied for a given register. */ 256 #define RL(r) \ 257 if (regs.rt == r ) \ 258 { \ 259 tprintf("register %d load stall\n", r); \ 260 regs.cycle_count ++; \ 261 STATS(register_stalls ++); \ 262 regs.rt = -1; \ 263 } 264 265 #define RLD(r) \ 266 if (memory_source) \ 267 { \ 268 tprintf ("Rt now %d\n", r); \ 269 new_rt = r; \ 270 } 271 272 static int 273 lsb_count (unsigned long v, int is_signed) 274 { 275 int i, lsb; 276 if (is_signed && (v & 0x80000000U)) 277 v = (unsigned long)(long)(-v); 278 for (i=31; i>=0; i--) 279 if (v & (1 << i)) 280 { 281 /* v is 0..31, we want 1=1-2, 2=3-4, 3=5-6, etc. */ 282 lsb = (i + 2) / 2; 283 return lsb; 284 } 285 return 0; 286 } 287 288 static int 289 divu_cycles(unsigned long num, unsigned long den) 290 { 291 int nb = lsb_count (num, 0); 292 int db = lsb_count (den, 0); 293 int rv; 294 295 if (nb < db) 296 rv = 2; 297 else 298 rv = 3 + nb - db; 299 E (rv); 300 return rv; 301 } 302 303 static int 304 div_cycles(long num, long den) 305 { 306 int nb = lsb_count ((unsigned long)num, 1); 307 int db = lsb_count ((unsigned long)den, 1); 308 int rv; 309 310 if (nb < db) 311 rv = 3; 312 else 313 rv = 5 + nb - db; 314 E (rv); 315 return rv; 316 } 317 318 #else /* !CYCLE_ACCURATE */ 319 320 #define cycles(t) 321 #define E(c) 322 #define E1 323 #define E2 324 #define EBIT 325 #define RL(r) 326 #define RLD(r) 327 328 #define divu_cycles(n,d) 329 #define div_cycles(n,d) 330 331 #endif /* else CYCLE_ACCURATE */ 332 333 static int size2bytes[] = { 334 4, 1, 1, 1, 2, 2, 2, 3, 4 335 }; 336 337 typedef struct { 338 unsigned long dpc; 339 } RX_Data; 340 341 #define rx_abort() _rx_abort(__FILE__, __LINE__) 342 static void 343 _rx_abort (const char *file, int line) 344 { 345 if (strrchr (file, '/')) 346 file = strrchr (file, '/') + 1; 347 fprintf(stderr, "abort at %s:%d\n", file, line); 348 abort(); 349 } 350 351 static unsigned char *get_byte_base; 352 static RX_Opcode_Decoded **decode_cache_base; 353 static SI get_byte_page; 354 355 void 356 reset_decoder (void) 357 { 358 get_byte_base = 0; 359 decode_cache_base = 0; 360 get_byte_page = 0; 361 } 362 363 static inline void 364 maybe_get_mem_page (SI tpc) 365 { 366 if (((tpc ^ get_byte_page) & NONPAGE_MASK) || enable_counting) 367 { 368 get_byte_page = tpc & NONPAGE_MASK; 369 get_byte_base = rx_mem_ptr (get_byte_page, MPA_READING) - get_byte_page; 370 decode_cache_base = rx_mem_decode_cache (get_byte_page) - get_byte_page; 371 } 372 } 373 374 /* This gets called a *lot* so optimize it. */ 375 static int 376 rx_get_byte (void *vdata) 377 { 378 RX_Data *rx_data = (RX_Data *)vdata; 379 SI tpc = rx_data->dpc; 380 381 /* See load.c for an explanation of this. */ 382 if (rx_big_endian) 383 tpc ^= 3; 384 385 maybe_get_mem_page (tpc); 386 387 rx_data->dpc ++; 388 return get_byte_base [tpc]; 389 } 390 391 static int 392 get_op (const RX_Opcode_Decoded *rd, int i) 393 { 394 const RX_Opcode_Operand *o = rd->op + i; 395 int addr, rv = 0; 396 397 switch (o->type) 398 { 399 case RX_Operand_None: 400 rx_abort (); 401 402 case RX_Operand_Immediate: /* #addend */ 403 return o->addend; 404 405 case RX_Operand_Register: /* Rn */ 406 RL (o->reg); 407 rv = get_reg (o->reg); 408 break; 409 410 case RX_Operand_Predec: /* [-Rn] */ 411 put_reg (o->reg, get_reg (o->reg) - size2bytes[o->size]); 412 /* fall through */ 413 case RX_Operand_Postinc: /* [Rn+] */ 414 case RX_Operand_Zero_Indirect: /* [Rn + 0] */ 415 case RX_Operand_Indirect: /* [Rn + addend] */ 416 case RX_Operand_TwoReg: /* [Rn + scale * R2] */ 417 #ifdef CYCLE_ACCURATE 418 RL (o->reg); 419 if (o->type == RX_Operand_TwoReg) 420 RL (rd->op[2].reg); 421 regs.rt = -1; 422 if (regs.m2m == M2M_BOTH) 423 { 424 tprintf("src memory stall\n"); 425 #ifdef CYCLE_STATS 426 memory_stalls ++; 427 #endif 428 regs.cycle_count ++; 429 regs.m2m = 0; 430 } 431 432 memory_source = 1; 433 #endif 434 435 if (o->type == RX_Operand_TwoReg) 436 addr = get_reg (o->reg) * size2bytes[rd->size] + get_reg (rd->op[2].reg); 437 else 438 addr = get_reg (o->reg) + o->addend; 439 440 switch (o->size) 441 { 442 default: 443 case RX_AnySize: 444 rx_abort (); 445 446 case RX_Byte: /* undefined extension */ 447 case RX_UByte: 448 case RX_SByte: 449 rv = mem_get_qi (addr); 450 break; 451 452 case RX_Word: /* undefined extension */ 453 case RX_UWord: 454 case RX_SWord: 455 rv = mem_get_hi (addr); 456 break; 457 458 case RX_3Byte: 459 rv = mem_get_psi (addr); 460 break; 461 462 case RX_Long: 463 rv = mem_get_si (addr); 464 break; 465 } 466 467 if (o->type == RX_Operand_Postinc) 468 put_reg (o->reg, get_reg (o->reg) + size2bytes[o->size]); 469 470 break; 471 472 case RX_Operand_Condition: /* eq, gtu, etc */ 473 return condition_true (o->reg); 474 475 case RX_Operand_Flag: /* [UIOSZC] */ 476 return (regs.r_psw & (1 << o->reg)) ? 1 : 0; 477 } 478 479 /* if we've gotten here, we need to clip/extend the value according 480 to the size. */ 481 switch (o->size) 482 { 483 default: 484 case RX_AnySize: 485 rx_abort (); 486 487 case RX_Byte: /* undefined extension */ 488 rv |= 0xdeadbe00; /* keep them honest */ 489 break; 490 491 case RX_UByte: 492 rv &= 0xff; 493 break; 494 495 case RX_SByte: 496 rv = sign_ext (rv, 8); 497 break; 498 499 case RX_Word: /* undefined extension */ 500 rv |= 0xdead0000; /* keep them honest */ 501 break; 502 503 case RX_UWord: 504 rv &= 0xffff; 505 break; 506 507 case RX_SWord: 508 rv = sign_ext (rv, 16); 509 break; 510 511 case RX_3Byte: 512 rv &= 0xffffff; 513 break; 514 515 case RX_Long: 516 break; 517 } 518 return rv; 519 } 520 521 static void 522 put_op (const RX_Opcode_Decoded *rd, int i, int v) 523 { 524 const RX_Opcode_Operand *o = rd->op + i; 525 int addr; 526 527 switch (o->size) 528 { 529 default: 530 case RX_AnySize: 531 if (o->type != RX_Operand_Register) 532 rx_abort (); 533 break; 534 535 case RX_Byte: /* undefined extension */ 536 v |= 0xdeadbe00; /* keep them honest */ 537 break; 538 539 case RX_UByte: 540 v &= 0xff; 541 break; 542 543 case RX_SByte: 544 v = sign_ext (v, 8); 545 break; 546 547 case RX_Word: /* undefined extension */ 548 v |= 0xdead0000; /* keep them honest */ 549 break; 550 551 case RX_UWord: 552 v &= 0xffff; 553 break; 554 555 case RX_SWord: 556 v = sign_ext (v, 16); 557 break; 558 559 case RX_3Byte: 560 v &= 0xffffff; 561 break; 562 563 case RX_Long: 564 break; 565 } 566 567 switch (o->type) 568 { 569 case RX_Operand_None: 570 /* Opcodes like TST and CMP use this. */ 571 break; 572 573 case RX_Operand_Immediate: /* #addend */ 574 case RX_Operand_Condition: /* eq, gtu, etc */ 575 rx_abort (); 576 577 case RX_Operand_Register: /* Rn */ 578 put_reg (o->reg, v); 579 RLD (o->reg); 580 break; 581 582 case RX_Operand_Predec: /* [-Rn] */ 583 put_reg (o->reg, get_reg (o->reg) - size2bytes[o->size]); 584 /* fall through */ 585 case RX_Operand_Postinc: /* [Rn+] */ 586 case RX_Operand_Zero_Indirect: /* [Rn + 0] */ 587 case RX_Operand_Indirect: /* [Rn + addend] */ 588 case RX_Operand_TwoReg: /* [Rn + scale * R2] */ 589 590 #ifdef CYCLE_ACCURATE 591 if (regs.m2m == M2M_BOTH) 592 { 593 tprintf("dst memory stall\n"); 594 regs.cycle_count ++; 595 #ifdef CYCLE_STATS 596 memory_stalls ++; 597 #endif 598 regs.m2m = 0; 599 } 600 memory_dest = 1; 601 #endif 602 603 if (o->type == RX_Operand_TwoReg) 604 addr = get_reg (o->reg) * size2bytes[rd->size] + get_reg (rd->op[2].reg); 605 else 606 addr = get_reg (o->reg) + o->addend; 607 608 switch (o->size) 609 { 610 default: 611 case RX_AnySize: 612 rx_abort (); 613 614 case RX_Byte: /* undefined extension */ 615 case RX_UByte: 616 case RX_SByte: 617 mem_put_qi (addr, v); 618 break; 619 620 case RX_Word: /* undefined extension */ 621 case RX_UWord: 622 case RX_SWord: 623 mem_put_hi (addr, v); 624 break; 625 626 case RX_3Byte: 627 mem_put_psi (addr, v); 628 break; 629 630 case RX_Long: 631 mem_put_si (addr, v); 632 break; 633 } 634 635 if (o->type == RX_Operand_Postinc) 636 put_reg (o->reg, get_reg (o->reg) + size2bytes[o->size]); 637 638 break; 639 640 case RX_Operand_Flag: /* [UIOSZC] */ 641 if (v) 642 regs.r_psw |= (1 << o->reg); 643 else 644 regs.r_psw &= ~(1 << o->reg); 645 break; 646 } 647 } 648 649 #define PD(x) put_op (opcode, 0, x) 650 #define PS(x) put_op (opcode, 1, x) 651 #define PS2(x) put_op (opcode, 2, x) 652 #define GD() get_op (opcode, 0) 653 #define GS() get_op (opcode, 1) 654 #define GS2() get_op (opcode, 2) 655 #define DSZ() size2bytes[opcode->op[0].size] 656 #define SSZ() size2bytes[opcode->op[0].size] 657 #define S2SZ() size2bytes[opcode->op[0].size] 658 659 /* "Universal" sources. */ 660 #define US1() ((opcode->op[2].type == RX_Operand_None) ? GD() : GS()) 661 #define US2() ((opcode->op[2].type == RX_Operand_None) ? GS() : GS2()) 662 663 static void 664 push(int val) 665 { 666 int rsp = get_reg (sp); 667 rsp -= 4; 668 put_reg (sp, rsp); 669 mem_put_si (rsp, val); 670 } 671 672 /* Just like the above, but tag the memory as "pushed pc" so if anyone 673 tries to write to it, it will cause an error. */ 674 static void 675 pushpc(int val) 676 { 677 int rsp = get_reg (sp); 678 rsp -= 4; 679 put_reg (sp, rsp); 680 mem_put_si (rsp, val); 681 mem_set_content_range (rsp, rsp+3, MC_PUSHED_PC); 682 } 683 684 static int 685 pop() 686 { 687 int rv; 688 int rsp = get_reg (sp); 689 rv = mem_get_si (rsp); 690 rsp += 4; 691 put_reg (sp, rsp); 692 return rv; 693 } 694 695 static int 696 poppc() 697 { 698 int rv; 699 int rsp = get_reg (sp); 700 if (mem_get_content_type (rsp) != MC_PUSHED_PC) 701 execution_error (SIM_ERR_CORRUPT_STACK, rsp); 702 rv = mem_get_si (rsp); 703 mem_set_content_range (rsp, rsp+3, MC_UNINIT); 704 rsp += 4; 705 put_reg (sp, rsp); 706 return rv; 707 } 708 709 #define MATH_OP(vop,c) \ 710 { \ 711 umb = US2(); \ 712 uma = US1(); \ 713 ll = (unsigned long long) uma vop (unsigned long long) umb vop c; \ 714 tprintf ("0x%x " #vop " 0x%x " #vop " 0x%x = 0x%llx\n", uma, umb, c, ll); \ 715 ma = sign_ext (uma, DSZ() * 8); \ 716 mb = sign_ext (umb, DSZ() * 8); \ 717 sll = (long long) ma vop (long long) mb vop c; \ 718 tprintf ("%d " #vop " %d " #vop " %d = %lld\n", ma, mb, c, sll); \ 719 set_oszc (sll, DSZ(), (long long) ll > ((1 vop 1) ? (long long) b2mask[DSZ()] : (long long) -1)); \ 720 PD (sll); \ 721 E (1); \ 722 } 723 724 #define LOGIC_OP(vop) \ 725 { \ 726 mb = US2(); \ 727 ma = US1(); \ 728 v = ma vop mb; \ 729 tprintf("0x%x " #vop " 0x%x = 0x%x\n", ma, mb, v); \ 730 set_sz (v, DSZ()); \ 731 PD(v); \ 732 E (1); \ 733 } 734 735 #define SHIFT_OP(val, type, count, OP, carry_mask) \ 736 { \ 737 int i, c=0; \ 738 count = US2(); \ 739 val = (type)US1(); \ 740 tprintf("%lld " #OP " %d\n", val, count); \ 741 for (i = 0; i < count; i ++) \ 742 { \ 743 c = val & carry_mask; \ 744 val OP 1; \ 745 } \ 746 set_oszc (val, 4, c); \ 747 PD (val); \ 748 } 749 750 typedef union { 751 int i; 752 float f; 753 } FloatInt; 754 755 static inline int 756 float2int (float f) 757 { 758 FloatInt fi; 759 fi.f = f; 760 return fi.i; 761 } 762 763 static inline float 764 int2float (int i) 765 { 766 FloatInt fi; 767 fi.i = i; 768 return fi.f; 769 } 770 771 static int 772 fop_fadd (fp_t s1, fp_t s2, fp_t *d) 773 { 774 *d = rxfp_add (s1, s2); 775 return 1; 776 } 777 778 static int 779 fop_fmul (fp_t s1, fp_t s2, fp_t *d) 780 { 781 *d = rxfp_mul (s1, s2); 782 return 1; 783 } 784 785 static int 786 fop_fdiv (fp_t s1, fp_t s2, fp_t *d) 787 { 788 *d = rxfp_div (s1, s2); 789 return 1; 790 } 791 792 static int 793 fop_fsub (fp_t s1, fp_t s2, fp_t *d) 794 { 795 *d = rxfp_sub (s1, s2); 796 return 1; 797 } 798 799 #define FPPENDING() (regs.r_fpsw & (FPSWBITS_CE | (FPSWBITS_FMASK & (regs.r_fpsw << FPSW_EFSH)))) 800 #define FPCLEAR() regs.r_fpsw &= FPSWBITS_CLEAR 801 #define FPCHECK() \ 802 if (FPPENDING()) \ 803 return do_fp_exception (opcode_pc) 804 805 #define FLOAT_OP(func) \ 806 { \ 807 int do_store; \ 808 fp_t fa, fb, fc; \ 809 FPCLEAR(); \ 810 fb = GS (); \ 811 fa = GD (); \ 812 do_store = fop_##func (fa, fb, &fc); \ 813 tprintf("%g " #func " %g = %g %08x\n", int2float(fa), int2float(fb), int2float(fc), fc); \ 814 FPCHECK(); \ 815 if (do_store) \ 816 PD (fc); \ 817 mb = 0; \ 818 if ((fc & 0x80000000UL) != 0) \ 819 mb |= FLAGBIT_S; \ 820 if ((fc & 0x7fffffffUL) == 0) \ 821 mb |= FLAGBIT_Z; \ 822 set_flags (FLAGBIT_S | FLAGBIT_Z, mb); \ 823 } 824 825 #define carry (FLAG_C ? 1 : 0) 826 827 static struct { 828 unsigned long vaddr; 829 const char *str; 830 int signal; 831 } exception_info[] = { 832 { 0xFFFFFFD0UL, "priviledged opcode", SIGILL }, 833 { 0xFFFFFFD4UL, "access violation", SIGSEGV }, 834 { 0xFFFFFFDCUL, "undefined opcode", SIGILL }, 835 { 0xFFFFFFE4UL, "floating point", SIGFPE } 836 }; 837 #define EX_PRIVILEDGED 0 838 #define EX_ACCESS 1 839 #define EX_UNDEFINED 2 840 #define EX_FLOATING 3 841 #define EXCEPTION(n) \ 842 return generate_exception (n, opcode_pc) 843 844 #define PRIVILEDGED() \ 845 if (FLAG_PM) \ 846 EXCEPTION (EX_PRIVILEDGED) 847 848 static int 849 generate_exception (unsigned long type, SI opcode_pc) 850 { 851 SI old_psw, old_pc, new_pc; 852 853 new_pc = mem_get_si (exception_info[type].vaddr); 854 /* 0x00020000 is the value used to initialise the known 855 exception vectors (see rx.ld), but it is a reserved 856 area of memory so do not try to access it, and if the 857 value has not been changed by the program then the 858 vector has not been installed. */ 859 if (new_pc == 0 || new_pc == 0x00020000) 860 { 861 if (rx_in_gdb) 862 return RX_MAKE_STOPPED (exception_info[type].signal); 863 864 fprintf(stderr, "Unhandled %s exception at pc = %#lx\n", 865 exception_info[type].str, (unsigned long) opcode_pc); 866 if (type == EX_FLOATING) 867 { 868 int mask = FPPENDING (); 869 fprintf (stderr, "Pending FP exceptions:"); 870 if (mask & FPSWBITS_FV) 871 fprintf(stderr, " Invalid"); 872 if (mask & FPSWBITS_FO) 873 fprintf(stderr, " Overflow"); 874 if (mask & FPSWBITS_FZ) 875 fprintf(stderr, " Division-by-zero"); 876 if (mask & FPSWBITS_FU) 877 fprintf(stderr, " Underflow"); 878 if (mask & FPSWBITS_FX) 879 fprintf(stderr, " Inexact"); 880 if (mask & FPSWBITS_CE) 881 fprintf(stderr, " Unimplemented"); 882 fprintf(stderr, "\n"); 883 } 884 return RX_MAKE_EXITED (1); 885 } 886 887 tprintf ("Triggering %s exception\n", exception_info[type].str); 888 889 old_psw = regs.r_psw; 890 regs.r_psw &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM); 891 old_pc = opcode_pc; 892 regs.r_pc = new_pc; 893 pushpc (old_psw); 894 pushpc (old_pc); 895 return RX_MAKE_STEPPED (); 896 } 897 898 void 899 generate_access_exception (void) 900 { 901 int rv; 902 903 rv = generate_exception (EX_ACCESS, regs.r_pc); 904 if (RX_EXITED (rv)) 905 longjmp (decode_jmp_buf, rv); 906 } 907 908 static int 909 do_fp_exception (unsigned long opcode_pc) 910 { 911 while (FPPENDING()) 912 EXCEPTION (EX_FLOATING); 913 return RX_MAKE_STEPPED (); 914 } 915 916 static int 917 op_is_memory (const RX_Opcode_Decoded *rd, int i) 918 { 919 switch (rd->op[i].type) 920 { 921 case RX_Operand_Predec: 922 case RX_Operand_Postinc: 923 case RX_Operand_Indirect: 924 return 1; 925 default: 926 return 0; 927 } 928 } 929 #define OM(i) op_is_memory (opcode, i) 930 931 #define DO_RETURN(x) { longjmp (decode_jmp_buf, x); } 932 933 int 934 decode_opcode () 935 { 936 unsigned int uma=0, umb=0; 937 int ma=0, mb=0; 938 int opcode_size, v; 939 unsigned long long ll; 940 long long sll; 941 unsigned long opcode_pc; 942 RX_Data rx_data; 943 const RX_Opcode_Decoded *opcode; 944 #ifdef CYCLE_STATS 945 unsigned long long prev_cycle_count; 946 #endif 947 #ifdef CYCLE_ACCURATE 948 unsigned int tx; 949 #endif 950 951 #ifdef CYCLE_STATS 952 prev_cycle_count = regs.cycle_count; 953 #endif 954 955 #ifdef CYCLE_ACCURATE 956 memory_source = 0; 957 memory_dest = 0; 958 #endif 959 960 rx_cycles ++; 961 962 maybe_get_mem_page (regs.r_pc); 963 964 opcode_pc = regs.r_pc; 965 966 /* Note that we don't word-swap this point, there's no point. */ 967 if (decode_cache_base[opcode_pc] == NULL) 968 { 969 RX_Opcode_Decoded *opcode_w; 970 rx_data.dpc = opcode_pc; 971 opcode_w = decode_cache_base[opcode_pc] = calloc (1, sizeof (RX_Opcode_Decoded)); 972 opcode_size = rx_decode_opcode (opcode_pc, opcode_w, 973 rx_get_byte, &rx_data); 974 opcode = opcode_w; 975 } 976 else 977 { 978 opcode = decode_cache_base[opcode_pc]; 979 opcode_size = opcode->n_bytes; 980 } 981 982 #ifdef CYCLE_ACCURATE 983 if (branch_alignment_penalty) 984 { 985 if ((regs.r_pc ^ (regs.r_pc + opcode_size - 1)) & ~7) 986 { 987 tprintf("1 cycle branch alignment penalty\n"); 988 cycles (branch_alignment_penalty); 989 #ifdef CYCLE_STATS 990 branch_alignment_stalls ++; 991 #endif 992 } 993 branch_alignment_penalty = 0; 994 } 995 #endif 996 997 regs.r_pc += opcode_size; 998 999 rx_flagmask = opcode->flags_s; 1000 rx_flagand = ~(int)opcode->flags_0; 1001 rx_flagor = opcode->flags_1; 1002 1003 switch (opcode->id) 1004 { 1005 case RXO_abs: 1006 sll = GS (); 1007 tprintf("|%lld| = ", sll); 1008 if (sll < 0) 1009 sll = -sll; 1010 tprintf("%lld\n", sll); 1011 PD (sll); 1012 set_osz (sll, 4); 1013 E (1); 1014 break; 1015 1016 case RXO_adc: 1017 MATH_OP (+,carry); 1018 break; 1019 1020 case RXO_add: 1021 MATH_OP (+,0); 1022 break; 1023 1024 case RXO_and: 1025 LOGIC_OP (&); 1026 break; 1027 1028 case RXO_bclr: 1029 ma = GD (); 1030 mb = GS (); 1031 if (opcode->op[0].type == RX_Operand_Register) 1032 mb &= 0x1f; 1033 else 1034 mb &= 0x07; 1035 ma &= ~(1 << mb); 1036 PD (ma); 1037 EBIT; 1038 break; 1039 1040 case RXO_bmcc: 1041 ma = GD (); 1042 mb = GS (); 1043 if (opcode->op[0].type == RX_Operand_Register) 1044 mb &= 0x1f; 1045 else 1046 mb &= 0x07; 1047 if (GS2 ()) 1048 ma |= (1 << mb); 1049 else 1050 ma &= ~(1 << mb); 1051 PD (ma); 1052 EBIT; 1053 break; 1054 1055 case RXO_bnot: 1056 ma = GD (); 1057 mb = GS (); 1058 if (opcode->op[0].type == RX_Operand_Register) 1059 mb &= 0x1f; 1060 else 1061 mb &= 0x07; 1062 ma ^= (1 << mb); 1063 PD (ma); 1064 EBIT; 1065 break; 1066 1067 case RXO_branch: 1068 if (opcode->op[1].type == RX_Operand_None || GS()) 1069 { 1070 #ifdef CYCLE_ACCURATE 1071 SI old_pc = regs.r_pc; 1072 int delta; 1073 #endif 1074 regs.r_pc = GD(); 1075 #ifdef CYCLE_ACCURATE 1076 delta = regs.r_pc - old_pc; 1077 if (delta >= 0 && delta < 16 1078 && opcode_size > 1) 1079 { 1080 tprintf("near forward branch bonus\n"); 1081 cycles (2); 1082 } 1083 else 1084 { 1085 cycles (3); 1086 branch_alignment_penalty = 1; 1087 } 1088 #ifdef CYCLE_STATS 1089 branch_stalls ++; 1090 #endif 1091 #endif 1092 } 1093 #ifdef CYCLE_ACCURATE 1094 else 1095 cycles (1); 1096 #endif 1097 break; 1098 1099 case RXO_branchrel: 1100 if (opcode->op[1].type == RX_Operand_None || GS()) 1101 { 1102 int delta = GD(); 1103 regs.r_pc = opcode_pc + delta; 1104 #ifdef CYCLE_ACCURATE 1105 /* Note: specs say 3, chip says 2. */ 1106 if (delta >= 0 && delta < 16 1107 && opcode_size > 1) 1108 { 1109 tprintf("near forward branch bonus\n"); 1110 cycles (2); 1111 } 1112 else 1113 { 1114 cycles (3); 1115 branch_alignment_penalty = 1; 1116 } 1117 #ifdef CYCLE_STATS 1118 branch_stalls ++; 1119 #endif 1120 #endif 1121 } 1122 #ifdef CYCLE_ACCURATE 1123 else 1124 cycles (1); 1125 #endif 1126 break; 1127 1128 case RXO_brk: 1129 { 1130 int old_psw = regs.r_psw; 1131 if (rx_in_gdb) 1132 DO_RETURN (RX_MAKE_HIT_BREAK ()); 1133 if (regs.r_intb == 0) 1134 { 1135 tprintf("BREAK hit, no vector table.\n"); 1136 DO_RETURN (RX_MAKE_EXITED(1)); 1137 } 1138 regs.r_psw &= ~(FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM); 1139 pushpc (old_psw); 1140 pushpc (regs.r_pc); 1141 regs.r_pc = mem_get_si (regs.r_intb); 1142 cycles(6); 1143 } 1144 break; 1145 1146 case RXO_bset: 1147 ma = GD (); 1148 mb = GS (); 1149 if (opcode->op[0].type == RX_Operand_Register) 1150 mb &= 0x1f; 1151 else 1152 mb &= 0x07; 1153 ma |= (1 << mb); 1154 PD (ma); 1155 EBIT; 1156 break; 1157 1158 case RXO_btst: 1159 ma = GS (); 1160 mb = GS2 (); 1161 if (opcode->op[1].type == RX_Operand_Register) 1162 mb &= 0x1f; 1163 else 1164 mb &= 0x07; 1165 umb = ma & (1 << mb); 1166 set_zc (! umb, umb); 1167 EBIT; 1168 break; 1169 1170 case RXO_clrpsw: 1171 v = 1 << opcode->op[0].reg; 1172 if (FLAG_PM 1173 && (v == FLAGBIT_I 1174 || v == FLAGBIT_U)) 1175 break; 1176 regs.r_psw &= ~v; 1177 cycles (1); 1178 break; 1179 1180 case RXO_div: /* d = d / s */ 1181 ma = GS(); 1182 mb = GD(); 1183 tprintf("%d / %d = ", mb, ma); 1184 if (ma == 0 || (ma == -1 && (unsigned int) mb == 0x80000000)) 1185 { 1186 tprintf("#NAN\n"); 1187 set_flags (FLAGBIT_O, FLAGBIT_O); 1188 cycles (3); 1189 } 1190 else 1191 { 1192 v = mb/ma; 1193 tprintf("%d\n", v); 1194 set_flags (FLAGBIT_O, 0); 1195 PD (v); 1196 div_cycles (mb, ma); 1197 } 1198 break; 1199 1200 case RXO_divu: /* d = d / s */ 1201 uma = GS(); 1202 umb = GD(); 1203 tprintf("%u / %u = ", umb, uma); 1204 if (uma == 0) 1205 { 1206 tprintf("#NAN\n"); 1207 set_flags (FLAGBIT_O, FLAGBIT_O); 1208 cycles (2); 1209 } 1210 else 1211 { 1212 v = umb / uma; 1213 tprintf("%u\n", v); 1214 set_flags (FLAGBIT_O, 0); 1215 PD (v); 1216 divu_cycles (umb, uma); 1217 } 1218 break; 1219 1220 case RXO_emul: 1221 ma = GD (); 1222 mb = GS (); 1223 sll = (long long)ma * (long long)mb; 1224 tprintf("%d * %d = %lld\n", ma, mb, sll); 1225 put_reg (opcode->op[0].reg, sll); 1226 put_reg (opcode->op[0].reg + 1, sll >> 32); 1227 E2; 1228 break; 1229 1230 case RXO_emulu: 1231 uma = GD (); 1232 umb = GS (); 1233 ll = (long long)uma * (long long)umb; 1234 tprintf("%#x * %#x = %#llx\n", uma, umb, ll); 1235 put_reg (opcode->op[0].reg, ll); 1236 put_reg (opcode->op[0].reg + 1, ll >> 32); 1237 E2; 1238 break; 1239 1240 case RXO_fadd: 1241 FLOAT_OP (fadd); 1242 E (4); 1243 break; 1244 1245 case RXO_fcmp: 1246 ma = GD(); 1247 mb = GS(); 1248 FPCLEAR (); 1249 rxfp_cmp (ma, mb); 1250 FPCHECK (); 1251 E (1); 1252 break; 1253 1254 case RXO_fdiv: 1255 FLOAT_OP (fdiv); 1256 E (16); 1257 break; 1258 1259 case RXO_fmul: 1260 FLOAT_OP (fmul); 1261 E (3); 1262 break; 1263 1264 case RXO_rtfi: 1265 PRIVILEDGED (); 1266 regs.r_psw = regs.r_bpsw; 1267 regs.r_pc = regs.r_bpc; 1268 #ifdef CYCLE_ACCURATE 1269 regs.fast_return = 0; 1270 cycles(3); 1271 #endif 1272 break; 1273 1274 case RXO_fsub: 1275 FLOAT_OP (fsub); 1276 E (4); 1277 break; 1278 1279 case RXO_ftoi: 1280 ma = GS (); 1281 FPCLEAR (); 1282 mb = rxfp_ftoi (ma, FPRM_ZERO); 1283 FPCHECK (); 1284 PD (mb); 1285 tprintf("(int) %g = %d\n", int2float(ma), mb); 1286 set_sz (mb, 4); 1287 E (2); 1288 break; 1289 1290 case RXO_int: 1291 v = GS (); 1292 if (v == 255) 1293 { 1294 int rc = rx_syscall (regs.r[5]); 1295 if (! RX_STEPPED (rc)) 1296 DO_RETURN (rc); 1297 } 1298 else 1299 { 1300 int old_psw = regs.r_psw; 1301 regs.r_psw &= ~(FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM); 1302 pushpc (old_psw); 1303 pushpc (regs.r_pc); 1304 regs.r_pc = mem_get_si (regs.r_intb + 4 * v); 1305 } 1306 cycles (6); 1307 break; 1308 1309 case RXO_itof: 1310 ma = GS (); 1311 FPCLEAR (); 1312 mb = rxfp_itof (ma, regs.r_fpsw); 1313 FPCHECK (); 1314 tprintf("(float) %d = %x\n", ma, mb); 1315 PD (mb); 1316 set_sz (ma, 4); 1317 E (2); 1318 break; 1319 1320 case RXO_jsr: 1321 case RXO_jsrrel: 1322 { 1323 #ifdef CYCLE_ACCURATE 1324 int delta; 1325 regs.m2m = 0; 1326 #endif 1327 v = GD (); 1328 #ifdef CYCLE_ACCURATE 1329 regs.link_register = regs.r_pc; 1330 #endif 1331 pushpc (get_reg (pc)); 1332 if (opcode->id == RXO_jsrrel) 1333 v += regs.r_pc; 1334 #ifdef CYCLE_ACCURATE 1335 delta = v - regs.r_pc; 1336 #endif 1337 put_reg (pc, v); 1338 #ifdef CYCLE_ACCURATE 1339 /* Note: docs say 3, chip says 2 */ 1340 if (delta >= 0 && delta < 16) 1341 { 1342 tprintf ("near forward jsr bonus\n"); 1343 cycles (2); 1344 } 1345 else 1346 { 1347 branch_alignment_penalty = 1; 1348 cycles (3); 1349 } 1350 regs.fast_return = 1; 1351 #endif 1352 } 1353 break; 1354 1355 case RXO_machi: 1356 ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16); 1357 ll <<= 16; 1358 put_reg64 (acc64, ll + regs.r_acc); 1359 E1; 1360 break; 1361 1362 case RXO_maclo: 1363 ll = (long long)(signed short)(GS()) * (long long)(signed short)(GS2 ()); 1364 ll <<= 16; 1365 put_reg64 (acc64, ll + regs.r_acc); 1366 E1; 1367 break; 1368 1369 case RXO_max: 1370 mb = GS(); 1371 ma = GD(); 1372 if (ma > mb) 1373 PD (ma); 1374 else 1375 PD (mb); 1376 E (1); 1377 break; 1378 1379 case RXO_min: 1380 mb = GS(); 1381 ma = GD(); 1382 if (ma < mb) 1383 PD (ma); 1384 else 1385 PD (mb); 1386 E (1); 1387 break; 1388 1389 case RXO_mov: 1390 v = GS (); 1391 1392 if (opcode->op[1].type == RX_Operand_Register 1393 && opcode->op[1].reg == 17 /* PC */) 1394 { 1395 /* Special case. We want the address of the insn, not the 1396 address of the next insn. */ 1397 v = opcode_pc; 1398 } 1399 1400 if (opcode->op[0].type == RX_Operand_Register 1401 && opcode->op[0].reg == 16 /* PSW */) 1402 { 1403 /* Special case, LDC and POPC can't ever modify PM. */ 1404 int pm = regs.r_psw & FLAGBIT_PM; 1405 v &= ~ FLAGBIT_PM; 1406 v |= pm; 1407 if (pm) 1408 { 1409 v &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL); 1410 v |= pm; 1411 } 1412 } 1413 if (FLAG_PM) 1414 { 1415 /* various things can't be changed in user mode. */ 1416 if (opcode->op[0].type == RX_Operand_Register) 1417 if (opcode->op[0].reg == 32) 1418 { 1419 v &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL); 1420 v |= regs.r_psw & (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL); 1421 } 1422 if (opcode->op[0].reg == 34 /* ISP */ 1423 || opcode->op[0].reg == 37 /* BPSW */ 1424 || opcode->op[0].reg == 39 /* INTB */ 1425 || opcode->op[0].reg == 38 /* VCT */) 1426 /* These are ignored. */ 1427 break; 1428 } 1429 if (OM(0) && OM(1)) 1430 cycles (2); 1431 else 1432 cycles (1); 1433 1434 PD (v); 1435 1436 #ifdef CYCLE_ACCURATE 1437 if ((opcode->op[0].type == RX_Operand_Predec 1438 && opcode->op[1].type == RX_Operand_Register) 1439 || (opcode->op[0].type == RX_Operand_Postinc 1440 && opcode->op[1].type == RX_Operand_Register)) 1441 { 1442 /* Special case: push reg doesn't cause a memory stall. */ 1443 memory_dest = 0; 1444 tprintf("push special case\n"); 1445 } 1446 #endif 1447 1448 set_sz (v, DSZ()); 1449 break; 1450 1451 case RXO_movbi: 1452 PD (GS ()); 1453 cycles (1); 1454 break; 1455 1456 case RXO_movbir: 1457 PS (GD ()); 1458 cycles (1); 1459 break; 1460 1461 case RXO_mul: 1462 v = US2 (); 1463 ll = (unsigned long long) US1() * (unsigned long long) v; 1464 PD(ll); 1465 E (1); 1466 break; 1467 1468 case RXO_mulhi: 1469 v = GS2 (); 1470 ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(v >> 16); 1471 ll <<= 16; 1472 put_reg64 (acc64, ll); 1473 E1; 1474 break; 1475 1476 case RXO_mullo: 1477 v = GS2 (); 1478 ll = (long long)(signed short)(GS()) * (long long)(signed short)(v); 1479 ll <<= 16; 1480 put_reg64 (acc64, ll); 1481 E1; 1482 break; 1483 1484 case RXO_mvfachi: 1485 PD (get_reg (acchi)); 1486 E1; 1487 break; 1488 1489 case RXO_mvfaclo: 1490 PD (get_reg (acclo)); 1491 E1; 1492 break; 1493 1494 case RXO_mvfacmi: 1495 PD (get_reg (accmi)); 1496 E1; 1497 break; 1498 1499 case RXO_mvtachi: 1500 put_reg (acchi, GS ()); 1501 E1; 1502 break; 1503 1504 case RXO_mvtaclo: 1505 put_reg (acclo, GS ()); 1506 E1; 1507 break; 1508 1509 case RXO_mvtipl: 1510 regs.r_psw &= ~ FLAGBITS_IPL; 1511 regs.r_psw |= (GS () << FLAGSHIFT_IPL) & FLAGBITS_IPL; 1512 E1; 1513 break; 1514 1515 case RXO_nop: 1516 case RXO_nop2: 1517 case RXO_nop3: 1518 case RXO_nop4: 1519 case RXO_nop5: 1520 case RXO_nop6: 1521 case RXO_nop7: 1522 E1; 1523 break; 1524 1525 case RXO_or: 1526 LOGIC_OP (|); 1527 break; 1528 1529 case RXO_popm: 1530 /* POPM cannot pop R0 (sp). */ 1531 if (opcode->op[1].reg == 0 || opcode->op[2].reg == 0) 1532 EXCEPTION (EX_UNDEFINED); 1533 if (opcode->op[1].reg >= opcode->op[2].reg) 1534 { 1535 regs.r_pc = opcode_pc; 1536 DO_RETURN (RX_MAKE_STOPPED (SIGILL)); 1537 } 1538 for (v = opcode->op[1].reg; v <= opcode->op[2].reg; v++) 1539 { 1540 cycles (1); 1541 RLD (v); 1542 put_reg (v, pop ()); 1543 } 1544 break; 1545 1546 case RXO_pushm: 1547 /* PUSHM cannot push R0 (sp). */ 1548 if (opcode->op[1].reg == 0 || opcode->op[2].reg == 0) 1549 EXCEPTION (EX_UNDEFINED); 1550 if (opcode->op[1].reg >= opcode->op[2].reg) 1551 { 1552 regs.r_pc = opcode_pc; 1553 return RX_MAKE_STOPPED (SIGILL); 1554 } 1555 for (v = opcode->op[2].reg; v >= opcode->op[1].reg; v--) 1556 { 1557 RL (v); 1558 push (get_reg (v)); 1559 } 1560 cycles (opcode->op[2].reg - opcode->op[1].reg + 1); 1561 break; 1562 1563 case RXO_racw: 1564 ll = get_reg64 (acc64) << GS (); 1565 ll += 0x80000000ULL; 1566 if ((signed long long)ll > (signed long long)0x00007fff00000000ULL) 1567 ll = 0x00007fff00000000ULL; 1568 else if ((signed long long)ll < (signed long long)0xffff800000000000ULL) 1569 ll = 0xffff800000000000ULL; 1570 else 1571 ll &= 0xffffffff00000000ULL; 1572 put_reg64 (acc64, ll); 1573 E1; 1574 break; 1575 1576 case RXO_rte: 1577 PRIVILEDGED (); 1578 regs.r_pc = poppc (); 1579 regs.r_psw = poppc (); 1580 if (FLAG_PM) 1581 regs.r_psw |= FLAGBIT_U; 1582 #ifdef CYCLE_ACCURATE 1583 regs.fast_return = 0; 1584 cycles (6); 1585 #endif 1586 break; 1587 1588 case RXO_revl: 1589 uma = GS (); 1590 umb = (((uma >> 24) & 0xff) 1591 | ((uma >> 8) & 0xff00) 1592 | ((uma << 8) & 0xff0000) 1593 | ((uma << 24) & 0xff000000UL)); 1594 PD (umb); 1595 E1; 1596 break; 1597 1598 case RXO_revw: 1599 uma = GS (); 1600 umb = (((uma >> 8) & 0x00ff00ff) 1601 | ((uma << 8) & 0xff00ff00UL)); 1602 PD (umb); 1603 E1; 1604 break; 1605 1606 case RXO_rmpa: 1607 RL(4); 1608 RL(5); 1609 #ifdef CYCLE_ACCURATE 1610 tx = regs.r[3]; 1611 #endif 1612 1613 while (regs.r[3] != 0) 1614 { 1615 long long tmp; 1616 1617 switch (opcode->size) 1618 { 1619 case RX_Long: 1620 ma = mem_get_si (regs.r[1]); 1621 mb = mem_get_si (regs.r[2]); 1622 regs.r[1] += 4; 1623 regs.r[2] += 4; 1624 break; 1625 case RX_Word: 1626 ma = sign_ext (mem_get_hi (regs.r[1]), 16); 1627 mb = sign_ext (mem_get_hi (regs.r[2]), 16); 1628 regs.r[1] += 2; 1629 regs.r[2] += 2; 1630 break; 1631 case RX_Byte: 1632 ma = sign_ext (mem_get_qi (regs.r[1]), 8); 1633 mb = sign_ext (mem_get_qi (regs.r[2]), 8); 1634 regs.r[1] += 1; 1635 regs.r[2] += 1; 1636 break; 1637 default: 1638 abort (); 1639 } 1640 /* We do the multiply as a signed value. */ 1641 sll = (long long)ma * (long long)mb; 1642 tprintf(" %016llx = %d * %d\n", sll, ma, mb); 1643 /* but we do the sum as unsigned, while sign extending the operands. */ 1644 tmp = regs.r[4] + (sll & 0xffffffffUL); 1645 regs.r[4] = tmp & 0xffffffffUL; 1646 tmp >>= 32; 1647 sll >>= 32; 1648 tmp += regs.r[5] + (sll & 0xffffffffUL); 1649 regs.r[5] = tmp & 0xffffffffUL; 1650 tmp >>= 32; 1651 sll >>= 32; 1652 tmp += regs.r[6] + (sll & 0xffffffffUL); 1653 regs.r[6] = tmp & 0xffffffffUL; 1654 tprintf("%08lx\033[36m%08lx\033[0m%08lx\n", 1655 (unsigned long) regs.r[6], 1656 (unsigned long) regs.r[5], 1657 (unsigned long) regs.r[4]); 1658 1659 regs.r[3] --; 1660 } 1661 if (regs.r[6] & 0x00008000) 1662 regs.r[6] |= 0xffff0000UL; 1663 else 1664 regs.r[6] &= 0x0000ffff; 1665 ma = (regs.r[6] & 0x80000000UL) ? FLAGBIT_S : 0; 1666 if (regs.r[6] != 0 && regs.r[6] != 0xffffffffUL) 1667 set_flags (FLAGBIT_O|FLAGBIT_S, ma | FLAGBIT_O); 1668 else 1669 set_flags (FLAGBIT_O|FLAGBIT_S, ma); 1670 #ifdef CYCLE_ACCURATE 1671 switch (opcode->size) 1672 { 1673 case RX_Long: 1674 cycles (6 + 4 * tx); 1675 break; 1676 case RX_Word: 1677 cycles (6 + 5 * (tx / 2) + 4 * (tx % 2)); 1678 break; 1679 case RX_Byte: 1680 cycles (6 + 7 * (tx / 4) + 4 * (tx % 4)); 1681 break; 1682 default: 1683 abort (); 1684 } 1685 #endif 1686 break; 1687 1688 case RXO_rolc: 1689 v = GD (); 1690 ma = v & 0x80000000UL; 1691 v <<= 1; 1692 v |= carry; 1693 set_szc (v, 4, ma); 1694 PD (v); 1695 E1; 1696 break; 1697 1698 case RXO_rorc: 1699 uma = GD (); 1700 mb = uma & 1; 1701 uma >>= 1; 1702 uma |= (carry ? 0x80000000UL : 0); 1703 set_szc (uma, 4, mb); 1704 PD (uma); 1705 E1; 1706 break; 1707 1708 case RXO_rotl: 1709 mb = GS (); 1710 uma = GD (); 1711 if (mb) 1712 { 1713 uma = (uma << mb) | (uma >> (32-mb)); 1714 mb = uma & 1; 1715 } 1716 set_szc (uma, 4, mb); 1717 PD (uma); 1718 E1; 1719 break; 1720 1721 case RXO_rotr: 1722 mb = GS (); 1723 uma = GD (); 1724 if (mb) 1725 { 1726 uma = (uma >> mb) | (uma << (32-mb)); 1727 mb = uma & 0x80000000; 1728 } 1729 set_szc (uma, 4, mb); 1730 PD (uma); 1731 E1; 1732 break; 1733 1734 case RXO_round: 1735 ma = GS (); 1736 FPCLEAR (); 1737 mb = rxfp_ftoi (ma, regs.r_fpsw); 1738 FPCHECK (); 1739 PD (mb); 1740 tprintf("(int) %g = %d\n", int2float(ma), mb); 1741 set_sz (mb, 4); 1742 E (2); 1743 break; 1744 1745 case RXO_rts: 1746 { 1747 #ifdef CYCLE_ACCURATE 1748 int cyc = 5; 1749 #endif 1750 regs.r_pc = poppc (); 1751 #ifdef CYCLE_ACCURATE 1752 /* Note: specs say 5, chip says 3. */ 1753 if (regs.fast_return && regs.link_register == regs.r_pc) 1754 { 1755 #ifdef CYCLE_STATS 1756 fast_returns ++; 1757 #endif 1758 tprintf("fast return bonus\n"); 1759 cyc -= 2; 1760 } 1761 cycles (cyc); 1762 regs.fast_return = 0; 1763 branch_alignment_penalty = 1; 1764 #endif 1765 } 1766 break; 1767 1768 case RXO_rtsd: 1769 if (opcode->op[2].type == RX_Operand_Register) 1770 { 1771 int i; 1772 /* RTSD cannot pop R0 (sp). */ 1773 put_reg (0, get_reg (0) + GS() - (opcode->op[0].reg-opcode->op[2].reg+1)*4); 1774 if (opcode->op[2].reg == 0) 1775 EXCEPTION (EX_UNDEFINED); 1776 #ifdef CYCLE_ACCURATE 1777 tx = opcode->op[0].reg - opcode->op[2].reg + 1; 1778 #endif 1779 for (i = opcode->op[2].reg; i <= opcode->op[0].reg; i ++) 1780 { 1781 RLD (i); 1782 put_reg (i, pop ()); 1783 } 1784 } 1785 else 1786 { 1787 #ifdef CYCLE_ACCURATE 1788 tx = 0; 1789 #endif 1790 put_reg (0, get_reg (0) + GS()); 1791 } 1792 put_reg (pc, poppc()); 1793 #ifdef CYCLE_ACCURATE 1794 if (regs.fast_return && regs.link_register == regs.r_pc) 1795 { 1796 tprintf("fast return bonus\n"); 1797 #ifdef CYCLE_STATS 1798 fast_returns ++; 1799 #endif 1800 cycles (tx < 3 ? 3 : tx + 1); 1801 } 1802 else 1803 { 1804 cycles (tx < 5 ? 5 : tx + 1); 1805 } 1806 regs.fast_return = 0; 1807 branch_alignment_penalty = 1; 1808 #endif 1809 break; 1810 1811 case RXO_sat: 1812 if (FLAG_O && FLAG_S) 1813 PD (0x7fffffffUL); 1814 else if (FLAG_O && ! FLAG_S) 1815 PD (0x80000000UL); 1816 E1; 1817 break; 1818 1819 case RXO_satr: 1820 if (FLAG_O && ! FLAG_S) 1821 { 1822 put_reg (6, 0x0); 1823 put_reg (5, 0x7fffffff); 1824 put_reg (4, 0xffffffff); 1825 } 1826 else if (FLAG_O && FLAG_S) 1827 { 1828 put_reg (6, 0xffffffff); 1829 put_reg (5, 0x80000000); 1830 put_reg (4, 0x0); 1831 } 1832 E1; 1833 break; 1834 1835 case RXO_sbb: 1836 MATH_OP (-, ! carry); 1837 break; 1838 1839 case RXO_sccnd: 1840 if (GS()) 1841 PD (1); 1842 else 1843 PD (0); 1844 E1; 1845 break; 1846 1847 case RXO_scmpu: 1848 #ifdef CYCLE_ACCURATE 1849 tx = regs.r[3]; 1850 #endif 1851 while (regs.r[3] != 0) 1852 { 1853 uma = mem_get_qi (regs.r[1] ++); 1854 umb = mem_get_qi (regs.r[2] ++); 1855 regs.r[3] --; 1856 if (uma != umb || uma == 0) 1857 break; 1858 } 1859 if (uma == umb) 1860 set_zc (1, 1); 1861 else 1862 set_zc (0, ((int)uma - (int)umb) >= 0); 1863 cycles (2 + 4 * (tx / 4) + 4 * (tx % 4)); 1864 break; 1865 1866 case RXO_setpsw: 1867 v = 1 << opcode->op[0].reg; 1868 if (FLAG_PM 1869 && (v == FLAGBIT_I 1870 || v == FLAGBIT_U)) 1871 break; 1872 regs.r_psw |= v; 1873 cycles (1); 1874 break; 1875 1876 case RXO_smovb: 1877 RL (3); 1878 #ifdef CYCLE_ACCURATE 1879 tx = regs.r[3]; 1880 #endif 1881 while (regs.r[3]) 1882 { 1883 uma = mem_get_qi (regs.r[2] --); 1884 mem_put_qi (regs.r[1]--, uma); 1885 regs.r[3] --; 1886 } 1887 #ifdef CYCLE_ACCURATE 1888 if (tx > 3) 1889 cycles (6 + 3 * (tx / 4) + 3 * (tx % 4)); 1890 else 1891 cycles (2 + 3 * (tx % 4)); 1892 #endif 1893 break; 1894 1895 case RXO_smovf: 1896 RL (3); 1897 #ifdef CYCLE_ACCURATE 1898 tx = regs.r[3]; 1899 #endif 1900 while (regs.r[3]) 1901 { 1902 uma = mem_get_qi (regs.r[2] ++); 1903 mem_put_qi (regs.r[1]++, uma); 1904 regs.r[3] --; 1905 } 1906 cycles (2 + 3 * (int)(tx / 4) + 3 * (tx % 4)); 1907 break; 1908 1909 case RXO_smovu: 1910 #ifdef CYCLE_ACCURATE 1911 tx = regs.r[3]; 1912 #endif 1913 while (regs.r[3] != 0) 1914 { 1915 uma = mem_get_qi (regs.r[2] ++); 1916 mem_put_qi (regs.r[1]++, uma); 1917 regs.r[3] --; 1918 if (uma == 0) 1919 break; 1920 } 1921 cycles (2 + 3 * (int)(tx / 4) + 3 * (tx % 4)); 1922 break; 1923 1924 case RXO_shar: /* d = ma >> mb */ 1925 SHIFT_OP (sll, int, mb, >>=, 1); 1926 E (1); 1927 break; 1928 1929 case RXO_shll: /* d = ma << mb */ 1930 SHIFT_OP (ll, int, mb, <<=, 0x80000000UL); 1931 E (1); 1932 break; 1933 1934 case RXO_shlr: /* d = ma >> mb */ 1935 SHIFT_OP (ll, unsigned int, mb, >>=, 1); 1936 E (1); 1937 break; 1938 1939 case RXO_sstr: 1940 RL (3); 1941 #ifdef CYCLE_ACCURATE 1942 tx = regs.r[3]; 1943 #endif 1944 switch (opcode->size) 1945 { 1946 case RX_Long: 1947 while (regs.r[3] != 0) 1948 { 1949 mem_put_si (regs.r[1], regs.r[2]); 1950 regs.r[1] += 4; 1951 regs.r[3] --; 1952 } 1953 cycles (2 + tx); 1954 break; 1955 case RX_Word: 1956 while (regs.r[3] != 0) 1957 { 1958 mem_put_hi (regs.r[1], regs.r[2]); 1959 regs.r[1] += 2; 1960 regs.r[3] --; 1961 } 1962 cycles (2 + (int)(tx / 2) + tx % 2); 1963 break; 1964 case RX_Byte: 1965 while (regs.r[3] != 0) 1966 { 1967 mem_put_qi (regs.r[1], regs.r[2]); 1968 regs.r[1] ++; 1969 regs.r[3] --; 1970 } 1971 cycles (2 + (int)(tx / 4) + tx % 4); 1972 break; 1973 default: 1974 abort (); 1975 } 1976 break; 1977 1978 case RXO_stcc: 1979 if (GS2()) 1980 PD (GS ()); 1981 E1; 1982 break; 1983 1984 case RXO_stop: 1985 PRIVILEDGED (); 1986 regs.r_psw |= FLAGBIT_I; 1987 DO_RETURN (RX_MAKE_STOPPED(0)); 1988 1989 case RXO_sub: 1990 MATH_OP (-, 0); 1991 break; 1992 1993 case RXO_suntil: 1994 RL(3); 1995 #ifdef CYCLE_ACCURATE 1996 tx = 0; 1997 #endif 1998 if (regs.r[3] == 0) 1999 { 2000 cycles (3); 2001 break; 2002 } 2003 switch (opcode->size) 2004 { 2005 case RX_Long: 2006 uma = get_reg (2); 2007 while (regs.r[3] != 0) 2008 { 2009 regs.r[3] --; 2010 umb = mem_get_si (get_reg (1)); 2011 regs.r[1] += 4; 2012 #ifdef CYCLE_ACCURATE 2013 tx ++; 2014 #endif 2015 if (umb == uma) 2016 break; 2017 } 2018 #ifdef CYCLE_ACCURATE 2019 cycles (3 + 3 * tx); 2020 #endif 2021 break; 2022 case RX_Word: 2023 uma = get_reg (2) & 0xffff; 2024 while (regs.r[3] != 0) 2025 { 2026 regs.r[3] --; 2027 umb = mem_get_hi (get_reg (1)); 2028 regs.r[1] += 2; 2029 #ifdef CYCLE_ACCURATE 2030 tx ++; 2031 #endif 2032 if (umb == uma) 2033 break; 2034 } 2035 #ifdef CYCLE_ACCURATE 2036 cycles (3 + 3 * (tx / 2) + 3 * (tx % 2)); 2037 #endif 2038 break; 2039 case RX_Byte: 2040 uma = get_reg (2) & 0xff; 2041 while (regs.r[3] != 0) 2042 { 2043 regs.r[3] --; 2044 umb = mem_get_qi (regs.r[1]); 2045 regs.r[1] += 1; 2046 #ifdef CYCLE_ACCURATE 2047 tx ++; 2048 #endif 2049 if (umb == uma) 2050 break; 2051 } 2052 #ifdef CYCLE_ACCURATE 2053 cycles (3 + 3 * (tx / 4) + 3 * (tx % 4)); 2054 #endif 2055 break; 2056 default: 2057 abort(); 2058 } 2059 if (uma == umb) 2060 set_zc (1, 1); 2061 else 2062 set_zc (0, ((int)uma - (int)umb) >= 0); 2063 break; 2064 2065 case RXO_swhile: 2066 RL(3); 2067 #ifdef CYCLE_ACCURATE 2068 tx = 0; 2069 #endif 2070 if (regs.r[3] == 0) 2071 break; 2072 switch (opcode->size) 2073 { 2074 case RX_Long: 2075 uma = get_reg (2); 2076 while (regs.r[3] != 0) 2077 { 2078 regs.r[3] --; 2079 umb = mem_get_si (get_reg (1)); 2080 regs.r[1] += 4; 2081 #ifdef CYCLE_ACCURATE 2082 tx ++; 2083 #endif 2084 if (umb != uma) 2085 break; 2086 } 2087 #ifdef CYCLE_ACCURATE 2088 cycles (3 + 3 * tx); 2089 #endif 2090 break; 2091 case RX_Word: 2092 uma = get_reg (2) & 0xffff; 2093 while (regs.r[3] != 0) 2094 { 2095 regs.r[3] --; 2096 umb = mem_get_hi (get_reg (1)); 2097 regs.r[1] += 2; 2098 #ifdef CYCLE_ACCURATE 2099 tx ++; 2100 #endif 2101 if (umb != uma) 2102 break; 2103 } 2104 #ifdef CYCLE_ACCURATE 2105 cycles (3 + 3 * (tx / 2) + 3 * (tx % 2)); 2106 #endif 2107 break; 2108 case RX_Byte: 2109 uma = get_reg (2) & 0xff; 2110 while (regs.r[3] != 0) 2111 { 2112 regs.r[3] --; 2113 umb = mem_get_qi (regs.r[1]); 2114 regs.r[1] += 1; 2115 #ifdef CYCLE_ACCURATE 2116 tx ++; 2117 #endif 2118 if (umb != uma) 2119 break; 2120 } 2121 #ifdef CYCLE_ACCURATE 2122 cycles (3 + 3 * (tx / 4) + 3 * (tx % 4)); 2123 #endif 2124 break; 2125 default: 2126 abort(); 2127 } 2128 if (uma == umb) 2129 set_zc (1, 1); 2130 else 2131 set_zc (0, ((int)uma - (int)umb) >= 0); 2132 break; 2133 2134 case RXO_wait: 2135 PRIVILEDGED (); 2136 regs.r_psw |= FLAGBIT_I; 2137 DO_RETURN (RX_MAKE_STOPPED(0)); 2138 2139 case RXO_xchg: 2140 #ifdef CYCLE_ACCURATE 2141 regs.m2m = 0; 2142 #endif 2143 v = GS (); /* This is the memory operand, if any. */ 2144 PS (GD ()); /* and this may change the address register. */ 2145 PD (v); 2146 E2; 2147 #ifdef CYCLE_ACCURATE 2148 /* all M cycles happen during xchg's cycles. */ 2149 memory_dest = 0; 2150 memory_source = 0; 2151 #endif 2152 break; 2153 2154 case RXO_xor: 2155 LOGIC_OP (^); 2156 break; 2157 2158 default: 2159 EXCEPTION (EX_UNDEFINED); 2160 } 2161 2162 #ifdef CYCLE_ACCURATE 2163 regs.m2m = 0; 2164 if (memory_source) 2165 regs.m2m |= M2M_SRC; 2166 if (memory_dest) 2167 regs.m2m |= M2M_DST; 2168 2169 regs.rt = new_rt; 2170 new_rt = -1; 2171 #endif 2172 2173 #ifdef CYCLE_STATS 2174 if (prev_cycle_count == regs.cycle_count) 2175 { 2176 printf("Cycle count not updated! id %s\n", id_names[opcode->id]); 2177 abort (); 2178 } 2179 #endif 2180 2181 #ifdef CYCLE_STATS 2182 if (running_benchmark) 2183 { 2184 int omap = op_lookup (opcode->op[0].type, opcode->op[1].type, opcode->op[2].type); 2185 2186 2187 cycles_per_id[opcode->id][omap] += regs.cycle_count - prev_cycle_count; 2188 times_per_id[opcode->id][omap] ++; 2189 2190 times_per_pair[prev_opcode_id][po0][opcode->id][omap] ++; 2191 2192 prev_opcode_id = opcode->id; 2193 po0 = omap; 2194 } 2195 #endif 2196 2197 return RX_MAKE_STEPPED (); 2198 } 2199 2200 #ifdef CYCLE_STATS 2201 void 2202 reset_pipeline_stats (void) 2203 { 2204 memset (cycles_per_id, 0, sizeof(cycles_per_id)); 2205 memset (times_per_id, 0, sizeof(times_per_id)); 2206 memory_stalls = 0; 2207 register_stalls = 0; 2208 branch_stalls = 0; 2209 branch_alignment_stalls = 0; 2210 fast_returns = 0; 2211 memset (times_per_pair, 0, sizeof(times_per_pair)); 2212 running_benchmark = 1; 2213 2214 benchmark_start_cycle = regs.cycle_count; 2215 } 2216 2217 void 2218 halt_pipeline_stats (void) 2219 { 2220 running_benchmark = 0; 2221 benchmark_end_cycle = regs.cycle_count; 2222 } 2223 #endif 2224 2225 void 2226 pipeline_stats (void) 2227 { 2228 #ifdef CYCLE_STATS 2229 int i, o1; 2230 int p, p1; 2231 #endif 2232 2233 #ifdef CYCLE_ACCURATE 2234 if (verbose == 1) 2235 { 2236 printf ("cycles: %llu\n", regs.cycle_count); 2237 return; 2238 } 2239 2240 printf ("cycles: %13s\n", comma (regs.cycle_count)); 2241 #endif 2242 2243 #ifdef CYCLE_STATS 2244 if (benchmark_start_cycle) 2245 printf ("bmark: %13s\n", comma (benchmark_end_cycle - benchmark_start_cycle)); 2246 2247 printf("\n"); 2248 for (i = 0; i < N_RXO; i++) 2249 for (o1 = 0; o1 < N_MAP; o1 ++) 2250 if (times_per_id[i][o1]) 2251 printf("%13s %13s %7.2f %s %s\n", 2252 comma (cycles_per_id[i][o1]), 2253 comma (times_per_id[i][o1]), 2254 (double)cycles_per_id[i][o1] / times_per_id[i][o1], 2255 op_cache_string(o1), 2256 id_names[i]+4); 2257 2258 printf("\n"); 2259 for (p = 0; p < N_RXO; p ++) 2260 for (p1 = 0; p1 < N_MAP; p1 ++) 2261 for (i = 0; i < N_RXO; i ++) 2262 for (o1 = 0; o1 < N_MAP; o1 ++) 2263 if (times_per_pair[p][p1][i][o1]) 2264 { 2265 printf("%13s %s %-9s -> %s %s\n", 2266 comma (times_per_pair[p][p1][i][o1]), 2267 op_cache_string(p1), 2268 id_names[p]+4, 2269 op_cache_string(o1), 2270 id_names[i]+4); 2271 } 2272 2273 printf("\n"); 2274 printf("%13s memory stalls\n", comma (memory_stalls)); 2275 printf("%13s register stalls\n", comma (register_stalls)); 2276 printf("%13s branches taken (non-return)\n", comma (branch_stalls)); 2277 printf("%13s branch alignment stalls\n", comma (branch_alignment_stalls)); 2278 printf("%13s fast returns\n", comma (fast_returns)); 2279 #endif 2280 } 2281