1 /* 2 * Helpers for HPPA instructions. 3 * 4 * Copyright (c) 2016 Richard Henderson <rth@twiddle.net> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library 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 GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "cpu.h" 22 #include "exec/exec-all.h" 23 #include "exec/helper-proto.h" 24 #include "exec/cpu_ldst.h" 25 #include "qemu/timer.h" 26 #include "sysemu/runstate.h" 27 #include "fpu/softfloat.h" 28 #include "trace.h" 29 30 void QEMU_NORETURN HELPER(excp)(CPUHPPAState *env, int excp) 31 { 32 CPUState *cs = env_cpu(env); 33 34 cs->exception_index = excp; 35 cpu_loop_exit(cs); 36 } 37 38 void QEMU_NORETURN hppa_dynamic_excp(CPUHPPAState *env, int excp, uintptr_t ra) 39 { 40 CPUState *cs = env_cpu(env); 41 42 cs->exception_index = excp; 43 cpu_loop_exit_restore(cs, ra); 44 } 45 46 void HELPER(tsv)(CPUHPPAState *env, target_ureg cond) 47 { 48 if (unlikely((target_sreg)cond < 0)) { 49 hppa_dynamic_excp(env, EXCP_OVERFLOW, GETPC()); 50 } 51 } 52 53 void HELPER(tcond)(CPUHPPAState *env, target_ureg cond) 54 { 55 if (unlikely(cond)) { 56 hppa_dynamic_excp(env, EXCP_COND, GETPC()); 57 } 58 } 59 60 static void atomic_store_3(CPUHPPAState *env, target_ulong addr, uint32_t val, 61 uint32_t mask, uintptr_t ra) 62 { 63 #ifdef CONFIG_USER_ONLY 64 uint32_t old, new, cmp; 65 66 uint32_t *haddr = g2h(addr - 1); 67 old = *haddr; 68 while (1) { 69 new = (old & ~mask) | (val & mask); 70 cmp = atomic_cmpxchg(haddr, old, new); 71 if (cmp == old) { 72 return; 73 } 74 old = cmp; 75 } 76 #else 77 /* FIXME -- we can do better. */ 78 cpu_loop_exit_atomic(env_cpu(env), ra); 79 #endif 80 } 81 82 static void do_stby_b(CPUHPPAState *env, target_ulong addr, target_ureg val, 83 bool parallel, uintptr_t ra) 84 { 85 switch (addr & 3) { 86 case 3: 87 cpu_stb_data_ra(env, addr, val, ra); 88 break; 89 case 2: 90 cpu_stw_data_ra(env, addr, val, ra); 91 break; 92 case 1: 93 /* The 3 byte store must appear atomic. */ 94 if (parallel) { 95 atomic_store_3(env, addr, val, 0x00ffffffu, ra); 96 } else { 97 cpu_stb_data_ra(env, addr, val >> 16, ra); 98 cpu_stw_data_ra(env, addr + 1, val, ra); 99 } 100 break; 101 default: 102 cpu_stl_data_ra(env, addr, val, ra); 103 break; 104 } 105 } 106 107 void HELPER(stby_b)(CPUHPPAState *env, target_ulong addr, target_ureg val) 108 { 109 do_stby_b(env, addr, val, false, GETPC()); 110 } 111 112 void HELPER(stby_b_parallel)(CPUHPPAState *env, target_ulong addr, 113 target_ureg val) 114 { 115 do_stby_b(env, addr, val, true, GETPC()); 116 } 117 118 static void do_stby_e(CPUHPPAState *env, target_ulong addr, target_ureg val, 119 bool parallel, uintptr_t ra) 120 { 121 switch (addr & 3) { 122 case 3: 123 /* The 3 byte store must appear atomic. */ 124 if (parallel) { 125 atomic_store_3(env, addr - 3, val, 0xffffff00u, ra); 126 } else { 127 cpu_stw_data_ra(env, addr - 3, val >> 16, ra); 128 cpu_stb_data_ra(env, addr - 1, val >> 8, ra); 129 } 130 break; 131 case 2: 132 cpu_stw_data_ra(env, addr - 2, val >> 16, ra); 133 break; 134 case 1: 135 cpu_stb_data_ra(env, addr - 1, val >> 24, ra); 136 break; 137 default: 138 /* Nothing is stored, but protection is checked and the 139 cacheline is marked dirty. */ 140 probe_write(env, addr, 0, cpu_mmu_index(env, 0), ra); 141 break; 142 } 143 } 144 145 void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, target_ureg val) 146 { 147 do_stby_e(env, addr, val, false, GETPC()); 148 } 149 150 void HELPER(stby_e_parallel)(CPUHPPAState *env, target_ulong addr, 151 target_ureg val) 152 { 153 do_stby_e(env, addr, val, true, GETPC()); 154 } 155 156 target_ureg HELPER(probe)(CPUHPPAState *env, target_ulong addr, 157 uint32_t level, uint32_t want) 158 { 159 #ifdef CONFIG_USER_ONLY 160 return page_check_range(addr, 1, want); 161 #else 162 int prot, excp; 163 hwaddr phys; 164 165 trace_hppa_tlb_probe(addr, level, want); 166 /* Fail if the requested privilege level is higher than current. */ 167 if (level < (env->iaoq_f & 3)) { 168 return 0; 169 } 170 171 excp = hppa_get_physical_address(env, addr, level, 0, &phys, &prot); 172 if (excp >= 0) { 173 if (env->psw & PSW_Q) { 174 /* ??? Needs tweaking for hppa64. */ 175 env->cr[CR_IOR] = addr; 176 env->cr[CR_ISR] = addr >> 32; 177 } 178 if (excp == EXCP_DTLB_MISS) { 179 excp = EXCP_NA_DTLB_MISS; 180 } 181 hppa_dynamic_excp(env, excp, GETPC()); 182 } 183 return (want & prot) != 0; 184 #endif 185 } 186 187 void HELPER(loaded_fr0)(CPUHPPAState *env) 188 { 189 uint32_t shadow = env->fr[0] >> 32; 190 int rm, d; 191 192 env->fr0_shadow = shadow; 193 194 switch (extract32(shadow, 9, 2)) { 195 default: 196 rm = float_round_nearest_even; 197 break; 198 case 1: 199 rm = float_round_to_zero; 200 break; 201 case 2: 202 rm = float_round_up; 203 break; 204 case 3: 205 rm = float_round_down; 206 break; 207 } 208 set_float_rounding_mode(rm, &env->fp_status); 209 210 d = extract32(shadow, 5, 1); 211 set_flush_to_zero(d, &env->fp_status); 212 set_flush_inputs_to_zero(d, &env->fp_status); 213 } 214 215 void cpu_hppa_loaded_fr0(CPUHPPAState *env) 216 { 217 helper_loaded_fr0(env); 218 } 219 220 #define CONVERT_BIT(X, SRC, DST) \ 221 ((SRC) > (DST) \ 222 ? (X) / ((SRC) / (DST)) & (DST) \ 223 : ((X) & (SRC)) * ((DST) / (SRC))) 224 225 static void update_fr0_op(CPUHPPAState *env, uintptr_t ra) 226 { 227 uint32_t soft_exp = get_float_exception_flags(&env->fp_status); 228 uint32_t hard_exp = 0; 229 uint32_t shadow = env->fr0_shadow; 230 231 if (likely(soft_exp == 0)) { 232 env->fr[0] = (uint64_t)shadow << 32; 233 return; 234 } 235 set_float_exception_flags(0, &env->fp_status); 236 237 hard_exp |= CONVERT_BIT(soft_exp, float_flag_inexact, 1u << 0); 238 hard_exp |= CONVERT_BIT(soft_exp, float_flag_underflow, 1u << 1); 239 hard_exp |= CONVERT_BIT(soft_exp, float_flag_overflow, 1u << 2); 240 hard_exp |= CONVERT_BIT(soft_exp, float_flag_divbyzero, 1u << 3); 241 hard_exp |= CONVERT_BIT(soft_exp, float_flag_invalid, 1u << 4); 242 shadow |= hard_exp << (32 - 5); 243 env->fr0_shadow = shadow; 244 env->fr[0] = (uint64_t)shadow << 32; 245 246 if (hard_exp & shadow) { 247 hppa_dynamic_excp(env, EXCP_ASSIST, ra); 248 } 249 } 250 251 float32 HELPER(fsqrt_s)(CPUHPPAState *env, float32 arg) 252 { 253 float32 ret = float32_sqrt(arg, &env->fp_status); 254 update_fr0_op(env, GETPC()); 255 return ret; 256 } 257 258 float32 HELPER(frnd_s)(CPUHPPAState *env, float32 arg) 259 { 260 float32 ret = float32_round_to_int(arg, &env->fp_status); 261 update_fr0_op(env, GETPC()); 262 return ret; 263 } 264 265 float32 HELPER(fadd_s)(CPUHPPAState *env, float32 a, float32 b) 266 { 267 float32 ret = float32_add(a, b, &env->fp_status); 268 update_fr0_op(env, GETPC()); 269 return ret; 270 } 271 272 float32 HELPER(fsub_s)(CPUHPPAState *env, float32 a, float32 b) 273 { 274 float32 ret = float32_sub(a, b, &env->fp_status); 275 update_fr0_op(env, GETPC()); 276 return ret; 277 } 278 279 float32 HELPER(fmpy_s)(CPUHPPAState *env, float32 a, float32 b) 280 { 281 float32 ret = float32_mul(a, b, &env->fp_status); 282 update_fr0_op(env, GETPC()); 283 return ret; 284 } 285 286 float32 HELPER(fdiv_s)(CPUHPPAState *env, float32 a, float32 b) 287 { 288 float32 ret = float32_div(a, b, &env->fp_status); 289 update_fr0_op(env, GETPC()); 290 return ret; 291 } 292 293 float64 HELPER(fsqrt_d)(CPUHPPAState *env, float64 arg) 294 { 295 float64 ret = float64_sqrt(arg, &env->fp_status); 296 update_fr0_op(env, GETPC()); 297 return ret; 298 } 299 300 float64 HELPER(frnd_d)(CPUHPPAState *env, float64 arg) 301 { 302 float64 ret = float64_round_to_int(arg, &env->fp_status); 303 update_fr0_op(env, GETPC()); 304 return ret; 305 } 306 307 float64 HELPER(fadd_d)(CPUHPPAState *env, float64 a, float64 b) 308 { 309 float64 ret = float64_add(a, b, &env->fp_status); 310 update_fr0_op(env, GETPC()); 311 return ret; 312 } 313 314 float64 HELPER(fsub_d)(CPUHPPAState *env, float64 a, float64 b) 315 { 316 float64 ret = float64_sub(a, b, &env->fp_status); 317 update_fr0_op(env, GETPC()); 318 return ret; 319 } 320 321 float64 HELPER(fmpy_d)(CPUHPPAState *env, float64 a, float64 b) 322 { 323 float64 ret = float64_mul(a, b, &env->fp_status); 324 update_fr0_op(env, GETPC()); 325 return ret; 326 } 327 328 float64 HELPER(fdiv_d)(CPUHPPAState *env, float64 a, float64 b) 329 { 330 float64 ret = float64_div(a, b, &env->fp_status); 331 update_fr0_op(env, GETPC()); 332 return ret; 333 } 334 335 float64 HELPER(fcnv_s_d)(CPUHPPAState *env, float32 arg) 336 { 337 float64 ret = float32_to_float64(arg, &env->fp_status); 338 update_fr0_op(env, GETPC()); 339 return ret; 340 } 341 342 float32 HELPER(fcnv_d_s)(CPUHPPAState *env, float64 arg) 343 { 344 float32 ret = float64_to_float32(arg, &env->fp_status); 345 update_fr0_op(env, GETPC()); 346 return ret; 347 } 348 349 float32 HELPER(fcnv_w_s)(CPUHPPAState *env, int32_t arg) 350 { 351 float32 ret = int32_to_float32(arg, &env->fp_status); 352 update_fr0_op(env, GETPC()); 353 return ret; 354 } 355 356 float32 HELPER(fcnv_dw_s)(CPUHPPAState *env, int64_t arg) 357 { 358 float32 ret = int64_to_float32(arg, &env->fp_status); 359 update_fr0_op(env, GETPC()); 360 return ret; 361 } 362 363 float64 HELPER(fcnv_w_d)(CPUHPPAState *env, int32_t arg) 364 { 365 float64 ret = int32_to_float64(arg, &env->fp_status); 366 update_fr0_op(env, GETPC()); 367 return ret; 368 } 369 370 float64 HELPER(fcnv_dw_d)(CPUHPPAState *env, int64_t arg) 371 { 372 float64 ret = int64_to_float64(arg, &env->fp_status); 373 update_fr0_op(env, GETPC()); 374 return ret; 375 } 376 377 int32_t HELPER(fcnv_s_w)(CPUHPPAState *env, float32 arg) 378 { 379 int32_t ret = float32_to_int32(arg, &env->fp_status); 380 update_fr0_op(env, GETPC()); 381 return ret; 382 } 383 384 int32_t HELPER(fcnv_d_w)(CPUHPPAState *env, float64 arg) 385 { 386 int32_t ret = float64_to_int32(arg, &env->fp_status); 387 update_fr0_op(env, GETPC()); 388 return ret; 389 } 390 391 int64_t HELPER(fcnv_s_dw)(CPUHPPAState *env, float32 arg) 392 { 393 int64_t ret = float32_to_int64(arg, &env->fp_status); 394 update_fr0_op(env, GETPC()); 395 return ret; 396 } 397 398 int64_t HELPER(fcnv_d_dw)(CPUHPPAState *env, float64 arg) 399 { 400 int64_t ret = float64_to_int64(arg, &env->fp_status); 401 update_fr0_op(env, GETPC()); 402 return ret; 403 } 404 405 int32_t HELPER(fcnv_t_s_w)(CPUHPPAState *env, float32 arg) 406 { 407 int32_t ret = float32_to_int32_round_to_zero(arg, &env->fp_status); 408 update_fr0_op(env, GETPC()); 409 return ret; 410 } 411 412 int32_t HELPER(fcnv_t_d_w)(CPUHPPAState *env, float64 arg) 413 { 414 int32_t ret = float64_to_int32_round_to_zero(arg, &env->fp_status); 415 update_fr0_op(env, GETPC()); 416 return ret; 417 } 418 419 int64_t HELPER(fcnv_t_s_dw)(CPUHPPAState *env, float32 arg) 420 { 421 int64_t ret = float32_to_int64_round_to_zero(arg, &env->fp_status); 422 update_fr0_op(env, GETPC()); 423 return ret; 424 } 425 426 int64_t HELPER(fcnv_t_d_dw)(CPUHPPAState *env, float64 arg) 427 { 428 int64_t ret = float64_to_int64_round_to_zero(arg, &env->fp_status); 429 update_fr0_op(env, GETPC()); 430 return ret; 431 } 432 433 float32 HELPER(fcnv_uw_s)(CPUHPPAState *env, uint32_t arg) 434 { 435 float32 ret = uint32_to_float32(arg, &env->fp_status); 436 update_fr0_op(env, GETPC()); 437 return ret; 438 } 439 440 float32 HELPER(fcnv_udw_s)(CPUHPPAState *env, uint64_t arg) 441 { 442 float32 ret = uint64_to_float32(arg, &env->fp_status); 443 update_fr0_op(env, GETPC()); 444 return ret; 445 } 446 447 float64 HELPER(fcnv_uw_d)(CPUHPPAState *env, uint32_t arg) 448 { 449 float64 ret = uint32_to_float64(arg, &env->fp_status); 450 update_fr0_op(env, GETPC()); 451 return ret; 452 } 453 454 float64 HELPER(fcnv_udw_d)(CPUHPPAState *env, uint64_t arg) 455 { 456 float64 ret = uint64_to_float64(arg, &env->fp_status); 457 update_fr0_op(env, GETPC()); 458 return ret; 459 } 460 461 uint32_t HELPER(fcnv_s_uw)(CPUHPPAState *env, float32 arg) 462 { 463 uint32_t ret = float32_to_uint32(arg, &env->fp_status); 464 update_fr0_op(env, GETPC()); 465 return ret; 466 } 467 468 uint32_t HELPER(fcnv_d_uw)(CPUHPPAState *env, float64 arg) 469 { 470 uint32_t ret = float64_to_uint32(arg, &env->fp_status); 471 update_fr0_op(env, GETPC()); 472 return ret; 473 } 474 475 uint64_t HELPER(fcnv_s_udw)(CPUHPPAState *env, float32 arg) 476 { 477 uint64_t ret = float32_to_uint64(arg, &env->fp_status); 478 update_fr0_op(env, GETPC()); 479 return ret; 480 } 481 482 uint64_t HELPER(fcnv_d_udw)(CPUHPPAState *env, float64 arg) 483 { 484 uint64_t ret = float64_to_uint64(arg, &env->fp_status); 485 update_fr0_op(env, GETPC()); 486 return ret; 487 } 488 489 uint32_t HELPER(fcnv_t_s_uw)(CPUHPPAState *env, float32 arg) 490 { 491 uint32_t ret = float32_to_uint32_round_to_zero(arg, &env->fp_status); 492 update_fr0_op(env, GETPC()); 493 return ret; 494 } 495 496 uint32_t HELPER(fcnv_t_d_uw)(CPUHPPAState *env, float64 arg) 497 { 498 uint32_t ret = float64_to_uint32_round_to_zero(arg, &env->fp_status); 499 update_fr0_op(env, GETPC()); 500 return ret; 501 } 502 503 uint64_t HELPER(fcnv_t_s_udw)(CPUHPPAState *env, float32 arg) 504 { 505 uint64_t ret = float32_to_uint64_round_to_zero(arg, &env->fp_status); 506 update_fr0_op(env, GETPC()); 507 return ret; 508 } 509 510 uint64_t HELPER(fcnv_t_d_udw)(CPUHPPAState *env, float64 arg) 511 { 512 uint64_t ret = float64_to_uint64_round_to_zero(arg, &env->fp_status); 513 update_fr0_op(env, GETPC()); 514 return ret; 515 } 516 517 static void update_fr0_cmp(CPUHPPAState *env, uint32_t y, uint32_t c, int r) 518 { 519 uint32_t shadow = env->fr0_shadow; 520 521 switch (r) { 522 case float_relation_greater: 523 c = extract32(c, 4, 1); 524 break; 525 case float_relation_less: 526 c = extract32(c, 3, 1); 527 break; 528 case float_relation_equal: 529 c = extract32(c, 2, 1); 530 break; 531 case float_relation_unordered: 532 c = extract32(c, 1, 1); 533 break; 534 default: 535 g_assert_not_reached(); 536 } 537 538 if (y) { 539 /* targeted comparison */ 540 /* set fpsr[ca[y - 1]] to current compare */ 541 shadow = deposit32(shadow, 21 - (y - 1), 1, c); 542 } else { 543 /* queued comparison */ 544 /* shift cq right by one place */ 545 shadow = deposit32(shadow, 11, 10, extract32(shadow, 12, 10)); 546 /* move fpsr[c] to fpsr[cq[0]] */ 547 shadow = deposit32(shadow, 21, 1, extract32(shadow, 26, 1)); 548 /* set fpsr[c] to current compare */ 549 shadow = deposit32(shadow, 26, 1, c); 550 } 551 552 env->fr0_shadow = shadow; 553 env->fr[0] = (uint64_t)shadow << 32; 554 } 555 556 void HELPER(fcmp_s)(CPUHPPAState *env, float32 a, float32 b, 557 uint32_t y, uint32_t c) 558 { 559 int r; 560 if (c & 1) { 561 r = float32_compare(a, b, &env->fp_status); 562 } else { 563 r = float32_compare_quiet(a, b, &env->fp_status); 564 } 565 update_fr0_op(env, GETPC()); 566 update_fr0_cmp(env, y, c, r); 567 } 568 569 void HELPER(fcmp_d)(CPUHPPAState *env, float64 a, float64 b, 570 uint32_t y, uint32_t c) 571 { 572 int r; 573 if (c & 1) { 574 r = float64_compare(a, b, &env->fp_status); 575 } else { 576 r = float64_compare_quiet(a, b, &env->fp_status); 577 } 578 update_fr0_op(env, GETPC()); 579 update_fr0_cmp(env, y, c, r); 580 } 581 582 float32 HELPER(fmpyfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c) 583 { 584 float32 ret = float32_muladd(a, b, c, 0, &env->fp_status); 585 update_fr0_op(env, GETPC()); 586 return ret; 587 } 588 589 float32 HELPER(fmpynfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c) 590 { 591 float32 ret = float32_muladd(a, b, c, float_muladd_negate_product, 592 &env->fp_status); 593 update_fr0_op(env, GETPC()); 594 return ret; 595 } 596 597 float64 HELPER(fmpyfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c) 598 { 599 float64 ret = float64_muladd(a, b, c, 0, &env->fp_status); 600 update_fr0_op(env, GETPC()); 601 return ret; 602 } 603 604 float64 HELPER(fmpynfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c) 605 { 606 float64 ret = float64_muladd(a, b, c, float_muladd_negate_product, 607 &env->fp_status); 608 update_fr0_op(env, GETPC()); 609 return ret; 610 } 611 612 target_ureg HELPER(read_interval_timer)(void) 613 { 614 #ifdef CONFIG_USER_ONLY 615 /* In user-mode, QEMU_CLOCK_VIRTUAL doesn't exist. 616 Just pass through the host cpu clock ticks. */ 617 return cpu_get_host_ticks(); 618 #else 619 /* In system mode we have access to a decent high-resolution clock. 620 In order to make OS-level time accounting work with the cr16, 621 present it with a well-timed clock fixed at 250MHz. */ 622 return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2; 623 #endif 624 } 625 626 #ifndef CONFIG_USER_ONLY 627 void HELPER(write_interval_timer)(CPUHPPAState *env, target_ureg val) 628 { 629 HPPACPU *cpu = env_archcpu(env); 630 uint64_t current = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 631 uint64_t timeout; 632 633 /* Even in 64-bit mode, the comparator is always 32-bit. But the 634 value we expose to the guest is 1/4 of the speed of the clock, 635 so moosh in 34 bits. */ 636 timeout = deposit64(current, 0, 34, (uint64_t)val << 2); 637 638 /* If the mooshing puts the clock in the past, advance to next round. */ 639 if (timeout < current + 1000) { 640 timeout += 1ULL << 34; 641 } 642 643 cpu->env.cr[CR_IT] = timeout; 644 timer_mod(cpu->alarm_timer, timeout); 645 } 646 647 void HELPER(halt)(CPUHPPAState *env) 648 { 649 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); 650 helper_excp(env, EXCP_HLT); 651 } 652 653 void HELPER(reset)(CPUHPPAState *env) 654 { 655 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 656 helper_excp(env, EXCP_HLT); 657 } 658 659 target_ureg HELPER(swap_system_mask)(CPUHPPAState *env, target_ureg nsm) 660 { 661 target_ulong psw = env->psw; 662 /* 663 * Setting the PSW Q bit to 1, if it was not already 1, is an 664 * undefined operation. 665 * 666 * However, HP-UX 10.20 does this with the SSM instruction. 667 * Tested this on HP9000/712 and HP9000/785/C3750 and both 668 * machines set the Q bit from 0 to 1 without an exception, 669 * so let this go without comment. 670 */ 671 env->psw = (psw & ~PSW_SM) | (nsm & PSW_SM); 672 return psw & PSW_SM; 673 } 674 675 void HELPER(rfi)(CPUHPPAState *env) 676 { 677 env->iasq_f = (uint64_t)env->cr[CR_IIASQ] << 32; 678 env->iasq_b = (uint64_t)env->cr_back[0] << 32; 679 env->iaoq_f = env->cr[CR_IIAOQ]; 680 env->iaoq_b = env->cr_back[1]; 681 cpu_hppa_put_psw(env, env->cr[CR_IPSW]); 682 } 683 684 void HELPER(rfi_r)(CPUHPPAState *env) 685 { 686 env->gr[1] = env->shadow[0]; 687 env->gr[8] = env->shadow[1]; 688 env->gr[9] = env->shadow[2]; 689 env->gr[16] = env->shadow[3]; 690 env->gr[17] = env->shadow[4]; 691 env->gr[24] = env->shadow[5]; 692 env->gr[25] = env->shadow[6]; 693 helper_rfi(env); 694 } 695 #endif 696