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