1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* common code with bug fixes from original version in trap.c */ 29 30 #include <sys/param.h> 31 #include <sys/types.h> 32 #include <sys/systm.h> 33 #include <sys/archsystm.h> 34 #include <sys/vmsystm.h> 35 #include <sys/fpu/fpusystm.h> 36 #include <sys/fpu/fpu_simulator.h> 37 #include <sys/inline.h> 38 #include <sys/debug.h> 39 #include <sys/privregs.h> 40 #include <sys/machpcb.h> 41 #include <sys/simulate.h> 42 #include <sys/proc.h> 43 #include <sys/cmn_err.h> 44 #include <sys/stack.h> 45 #include <sys/watchpoint.h> 46 #include <sys/trap.h> 47 #include <sys/machtrap.h> 48 #include <sys/mman.h> 49 #include <sys/asi.h> 50 #include <sys/copyops.h> 51 #include <vm/as.h> 52 #include <vm/page.h> 53 #include <sys/model.h> 54 #include <vm/seg_vn.h> 55 #include <sys/byteorder.h> 56 57 #define IS_IBIT_SET(x) (x & 0x2000) 58 #define IS_VIS1(op, op3)(op == 2 && op3 == 0x36) 59 #define IS_FLOAT_QUAD_OP(op, op3)(op == 2 && (op3 == 0x34 || \ 60 op3 == 0x35)) 61 #define IS_PARTIAL_OR_SHORT_FLOAT_LD_ST(op, op3, asi) \ 62 (op == 3 && (op3 == IOP_V8_LDDFA || \ 63 op3 == IOP_V8_STDFA) && asi > ASI_SNFL) 64 65 static int aligndebug = 0; 66 67 /* 68 * For the sake of those who must be compatible with unaligned 69 * architectures, users can link their programs to use a 70 * corrective trap handler that will fix unaligned references 71 * a special trap #6 (T_FIX_ALIGN) enables this 'feature'. 72 * Returns 1 for success, 0 for failure. 73 */ 74 75 int 76 do_unaligned(struct regs *rp, caddr_t *badaddr) 77 { 78 uint_t inst, op3, asi = 0; 79 uint_t rd, rs1, rs2; 80 int sz, nf = 0, ltlend = 0; 81 int floatflg; 82 int fsrflg; 83 int immflg; 84 int lddstdflg; 85 caddr_t addr; 86 uint64_t val; 87 union { 88 uint64_t l[2]; 89 uint32_t i[4]; 90 uint16_t s[8]; 91 uint8_t c[16]; 92 } data; 93 94 ASSERT(USERMODE(rp->r_tstate)); 95 inst = fetch_user_instr((caddr_t)rp->r_pc); 96 97 op3 = (inst >> 19) & 0x3f; 98 rd = (inst >> 25) & 0x1f; 99 rs1 = (inst >> 14) & 0x1f; 100 rs2 = inst & 0x1f; 101 floatflg = (inst >> 24) & 1; 102 immflg = (inst >> 13) & 1; 103 lddstdflg = fsrflg = 0; 104 105 /* if not load or store do nothing */ 106 if ((inst >> 30) != 3) 107 return (0); 108 109 /* if ldstub or swap, do nothing */ 110 if ((inst & 0xc1680000) == 0xc0680000) 111 return (0); 112 113 /* if cas/casx, do nothing */ 114 if ((inst & 0xc1e00000) == 0xc1e00000) 115 return (0); 116 117 if (floatflg) { 118 switch ((inst >> 19) & 3) { /* map size bits to a number */ 119 case 0: sz = 4; 120 break; /* ldf{a}/stf{a} */ 121 case 1: fsrflg = 1; 122 if (rd == 0) 123 sz = 4; /* ldfsr/stfsr */ 124 else if (rd == 1) 125 sz = 8; /* ldxfsr/stxfsr */ 126 else 127 return (SIMU_ILLEGAL); 128 break; 129 case 2: sz = 16; 130 break; /* ldqf{a}/stqf{a} */ 131 case 3: sz = 8; 132 break; /* lddf{a}/stdf{a} */ 133 } 134 /* 135 * Fix to access extra double register encoding plus 136 * compensate to access the correct fpu_dreg. 137 */ 138 if ((sz > 4) && (fsrflg == 0)) { 139 if ((rd & 1) == 1) 140 rd = (rd & 0x1e) | 0x20; 141 rd = rd >> 1; 142 if ((sz == 16) && ((rd & 0x1) != 0)) 143 return (SIMU_ILLEGAL); 144 } 145 } else { 146 int sz_bits = (inst >> 19) & 0xf; 147 switch (sz_bits) { /* map size bits to a number */ 148 case 0: /* lduw{a} */ 149 case 4: /* stw{a} */ 150 case 8: /* ldsw{a} */ 151 case 0xf: /* swap */ 152 sz = 4; break; 153 case 1: /* ldub{a} */ 154 case 5: /* stb{a} */ 155 case 9: /* ldsb{a} */ 156 case 0xd: /* ldstub */ 157 sz = 1; break; 158 case 2: /* lduh{a} */ 159 case 6: /* sth{a} */ 160 case 0xa: /* ldsh{a} */ 161 sz = 2; break; 162 case 3: /* ldd{a} */ 163 case 7: /* std{a} */ 164 lddstdflg = 1; 165 sz = 8; break; 166 case 0xb: /* ldx{a} */ 167 case 0xe: /* stx{a} */ 168 sz = 8; break; 169 } 170 } 171 172 173 /* only support primary and secondary asi's */ 174 if ((op3 >> 4) & 1) { 175 if (immflg) { 176 asi = (uint_t)(rp->r_tstate >> TSTATE_ASI_SHIFT) & 177 TSTATE_ASI_MASK; 178 } else { 179 asi = (inst >> 5) & 0xff; 180 } 181 switch (asi) { 182 case ASI_P: 183 case ASI_S: 184 break; 185 case ASI_PNF: 186 case ASI_SNF: 187 nf = 1; 188 break; 189 case ASI_PL: 190 case ASI_SL: 191 ltlend = 1; 192 break; 193 case ASI_PNFL: 194 case ASI_SNFL: 195 ltlend = 1; 196 nf = 1; 197 break; 198 default: 199 return (0); 200 } 201 /* 202 * Non-faulting stores generate a data_access_exception trap, 203 * according to the Spitfire manual, which should be signaled 204 * as an illegal instruction trap, because it can't be fixed. 205 */ 206 if ((nf) && ((op3 == IOP_V8_STQFA) || (op3 == IOP_V8_STDFA))) 207 return (SIMU_ILLEGAL); 208 } 209 210 if (aligndebug) { 211 printf("unaligned access at %p, instruction: 0x%x\n", 212 (void *)rp->r_pc, inst); 213 printf("type %s", (((inst >> 21) & 1) ? "st" : "ld")); 214 if (((inst >> 21) & 1) == 0) 215 printf(" %s", (((inst >> 22) & 1) ? "signed" : "unsigned")); 216 printf(" asi 0x%x size %d immflg %d\n", asi, sz, immflg); 217 printf("rd = %d, op3 = 0x%x, rs1 = %d, rs2 = %d, imm13=0x%x\n", 218 rd, op3, rs1, rs2, (inst & 0x1fff)); 219 } 220 221 (void) flush_user_windows_to_stack(NULL); 222 if (getreg(rp, rs1, &val, badaddr)) 223 return (SIMU_FAULT); 224 addr = (caddr_t)val; /* convert to 32/64 bit address */ 225 if (aligndebug) 226 printf("addr 1 = %p\n", (void *)addr); 227 228 /* check immediate bit and use immediate field or reg (rs2) */ 229 if (immflg) { 230 int imm; 231 imm = inst & 0x1fff; /* mask out immediate field */ 232 imm <<= 19; /* sign extend it */ 233 imm >>= 19; 234 addr += imm; /* compute address */ 235 } else { 236 if (getreg(rp, rs2, &val, badaddr)) 237 return (SIMU_FAULT); 238 addr += val; 239 } 240 241 /* 242 * If this is a 32-bit program, chop the address accordingly. The 243 * intermediate uintptr_t casts prevent warnings under a certain 244 * compiler, and the temporary 32 bit storage is intended to force 245 * proper code generation and break up what would otherwise be a 246 * quadruple cast. 247 */ 248 if (curproc->p_model == DATAMODEL_ILP32) { 249 caddr32_t addr32 = (caddr32_t)(uintptr_t)addr; 250 addr = (caddr_t)(uintptr_t)addr32; 251 } 252 253 if (aligndebug) 254 printf("addr 2 = %p\n", (void *)addr); 255 256 if (addr >= curproc->p_as->a_userlimit) { 257 *badaddr = addr; 258 goto badret; 259 } 260 261 /* a single bit differentiates ld and st */ 262 if ((inst >> 21) & 1) { /* store */ 263 if (floatflg) { 264 klwp_id_t lwp = ttolwp(curthread); 265 kfpu_t *fp = lwptofpu(lwp); 266 /* Ensure fp has been enabled */ 267 if (fpu_exists) { 268 if (!(_fp_read_fprs() & FPRS_FEF)) 269 fp_enable(); 270 } else { 271 if (!fp->fpu_en) 272 fp_enable(); 273 } 274 /* if fpu_exists read fpu reg */ 275 if (fpu_exists) { 276 if (fsrflg) { 277 _fp_read_pfsr(&data.l[0]); 278 } else { 279 if (sz == 4) { 280 data.i[0] = 0; 281 _fp_read_pfreg( 282 (unsigned *)&data.i[1], rd); 283 } 284 if (sz >= 8) 285 _fp_read_pdreg( 286 &data.l[0], rd); 287 if (sz == 16) 288 _fp_read_pdreg( 289 &data.l[1], rd+1); 290 } 291 } else { 292 if (fsrflg) { 293 /* Clear reserved bits, set version=7 */ 294 fp->fpu_fsr &= ~0x30301000; 295 fp->fpu_fsr |= 0xE0000; 296 data.l[0] = fp->fpu_fsr; 297 } else { 298 if (sz == 4) { 299 data.i[0] = 0; 300 data.i[1] = 301 (unsigned)fp->fpu_fr.fpu_regs[rd]; 302 } 303 if (sz >= 8) 304 data.l[0] = 305 fp->fpu_fr.fpu_dregs[rd]; 306 if (sz == 16) 307 data.l[1] = 308 fp->fpu_fr.fpu_dregs[rd+1]; 309 } 310 } 311 } else { 312 if (lddstdflg) { /* combine the data */ 313 if (getreg(rp, rd, &data.l[0], badaddr)) 314 return (SIMU_FAULT); 315 if (getreg(rp, rd+1, &data.l[1], badaddr)) 316 return (SIMU_FAULT); 317 if (ltlend) { 318 /* 319 * For STD, each 32-bit word is byte- 320 * swapped individually. For 321 * simplicity we don't want to do that 322 * below, so we swap the words now to 323 * get the desired result in the end. 324 */ 325 data.i[0] = data.i[3]; 326 } else { 327 data.i[0] = data.i[1]; 328 data.i[1] = data.i[3]; 329 } 330 } else { 331 if (getreg(rp, rd, &data.l[0], badaddr)) 332 return (SIMU_FAULT); 333 } 334 } 335 336 if (aligndebug) { 337 if (sz == 16) { 338 printf("data %x %x %x %x\n", 339 data.i[0], data.i[1], data.i[2], data.c[3]); 340 } else { 341 printf("data %x %x %x %x %x %x %x %x\n", 342 data.c[0], data.c[1], data.c[2], data.c[3], 343 data.c[4], data.c[5], data.c[6], data.c[7]); 344 } 345 } 346 347 if (ltlend) { 348 if (sz == 1) { 349 if (xcopyout_little(&data.c[7], addr, 350 (size_t)sz) != 0) 351 goto badret; 352 } else if (sz == 2) { 353 if (xcopyout_little(&data.s[3], addr, 354 (size_t)sz) != 0) 355 goto badret; 356 } else if (sz == 4) { 357 if (xcopyout_little(&data.i[1], addr, 358 (size_t)sz) != 0) 359 goto badret; 360 } else { 361 if (xcopyout_little(&data.l[0], addr, 362 (size_t)sz) != 0) 363 goto badret; 364 } 365 } else { 366 if (sz == 1) { 367 if (copyout(&data.c[7], addr, (size_t)sz) == -1) 368 goto badret; 369 } else if (sz == 2) { 370 if (copyout(&data.s[3], addr, (size_t)sz) == -1) 371 goto badret; 372 } else if (sz == 4) { 373 if (copyout(&data.i[1], addr, (size_t)sz) == -1) 374 goto badret; 375 } else { 376 if (copyout(&data.l[0], addr, (size_t)sz) == -1) 377 goto badret; 378 } 379 } 380 } else { /* load */ 381 if (sz == 1) { 382 if (ltlend) { 383 if (xcopyin_little(addr, &data.c[7], 384 (size_t)sz) != 0) { 385 if (nf) 386 data.c[7] = 0; 387 else 388 goto badret; 389 } 390 } else { 391 if (copyin(addr, &data.c[7], 392 (size_t)sz) == -1) { 393 if (nf) 394 data.c[7] = 0; 395 else 396 goto badret; 397 } 398 } 399 /* if signed and the sign bit is set extend it */ 400 if (((inst >> 22) & 1) && ((data.c[7] >> 7) & 1)) { 401 data.i[0] = (uint_t)-1; /* extend sign bit */ 402 data.s[2] = (ushort_t)-1; 403 data.c[6] = (uchar_t)-1; 404 } else { 405 data.i[0] = 0; /* clear upper 32+24 bits */ 406 data.s[2] = 0; 407 data.c[6] = 0; 408 } 409 } else if (sz == 2) { 410 if (ltlend) { 411 if (xcopyin_little(addr, &data.s[3], 412 (size_t)sz) != 0) { 413 if (nf) 414 data.s[3] = 0; 415 else 416 goto badret; 417 } 418 } else { 419 if (copyin(addr, &data.s[3], 420 (size_t)sz) == -1) { 421 if (nf) 422 data.s[3] = 0; 423 else 424 goto badret; 425 } 426 } 427 /* if signed and the sign bit is set extend it */ 428 if (((inst >> 22) & 1) && ((data.s[3] >> 15) & 1)) { 429 data.i[0] = (uint_t)-1; /* extend sign bit */ 430 data.s[2] = (ushort_t)-1; 431 } else { 432 data.i[0] = 0; /* clear upper 32+16 bits */ 433 data.s[2] = 0; 434 } 435 } else if (sz == 4) { 436 if (ltlend) { 437 if (xcopyin_little(addr, &data.i[1], 438 (size_t)sz) != 0) { 439 if (!nf) 440 goto badret; 441 data.i[1] = 0; 442 } 443 } else { 444 if (copyin(addr, &data.i[1], 445 (size_t)sz) == -1) { 446 if (!nf) 447 goto badret; 448 data.i[1] = 0; 449 } 450 } 451 /* if signed and the sign bit is set extend it */ 452 if (((inst >> 22) & 1) && ((data.i[1] >> 31) & 1)) { 453 data.i[0] = (uint_t)-1; /* extend sign bit */ 454 } else { 455 data.i[0] = 0; /* clear upper 32 bits */ 456 } 457 } else { 458 if (ltlend) { 459 if (xcopyin_little(addr, &data.l[0], 460 (size_t)sz) != 0) { 461 if (!nf) 462 goto badret; 463 data.l[0] = 0; 464 } 465 } else { 466 if (copyin(addr, &data.l[0], 467 (size_t)sz) == -1) { 468 if (!nf) 469 goto badret; 470 data.l[0] = 0; 471 } 472 } 473 } 474 475 if (aligndebug) { 476 if (sz == 16) { 477 printf("data %x %x %x %x\n", 478 data.i[0], data.i[1], data.i[2], data.c[3]); 479 } else { 480 printf("data %x %x %x %x %x %x %x %x\n", 481 data.c[0], data.c[1], data.c[2], data.c[3], 482 data.c[4], data.c[5], data.c[6], data.c[7]); 483 } 484 } 485 486 if (floatflg) { /* if fpu_exists write fpu reg */ 487 klwp_id_t lwp = ttolwp(curthread); 488 kfpu_t *fp = lwptofpu(lwp); 489 /* Ensure fp has been enabled */ 490 if (fpu_exists) { 491 if (!(_fp_read_fprs() & FPRS_FEF)) 492 fp_enable(); 493 } else { 494 if (!fp->fpu_en) 495 fp_enable(); 496 } 497 /* if fpu_exists read fpu reg */ 498 if (fpu_exists) { 499 if (fsrflg) { 500 _fp_write_pfsr(&data.l[0]); 501 } else { 502 if (sz == 4) 503 _fp_write_pfreg( 504 (unsigned *)&data.i[1], rd); 505 if (sz >= 8) 506 _fp_write_pdreg( 507 &data.l[0], rd); 508 if (sz == 16) 509 _fp_write_pdreg( 510 &data.l[1], rd+1); 511 } 512 } else { 513 if (fsrflg) { 514 fp->fpu_fsr = data.l[0]; 515 } else { 516 if (sz == 4) 517 fp->fpu_fr.fpu_regs[rd] = 518 (unsigned)data.i[1]; 519 if (sz >= 8) 520 fp->fpu_fr.fpu_dregs[rd] = 521 data.l[0]; 522 if (sz == 16) 523 fp->fpu_fr.fpu_dregs[rd+1] = 524 data.l[1]; 525 } 526 } 527 } else { 528 if (lddstdflg) { /* split the data */ 529 if (ltlend) { 530 /* 531 * For LDD, each 32-bit word is byte- 532 * swapped individually. We didn't 533 * do that above, but this will give 534 * us the desired result. 535 */ 536 data.i[3] = data.i[0]; 537 } else { 538 data.i[3] = data.i[1]; 539 data.i[1] = data.i[0]; 540 } 541 data.i[0] = 0; 542 data.i[2] = 0; 543 if (putreg(&data.l[0], rp, rd, badaddr) == -1) 544 goto badret; 545 if (putreg(&data.l[1], rp, rd+1, badaddr) == -1) 546 goto badret; 547 } else { 548 if (putreg(&data.l[0], rp, rd, badaddr) == -1) 549 goto badret; 550 } 551 } 552 } 553 return (SIMU_SUCCESS); 554 badret: 555 return (SIMU_FAULT); 556 } 557 558 559 int 560 simulate_lddstd(struct regs *rp, caddr_t *badaddr) 561 { 562 uint_t inst, op3, asi = 0; 563 uint_t rd, rs1, rs2; 564 int nf = 0, ltlend = 0, usermode; 565 int immflg; 566 uint64_t reven; 567 uint64_t rodd; 568 caddr_t addr; 569 uint64_t val; 570 uint64_t data; 571 572 usermode = USERMODE(rp->r_tstate); 573 574 if (usermode) 575 inst = fetch_user_instr((caddr_t)rp->r_pc); 576 else 577 inst = *(uint_t *)rp->r_pc; 578 579 op3 = (inst >> 19) & 0x3f; 580 rd = (inst >> 25) & 0x1f; 581 rs1 = (inst >> 14) & 0x1f; 582 rs2 = inst & 0x1f; 583 immflg = (inst >> 13) & 1; 584 585 if (USERMODE(rp->r_tstate)) 586 (void) flush_user_windows_to_stack(NULL); 587 else 588 flush_windows(); 589 590 if ((op3 >> 4) & 1) { /* is this LDDA/STDA? */ 591 if (immflg) { 592 asi = (uint_t)(rp->r_tstate >> TSTATE_ASI_SHIFT) & 593 TSTATE_ASI_MASK; 594 } else { 595 asi = (inst >> 5) & 0xff; 596 } 597 switch (asi) { 598 case ASI_P: 599 case ASI_S: 600 break; 601 case ASI_PNF: 602 case ASI_SNF: 603 nf = 1; 604 break; 605 case ASI_PL: 606 case ASI_SL: 607 ltlend = 1; 608 break; 609 case ASI_PNFL: 610 case ASI_SNFL: 611 ltlend = 1; 612 nf = 1; 613 break; 614 case ASI_AIUP: 615 case ASI_AIUS: 616 usermode = 1; 617 break; 618 case ASI_AIUPL: 619 case ASI_AIUSL: 620 usermode = 1; 621 ltlend = 1; 622 break; 623 default: 624 return (SIMU_ILLEGAL); 625 } 626 } 627 628 if (getreg(rp, rs1, &val, badaddr)) 629 return (SIMU_FAULT); 630 addr = (caddr_t)val; /* convert to 32/64 bit address */ 631 632 /* check immediate bit and use immediate field or reg (rs2) */ 633 if (immflg) { 634 int imm; 635 imm = inst & 0x1fff; /* mask out immediate field */ 636 imm <<= 19; /* sign extend it */ 637 imm >>= 19; 638 addr += imm; /* compute address */ 639 } else { 640 if (getreg(rp, rs2, &val, badaddr)) 641 return (SIMU_FAULT); 642 addr += val; 643 } 644 645 /* 646 * T_UNIMP_LDD and T_UNIMP_STD are higher priority than 647 * T_ALIGNMENT. So we have to make sure that the address is 648 * kosher before trying to use it, because the hardware hasn't 649 * checked it for us yet. 650 */ 651 if (((uintptr_t)addr & 0x7) != 0) { 652 if (curproc->p_fixalignment) 653 return (do_unaligned(rp, badaddr)); 654 else 655 return (SIMU_UNALIGN); 656 } 657 658 /* 659 * If this is a 32-bit program, chop the address accordingly. The 660 * intermediate uintptr_t casts prevent warnings under a certain 661 * compiler, and the temporary 32 bit storage is intended to force 662 * proper code generation and break up what would otherwise be a 663 * quadruple cast. 664 */ 665 if (curproc->p_model == DATAMODEL_ILP32 && usermode) { 666 caddr32_t addr32 = (caddr32_t)(uintptr_t)addr; 667 addr = (caddr_t)(uintptr_t)addr32; 668 } 669 670 if ((inst >> 21) & 1) { /* store */ 671 if (getreg(rp, rd, &reven, badaddr)) 672 return (SIMU_FAULT); 673 if (getreg(rp, rd+1, &rodd, badaddr)) 674 return (SIMU_FAULT); 675 if (ltlend) { 676 reven = BSWAP_32(reven); 677 rodd = BSWAP_32(rodd); 678 } 679 data = (reven << 32) | rodd; 680 if (usermode) { 681 if (suword64_nowatch(addr, data) == -1) 682 return (SIMU_FAULT); 683 } else { 684 *(uint64_t *)addr = data; 685 } 686 } else { /* load */ 687 if (usermode) { 688 if (fuword64_nowatch(addr, &data)) { 689 if (nf) 690 data = 0; 691 else 692 return (SIMU_FAULT); 693 } 694 } else 695 data = *(uint64_t *)addr; 696 697 reven = (data >> 32); 698 rodd = (uint64_t)(uint32_t)data; 699 if (ltlend) { 700 reven = BSWAP_32(reven); 701 rodd = BSWAP_32(rodd); 702 } 703 704 if (putreg(&reven, rp, rd, badaddr) == -1) 705 return (SIMU_FAULT); 706 if (putreg(&rodd, rp, rd+1, badaddr) == -1) 707 return (SIMU_FAULT); 708 } 709 return (SIMU_SUCCESS); 710 } 711 712 713 /* 714 * simulate popc 715 */ 716 static int 717 simulate_popc(struct regs *rp, caddr_t *badaddr, uint_t inst) 718 { 719 uint_t rd, rs2, rs1; 720 uint_t immflg; 721 uint64_t val, cnt = 0; 722 723 rd = (inst >> 25) & 0x1f; 724 rs1 = (inst >> 14) & 0x1f; 725 rs2 = inst & 0x1f; 726 immflg = (inst >> 13) & 1; 727 728 if (rs1 > 0) 729 return (SIMU_ILLEGAL); 730 731 (void) flush_user_windows_to_stack(NULL); 732 733 /* check immediate bit and use immediate field or reg (rs2) */ 734 if (immflg) { 735 int64_t imm; 736 imm = inst & 0x1fff; /* mask out immediate field */ 737 imm <<= 51; /* sign extend it */ 738 imm >>= 51; 739 if (imm != 0) { 740 for (cnt = 0; imm != 0; imm &= imm-1) 741 cnt++; 742 } 743 } else { 744 if (getreg(rp, rs2, &val, badaddr)) 745 return (SIMU_FAULT); 746 if (val != 0) { 747 for (cnt = 0; val != 0; val &= val-1) 748 cnt++; 749 } 750 } 751 752 if (putreg(&cnt, rp, rd, badaddr) == -1) 753 return (SIMU_FAULT); 754 755 return (SIMU_SUCCESS); 756 } 757 758 /* 759 * simulate unimplemented instructions (popc, ldqf{a}, stqf{a}) 760 */ 761 int 762 simulate_unimp(struct regs *rp, caddr_t *badaddr) 763 { 764 uint_t inst, optype, op3, asi; 765 uint_t rs1, rd; 766 uint_t ignor, i; 767 machpcb_t *mpcb = lwptompcb(ttolwp(curthread)); 768 int nomatch = 0; 769 caddr_t addr = (caddr_t)rp->r_pc; 770 struct as *as; 771 caddr_t ka; 772 pfn_t pfnum; 773 page_t *pp; 774 proc_t *p = ttoproc(curthread); 775 struct seg *mapseg; 776 struct segvn_data *svd; 777 778 ASSERT(USERMODE(rp->r_tstate)); 779 inst = fetch_user_instr(addr); 780 if (inst == (uint_t)-1) { 781 mpcb->mpcb_illexcaddr = addr; 782 mpcb->mpcb_illexcinsn = (uint32_t)-1; 783 return (SIMU_ILLEGAL); 784 } 785 786 /* 787 * When fixing dirty v8 instructions there's a race if two processors 788 * are executing the dirty executable at the same time. If one 789 * cleans the instruction as the other is executing it the second 790 * processor will see a clean instruction when it comes through this 791 * code and will return SIMU_ILLEGAL. To work around the race 792 * this code will keep track of the last illegal instruction seen 793 * by each lwp and will only take action if the illegal instruction 794 * is repeatable. 795 */ 796 if (addr != mpcb->mpcb_illexcaddr || 797 inst != mpcb->mpcb_illexcinsn) 798 nomatch = 1; 799 mpcb->mpcb_illexcaddr = addr; 800 mpcb->mpcb_illexcinsn = inst; 801 802 /* instruction fields */ 803 i = (inst >> 13) & 0x1; 804 rd = (inst >> 25) & 0x1f; 805 optype = (inst >> 30) & 0x3; 806 op3 = (inst >> 19) & 0x3f; 807 ignor = (inst >> 5) & 0xff; 808 if (IS_IBIT_SET(inst)) { 809 asi = (uint32_t)((rp->r_tstate >> TSTATE_ASI_SHIFT) & 810 TSTATE_ASI_MASK); 811 } else { 812 asi = ignor; 813 } 814 815 if (IS_VIS1(optype, op3) || 816 IS_PARTIAL_OR_SHORT_FLOAT_LD_ST(optype, op3, asi) || 817 IS_FLOAT_QUAD_OP(optype, op3)) { 818 klwp_t *lwp = ttolwp(curthread); 819 kfpu_t *fp = lwptofpu(lwp); 820 if (fpu_exists) { 821 if (!(_fp_read_fprs() & FPRS_FEF)) 822 fp_enable(); 823 _fp_read_pfsr(&fp->fpu_fsr); 824 } else { 825 if (!fp->fpu_en) 826 fp_enable(); 827 } 828 fp_precise(rp); 829 return (SIMU_RETRY); 830 } 831 832 if (optype == 2 && op3 == IOP_V8_POPC) { 833 return (simulate_popc(rp, badaddr, inst)); 834 } else if (optype == 3 && op3 == IOP_V8_POPC) { 835 return (SIMU_ILLEGAL); 836 } 837 838 if (optype == OP_V8_LDSTR) { 839 if (op3 == IOP_V8_LDQF || op3 == IOP_V8_LDQFA || 840 op3 == IOP_V8_STQF || op3 == IOP_V8_STQFA) 841 return (do_unaligned(rp, badaddr)); 842 } 843 844 if (nomatch) 845 return (SIMU_RETRY); 846 847 /* 848 * The rest of the code handles v8 binaries with instructions 849 * that have dirty (non-zero) bits in reserved or 'ignored' 850 * fields; these will cause core dumps on v9 machines. 851 * 852 * We only clean dirty instructions in 32-bit programs (ie, v8) 853 * running on SPARCv9 processors. True v9 programs are forced 854 * to use the instruction set as intended. 855 */ 856 if (lwp_getdatamodel(curthread->t_lwp) != DATAMODEL_ILP32) 857 return (SIMU_ILLEGAL); 858 switch (optype) { 859 case OP_V8_BRANCH: 860 case OP_V8_CALL: 861 return (SIMU_ILLEGAL); /* these don't have ignored fields */ 862 /*NOTREACHED*/ 863 case OP_V8_ARITH: 864 switch (op3) { 865 case IOP_V8_RETT: 866 if (rd == 0 && !(i == 0 && ignor)) 867 return (SIMU_ILLEGAL); 868 if (rd) 869 inst &= ~(0x1f << 25); 870 if (i == 0 && ignor) 871 inst &= ~(0xff << 5); 872 break; 873 case IOP_V8_TCC: 874 if (i == 0 && ignor != 0) { 875 inst &= ~(0xff << 5); 876 } else if (i == 1 && (((inst >> 7) & 0x3f) != 0)) { 877 inst &= ~(0x3f << 7); 878 } else { 879 return (SIMU_ILLEGAL); 880 } 881 break; 882 case IOP_V8_JMPL: 883 case IOP_V8_RESTORE: 884 case IOP_V8_SAVE: 885 if ((op3 == IOP_V8_RETT && rd) || 886 (i == 0 && ignor)) { 887 inst &= ~(0xff << 5); 888 } else { 889 return (SIMU_ILLEGAL); 890 } 891 break; 892 case IOP_V8_FCMP: 893 if (rd == 0) 894 return (SIMU_ILLEGAL); 895 inst &= ~(0x1f << 25); 896 break; 897 case IOP_V8_RDASR: 898 rs1 = ((inst >> 14) & 0x1f); 899 if (rs1 == 1 || (rs1 >= 7 && rs1 <= 14)) { 900 /* 901 * The instruction specifies an invalid 902 * state register - better bail out than 903 * "fix" it when we're not sure what was 904 * intended. 905 */ 906 return (SIMU_ILLEGAL); 907 } 908 /* 909 * Note: this case includes the 'stbar' 910 * instruction (rs1 == 15 && i == 0). 911 */ 912 if ((ignor = (inst & 0x3fff)) != 0) 913 inst &= ~(0x3fff); 914 break; 915 case IOP_V8_SRA: 916 case IOP_V8_SRL: 917 case IOP_V8_SLL: 918 if (ignor == 0) 919 return (SIMU_ILLEGAL); 920 inst &= ~(0xff << 5); 921 break; 922 case IOP_V8_ADD: 923 case IOP_V8_AND: 924 case IOP_V8_OR: 925 case IOP_V8_XOR: 926 case IOP_V8_SUB: 927 case IOP_V8_ANDN: 928 case IOP_V8_ORN: 929 case IOP_V8_XNOR: 930 case IOP_V8_ADDC: 931 case IOP_V8_UMUL: 932 case IOP_V8_SMUL: 933 case IOP_V8_SUBC: 934 case IOP_V8_UDIV: 935 case IOP_V8_SDIV: 936 case IOP_V8_ADDcc: 937 case IOP_V8_ANDcc: 938 case IOP_V8_ORcc: 939 case IOP_V8_XORcc: 940 case IOP_V8_SUBcc: 941 case IOP_V8_ANDNcc: 942 case IOP_V8_ORNcc: 943 case IOP_V8_XNORcc: 944 case IOP_V8_ADDCcc: 945 case IOP_V8_UMULcc: 946 case IOP_V8_SMULcc: 947 case IOP_V8_SUBCcc: 948 case IOP_V8_UDIVcc: 949 case IOP_V8_SDIVcc: 950 case IOP_V8_TADDcc: 951 case IOP_V8_TSUBcc: 952 case IOP_V8_TADDccTV: 953 case IOP_V8_TSUBccTV: 954 case IOP_V8_MULScc: 955 case IOP_V8_WRASR: 956 case IOP_V8_FLUSH: 957 if (i != 0 || ignor == 0) 958 return (SIMU_ILLEGAL); 959 inst &= ~(0xff << 5); 960 break; 961 default: 962 return (SIMU_ILLEGAL); 963 } 964 break; 965 case OP_V8_LDSTR: 966 switch (op3) { 967 case IOP_V8_STFSR: 968 case IOP_V8_LDFSR: 969 if (rd == 0 && !(i == 0 && ignor)) 970 return (SIMU_ILLEGAL); 971 if (rd) 972 inst &= ~(0x1f << 25); 973 if (i == 0 && ignor) 974 inst &= ~(0xff << 5); 975 break; 976 default: 977 if (optype == OP_V8_LDSTR && !IS_LDST_ALT(op3) && 978 i == 0 && ignor) 979 inst &= ~(0xff << 5); 980 else 981 return (SIMU_ILLEGAL); 982 break; 983 } 984 break; 985 default: 986 return (SIMU_ILLEGAL); 987 } 988 989 as = p->p_as; 990 991 AS_LOCK_ENTER(as, &as->a_lock, RW_READER); 992 mapseg = as_findseg(as, (caddr_t)rp->r_pc, 0); 993 ASSERT(mapseg != NULL); 994 svd = (struct segvn_data *)mapseg->s_data; 995 996 /* 997 * We only create COW page for MAP_PRIVATE mappings. 998 */ 999 SEGVN_LOCK_ENTER(as, &svd->lock, RW_READER); 1000 if ((svd->type & MAP_TYPE) & MAP_SHARED) { 1001 SEGVN_LOCK_EXIT(as, &svd->lock); 1002 AS_LOCK_EXIT(as, &as->a_lock); 1003 return (SIMU_ILLEGAL); 1004 } 1005 SEGVN_LOCK_EXIT(as, &svd->lock); 1006 AS_LOCK_EXIT(as, &as->a_lock); 1007 1008 /* 1009 * A "flush" instruction using the user PC's vaddr will not work 1010 * here, at least on Spitfire. Instead we create a temporary kernel 1011 * mapping to the user's text page, then modify and flush that. 1012 * Break COW by locking user page. 1013 */ 1014 if (as_fault(as->a_hat, as, (caddr_t)(rp->r_pc & PAGEMASK), PAGESIZE, 1015 F_SOFTLOCK, S_READ)) 1016 return (SIMU_FAULT); 1017 1018 AS_LOCK_ENTER(as, &as->a_lock, RW_READER); 1019 pfnum = hat_getpfnum(as->a_hat, (caddr_t)rp->r_pc); 1020 AS_LOCK_EXIT(as, &as->a_lock); 1021 if (pf_is_memory(pfnum)) { 1022 pp = page_numtopp_nolock(pfnum); 1023 ASSERT(pp == NULL || PAGE_LOCKED(pp)); 1024 } else { 1025 (void) as_fault(as->a_hat, as, (caddr_t)(rp->r_pc & PAGEMASK), 1026 PAGESIZE, F_SOFTUNLOCK, S_READ); 1027 return (SIMU_FAULT); 1028 } 1029 1030 AS_LOCK_ENTER(as, &as->a_lock, RW_READER); 1031 ka = ppmapin(pp, PROT_READ|PROT_WRITE, (caddr_t)rp->r_pc); 1032 *(uint_t *)(ka + (uintptr_t)(rp->r_pc % PAGESIZE)) = inst; 1033 doflush(ka + (uintptr_t)(rp->r_pc % PAGESIZE)); 1034 ppmapout(ka); 1035 AS_LOCK_EXIT(as, &as->a_lock); 1036 1037 (void) as_fault(as->a_hat, as, (caddr_t)(rp->r_pc & PAGEMASK), 1038 PAGESIZE, F_SOFTUNLOCK, S_READ); 1039 return (SIMU_RETRY); 1040 } 1041 1042 /* 1043 * Get the value of a register for instruction simulation 1044 * by using the regs or window structure pointers. 1045 * Return 0 for success, and -1 for failure. If there is a failure, 1046 * save the faulting address using badaddr pointer. 1047 * We have 64 bit globals and outs, and 32 or 64 bit ins and locals. 1048 * Don't truncate globals/outs for 32 bit programs, for v8+ support. 1049 */ 1050 int 1051 getreg(struct regs *rp, uint_t reg, uint64_t *val, caddr_t *badaddr) 1052 { 1053 uint64_t *rgs, *sp; 1054 int rv = 0; 1055 1056 rgs = (uint64_t *)&rp->r_ps; /* globals and outs */ 1057 sp = (uint64_t *)rp->r_sp; /* ins and locals */ 1058 if (reg == 0) { 1059 *val = 0; 1060 } else if (reg < 16) { 1061 *val = rgs[reg]; 1062 } else if (IS_V9STACK(sp)) { 1063 uint64_t *rw = (uint64_t *)((uintptr_t)sp + V9BIAS64); 1064 uint64_t *addr = (uint64_t *)&rw[reg - 16]; 1065 uint64_t res; 1066 1067 if (USERMODE(rp->r_tstate)) { 1068 if (fuword64_nowatch(addr, &res) == -1) { 1069 *badaddr = (caddr_t)addr; 1070 rv = -1; 1071 } 1072 } else { 1073 res = *addr; 1074 } 1075 *val = res; 1076 } else { 1077 caddr32_t sp32 = (caddr32_t)(uintptr_t)sp; 1078 uint32_t *rw = (uint32_t *)(uintptr_t)sp32; 1079 uint32_t *addr = (uint32_t *)&rw[reg - 16]; 1080 uint32_t res; 1081 1082 if (USERMODE(rp->r_tstate)) { 1083 if (fuword32_nowatch(addr, &res) == -1) { 1084 *badaddr = (caddr_t)addr; 1085 rv = -1; 1086 } 1087 } else { 1088 res = *addr; 1089 } 1090 *val = (uint64_t)res; 1091 } 1092 return (rv); 1093 } 1094 1095 /* 1096 * Set the value of a register after instruction simulation 1097 * by using the regs or window structure pointers. 1098 * Return 0 for succes -1 failure. 1099 * save the faulting address using badaddr pointer. 1100 * We have 64 bit globals and outs, and 32 or 64 bit ins and locals. 1101 * Don't truncate globals/outs for 32 bit programs, for v8+ support. 1102 */ 1103 int 1104 putreg(uint64_t *data, struct regs *rp, uint_t reg, caddr_t *badaddr) 1105 { 1106 uint64_t *rgs, *sp; 1107 int rv = 0; 1108 1109 rgs = (uint64_t *)&rp->r_ps; /* globals and outs */ 1110 sp = (uint64_t *)rp->r_sp; /* ins and locals */ 1111 if (reg == 0) { 1112 return (0); 1113 } else if (reg < 16) { 1114 rgs[reg] = *data; 1115 } else if (IS_V9STACK(sp)) { 1116 uint64_t *rw = (uint64_t *)((uintptr_t)sp + V9BIAS64); 1117 uint64_t *addr = (uint64_t *)&rw[reg - 16]; 1118 uint64_t res; 1119 1120 if (USERMODE(rp->r_tstate)) { 1121 struct machpcb *mpcb = lwptompcb(curthread->t_lwp); 1122 1123 res = *data; 1124 if (suword64_nowatch(addr, res) != 0) { 1125 *badaddr = (caddr_t)addr; 1126 rv = -1; 1127 } 1128 /* 1129 * We have changed a local or in register; 1130 * nuke the watchpoint return windows. 1131 */ 1132 mpcb->mpcb_rsp[0] = NULL; 1133 mpcb->mpcb_rsp[1] = NULL; 1134 } else { 1135 res = *data; 1136 *addr = res; 1137 } 1138 } else { 1139 caddr32_t sp32 = (caddr32_t)(uintptr_t)sp; 1140 uint32_t *rw = (uint32_t *)(uintptr_t)sp32; 1141 uint32_t *addr = (uint32_t *)&rw[reg - 16]; 1142 uint32_t res; 1143 1144 if (USERMODE(rp->r_tstate)) { 1145 struct machpcb *mpcb = lwptompcb(curthread->t_lwp); 1146 1147 res = (uint_t)*data; 1148 if (suword32_nowatch(addr, res) != 0) { 1149 *badaddr = (caddr_t)addr; 1150 rv = -1; 1151 } 1152 /* 1153 * We have changed a local or in register; 1154 * nuke the watchpoint return windows. 1155 */ 1156 mpcb->mpcb_rsp[0] = NULL; 1157 mpcb->mpcb_rsp[1] = NULL; 1158 1159 } else { 1160 res = (uint_t)*data; 1161 *addr = res; 1162 } 1163 } 1164 return (rv); 1165 } 1166 1167 /* 1168 * Calculate a memory reference address from instruction 1169 * operands, used to return the address of a fault, instead 1170 * of the instruction when an error occurs. This is code that is 1171 * common with most of the routines that simulate instructions. 1172 */ 1173 int 1174 calc_memaddr(struct regs *rp, caddr_t *badaddr) 1175 { 1176 uint_t inst; 1177 uint_t rd, rs1, rs2; 1178 int sz; 1179 int immflg; 1180 int floatflg; 1181 caddr_t addr; 1182 uint64_t val; 1183 1184 if (USERMODE(rp->r_tstate)) 1185 inst = fetch_user_instr((caddr_t)rp->r_pc); 1186 else 1187 inst = *(uint_t *)rp->r_pc; 1188 1189 rd = (inst >> 25) & 0x1f; 1190 rs1 = (inst >> 14) & 0x1f; 1191 rs2 = inst & 0x1f; 1192 floatflg = (inst >> 24) & 1; 1193 immflg = (inst >> 13) & 1; 1194 1195 if (floatflg) { 1196 switch ((inst >> 19) & 3) { /* map size bits to a number */ 1197 case 0: sz = 4; break; /* ldf/stf */ 1198 case 1: return (0); /* ld[x]fsr/st[x]fsr */ 1199 case 2: sz = 16; break; /* ldqf/stqf */ 1200 case 3: sz = 8; break; /* lddf/stdf */ 1201 } 1202 /* 1203 * Fix to access extra double register encoding plus 1204 * compensate to access the correct fpu_dreg. 1205 */ 1206 if (sz > 4) { 1207 if ((rd & 1) == 1) 1208 rd = (rd & 0x1e) | 0x20; 1209 rd = rd >> 1; 1210 } 1211 } else { 1212 switch ((inst >> 19) & 0xf) { /* map size bits to a number */ 1213 case 0: /* lduw */ 1214 case 4: /* stw */ 1215 case 8: /* ldsw */ 1216 case 0xf: /* swap */ 1217 sz = 4; break; 1218 case 1: /* ldub */ 1219 case 5: /* stb */ 1220 case 9: /* ldsb */ 1221 case 0xd: /* ldstub */ 1222 sz = 1; break; 1223 case 2: /* lduh */ 1224 case 6: /* sth */ 1225 case 0xa: /* ldsh */ 1226 sz = 2; break; 1227 case 3: /* ldd */ 1228 case 7: /* std */ 1229 case 0xb: /* ldx */ 1230 case 0xe: /* stx */ 1231 sz = 8; break; 1232 } 1233 } 1234 1235 if (USERMODE(rp->r_tstate)) 1236 (void) flush_user_windows_to_stack(NULL); 1237 else 1238 flush_windows(); 1239 1240 if (getreg(rp, rs1, &val, badaddr)) 1241 return (SIMU_FAULT); 1242 addr = (caddr_t)val; 1243 1244 /* check immediate bit and use immediate field or reg (rs2) */ 1245 if (immflg) { 1246 int imm; 1247 imm = inst & 0x1fff; /* mask out immediate field */ 1248 imm <<= 19; /* sign extend it */ 1249 imm >>= 19; 1250 addr += imm; /* compute address */ 1251 } else { 1252 if (getreg(rp, rs2, &val, badaddr)) 1253 return (SIMU_FAULT); 1254 addr += val; 1255 } 1256 1257 /* 1258 * If this is a 32-bit program, chop the address accordingly. The 1259 * intermediate uintptr_t casts prevent warnings under a certain 1260 * compiler, and the temporary 32 bit storage is intended to force 1261 * proper code generation and break up what would otherwise be a 1262 * quadruple cast. 1263 */ 1264 if (curproc->p_model == DATAMODEL_ILP32 && USERMODE(rp->r_tstate)) { 1265 caddr32_t addr32 = (caddr32_t)(uintptr_t)addr; 1266 addr = (caddr_t)(uintptr_t)addr32; 1267 } 1268 1269 *badaddr = addr; 1270 return ((uintptr_t)addr & (sz - 1) ? SIMU_UNALIGN : SIMU_SUCCESS); 1271 } 1272 1273 /* 1274 * Return the size of a load or store instruction (1, 2, 4, 8, 16, 64). 1275 * Also compute the precise address by instruction disassembly. 1276 * (v9 page faults only provide the page address via the hardware.) 1277 * Return 0 on failure (not a load or store instruction). 1278 */ 1279 int 1280 instr_size(struct regs *rp, caddr_t *addrp, enum seg_rw rdwr) 1281 { 1282 uint_t inst, op3, asi; 1283 uint_t rd, rs1, rs2; 1284 int sz = 0; 1285 int immflg; 1286 int floatflg; 1287 caddr_t addr; 1288 caddr_t badaddr; 1289 uint64_t val; 1290 1291 if (rdwr == S_EXEC) { 1292 *addrp = (caddr_t)rp->r_pc; 1293 return (4); 1294 } 1295 1296 /* 1297 * Fetch the instruction from user-level. 1298 * We would like to assert this: 1299 * ASSERT(USERMODE(rp->r_tstate)); 1300 * but we can't because we can reach this point from a 1301 * register window underflow/overflow and the v9 wbuf 1302 * traps call trap() with T_USER even though r_tstate 1303 * indicates a system trap, not a user trap. 1304 */ 1305 inst = fetch_user_instr((caddr_t)rp->r_pc); 1306 1307 op3 = (inst >> 19) & 0x3f; 1308 rd = (inst >> 25) & 0x1f; 1309 rs1 = (inst >> 14) & 0x1f; 1310 rs2 = inst & 0x1f; 1311 floatflg = (inst >> 24) & 1; 1312 immflg = (inst >> 13) & 1; 1313 1314 /* if not load or store do nothing. can't happen? */ 1315 if ((inst >> 30) != 3) 1316 return (0); 1317 1318 if (immflg) 1319 asi = (uint_t)((rp->r_tstate >> TSTATE_ASI_SHIFT) & 1320 TSTATE_ASI_MASK); 1321 else 1322 asi = (inst >> 5) & 0xff; 1323 1324 if (floatflg) { 1325 /* check for ld/st alternate and highest defined V9 asi */ 1326 if ((op3 & 0x30) == 0x30 && asi > ASI_SNFL) { 1327 sz = extended_asi_size(asi); 1328 } else { 1329 switch (op3 & 3) { 1330 case 0: 1331 sz = 4; /* ldf/stf/cas */ 1332 break; 1333 case 1: 1334 if (rd == 0) 1335 sz = 4; /* ldfsr/stfsr */ 1336 else 1337 sz = 8; /* ldxfsr/stxfsr */ 1338 break; 1339 case 2: 1340 if (op3 == 0x3e) 1341 sz = 8; /* casx */ 1342 else 1343 sz = 16; /* ldqf/stqf */ 1344 break; 1345 case 3: 1346 sz = 8; /* lddf/stdf */ 1347 break; 1348 } 1349 } 1350 } else { 1351 switch (op3 & 0xf) { /* map size bits to a number */ 1352 case 0: /* lduw */ 1353 case 4: /* stw */ 1354 case 8: /* ldsw */ 1355 case 0xf: /* swap */ 1356 sz = 4; break; 1357 case 1: /* ldub */ 1358 case 5: /* stb */ 1359 case 9: /* ldsb */ 1360 case 0xd: /* ldstub */ 1361 sz = 1; break; 1362 case 2: /* lduh */ 1363 case 6: /* sth */ 1364 case 0xa: /* ldsh */ 1365 sz = 2; break; 1366 case 3: /* ldd */ 1367 case 7: /* std */ 1368 case 0xb: /* ldx */ 1369 case 0xe: /* stx */ 1370 sz = 8; break; 1371 } 1372 } 1373 1374 if (sz == 0) /* can't happen? */ 1375 return (0); 1376 (void) flush_user_windows_to_stack(NULL); 1377 1378 if (getreg(rp, rs1, &val, &badaddr)) 1379 return (0); 1380 addr = (caddr_t)val; 1381 1382 /* cas/casx don't use rs2 / simm13 to compute the address */ 1383 if ((op3 & 0x3d) != 0x3c) { 1384 /* check immediate bit and use immediate field or reg (rs2) */ 1385 if (immflg) { 1386 int imm; 1387 imm = inst & 0x1fff; /* mask out immediate field */ 1388 imm <<= 19; /* sign extend it */ 1389 imm >>= 19; 1390 addr += imm; /* compute address */ 1391 } else { 1392 /* 1393 * asi's in the 0xCx range are partial store 1394 * instructions. For these, rs2 is a mask, not part of 1395 * the address. 1396 */ 1397 if (!(floatflg && (asi & 0xf0) == 0xc0)) { 1398 if (getreg(rp, rs2, &val, &badaddr)) 1399 return (0); 1400 addr += val; 1401 } 1402 } 1403 } 1404 1405 /* 1406 * If this is a 32-bit program, chop the address accordingly. The 1407 * intermediate uintptr_t casts prevent warnings under a certain 1408 * compiler, and the temporary 32 bit storage is intended to force 1409 * proper code generation and break up what would otherwise be a 1410 * quadruple cast. 1411 */ 1412 if (curproc->p_model == DATAMODEL_ILP32) { 1413 caddr32_t addr32 = (caddr32_t)(uintptr_t)addr; 1414 addr = (caddr_t)(uintptr_t)addr32; 1415 } 1416 1417 *addrp = addr; 1418 ASSERT(sz != 0); 1419 return (sz); 1420 } 1421 1422 /* 1423 * Fetch an instruction from user-level. 1424 * Deal with watchpoints, if they are in effect. 1425 */ 1426 int32_t 1427 fetch_user_instr(caddr_t vaddr) 1428 { 1429 proc_t *p = curproc; 1430 int32_t instr; 1431 1432 /* 1433 * If this is a 32-bit program, chop the address accordingly. The 1434 * intermediate uintptr_t casts prevent warnings under a certain 1435 * compiler, and the temporary 32 bit storage is intended to force 1436 * proper code generation and break up what would otherwise be a 1437 * quadruple cast. 1438 */ 1439 if (p->p_model == DATAMODEL_ILP32) { 1440 caddr32_t vaddr32 = (caddr32_t)(uintptr_t)vaddr; 1441 vaddr = (caddr_t)(uintptr_t)vaddr32; 1442 } 1443 1444 if (fuword32_nowatch(vaddr, (uint32_t *)&instr) == -1) 1445 instr = -1; 1446 1447 return (instr); 1448 } 1449