1 /* This file is part of SIS (SPARC instruction simulator) 2 3 Copyright (C) 1995-2023 Free Software Foundation, Inc. 4 Contributed by Jiri Gaisler, European Space Agency 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 /* This must come before any other includes. */ 20 #include "defs.h" 21 22 #include "sis.h" 23 #include <math.h> 24 #include <stdio.h> 25 26 extern int32_t sis_verbose, sparclite; 27 int ext_irl = 0; 28 29 /* Load/store interlock delay */ 30 #define FLSTHOLD 1 31 32 /* Load delay (delete if unwanted - speeds up simulation) */ 33 #define LOAD_DEL 1 34 35 #define T_LD 2 36 #define T_LDD 3 37 #define T_ST 3 38 #define T_STD 4 39 #define T_LDST 4 40 #define T_JMPL 2 41 #define T_RETT 2 42 43 #define FSR_QNE 0x2000 44 #define FP_EXE_MODE 0 45 #define FP_EXC_PE 1 46 #define FP_EXC_MODE 2 47 48 #define FBA 8 49 #define FBN 0 50 #define FBNE 1 51 #define FBLG 2 52 #define FBUL 3 53 #define FBL 4 54 #define FBUG 5 55 #define FBG 6 56 #define FBU 7 57 #define FBA 8 58 #define FBE 9 59 #define FBUE 10 60 #define FBGE 11 61 #define FBUGE 12 62 #define FBLE 13 63 #define FBULE 14 64 #define FBO 15 65 66 #define FCC_E 0 67 #define FCC_L 1 68 #define FCC_G 2 69 #define FCC_U 3 70 71 #define PSR_ET 0x20 72 #define PSR_EF 0x1000 73 #define PSR_PS 0x40 74 #define PSR_S 0x80 75 #define PSR_N 0x0800000 76 #define PSR_Z 0x0400000 77 #define PSR_V 0x0200000 78 #define PSR_C 0x0100000 79 #define PSR_CC 0x0F00000 80 #define PSR_CWP 0x7 81 #define PSR_PIL 0x0f00 82 83 #define ICC_N (icc >> 3) 84 #define ICC_Z (icc >> 2) 85 #define ICC_V (icc >> 1) 86 #define ICC_C (icc) 87 88 #define FP_PRES (sregs->fpu_pres) 89 90 #define TRAP_IEXC 1 91 #define TRAP_UNIMP 2 92 #define TRAP_PRIVI 3 93 #define TRAP_FPDIS 4 94 #define TRAP_WOFL 5 95 #define TRAP_WUFL 6 96 #define TRAP_UNALI 7 97 #define TRAP_FPEXC 8 98 #define TRAP_DEXC 9 99 #define TRAP_TAG 10 100 #define TRAP_DIV0 0x2a 101 102 #define FSR_TT 0x1C000 103 #define FP_IEEE 0x04000 104 #define FP_UNIMP 0x0C000 105 #define FP_SEQ_ERR 0x10000 106 107 #define BICC_BN 0 108 #define BICC_BE 1 109 #define BICC_BLE 2 110 #define BICC_BL 3 111 #define BICC_BLEU 4 112 #define BICC_BCS 5 113 #define BICC_NEG 6 114 #define BICC_BVS 7 115 #define BICC_BA 8 116 #define BICC_BNE 9 117 #define BICC_BG 10 118 #define BICC_BGE 11 119 #define BICC_BGU 12 120 #define BICC_BCC 13 121 #define BICC_POS 14 122 #define BICC_BVC 15 123 124 #define INST_SIMM13 0x1fff 125 #define INST_RS2 0x1f 126 #define INST_I 0x2000 127 #define ADD 0x00 128 #define ADDCC 0x10 129 #define ADDX 0x08 130 #define ADDXCC 0x18 131 #define TADDCC 0x20 132 #define TSUBCC 0x21 133 #define TADDCCTV 0x22 134 #define TSUBCCTV 0x23 135 #define IAND 0x01 136 #define IANDCC 0x11 137 #define IANDN 0x05 138 #define IANDNCC 0x15 139 #define MULScc 0x24 140 #define DIVScc 0x1D 141 #define SMUL 0x0B 142 #define SMULCC 0x1B 143 #define UMUL 0x0A 144 #define UMULCC 0x1A 145 #define SDIV 0x0F 146 #define SDIVCC 0x1F 147 #define UDIV 0x0E 148 #define UDIVCC 0x1E 149 #define IOR 0x02 150 #define IORCC 0x12 151 #define IORN 0x06 152 #define IORNCC 0x16 153 #define SLL 0x25 154 #define SRA 0x27 155 #define SRL 0x26 156 #define SUB 0x04 157 #define SUBCC 0x14 158 #define SUBX 0x0C 159 #define SUBXCC 0x1C 160 #define IXNOR 0x07 161 #define IXNORCC 0x17 162 #define IXOR 0x03 163 #define IXORCC 0x13 164 #define SETHI 0x04 165 #define BICC 0x02 166 #define FPBCC 0x06 167 #define RDY 0x28 168 #define RDPSR 0x29 169 #define RDWIM 0x2A 170 #define RDTBR 0x2B 171 #define SCAN 0x2C 172 #define WRY 0x30 173 #define WRPSR 0x31 174 #define WRWIM 0x32 175 #define WRTBR 0x33 176 #define JMPL 0x38 177 #define RETT 0x39 178 #define TICC 0x3A 179 #define SAVE 0x3C 180 #define RESTORE 0x3D 181 #define LDD 0x03 182 #define LDDA 0x13 183 #define LD 0x00 184 #define LDA 0x10 185 #define LDF 0x20 186 #define LDDF 0x23 187 #define LDSTUB 0x0D 188 #define LDSTUBA 0x1D 189 #define LDUB 0x01 190 #define LDUBA 0x11 191 #define LDSB 0x09 192 #define LDSBA 0x19 193 #define LDUH 0x02 194 #define LDUHA 0x12 195 #define LDSH 0x0A 196 #define LDSHA 0x1A 197 #define LDFSR 0x21 198 #define ST 0x04 199 #define STA 0x14 200 #define STB 0x05 201 #define STBA 0x15 202 #define STD 0x07 203 #define STDA 0x17 204 #define STF 0x24 205 #define STDFQ 0x26 206 #define STDF 0x27 207 #define STFSR 0x25 208 #define STH 0x06 209 #define STHA 0x16 210 #define SWAP 0x0F 211 #define SWAPA 0x1F 212 #define FLUSH 0x3B 213 214 #define SIGN_BIT 0x80000000 215 216 /* # of cycles overhead when a trap is taken */ 217 #define TRAP_C 3 218 219 /* Forward declarations */ 220 221 static uint32_t sub_cc (uint32_t psr, int32_t operand1, int32_t operand2, 222 int32_t result); 223 static uint32_t add_cc (uint32_t psr, int32_t operand1, int32_t operand2, 224 int32_t result); 225 static void log_cc (int32_t result, struct pstate *sregs); 226 static int fpexec (uint32_t op3, uint32_t rd, uint32_t rs1, uint32_t rs2, 227 struct pstate *sregs); 228 static int chk_asi (struct pstate *sregs, uint32_t *asi, uint32_t op3); 229 230 231 extern struct estate ebase; 232 extern int32_t nfp,ift; 233 234 #ifdef ERRINJ 235 extern uint32_t errtt, errftt; 236 #endif 237 238 static uint32_t 239 sub_cc(uint32_t psr, int32_t operand1, int32_t operand2, int32_t result) 240 { 241 psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N)); 242 if (result) 243 psr &= ~PSR_Z; 244 else 245 psr |= PSR_Z; 246 psr = (psr & ~PSR_V) | ((((operand1 & ~operand2 & ~result) | 247 (~operand1 & operand2 & result)) >> 10) & PSR_V); 248 psr = (psr & ~PSR_C) | ((((~operand1 & operand2) | 249 ((~operand1 | operand2) & result)) >> 11) & PSR_C); 250 return psr; 251 } 252 253 uint32_t 254 add_cc(uint32_t psr, int32_t operand1, int32_t operand2, int32_t result) 255 { 256 psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N)); 257 if (result) 258 psr &= ~PSR_Z; 259 else 260 psr |= PSR_Z; 261 psr = (psr & ~PSR_V) | ((((operand1 & operand2 & ~result) | 262 (~operand1 & ~operand2 & result)) >> 10) & PSR_V); 263 psr = (psr & ~PSR_C) | ((((operand1 & operand2) | 264 ((operand1 | operand2) & ~result)) >> 11) & PSR_C); 265 return psr; 266 } 267 268 static void 269 log_cc(int32_t result, struct pstate *sregs) 270 { 271 sregs->psr &= ~(PSR_CC); /* Zero CC bits */ 272 sregs->psr = (sregs->psr | ((result >> 8) & PSR_N)); 273 if (result == 0) 274 sregs->psr |= PSR_Z; 275 } 276 277 /* Add two unsigned 32-bit integers, and calculate the carry out. */ 278 279 static uint32_t 280 add32 (uint32_t n1, uint32_t n2, int *carry) 281 { 282 uint32_t result = n1 + n2; 283 284 *carry = result < n1 || result < n2; 285 return result; 286 } 287 288 /* Multiply two 32-bit integers. */ 289 290 static void 291 mul64 (uint32_t n1, uint32_t n2, uint32_t *result_hi, uint32_t *result_lo, int msigned) 292 { 293 uint32_t lo, mid1, mid2, hi, reg_lo, reg_hi; 294 int carry; 295 int sign = 0; 296 297 /* If this is a signed multiply, calculate the sign of the result 298 and make the operands positive. */ 299 if (msigned) 300 { 301 sign = (n1 ^ n2) & SIGN_BIT; 302 if (n1 & SIGN_BIT) 303 n1 = -n1; 304 if (n2 & SIGN_BIT) 305 n2 = -n2; 306 307 } 308 309 /* We can split the 32x32 into four 16x16 operations. This ensures 310 that we do not lose precision on 32bit only hosts: */ 311 lo = ((n1 & 0xFFFF) * (n2 & 0xFFFF)); 312 mid1 = ((n1 & 0xFFFF) * ((n2 >> 16) & 0xFFFF)); 313 mid2 = (((n1 >> 16) & 0xFFFF) * (n2 & 0xFFFF)); 314 hi = (((n1 >> 16) & 0xFFFF) * ((n2 >> 16) & 0xFFFF)); 315 316 /* We now need to add all of these results together, taking care 317 to propogate the carries from the additions: */ 318 reg_lo = add32 (lo, (mid1 << 16), &carry); 319 reg_hi = carry; 320 reg_lo = add32 (reg_lo, (mid2 << 16), &carry); 321 reg_hi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi); 322 323 /* Negate result if necessary. */ 324 if (sign) 325 { 326 reg_hi = ~ reg_hi; 327 reg_lo = - reg_lo; 328 if (reg_lo == 0) 329 reg_hi++; 330 } 331 332 *result_lo = reg_lo; 333 *result_hi = reg_hi; 334 } 335 336 337 /* Divide a 64-bit integer by a 32-bit integer. We cheat and assume 338 that the host compiler supports long long operations. */ 339 340 static void 341 div64 (uint32_t n1_hi, uint32_t n1_low, uint32_t n2, uint32_t *result, int msigned) 342 { 343 uint64_t n1; 344 345 n1 = ((uint64_t) n1_hi) << 32; 346 n1 |= ((uint64_t) n1_low) & 0xffffffff; 347 348 if (msigned) 349 { 350 int64_t n1_s = (int64_t) n1; 351 int32_t n2_s = (int32_t) n2; 352 n1_s = n1_s / n2_s; 353 n1 = (uint64_t) n1_s; 354 } 355 else 356 n1 = n1 / n2; 357 358 *result = (uint32_t) (n1 & 0xffffffff); 359 } 360 361 362 static int 363 extract_short (uint32_t data, uint32_t address) 364 { 365 return ((data >> ((2 - (address & 2)) * 8)) & 0xffff); 366 } 367 368 static int 369 extract_short_signed (uint32_t data, uint32_t address) 370 { 371 uint32_t tmp = ((data >> ((2 - (address & 2)) * 8)) & 0xffff); 372 if (tmp & 0x8000) 373 tmp |= 0xffff0000; 374 return tmp; 375 } 376 377 static int 378 extract_byte (uint32_t data, uint32_t address) 379 { 380 return ((data >> ((3 - (address & 3)) * 8)) & 0xff); 381 } 382 383 static int 384 extract_byte_signed (uint32_t data, uint32_t address) 385 { 386 uint32_t tmp = ((data >> ((3 - (address & 3)) * 8)) & 0xff); 387 if (tmp & 0x80) 388 tmp |= 0xffffff00; 389 return tmp; 390 } 391 392 int 393 dispatch_instruction(struct pstate *sregs) 394 { 395 396 uint32_t cwp, op, op2, op3, asi, rd, cond, rs1, 397 rs2; 398 uint32_t ldep, icc, data, *rdd; 399 int32_t operand1, operand2, result, eicc, 400 new_cwp; 401 int32_t pc, npc, address, ws, mexc, fcc; 402 uint32_t ddata[2]; 403 404 sregs->ninst++; 405 cwp = ((sregs->psr & PSR_CWP) << 4); 406 op = sregs->inst >> 30; 407 pc = sregs->npc; 408 npc = sregs->npc + 4; 409 op3 = rd = rs1 = operand2 = eicc = 0; 410 rdd = 0; 411 if (op & 2) { 412 413 op3 = (sregs->inst >> 19) & 0x3f; 414 rs1 = (sregs->inst >> 14) & 0x1f; 415 rd = (sregs->inst >> 25) & 0x1f; 416 417 #ifdef LOAD_DEL 418 419 /* Check if load dependecy is possible */ 420 if (ebase.simtime <= sregs->ildtime) 421 ldep = (((op3 & 0x38) != 0x28) && ((op3 & 0x3e) != 0x34) && (sregs->ildreg != 0)); 422 else 423 ldep = 0; 424 if (sregs->inst & INST_I) { 425 if (ldep && (sregs->ildreg == rs1)) 426 sregs->hold++; 427 operand2 = sregs->inst; 428 operand2 = ((operand2 << 19) >> 19); /* sign extend */ 429 } else { 430 rs2 = sregs->inst & INST_RS2; 431 if (rs2 > 7) 432 operand2 = sregs->r[(cwp + rs2) & 0x7f]; 433 else 434 operand2 = sregs->g[rs2]; 435 if (ldep && ((sregs->ildreg == rs1) || (sregs->ildreg == rs2))) 436 sregs->hold++; 437 } 438 #else 439 if (sregs->inst & INST_I) { 440 operand2 = sregs->inst; 441 operand2 = ((operand2 << 19) >> 19); /* sign extend */ 442 } else { 443 rs2 = sregs->inst & INST_RS2; 444 if (rs2 > 7) 445 operand2 = sregs->r[(cwp + rs2) & 0x7f]; 446 else 447 operand2 = sregs->g[rs2]; 448 } 449 #endif 450 451 if (rd > 7) 452 rdd = &(sregs->r[(cwp + rd) & 0x7f]); 453 else 454 rdd = &(sregs->g[rd]); 455 if (rs1 > 7) 456 rs1 = sregs->r[(cwp + rs1) & 0x7f]; 457 else 458 rs1 = sregs->g[rs1]; 459 } 460 switch (op) { 461 case 0: 462 op2 = (sregs->inst >> 22) & 0x7; 463 switch (op2) { 464 case SETHI: 465 rd = (sregs->inst >> 25) & 0x1f; 466 if (rd > 7) 467 rdd = &(sregs->r[(cwp + rd) & 0x7f]); 468 else 469 rdd = &(sregs->g[rd]); 470 *rdd = sregs->inst << 10; 471 break; 472 case BICC: 473 #ifdef STAT 474 sregs->nbranch++; 475 #endif 476 icc = sregs->psr >> 20; 477 cond = ((sregs->inst >> 25) & 0x0f); 478 switch (cond) { 479 case BICC_BN: 480 eicc = 0; 481 break; 482 case BICC_BE: 483 eicc = ICC_Z; 484 break; 485 case BICC_BLE: 486 eicc = ICC_Z | (ICC_N ^ ICC_V); 487 break; 488 case BICC_BL: 489 eicc = (ICC_N ^ ICC_V); 490 break; 491 case BICC_BLEU: 492 eicc = ICC_C | ICC_Z; 493 break; 494 case BICC_BCS: 495 eicc = ICC_C; 496 break; 497 case BICC_NEG: 498 eicc = ICC_N; 499 break; 500 case BICC_BVS: 501 eicc = ICC_V; 502 break; 503 case BICC_BA: 504 eicc = 1; 505 if (sregs->inst & 0x20000000) 506 sregs->annul = 1; 507 break; 508 case BICC_BNE: 509 eicc = ~(ICC_Z); 510 break; 511 case BICC_BG: 512 eicc = ~(ICC_Z | (ICC_N ^ ICC_V)); 513 break; 514 case BICC_BGE: 515 eicc = ~(ICC_N ^ ICC_V); 516 break; 517 case BICC_BGU: 518 eicc = ~(ICC_C | ICC_Z); 519 break; 520 case BICC_BCC: 521 eicc = ~(ICC_C); 522 break; 523 case BICC_POS: 524 eicc = ~(ICC_N); 525 break; 526 case BICC_BVC: 527 eicc = ~(ICC_V); 528 break; 529 } 530 if (eicc & 1) { 531 operand1 = sregs->inst; 532 operand1 = ((operand1 << 10) >> 8); /* sign extend */ 533 npc = sregs->pc + operand1; 534 } else { 535 if (sregs->inst & 0x20000000) 536 sregs->annul = 1; 537 } 538 break; 539 case FPBCC: 540 #ifdef STAT 541 sregs->nbranch++; 542 #endif 543 if (!((sregs->psr & PSR_EF) && FP_PRES)) { 544 sregs->trap = TRAP_FPDIS; 545 break; 546 } 547 if (ebase.simtime < sregs->ftime) { 548 sregs->ftime = ebase.simtime + sregs->hold; 549 } 550 cond = ((sregs->inst >> 25) & 0x0f); 551 fcc = (sregs->fsr >> 10) & 0x3; 552 switch (cond) { 553 case FBN: 554 eicc = 0; 555 break; 556 case FBNE: 557 eicc = (fcc != FCC_E); 558 break; 559 case FBLG: 560 eicc = (fcc == FCC_L) || (fcc == FCC_G); 561 break; 562 case FBUL: 563 eicc = (fcc == FCC_L) || (fcc == FCC_U); 564 break; 565 case FBL: 566 eicc = (fcc == FCC_L); 567 break; 568 case FBUG: 569 eicc = (fcc == FCC_G) || (fcc == FCC_U); 570 break; 571 case FBG: 572 eicc = (fcc == FCC_G); 573 break; 574 case FBU: 575 eicc = (fcc == FCC_U); 576 break; 577 case FBA: 578 eicc = 1; 579 if (sregs->inst & 0x20000000) 580 sregs->annul = 1; 581 break; 582 case FBE: 583 eicc = !(fcc != FCC_E); 584 break; 585 case FBUE: 586 eicc = !((fcc == FCC_L) || (fcc == FCC_G)); 587 break; 588 case FBGE: 589 eicc = !((fcc == FCC_L) || (fcc == FCC_U)); 590 break; 591 case FBUGE: 592 eicc = !(fcc == FCC_L); 593 break; 594 case FBLE: 595 eicc = !((fcc == FCC_G) || (fcc == FCC_U)); 596 break; 597 case FBULE: 598 eicc = !(fcc == FCC_G); 599 break; 600 case FBO: 601 eicc = !(fcc == FCC_U); 602 break; 603 } 604 if (eicc) { 605 operand1 = sregs->inst; 606 operand1 = ((operand1 << 10) >> 8); /* sign extend */ 607 npc = sregs->pc + operand1; 608 } else { 609 if (sregs->inst & 0x20000000) 610 sregs->annul = 1; 611 } 612 break; 613 614 default: 615 sregs->trap = TRAP_UNIMP; 616 break; 617 } 618 break; 619 case 1: /* CALL */ 620 #ifdef STAT 621 sregs->nbranch++; 622 #endif 623 sregs->r[(cwp + 15) & 0x7f] = sregs->pc; 624 npc = sregs->pc + (sregs->inst << 2); 625 break; 626 627 case 2: 628 if ((op3 >> 1) == 0x1a) { 629 if (!((sregs->psr & PSR_EF) && FP_PRES)) { 630 sregs->trap = TRAP_FPDIS; 631 } else { 632 rs1 = (sregs->inst >> 14) & 0x1f; 633 rs2 = sregs->inst & 0x1f; 634 sregs->trap = fpexec(op3, rd, rs1, rs2, sregs); 635 } 636 } else { 637 638 switch (op3) { 639 case TICC: 640 icc = sregs->psr >> 20; 641 cond = ((sregs->inst >> 25) & 0x0f); 642 switch (cond) { 643 case BICC_BN: 644 eicc = 0; 645 break; 646 case BICC_BE: 647 eicc = ICC_Z; 648 break; 649 case BICC_BLE: 650 eicc = ICC_Z | (ICC_N ^ ICC_V); 651 break; 652 case BICC_BL: 653 eicc = (ICC_N ^ ICC_V); 654 break; 655 case BICC_BLEU: 656 eicc = ICC_C | ICC_Z; 657 break; 658 case BICC_BCS: 659 eicc = ICC_C; 660 break; 661 case BICC_NEG: 662 eicc = ICC_N; 663 break; 664 case BICC_BVS: 665 eicc = ICC_V; 666 break; 667 case BICC_BA: 668 eicc = 1; 669 break; 670 case BICC_BNE: 671 eicc = ~(ICC_Z); 672 break; 673 case BICC_BG: 674 eicc = ~(ICC_Z | (ICC_N ^ ICC_V)); 675 break; 676 case BICC_BGE: 677 eicc = ~(ICC_N ^ ICC_V); 678 break; 679 case BICC_BGU: 680 eicc = ~(ICC_C | ICC_Z); 681 break; 682 case BICC_BCC: 683 eicc = ~(ICC_C); 684 break; 685 case BICC_POS: 686 eicc = ~(ICC_N); 687 break; 688 case BICC_BVC: 689 eicc = ~(ICC_V); 690 break; 691 } 692 if (eicc & 1) { 693 sregs->trap = (0x80 | ((rs1 + operand2) & 0x7f)); 694 } 695 break; 696 697 case MULScc: 698 operand1 = 699 (((sregs->psr & PSR_V) ^ ((sregs->psr & PSR_N) >> 2)) 700 << 10) | (rs1 >> 1); 701 if ((sregs->y & 1) == 0) 702 operand2 = 0; 703 *rdd = operand1 + operand2; 704 sregs->y = (rs1 << 31) | (sregs->y >> 1); 705 sregs->psr = add_cc(sregs->psr, operand1, operand2, *rdd); 706 break; 707 case DIVScc: 708 { 709 int sign; 710 uint32_t result, remainder; 711 int c0, y31; 712 713 if (!sparclite) { 714 sregs->trap = TRAP_UNIMP; 715 break; 716 } 717 718 sign = ((sregs->psr & PSR_V) != 0) ^ ((sregs->psr & PSR_N) != 0); 719 720 remainder = (sregs->y << 1) | (rs1 >> 31); 721 722 /* If true sign is positive, calculate remainder - divisor. 723 Otherwise, calculate remainder + divisor. */ 724 if (sign == 0) 725 operand2 = ~operand2 + 1; 726 result = remainder + operand2; 727 728 /* The SPARClite User's Manual is not clear on how 729 the "carry out" of the above ALU operation is to 730 be calculated. From trial and error tests 731 on the the chip itself, it appears that it is 732 a normal addition carry, and not a subtraction borrow, 733 even in cases where the divisor is subtracted 734 from the remainder. FIXME: get the true story 735 from Fujitsu. */ 736 c0 = result < (uint32_t) remainder 737 || result < (uint32_t) operand2; 738 739 if (result & 0x80000000) 740 sregs->psr |= PSR_N; 741 else 742 sregs->psr &= ~PSR_N; 743 744 y31 = (sregs->y & 0x80000000) == 0x80000000; 745 746 if (result == 0 && sign == y31) 747 sregs->psr |= PSR_Z; 748 else 749 sregs->psr &= ~PSR_Z; 750 751 sign = (sign && !y31) || (!c0 && (sign || !y31)); 752 753 if (sign ^ (result >> 31)) 754 sregs->psr |= PSR_V; 755 else 756 sregs->psr &= ~PSR_V; 757 758 if (!sign) 759 sregs->psr |= PSR_C; 760 else 761 sregs->psr &= ~PSR_C; 762 763 sregs->y = result; 764 765 if (rd != 0) 766 *rdd = (rs1 << 1) | !sign; 767 } 768 break; 769 case SMUL: 770 { 771 mul64 (rs1, operand2, &sregs->y, rdd, 1); 772 } 773 break; 774 case SMULCC: 775 { 776 uint32_t result; 777 778 mul64 (rs1, operand2, &sregs->y, &result, 1); 779 780 if (result & 0x80000000) 781 sregs->psr |= PSR_N; 782 else 783 sregs->psr &= ~PSR_N; 784 785 if (result == 0) 786 sregs->psr |= PSR_Z; 787 else 788 sregs->psr &= ~PSR_Z; 789 790 *rdd = result; 791 } 792 break; 793 case UMUL: 794 { 795 mul64 (rs1, operand2, &sregs->y, rdd, 0); 796 } 797 break; 798 case UMULCC: 799 { 800 uint32_t result; 801 802 mul64 (rs1, operand2, &sregs->y, &result, 0); 803 804 if (result & 0x80000000) 805 sregs->psr |= PSR_N; 806 else 807 sregs->psr &= ~PSR_N; 808 809 if (result == 0) 810 sregs->psr |= PSR_Z; 811 else 812 sregs->psr &= ~PSR_Z; 813 814 *rdd = result; 815 } 816 break; 817 case SDIV: 818 { 819 if (sparclite) { 820 sregs->trap = TRAP_UNIMP; 821 break; 822 } 823 824 if (operand2 == 0) { 825 sregs->trap = TRAP_DIV0; 826 break; 827 } 828 829 div64 (sregs->y, rs1, operand2, rdd, 1); 830 } 831 break; 832 case SDIVCC: 833 { 834 uint32_t result; 835 836 if (sparclite) { 837 sregs->trap = TRAP_UNIMP; 838 break; 839 } 840 841 if (operand2 == 0) { 842 sregs->trap = TRAP_DIV0; 843 break; 844 } 845 846 div64 (sregs->y, rs1, operand2, &result, 1); 847 848 if (result & 0x80000000) 849 sregs->psr |= PSR_N; 850 else 851 sregs->psr &= ~PSR_N; 852 853 if (result == 0) 854 sregs->psr |= PSR_Z; 855 else 856 sregs->psr &= ~PSR_Z; 857 858 /* FIXME: should set overflow flag correctly. */ 859 sregs->psr &= ~(PSR_C | PSR_V); 860 861 *rdd = result; 862 } 863 break; 864 case UDIV: 865 { 866 if (sparclite) { 867 sregs->trap = TRAP_UNIMP; 868 break; 869 } 870 871 if (operand2 == 0) { 872 sregs->trap = TRAP_DIV0; 873 break; 874 } 875 876 div64 (sregs->y, rs1, operand2, rdd, 0); 877 } 878 break; 879 case UDIVCC: 880 { 881 uint32_t result; 882 883 if (sparclite) { 884 sregs->trap = TRAP_UNIMP; 885 break; 886 } 887 888 if (operand2 == 0) { 889 sregs->trap = TRAP_DIV0; 890 break; 891 } 892 893 div64 (sregs->y, rs1, operand2, &result, 0); 894 895 if (result & 0x80000000) 896 sregs->psr |= PSR_N; 897 else 898 sregs->psr &= ~PSR_N; 899 900 if (result == 0) 901 sregs->psr |= PSR_Z; 902 else 903 sregs->psr &= ~PSR_Z; 904 905 /* FIXME: should set overflow flag correctly. */ 906 sregs->psr &= ~(PSR_C | PSR_V); 907 908 *rdd = result; 909 } 910 break; 911 case IXNOR: 912 *rdd = rs1 ^ ~operand2; 913 break; 914 case IXNORCC: 915 *rdd = rs1 ^ ~operand2; 916 log_cc(*rdd, sregs); 917 break; 918 case IXOR: 919 *rdd = rs1 ^ operand2; 920 break; 921 case IXORCC: 922 *rdd = rs1 ^ operand2; 923 log_cc(*rdd, sregs); 924 break; 925 case IOR: 926 *rdd = rs1 | operand2; 927 break; 928 case IORCC: 929 *rdd = rs1 | operand2; 930 log_cc(*rdd, sregs); 931 break; 932 case IORN: 933 *rdd = rs1 | ~operand2; 934 break; 935 case IORNCC: 936 *rdd = rs1 | ~operand2; 937 log_cc(*rdd, sregs); 938 break; 939 case IANDNCC: 940 *rdd = rs1 & ~operand2; 941 log_cc(*rdd, sregs); 942 break; 943 case IANDN: 944 *rdd = rs1 & ~operand2; 945 break; 946 case IAND: 947 *rdd = rs1 & operand2; 948 break; 949 case IANDCC: 950 *rdd = rs1 & operand2; 951 log_cc(*rdd, sregs); 952 break; 953 case SUB: 954 *rdd = rs1 - operand2; 955 break; 956 case SUBCC: 957 *rdd = rs1 - operand2; 958 sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd); 959 break; 960 case SUBX: 961 *rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1); 962 break; 963 case SUBXCC: 964 *rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1); 965 sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd); 966 break; 967 case ADD: 968 *rdd = rs1 + operand2; 969 break; 970 case ADDCC: 971 *rdd = rs1 + operand2; 972 sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd); 973 break; 974 case ADDX: 975 *rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1); 976 break; 977 case ADDXCC: 978 *rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1); 979 sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd); 980 break; 981 case TADDCC: 982 *rdd = rs1 + operand2; 983 sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd); 984 if ((rs1 | operand2) & 0x3) 985 sregs->psr |= PSR_V; 986 break; 987 case TSUBCC: 988 *rdd = rs1 - operand2; 989 sregs->psr = sub_cc (sregs->psr, rs1, operand2, *rdd); 990 if ((rs1 | operand2) & 0x3) 991 sregs->psr |= PSR_V; 992 break; 993 case TADDCCTV: 994 *rdd = rs1 + operand2; 995 result = add_cc(0, rs1, operand2, *rdd); 996 if ((rs1 | operand2) & 0x3) 997 result |= PSR_V; 998 if (result & PSR_V) { 999 sregs->trap = TRAP_TAG; 1000 } else { 1001 sregs->psr = (sregs->psr & ~PSR_CC) | result; 1002 } 1003 break; 1004 case TSUBCCTV: 1005 *rdd = rs1 - operand2; 1006 result = add_cc (0, rs1, operand2, *rdd); 1007 if ((rs1 | operand2) & 0x3) 1008 result |= PSR_V; 1009 if (result & PSR_V) 1010 { 1011 sregs->trap = TRAP_TAG; 1012 } 1013 else 1014 { 1015 sregs->psr = (sregs->psr & ~PSR_CC) | result; 1016 } 1017 break; 1018 case SLL: 1019 *rdd = rs1 << (operand2 & 0x1f); 1020 break; 1021 case SRL: 1022 *rdd = rs1 >> (operand2 & 0x1f); 1023 break; 1024 case SRA: 1025 *rdd = ((int) rs1) >> (operand2 & 0x1f); 1026 break; 1027 case FLUSH: 1028 if (ift) sregs->trap = TRAP_UNIMP; 1029 break; 1030 case SAVE: 1031 new_cwp = ((sregs->psr & PSR_CWP) - 1) & PSR_CWP; 1032 if (sregs->wim & (1 << new_cwp)) { 1033 sregs->trap = TRAP_WOFL; 1034 break; 1035 } 1036 if (rd > 7) 1037 rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]); 1038 *rdd = rs1 + operand2; 1039 sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp; 1040 break; 1041 case RESTORE: 1042 1043 new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP; 1044 if (sregs->wim & (1 << new_cwp)) { 1045 sregs->trap = TRAP_WUFL; 1046 break; 1047 } 1048 if (rd > 7) 1049 rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]); 1050 *rdd = rs1 + operand2; 1051 sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp; 1052 break; 1053 case RDPSR: 1054 if (!(sregs->psr & PSR_S)) { 1055 sregs->trap = TRAP_PRIVI; 1056 break; 1057 } 1058 *rdd = sregs->psr; 1059 break; 1060 case RDY: 1061 if (!sparclite) 1062 *rdd = sregs->y; 1063 else { 1064 int rs1_is_asr = (sregs->inst >> 14) & 0x1f; 1065 if ( 0 == rs1_is_asr ) 1066 *rdd = sregs->y; 1067 else if ( 17 == rs1_is_asr ) 1068 *rdd = sregs->asr17; 1069 else { 1070 sregs->trap = TRAP_UNIMP; 1071 break; 1072 } 1073 } 1074 break; 1075 case RDWIM: 1076 if (!(sregs->psr & PSR_S)) { 1077 sregs->trap = TRAP_PRIVI; 1078 break; 1079 } 1080 *rdd = sregs->wim; 1081 break; 1082 case RDTBR: 1083 if (!(sregs->psr & PSR_S)) { 1084 sregs->trap = TRAP_PRIVI; 1085 break; 1086 } 1087 *rdd = sregs->tbr; 1088 break; 1089 case WRPSR: 1090 if ((sregs->psr & 0x1f) > 7) { 1091 sregs->trap = TRAP_UNIMP; 1092 break; 1093 } 1094 if (!(sregs->psr & PSR_S)) { 1095 sregs->trap = TRAP_PRIVI; 1096 break; 1097 } 1098 sregs->psr = (sregs->psr & 0xff000000) | 1099 ((rs1 ^ operand2) & 0x00f03fff); 1100 break; 1101 case WRWIM: 1102 if (!(sregs->psr & PSR_S)) { 1103 sregs->trap = TRAP_PRIVI; 1104 break; 1105 } 1106 sregs->wim = (rs1 ^ operand2) & 0x0ff; 1107 break; 1108 case WRTBR: 1109 if (!(sregs->psr & PSR_S)) { 1110 sregs->trap = TRAP_PRIVI; 1111 break; 1112 } 1113 sregs->tbr = (sregs->tbr & 0x00000ff0) | 1114 ((rs1 ^ operand2) & 0xfffff000); 1115 break; 1116 case WRY: 1117 if (!sparclite) 1118 sregs->y = (rs1 ^ operand2); 1119 else { 1120 if ( 0 == rd ) 1121 sregs->y = (rs1 ^ operand2); 1122 else if ( 17 == rd ) 1123 sregs->asr17 = (rs1 ^ operand2); 1124 else { 1125 sregs->trap = TRAP_UNIMP; 1126 break; 1127 } 1128 } 1129 break; 1130 case JMPL: 1131 1132 #ifdef STAT 1133 sregs->nbranch++; 1134 #endif 1135 sregs->icnt = T_JMPL; /* JMPL takes two cycles */ 1136 if (rs1 & 0x3) { 1137 sregs->trap = TRAP_UNALI; 1138 break; 1139 } 1140 *rdd = sregs->pc; 1141 npc = rs1 + operand2; 1142 break; 1143 case RETT: 1144 address = rs1 + operand2; 1145 new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP; 1146 sregs->icnt = T_RETT; /* RETT takes two cycles */ 1147 if (sregs->psr & PSR_ET) { 1148 sregs->trap = TRAP_UNIMP; 1149 break; 1150 } 1151 if (!(sregs->psr & PSR_S)) { 1152 sregs->trap = TRAP_PRIVI; 1153 break; 1154 } 1155 if (sregs->wim & (1 << new_cwp)) { 1156 sregs->trap = TRAP_WUFL; 1157 break; 1158 } 1159 if (address & 0x3) { 1160 sregs->trap = TRAP_UNALI; 1161 break; 1162 } 1163 sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp | PSR_ET; 1164 sregs->psr = 1165 (sregs->psr & ~PSR_S) | ((sregs->psr & PSR_PS) << 1); 1166 npc = address; 1167 break; 1168 1169 case SCAN: 1170 { 1171 uint32_t result, mask; 1172 int i; 1173 1174 if (!sparclite) { 1175 sregs->trap = TRAP_UNIMP; 1176 break; 1177 } 1178 mask = (operand2 & 0x80000000) | (operand2 >> 1); 1179 result = rs1 ^ mask; 1180 1181 for (i = 0; i < 32; i++) { 1182 if (result & 0x80000000) 1183 break; 1184 result <<= 1; 1185 } 1186 1187 *rdd = i == 32 ? 63 : i; 1188 } 1189 break; 1190 1191 default: 1192 sregs->trap = TRAP_UNIMP; 1193 break; 1194 } 1195 } 1196 break; 1197 case 3: /* Load/store instructions */ 1198 1199 address = rs1 + operand2; 1200 1201 if (sregs->psr & PSR_S) 1202 asi = 11; 1203 else 1204 asi = 10; 1205 1206 if (op3 & 4) { 1207 sregs->icnt = T_ST; /* Set store instruction count */ 1208 #ifdef STAT 1209 sregs->nstore++; 1210 #endif 1211 } else { 1212 sregs->icnt = T_LD; /* Set load instruction count */ 1213 #ifdef STAT 1214 sregs->nload++; 1215 #endif 1216 } 1217 1218 /* Decode load/store instructions */ 1219 1220 switch (op3) { 1221 case LDDA: 1222 if (!chk_asi(sregs, &asi, op3)) break; 1223 case LDD: 1224 if (address & 0x7) { 1225 sregs->trap = TRAP_UNALI; 1226 break; 1227 } 1228 if (rd & 1) { 1229 rd &= 0x1e; 1230 if (rd > 7) 1231 rdd = &(sregs->r[(cwp + rd) & 0x7f]); 1232 else 1233 rdd = &(sregs->g[rd]); 1234 } 1235 mexc = memory_read (asi, address, ddata, 2, &ws); 1236 sregs->hold += ws; 1237 mexc |= memory_read (asi, address+4, &ddata[1], 2, &ws); 1238 sregs->hold += ws; 1239 sregs->icnt = T_LDD; 1240 if (mexc) { 1241 sregs->trap = TRAP_DEXC; 1242 } else { 1243 rdd[0] = ddata[0]; 1244 rdd[1] = ddata[1]; 1245 #ifdef STAT 1246 sregs->nload++; /* Double load counts twice */ 1247 #endif 1248 } 1249 break; 1250 1251 case LDA: 1252 if (!chk_asi(sregs, &asi, op3)) break; 1253 case LD: 1254 if (address & 0x3) { 1255 sregs->trap = TRAP_UNALI; 1256 break; 1257 } 1258 mexc = memory_read(asi, address, &data, 2, &ws); 1259 sregs->hold += ws; 1260 if (mexc) { 1261 sregs->trap = TRAP_DEXC; 1262 } else { 1263 *rdd = data; 1264 } 1265 break; 1266 case LDSTUBA: 1267 if (!chk_asi(sregs, &asi, op3)) break; 1268 case LDSTUB: 1269 mexc = memory_read(asi, address, &data, 0, &ws); 1270 sregs->hold += ws; 1271 sregs->icnt = T_LDST; 1272 if (mexc) { 1273 sregs->trap = TRAP_DEXC; 1274 break; 1275 } 1276 data = extract_byte (data, address); 1277 *rdd = data; 1278 data = 0x0ff; 1279 mexc = memory_write(asi, address, &data, 0, &ws); 1280 sregs->hold += ws; 1281 if (mexc) { 1282 sregs->trap = TRAP_DEXC; 1283 } 1284 #ifdef STAT 1285 sregs->nload++; 1286 #endif 1287 break; 1288 case LDSBA: 1289 case LDUBA: 1290 if (!chk_asi(sregs, &asi, op3)) break; 1291 case LDSB: 1292 case LDUB: 1293 mexc = memory_read(asi, address, &data, 0, &ws); 1294 sregs->hold += ws; 1295 if (mexc) { 1296 sregs->trap = TRAP_DEXC; 1297 break; 1298 } 1299 if (op3 == LDSB) 1300 data = extract_byte_signed (data, address); 1301 else 1302 data = extract_byte (data, address); 1303 *rdd = data; 1304 break; 1305 case LDSHA: 1306 case LDUHA: 1307 if (!chk_asi(sregs, &asi, op3)) break; 1308 case LDSH: 1309 case LDUH: 1310 if (address & 0x1) { 1311 sregs->trap = TRAP_UNALI; 1312 break; 1313 } 1314 mexc = memory_read(asi, address, &data, 1, &ws); 1315 sregs->hold += ws; 1316 if (mexc) { 1317 sregs->trap = TRAP_DEXC; 1318 break; 1319 } 1320 if (op3 == LDSH) 1321 data = extract_short_signed (data, address); 1322 else 1323 data = extract_short (data, address); 1324 *rdd = data; 1325 break; 1326 case LDF: 1327 if (!((sregs->psr & PSR_EF) && FP_PRES)) { 1328 sregs->trap = TRAP_FPDIS; 1329 break; 1330 } 1331 if (address & 0x3) { 1332 sregs->trap = TRAP_UNALI; 1333 break; 1334 } 1335 if (ebase.simtime < sregs->ftime) { 1336 if ((sregs->frd == rd) || (sregs->frs1 == rd) || 1337 (sregs->frs2 == rd)) 1338 sregs->fhold += (sregs->ftime - ebase.simtime); 1339 } 1340 mexc = memory_read(asi, address, &data, 2, &ws); 1341 sregs->hold += ws; 1342 sregs->flrd = rd; 1343 sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD + 1344 sregs->hold + sregs->fhold; 1345 if (mexc) { 1346 sregs->trap = TRAP_DEXC; 1347 } else { 1348 memcpy (&sregs->fs[rd], &data, sizeof (sregs->fs[rd])); 1349 } 1350 break; 1351 case LDDF: 1352 if (!((sregs->psr & PSR_EF) && FP_PRES)) { 1353 sregs->trap = TRAP_FPDIS; 1354 break; 1355 } 1356 if (address & 0x7) { 1357 sregs->trap = TRAP_UNALI; 1358 break; 1359 } 1360 if (ebase.simtime < sregs->ftime) { 1361 if (((sregs->frd >> 1) == (rd >> 1)) || 1362 ((sregs->frs1 >> 1) == (rd >> 1)) || 1363 ((sregs->frs2 >> 1) == (rd >> 1))) 1364 sregs->fhold += (sregs->ftime - ebase.simtime); 1365 } 1366 mexc = memory_read (asi, address, ddata, 2, &ws); 1367 sregs->hold += ws; 1368 mexc |= memory_read (asi, address+4, &ddata[1], 2, &ws); 1369 sregs->hold += ws; 1370 sregs->icnt = T_LDD; 1371 if (mexc) { 1372 sregs->trap = TRAP_DEXC; 1373 } else { 1374 rd &= 0x1E; 1375 sregs->flrd = rd; 1376 memcpy (&sregs->fs[rd], &ddata[0], sizeof (sregs->fs[rd])); 1377 #ifdef STAT 1378 sregs->nload++; /* Double load counts twice */ 1379 #endif 1380 memcpy (&sregs->fs[rd + 1], &ddata[1], 1381 sizeof (sregs->fs[rd + 1])); 1382 sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD + 1383 sregs->hold + sregs->fhold; 1384 } 1385 break; 1386 case LDFSR: 1387 if (ebase.simtime < sregs->ftime) { 1388 sregs->fhold += (sregs->ftime - ebase.simtime); 1389 } 1390 if (!((sregs->psr & PSR_EF) && FP_PRES)) { 1391 sregs->trap = TRAP_FPDIS; 1392 break; 1393 } 1394 if (address & 0x3) { 1395 sregs->trap = TRAP_UNALI; 1396 break; 1397 } 1398 mexc = memory_read(asi, address, &data, 2, &ws); 1399 sregs->hold += ws; 1400 if (mexc) { 1401 sregs->trap = TRAP_DEXC; 1402 } else { 1403 sregs->fsr = 1404 (sregs->fsr & 0x7FF000) | (data & ~0x7FF000); 1405 set_fsr(sregs->fsr); 1406 } 1407 break; 1408 case STFSR: 1409 if (!((sregs->psr & PSR_EF) && FP_PRES)) { 1410 sregs->trap = TRAP_FPDIS; 1411 break; 1412 } 1413 if (address & 0x3) { 1414 sregs->trap = TRAP_UNALI; 1415 break; 1416 } 1417 if (ebase.simtime < sregs->ftime) { 1418 sregs->fhold += (sregs->ftime - ebase.simtime); 1419 } 1420 mexc = memory_write(asi, address, &sregs->fsr, 2, &ws); 1421 sregs->hold += ws; 1422 if (mexc) { 1423 sregs->trap = TRAP_DEXC; 1424 } 1425 break; 1426 1427 case STA: 1428 if (!chk_asi(sregs, &asi, op3)) break; 1429 case ST: 1430 if (address & 0x3) { 1431 sregs->trap = TRAP_UNALI; 1432 break; 1433 } 1434 mexc = memory_write(asi, address, rdd, 2, &ws); 1435 sregs->hold += ws; 1436 if (mexc) { 1437 sregs->trap = TRAP_DEXC; 1438 } 1439 break; 1440 case STBA: 1441 if (!chk_asi(sregs, &asi, op3)) break; 1442 case STB: 1443 mexc = memory_write(asi, address, rdd, 0, &ws); 1444 sregs->hold += ws; 1445 if (mexc) { 1446 sregs->trap = TRAP_DEXC; 1447 } 1448 break; 1449 case STDA: 1450 if (!chk_asi(sregs, &asi, op3)) break; 1451 case STD: 1452 if (address & 0x7) { 1453 sregs->trap = TRAP_UNALI; 1454 break; 1455 } 1456 if (rd & 1) { 1457 rd &= 0x1e; 1458 if (rd > 7) 1459 rdd = &(sregs->r[(cwp + rd) & 0x7f]); 1460 else 1461 rdd = &(sregs->g[rd]); 1462 } 1463 mexc = memory_write(asi, address, rdd, 3, &ws); 1464 sregs->hold += ws; 1465 sregs->icnt = T_STD; 1466 #ifdef STAT 1467 sregs->nstore++; /* Double store counts twice */ 1468 #endif 1469 if (mexc) { 1470 sregs->trap = TRAP_DEXC; 1471 break; 1472 } 1473 break; 1474 case STDFQ: 1475 if ((sregs->psr & 0x1f) > 7) { 1476 sregs->trap = TRAP_UNIMP; 1477 break; 1478 } 1479 if (!((sregs->psr & PSR_EF) && FP_PRES)) { 1480 sregs->trap = TRAP_FPDIS; 1481 break; 1482 } 1483 if (address & 0x7) { 1484 sregs->trap = TRAP_UNALI; 1485 break; 1486 } 1487 if (!(sregs->fsr & FSR_QNE)) { 1488 sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR; 1489 break; 1490 } 1491 rdd = &(sregs->fpq[0]); 1492 mexc = memory_write(asi, address, rdd, 3, &ws); 1493 sregs->hold += ws; 1494 sregs->icnt = T_STD; 1495 #ifdef STAT 1496 sregs->nstore++; /* Double store counts twice */ 1497 #endif 1498 if (mexc) { 1499 sregs->trap = TRAP_DEXC; 1500 break; 1501 } else { 1502 sregs->fsr &= ~FSR_QNE; 1503 sregs->fpstate = FP_EXE_MODE; 1504 } 1505 break; 1506 case STHA: 1507 if (!chk_asi(sregs, &asi, op3)) break; 1508 case STH: 1509 if (address & 0x1) { 1510 sregs->trap = TRAP_UNALI; 1511 break; 1512 } 1513 mexc = memory_write(asi, address, rdd, 1, &ws); 1514 sregs->hold += ws; 1515 if (mexc) { 1516 sregs->trap = TRAP_DEXC; 1517 } 1518 break; 1519 case STF: 1520 if (!((sregs->psr & PSR_EF) && FP_PRES)) { 1521 sregs->trap = TRAP_FPDIS; 1522 break; 1523 } 1524 if (address & 0x3) { 1525 sregs->trap = TRAP_UNALI; 1526 break; 1527 } 1528 if (ebase.simtime < sregs->ftime) { 1529 if (sregs->frd == rd) 1530 sregs->fhold += (sregs->ftime - ebase.simtime); 1531 } 1532 mexc = memory_write(asi, address, (uint32_t *)&sregs->fsi[rd], 2, &ws); 1533 sregs->hold += ws; 1534 if (mexc) { 1535 sregs->trap = TRAP_DEXC; 1536 } 1537 break; 1538 case STDF: 1539 if (!((sregs->psr & PSR_EF) && FP_PRES)) { 1540 sregs->trap = TRAP_FPDIS; 1541 break; 1542 } 1543 if (address & 0x7) { 1544 sregs->trap = TRAP_UNALI; 1545 break; 1546 } 1547 rd &= 0x1E; 1548 if (ebase.simtime < sregs->ftime) { 1549 if ((sregs->frd == rd) || (sregs->frd + 1 == rd)) 1550 sregs->fhold += (sregs->ftime - ebase.simtime); 1551 } 1552 mexc = memory_write(asi, address, (uint32_t *)&sregs->fsi[rd], 3, &ws); 1553 sregs->hold += ws; 1554 sregs->icnt = T_STD; 1555 #ifdef STAT 1556 sregs->nstore++; /* Double store counts twice */ 1557 #endif 1558 if (mexc) { 1559 sregs->trap = TRAP_DEXC; 1560 } 1561 break; 1562 case SWAPA: 1563 if (!chk_asi(sregs, &asi, op3)) break; 1564 case SWAP: 1565 if (address & 0x3) { 1566 sregs->trap = TRAP_UNALI; 1567 break; 1568 } 1569 mexc = memory_read(asi, address, &data, 2, &ws); 1570 sregs->hold += ws; 1571 if (mexc) { 1572 sregs->trap = TRAP_DEXC; 1573 break; 1574 } 1575 mexc = memory_write(asi, address, rdd, 2, &ws); 1576 sregs->hold += ws; 1577 sregs->icnt = T_LDST; 1578 if (mexc) { 1579 sregs->trap = TRAP_DEXC; 1580 break; 1581 } else 1582 *rdd = data; 1583 #ifdef STAT 1584 sregs->nload++; 1585 #endif 1586 break; 1587 1588 1589 default: 1590 sregs->trap = TRAP_UNIMP; 1591 break; 1592 } 1593 1594 #ifdef LOAD_DEL 1595 1596 if (!(op3 & 4)) { 1597 sregs->ildtime = ebase.simtime + sregs->hold + sregs->icnt; 1598 sregs->ildreg = rd; 1599 if ((op3 | 0x10) == 0x13) 1600 sregs->ildreg |= 1; /* Double load, odd register loaded 1601 * last */ 1602 } 1603 #endif 1604 break; 1605 1606 default: 1607 sregs->trap = TRAP_UNIMP; 1608 break; 1609 } 1610 sregs->g[0] = 0; 1611 if (!sregs->trap) { 1612 sregs->pc = pc; 1613 sregs->npc = npc; 1614 } 1615 return 0; 1616 } 1617 1618 #define T_FABSs 2 1619 #define T_FADDs 4 1620 #define T_FADDd 4 1621 #define T_FCMPs 4 1622 #define T_FCMPd 4 1623 #define T_FDIVs 20 1624 #define T_FDIVd 35 1625 #define T_FMOVs 2 1626 #define T_FMULs 5 1627 #define T_FMULd 9 1628 #define T_FNEGs 2 1629 #define T_FSQRTs 37 1630 #define T_FSQRTd 65 1631 #define T_FSUBs 4 1632 #define T_FSUBd 4 1633 #define T_FdTOi 7 1634 #define T_FdTOs 3 1635 #define T_FiTOs 6 1636 #define T_FiTOd 6 1637 #define T_FsTOi 6 1638 #define T_FsTOd 2 1639 1640 #define FABSs 0x09 1641 #define FADDs 0x41 1642 #define FADDd 0x42 1643 #define FCMPs 0x51 1644 #define FCMPd 0x52 1645 #define FCMPEs 0x55 1646 #define FCMPEd 0x56 1647 #define FDIVs 0x4D 1648 #define FDIVd 0x4E 1649 #define FMOVs 0x01 1650 #define FMULs 0x49 1651 #define FMULd 0x4A 1652 #define FNEGs 0x05 1653 #define FSQRTs 0x29 1654 #define FSQRTd 0x2A 1655 #define FSUBs 0x45 1656 #define FSUBd 0x46 1657 #define FdTOi 0xD2 1658 #define FdTOs 0xC6 1659 #define FiTOs 0xC4 1660 #define FiTOd 0xC8 1661 #define FsTOi 0xD1 1662 #define FsTOd 0xC9 1663 1664 1665 static int 1666 fpexec(uint32_t op3, uint32_t rd, uint32_t rs1, uint32_t rs2, struct pstate *sregs) 1667 { 1668 uint32_t opf, tem, accex; 1669 int32_t fcc; 1670 uint32_t ldadj; 1671 1672 if (sregs->fpstate == FP_EXC_MODE) { 1673 sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR; 1674 sregs->fpstate = FP_EXC_PE; 1675 return 0; 1676 } 1677 if (sregs->fpstate == FP_EXC_PE) { 1678 sregs->fpstate = FP_EXC_MODE; 1679 return TRAP_FPEXC; 1680 } 1681 opf = (sregs->inst >> 5) & 0x1ff; 1682 1683 /* 1684 * Check if we already have an FPop in the pipe. If so, halt until it is 1685 * finished by incrementing fhold with the remaining execution time 1686 */ 1687 1688 if (ebase.simtime < sregs->ftime) { 1689 sregs->fhold = (sregs->ftime - ebase.simtime); 1690 } else { 1691 sregs->fhold = 0; 1692 1693 /* Check load dependencies. */ 1694 1695 if (ebase.simtime < sregs->ltime) { 1696 1697 /* Don't check rs1 if single operand instructions */ 1698 1699 if (((opf >> 6) == 0) || ((opf >> 6) == 3)) 1700 rs1 = 32; 1701 1702 /* Adjust for double floats */ 1703 1704 ldadj = opf & 1; 1705 if (!(((sregs->flrd - rs1) >> ldadj) && ((sregs->flrd - rs2) >> ldadj))) 1706 sregs->fhold++; 1707 } 1708 } 1709 1710 sregs->finst++; 1711 1712 sregs->frs1 = rs1; /* Store src and dst for dependecy check */ 1713 sregs->frs2 = rs2; 1714 sregs->frd = rd; 1715 1716 sregs->ftime = ebase.simtime + sregs->hold + sregs->fhold; 1717 1718 /* SPARC is big-endian - swap double floats if host is little-endian */ 1719 /* This is ugly - I know ... */ 1720 1721 /* FIXME: should use (HOST_BYTE_ORDER == CURRENT_TARGET_BYTE_ORDER) 1722 but what about machines where float values are different endianness 1723 from integer values? */ 1724 1725 #ifdef HOST_LITTLE_ENDIAN 1726 rs1 &= 0x1f; 1727 switch (opf) { 1728 case FADDd: 1729 case FDIVd: 1730 case FMULd: 1731 case FSQRTd: 1732 case FSUBd: 1733 case FCMPd: 1734 case FCMPEd: 1735 case FdTOi: 1736 case FdTOs: 1737 sregs->fdp[rs1 | 1] = sregs->fs[rs1 & ~1]; 1738 sregs->fdp[rs1 & ~1] = sregs->fs[rs1 | 1]; 1739 sregs->fdp[rs2 | 1] = sregs->fs[rs2 & ~1]; 1740 sregs->fdp[rs2 & ~1] = sregs->fs[rs2 | 1]; 1741 default: 1742 break; 1743 } 1744 #endif 1745 1746 clear_accex(); 1747 1748 switch (opf) { 1749 case FABSs: 1750 sregs->fs[rd] = fabs(sregs->fs[rs2]); 1751 sregs->ftime += T_FABSs; 1752 sregs->frs1 = 32; /* rs1 ignored */ 1753 break; 1754 case FADDs: 1755 sregs->fs[rd] = sregs->fs[rs1] + sregs->fs[rs2]; 1756 sregs->ftime += T_FADDs; 1757 break; 1758 case FADDd: 1759 sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] + sregs->fd[rs2 >> 1]; 1760 sregs->ftime += T_FADDd; 1761 break; 1762 case FCMPs: 1763 case FCMPEs: 1764 if (sregs->fs[rs1] == sregs->fs[rs2]) 1765 fcc = 3; 1766 else if (sregs->fs[rs1] < sregs->fs[rs2]) 1767 fcc = 2; 1768 else if (sregs->fs[rs1] > sregs->fs[rs2]) 1769 fcc = 1; 1770 else 1771 fcc = 0; 1772 sregs->fsr |= 0x0C00; 1773 sregs->fsr &= ~(fcc << 10); 1774 sregs->ftime += T_FCMPs; 1775 sregs->frd = 32; /* rd ignored */ 1776 if ((fcc == 0) && (opf == FCMPEs)) { 1777 sregs->fpstate = FP_EXC_PE; 1778 sregs->fsr = (sregs->fsr & ~0x1C000) | (1 << 14); 1779 } 1780 break; 1781 case FCMPd: 1782 case FCMPEd: 1783 if (sregs->fd[rs1 >> 1] == sregs->fd[rs2 >> 1]) 1784 fcc = 3; 1785 else if (sregs->fd[rs1 >> 1] < sregs->fd[rs2 >> 1]) 1786 fcc = 2; 1787 else if (sregs->fd[rs1 >> 1] > sregs->fd[rs2 >> 1]) 1788 fcc = 1; 1789 else 1790 fcc = 0; 1791 sregs->fsr |= 0x0C00; 1792 sregs->fsr &= ~(fcc << 10); 1793 sregs->ftime += T_FCMPd; 1794 sregs->frd = 32; /* rd ignored */ 1795 if ((fcc == 0) && (opf == FCMPEd)) { 1796 sregs->fpstate = FP_EXC_PE; 1797 sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE; 1798 } 1799 break; 1800 case FDIVs: 1801 sregs->fs[rd] = sregs->fs[rs1] / sregs->fs[rs2]; 1802 sregs->ftime += T_FDIVs; 1803 break; 1804 case FDIVd: 1805 sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] / sregs->fd[rs2 >> 1]; 1806 sregs->ftime += T_FDIVd; 1807 break; 1808 case FMOVs: 1809 sregs->fs[rd] = sregs->fs[rs2]; 1810 sregs->ftime += T_FMOVs; 1811 sregs->frs1 = 32; /* rs1 ignored */ 1812 break; 1813 case FMULs: 1814 sregs->fs[rd] = sregs->fs[rs1] * sregs->fs[rs2]; 1815 sregs->ftime += T_FMULs; 1816 break; 1817 case FMULd: 1818 sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] * sregs->fd[rs2 >> 1]; 1819 sregs->ftime += T_FMULd; 1820 break; 1821 case FNEGs: 1822 sregs->fs[rd] = -sregs->fs[rs2]; 1823 sregs->ftime += T_FNEGs; 1824 sregs->frs1 = 32; /* rs1 ignored */ 1825 break; 1826 case FSQRTs: 1827 if (sregs->fs[rs2] < 0.0) { 1828 sregs->fpstate = FP_EXC_PE; 1829 sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE; 1830 sregs->fsr = (sregs->fsr & 0x1f) | 0x10; 1831 break; 1832 } 1833 sregs->fs[rd] = sqrt(sregs->fs[rs2]); 1834 sregs->ftime += T_FSQRTs; 1835 sregs->frs1 = 32; /* rs1 ignored */ 1836 break; 1837 case FSQRTd: 1838 if (sregs->fd[rs2 >> 1] < 0.0) { 1839 sregs->fpstate = FP_EXC_PE; 1840 sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE; 1841 sregs->fsr = (sregs->fsr & 0x1f) | 0x10; 1842 break; 1843 } 1844 sregs->fd[rd >> 1] = sqrt(sregs->fd[rs2 >> 1]); 1845 sregs->ftime += T_FSQRTd; 1846 sregs->frs1 = 32; /* rs1 ignored */ 1847 break; 1848 case FSUBs: 1849 sregs->fs[rd] = sregs->fs[rs1] - sregs->fs[rs2]; 1850 sregs->ftime += T_FSUBs; 1851 break; 1852 case FSUBd: 1853 sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] - sregs->fd[rs2 >> 1]; 1854 sregs->ftime += T_FSUBd; 1855 break; 1856 case FdTOi: 1857 sregs->fsi[rd] = (int) sregs->fd[rs2 >> 1]; 1858 sregs->ftime += T_FdTOi; 1859 sregs->frs1 = 32; /* rs1 ignored */ 1860 break; 1861 case FdTOs: 1862 sregs->fs[rd] = (float32) sregs->fd[rs2 >> 1]; 1863 sregs->ftime += T_FdTOs; 1864 sregs->frs1 = 32; /* rs1 ignored */ 1865 break; 1866 case FiTOs: 1867 sregs->fs[rd] = (float32) sregs->fsi[rs2]; 1868 sregs->ftime += T_FiTOs; 1869 sregs->frs1 = 32; /* rs1 ignored */ 1870 break; 1871 case FiTOd: 1872 sregs->fd[rd >> 1] = (float64) sregs->fsi[rs2]; 1873 sregs->ftime += T_FiTOd; 1874 sregs->frs1 = 32; /* rs1 ignored */ 1875 break; 1876 case FsTOi: 1877 sregs->fsi[rd] = (int) sregs->fs[rs2]; 1878 sregs->ftime += T_FsTOi; 1879 sregs->frs1 = 32; /* rs1 ignored */ 1880 break; 1881 case FsTOd: 1882 sregs->fd[rd >> 1] = sregs->fs[rs2]; 1883 sregs->ftime += T_FsTOd; 1884 sregs->frs1 = 32; /* rs1 ignored */ 1885 break; 1886 1887 default: 1888 sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_UNIMP; 1889 sregs->fpstate = FP_EXC_PE; 1890 } 1891 1892 #ifdef ERRINJ 1893 if (errftt) { 1894 sregs->fsr = (sregs->fsr & ~FSR_TT) | (errftt << 14); 1895 sregs->fpstate = FP_EXC_PE; 1896 if (sis_verbose) printf("Inserted fpu error %X\n",errftt); 1897 errftt = 0; 1898 } 1899 #endif 1900 1901 accex = get_accex(); 1902 1903 #ifdef HOST_LITTLE_ENDIAN 1904 switch (opf) { 1905 case FADDd: 1906 case FDIVd: 1907 case FMULd: 1908 case FSQRTd: 1909 case FSUBd: 1910 case FiTOd: 1911 case FsTOd: 1912 sregs->fs[rd & ~1] = sregs->fdp[rd | 1]; 1913 sregs->fs[rd | 1] = sregs->fdp[rd & ~1]; 1914 default: 1915 break; 1916 } 1917 #endif 1918 if (sregs->fpstate == FP_EXC_PE) { 1919 sregs->fpq[0] = sregs->pc; 1920 sregs->fpq[1] = sregs->inst; 1921 sregs->fsr |= FSR_QNE; 1922 } else { 1923 tem = (sregs->fsr >> 23) & 0x1f; 1924 if (tem & accex) { 1925 sregs->fpstate = FP_EXC_PE; 1926 sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE; 1927 sregs->fsr = ((sregs->fsr & ~0x1f) | accex); 1928 } else { 1929 sregs->fsr = ((((sregs->fsr >> 5) | accex) << 5) | accex); 1930 } 1931 if (sregs->fpstate == FP_EXC_PE) { 1932 sregs->fpq[0] = sregs->pc; 1933 sregs->fpq[1] = sregs->inst; 1934 sregs->fsr |= FSR_QNE; 1935 } 1936 } 1937 clear_accex(); 1938 1939 return 0; 1940 1941 1942 } 1943 1944 static int 1945 chk_asi(struct pstate *sregs, uint32_t *asi, uint32_t op3) 1946 { 1947 if (!(sregs->psr & PSR_S)) { 1948 sregs->trap = TRAP_PRIVI; 1949 return 0; 1950 } else if (sregs->inst & INST_I) { 1951 sregs->trap = TRAP_UNIMP; 1952 return 0; 1953 } else 1954 *asi = (sregs->inst >> 5) & 0x0ff; 1955 return 1; 1956 } 1957 1958 int 1959 execute_trap(struct pstate *sregs) 1960 { 1961 int32_t cwp; 1962 1963 if (sregs->trap == 256) { 1964 sregs->pc = 0; 1965 sregs->npc = 4; 1966 sregs->trap = 0; 1967 } else if (sregs->trap == 257) { 1968 return ERROR; 1969 } else { 1970 1971 if ((sregs->psr & PSR_ET) == 0) 1972 return ERROR; 1973 1974 sregs->tbr = (sregs->tbr & 0xfffff000) | (sregs->trap << 4); 1975 sregs->trap = 0; 1976 sregs->psr &= ~PSR_ET; 1977 sregs->psr |= ((sregs->psr & PSR_S) >> 1); 1978 sregs->annul = 0; 1979 sregs->psr = (((sregs->psr & PSR_CWP) - 1) & 0x7) | (sregs->psr & ~PSR_CWP); 1980 cwp = ((sregs->psr & PSR_CWP) << 4); 1981 sregs->r[(cwp + 17) & 0x7f] = sregs->pc; 1982 sregs->r[(cwp + 18) & 0x7f] = sregs->npc; 1983 sregs->psr |= PSR_S; 1984 sregs->pc = sregs->tbr; 1985 sregs->npc = sregs->tbr + 4; 1986 1987 if ( 0 != (1 & sregs->asr17) ) { 1988 /* single vector trapping! */ 1989 sregs->pc = sregs->tbr & 0xfffff000; 1990 sregs->npc = sregs->pc + 4; 1991 } 1992 1993 /* Increase simulator time */ 1994 sregs->icnt = TRAP_C; 1995 1996 } 1997 1998 1999 return 0; 2000 2001 } 2002 2003 extern struct irqcell irqarr[16]; 2004 2005 int 2006 check_interrupts(struct pstate *sregs) 2007 { 2008 #ifdef ERRINJ 2009 if (errtt) { 2010 sregs->trap = errtt; 2011 if (sis_verbose) printf("Inserted error trap 0x%02X\n",errtt); 2012 errtt = 0; 2013 } 2014 #endif 2015 2016 if ((ext_irl) && (sregs->psr & PSR_ET) && 2017 ((ext_irl == 15) || (ext_irl > (int) ((sregs->psr & PSR_PIL) >> 8)))) { 2018 if (sregs->trap == 0) { 2019 sregs->trap = 16 + ext_irl; 2020 irqarr[ext_irl & 0x0f].callback(irqarr[ext_irl & 0x0f].arg); 2021 return 1; 2022 } 2023 } 2024 return 0; 2025 } 2026 2027 void 2028 init_regs(struct pstate *sregs) 2029 { 2030 sregs->pc = 0; 2031 sregs->npc = 4; 2032 sregs->trap = 0; 2033 sregs->psr &= 0x00f03fdf; 2034 sregs->psr |= 0x11000080; /* Set supervisor bit */ 2035 sregs->breakpoint = 0; 2036 sregs->annul = 0; 2037 sregs->fpstate = FP_EXE_MODE; 2038 sregs->fpqn = 0; 2039 sregs->ftime = 0; 2040 sregs->ltime = 0; 2041 sregs->err_mode = 0; 2042 ext_irl = 0; 2043 sregs->g[0] = 0; 2044 #ifdef HOST_LITTLE_ENDIAN 2045 sregs->fdp = (float32 *) sregs->fd; 2046 sregs->fsi = (int32_t *) sregs->fs; 2047 #else 2048 sregs->fs = (float32 *) sregs->fd; 2049 sregs->fsi = (int32_t *) sregs->fd; 2050 #endif 2051 sregs->fsr = 0; 2052 sregs->fpu_pres = !nfp; 2053 set_fsr(sregs->fsr); 2054 sregs->bphit = 0; 2055 sregs->ildreg = 0; 2056 sregs->ildtime = 0; 2057 2058 sregs->y = 0; 2059 sregs->asr17 = 0; 2060 2061 sregs->rett_err = 0; 2062 sregs->jmpltime = 0; 2063 } 2064