1/* 2 * Power ISA decode for Fixed-Point Facility instructions 3 * 4 * Copyright (c) 2021 Instituto de Pesquisas Eldorado (eldorado.org.br) 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.1 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/* 21 * Fixed-Point Load/Store Instructions 22 */ 23 24static bool do_ldst(DisasContext *ctx, int rt, int ra, TCGv displ, bool update, 25 bool store, MemOp mop) 26{ 27 TCGv ea; 28 29 if (update && (ra == 0 || (!store && ra == rt))) { 30 gen_invalid(ctx); 31 return true; 32 } 33 gen_set_access_type(ctx, ACCESS_INT); 34 35 ea = do_ea_calc(ctx, ra, displ); 36 mop ^= ctx->default_tcg_memop_mask; 37 if (store) { 38 tcg_gen_qemu_st_tl(cpu_gpr[rt], ea, ctx->mem_idx, mop); 39 } else { 40 tcg_gen_qemu_ld_tl(cpu_gpr[rt], ea, ctx->mem_idx, mop); 41 } 42 if (update) { 43 tcg_gen_mov_tl(cpu_gpr[ra], ea); 44 } 45 return true; 46} 47 48static bool do_ldst_D(DisasContext *ctx, arg_D *a, bool update, bool store, 49 MemOp mop) 50{ 51 return do_ldst(ctx, a->rt, a->ra, tcg_constant_tl(a->si), update, store, mop); 52} 53 54static bool do_ldst_PLS_D(DisasContext *ctx, arg_PLS_D *a, bool update, 55 bool store, MemOp mop) 56{ 57 arg_D d; 58 if (!resolve_PLS_D(ctx, &d, a)) { 59 return true; 60 } 61 return do_ldst_D(ctx, &d, update, store, mop); 62} 63 64static bool do_ldst_X(DisasContext *ctx, arg_X *a, bool update, 65 bool store, MemOp mop) 66{ 67 return do_ldst(ctx, a->rt, a->ra, cpu_gpr[a->rb], update, store, mop); 68} 69 70static bool do_ldst_quad(DisasContext *ctx, arg_D *a, bool store, bool prefixed) 71{ 72#if defined(TARGET_PPC64) 73 TCGv ea; 74 TCGv_i64 lo, hi; 75 TCGv_i128 t16; 76 77 REQUIRE_INSNS_FLAGS(ctx, 64BX); 78 79 if (!prefixed && !(ctx->insns_flags2 & PPC2_LSQ_ISA207)) { 80 /* lq and stq were privileged prior to V. 2.07 */ 81 REQUIRE_SV(ctx); 82 83 if (ctx->le_mode) { 84 gen_align_no_le(ctx); 85 return true; 86 } 87 } 88 89 if (!store && unlikely(a->ra == a->rt)) { 90 gen_invalid(ctx); 91 return true; 92 } 93 94 gen_set_access_type(ctx, ACCESS_INT); 95 ea = do_ea_calc(ctx, a->ra, tcg_constant_tl(a->si)); 96 97 if (ctx->le_mode && prefixed) { 98 lo = cpu_gpr[a->rt]; 99 hi = cpu_gpr[a->rt + 1]; 100 } else { 101 lo = cpu_gpr[a->rt + 1]; 102 hi = cpu_gpr[a->rt]; 103 } 104 t16 = tcg_temp_new_i128(); 105 106 if (store) { 107 tcg_gen_concat_i64_i128(t16, lo, hi); 108 tcg_gen_qemu_st_i128(t16, ea, ctx->mem_idx, DEF_MEMOP(MO_128)); 109 } else { 110 tcg_gen_qemu_ld_i128(t16, ea, ctx->mem_idx, DEF_MEMOP(MO_128)); 111 tcg_gen_extr_i128_i64(lo, hi, t16); 112 } 113#else 114 qemu_build_not_reached(); 115#endif 116 117 return true; 118} 119 120static bool do_ldst_quad_PLS_D(DisasContext *ctx, arg_PLS_D *a, bool store) 121{ 122 arg_D d; 123 if (!resolve_PLS_D(ctx, &d, a)) { 124 return true; 125 } 126 127 return do_ldst_quad(ctx, &d, store, true); 128} 129 130/* Load Byte and Zero */ 131TRANS(LBZ, do_ldst_D, false, false, MO_UB) 132TRANS(LBZX, do_ldst_X, false, false, MO_UB) 133TRANS(LBZU, do_ldst_D, true, false, MO_UB) 134TRANS(LBZUX, do_ldst_X, true, false, MO_UB) 135TRANS(PLBZ, do_ldst_PLS_D, false, false, MO_UB) 136 137/* Load Halfword and Zero */ 138TRANS(LHZ, do_ldst_D, false, false, MO_UW) 139TRANS(LHZX, do_ldst_X, false, false, MO_UW) 140TRANS(LHZU, do_ldst_D, true, false, MO_UW) 141TRANS(LHZUX, do_ldst_X, true, false, MO_UW) 142TRANS(PLHZ, do_ldst_PLS_D, false, false, MO_UW) 143 144/* Load Halfword Algebraic */ 145TRANS(LHA, do_ldst_D, false, false, MO_SW) 146TRANS(LHAX, do_ldst_X, false, false, MO_SW) 147TRANS(LHAU, do_ldst_D, true, false, MO_SW) 148TRANS(LHAXU, do_ldst_X, true, false, MO_SW) 149TRANS(PLHA, do_ldst_PLS_D, false, false, MO_SW) 150 151/* Load Word and Zero */ 152TRANS(LWZ, do_ldst_D, false, false, MO_UL) 153TRANS(LWZX, do_ldst_X, false, false, MO_UL) 154TRANS(LWZU, do_ldst_D, true, false, MO_UL) 155TRANS(LWZUX, do_ldst_X, true, false, MO_UL) 156TRANS(PLWZ, do_ldst_PLS_D, false, false, MO_UL) 157 158/* Load Word Algebraic */ 159TRANS64(LWA, do_ldst_D, false, false, MO_SL) 160TRANS64(LWAX, do_ldst_X, false, false, MO_SL) 161TRANS64(LWAUX, do_ldst_X, true, false, MO_SL) 162TRANS64(PLWA, do_ldst_PLS_D, false, false, MO_SL) 163 164/* Load Doubleword */ 165TRANS64(LD, do_ldst_D, false, false, MO_UQ) 166TRANS64(LDX, do_ldst_X, false, false, MO_UQ) 167TRANS64(LDU, do_ldst_D, true, false, MO_UQ) 168TRANS64(LDUX, do_ldst_X, true, false, MO_UQ) 169TRANS64(PLD, do_ldst_PLS_D, false, false, MO_UQ) 170 171/* Load Quadword */ 172TRANS64(LQ, do_ldst_quad, false, false); 173TRANS64(PLQ, do_ldst_quad_PLS_D, false); 174 175/* Store Byte */ 176TRANS(STB, do_ldst_D, false, true, MO_UB) 177TRANS(STBX, do_ldst_X, false, true, MO_UB) 178TRANS(STBU, do_ldst_D, true, true, MO_UB) 179TRANS(STBUX, do_ldst_X, true, true, MO_UB) 180TRANS(PSTB, do_ldst_PLS_D, false, true, MO_UB) 181 182/* Store Halfword */ 183TRANS(STH, do_ldst_D, false, true, MO_UW) 184TRANS(STHX, do_ldst_X, false, true, MO_UW) 185TRANS(STHU, do_ldst_D, true, true, MO_UW) 186TRANS(STHUX, do_ldst_X, true, true, MO_UW) 187TRANS(PSTH, do_ldst_PLS_D, false, true, MO_UW) 188 189/* Store Word */ 190TRANS(STW, do_ldst_D, false, true, MO_UL) 191TRANS(STWX, do_ldst_X, false, true, MO_UL) 192TRANS(STWU, do_ldst_D, true, true, MO_UL) 193TRANS(STWUX, do_ldst_X, true, true, MO_UL) 194TRANS(PSTW, do_ldst_PLS_D, false, true, MO_UL) 195 196/* Store Doubleword */ 197TRANS64(STD, do_ldst_D, false, true, MO_UQ) 198TRANS64(STDX, do_ldst_X, false, true, MO_UQ) 199TRANS64(STDU, do_ldst_D, true, true, MO_UQ) 200TRANS64(STDUX, do_ldst_X, true, true, MO_UQ) 201TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_UQ) 202 203/* Store Quadword */ 204TRANS64(STQ, do_ldst_quad, true, false); 205TRANS64(PSTQ, do_ldst_quad_PLS_D, true); 206 207/* 208 * Fixed-Point Compare Instructions 209 */ 210 211static bool do_cmp_X(DisasContext *ctx, arg_X_bfl *a, bool s) 212{ 213 if ((ctx->insns_flags & PPC_64B) == 0) { 214 /* 215 * For 32-bit implementations, The Programming Environments Manual says 216 * that "the L field must be cleared, otherwise the instruction form is 217 * invalid." It seems, however, that most 32-bit CPUs ignore invalid 218 * forms (e.g., section "Instruction Formats" of the 405 and 440 219 * manuals, "Integer Compare Instructions" of the 601 manual), with the 220 * notable exception of the e500 and e500mc, where L=1 was reported to 221 * cause an exception. 222 */ 223 if (a->l) { 224 if ((ctx->insns_flags2 & PPC2_BOOKE206)) { 225 /* 226 * For 32-bit Book E v2.06 implementations (i.e. e500/e500mc), 227 * generate an illegal instruction exception. 228 */ 229 return false; 230 } else { 231 qemu_log_mask(LOG_GUEST_ERROR, 232 "Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n", 233 s ? "" : "L", ctx->cia); 234 } 235 } 236 gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf); 237 return true; 238 } 239 240 /* For 64-bit implementations, deal with bit L accordingly. */ 241 if (a->l) { 242 gen_op_cmp(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf); 243 } else { 244 gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf); 245 } 246 return true; 247} 248 249static bool do_cmp_D(DisasContext *ctx, arg_D_bf *a, bool s) 250{ 251 if ((ctx->insns_flags & PPC_64B) == 0) { 252 /* 253 * For 32-bit implementations, The Programming Environments Manual says 254 * that "the L field must be cleared, otherwise the instruction form is 255 * invalid." It seems, however, that most 32-bit CPUs ignore invalid 256 * forms (e.g., section "Instruction Formats" of the 405 and 440 257 * manuals, "Integer Compare Instructions" of the 601 manual), with the 258 * notable exception of the e500 and e500mc, where L=1 was reported to 259 * cause an exception. 260 */ 261 if (a->l) { 262 if ((ctx->insns_flags2 & PPC2_BOOKE206)) { 263 /* 264 * For 32-bit Book E v2.06 implementations (i.e. e500/e500mc), 265 * generate an illegal instruction exception. 266 */ 267 return false; 268 } else { 269 qemu_log_mask(LOG_GUEST_ERROR, 270 "Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n", 271 s ? "I" : "LI", ctx->cia); 272 } 273 } 274 gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf); 275 return true; 276 } 277 278 /* For 64-bit implementations, deal with bit L accordingly. */ 279 if (a->l) { 280 gen_op_cmp(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf); 281 } else { 282 gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf); 283 } 284 return true; 285} 286 287TRANS(CMP, do_cmp_X, true); 288TRANS(CMPL, do_cmp_X, false); 289TRANS(CMPI, do_cmp_D, true); 290TRANS(CMPLI, do_cmp_D, false); 291 292/* 293 * Fixed-Point Arithmetic Instructions 294 */ 295 296static bool trans_ADDI(DisasContext *ctx, arg_D *a) 297{ 298 if (a->ra) { 299 tcg_gen_addi_tl(cpu_gpr[a->rt], cpu_gpr[a->ra], a->si); 300 } else { 301 tcg_gen_movi_tl(cpu_gpr[a->rt], a->si); 302 } 303 return true; 304} 305 306static bool trans_PADDI(DisasContext *ctx, arg_PLS_D *a) 307{ 308 arg_D d; 309 if (!resolve_PLS_D(ctx, &d, a)) { 310 return true; 311 } 312 return trans_ADDI(ctx, &d); 313} 314 315static bool trans_ADDIS(DisasContext *ctx, arg_D *a) 316{ 317 a->si <<= 16; 318 return trans_ADDI(ctx, a); 319} 320 321static bool trans_ADDPCIS(DisasContext *ctx, arg_DX *a) 322{ 323 REQUIRE_INSNS_FLAGS2(ctx, ISA300); 324 tcg_gen_movi_tl(cpu_gpr[a->rt], ctx->base.pc_next + (a->d << 16)); 325 return true; 326} 327 328static bool trans_ADDEX(DisasContext *ctx, arg_X *a) 329{ 330 REQUIRE_INSNS_FLAGS2(ctx, ISA300); 331 gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb], 332 cpu_ov, cpu_ov32, true, true, false, false); 333 return true; 334} 335 336static bool do_add_D(DisasContext *ctx, arg_D *a, bool add_ca, bool compute_ca, 337 bool compute_ov, bool compute_rc0) 338{ 339 gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], 340 tcg_constant_tl(a->si), cpu_ca, cpu_ca32, 341 add_ca, compute_ca, compute_ov, compute_rc0); 342 return true; 343} 344 345static bool do_add_XO(DisasContext *ctx, arg_XO *a, bool add_ca, 346 bool compute_ca) 347{ 348 gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb], 349 cpu_ca, cpu_ca32, add_ca, compute_ca, a->oe, a->rc); 350 return true; 351} 352 353static bool do_add_const_XO(DisasContext *ctx, arg_XO_ta *a, TCGv const_val, 354 bool add_ca, bool compute_ca) 355{ 356 gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], const_val, 357 cpu_ca, cpu_ca32, add_ca, compute_ca, a->oe, a->rc); 358 return true; 359} 360 361TRANS(ADD, do_add_XO, false, false); 362TRANS(ADDC, do_add_XO, false, true); 363TRANS(ADDE, do_add_XO, true, true); 364TRANS(ADDME, do_add_const_XO, tcg_constant_tl(-1LL), true, true); 365TRANS(ADDZE, do_add_const_XO, tcg_constant_tl(0), true, true); 366TRANS(ADDIC, do_add_D, false, true, false, false); 367TRANS(ADDIC_, do_add_D, false, true, false, true); 368 369static bool trans_SUBFIC(DisasContext *ctx, arg_D *a) 370{ 371 gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], 372 tcg_constant_tl(a->si), false, true, false, false); 373 return true; 374} 375 376static bool do_subf_XO(DisasContext *ctx, arg_XO *a, bool add_ca, 377 bool compute_ca) 378{ 379 gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb], 380 add_ca, compute_ca, a->oe, a->rc); 381 return true; 382} 383 384static bool do_subf_const_XO(DisasContext *ctx, arg_XO_ta *a, TCGv const_val, 385 bool add_ca, bool compute_ca) 386{ 387 gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], const_val, 388 add_ca, compute_ca, a->oe, a->rc); 389 return true; 390} 391 392TRANS(SUBF, do_subf_XO, false, false) 393TRANS(SUBFC, do_subf_XO, false, true) 394TRANS(SUBFE, do_subf_XO, true, true) 395TRANS(SUBFME, do_subf_const_XO, tcg_constant_tl(-1LL), true, true) 396TRANS(SUBFZE, do_subf_const_XO, tcg_constant_tl(0), true, true) 397 398static bool trans_INVALID(DisasContext *ctx, arg_INVALID *a) 399{ 400 gen_invalid(ctx); 401 return true; 402} 403 404static bool trans_PNOP(DisasContext *ctx, arg_PNOP *a) 405{ 406 return true; 407} 408 409static bool do_set_bool_cond(DisasContext *ctx, arg_X_bi *a, bool neg, bool rev) 410{ 411 REQUIRE_INSNS_FLAGS2(ctx, ISA310); 412 uint32_t mask = 0x08 >> (a->bi & 0x03); 413 TCGCond cond = rev ? TCG_COND_EQ : TCG_COND_NE; 414 TCGv temp = tcg_temp_new(); 415 TCGv zero = tcg_constant_tl(0); 416 417 tcg_gen_extu_i32_tl(temp, cpu_crf[a->bi >> 2]); 418 tcg_gen_andi_tl(temp, temp, mask); 419 if (neg) { 420 tcg_gen_negsetcond_tl(cond, cpu_gpr[a->rt], temp, zero); 421 } else { 422 tcg_gen_setcond_tl(cond, cpu_gpr[a->rt], temp, zero); 423 } 424 return true; 425} 426 427TRANS(SETBC, do_set_bool_cond, false, false) 428TRANS(SETBCR, do_set_bool_cond, false, true) 429TRANS(SETNBC, do_set_bool_cond, true, false) 430TRANS(SETNBCR, do_set_bool_cond, true, true) 431 432static bool trans_CFUGED(DisasContext *ctx, arg_X *a) 433{ 434 REQUIRE_64BIT(ctx); 435 REQUIRE_INSNS_FLAGS2(ctx, ISA310); 436#if defined(TARGET_PPC64) 437 gen_helper_CFUGED(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]); 438#else 439 qemu_build_not_reached(); 440#endif 441 return true; 442} 443 444static void do_cntzdm(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 mask, int64_t trail) 445{ 446 TCGv_i64 t0, t1; 447 448 t0 = tcg_temp_new_i64(); 449 t1 = tcg_temp_new_i64(); 450 451 tcg_gen_and_i64(t0, src, mask); 452 if (trail) { 453 tcg_gen_ctzi_i64(t0, t0, -1); 454 } else { 455 tcg_gen_clzi_i64(t0, t0, -1); 456 } 457 458 tcg_gen_setcondi_i64(TCG_COND_NE, t1, t0, -1); 459 tcg_gen_andi_i64(t0, t0, 63); 460 tcg_gen_xori_i64(t0, t0, 63); 461 if (trail) { 462 tcg_gen_shl_i64(t0, mask, t0); 463 tcg_gen_shl_i64(t0, t0, t1); 464 } else { 465 tcg_gen_shr_i64(t0, mask, t0); 466 tcg_gen_shr_i64(t0, t0, t1); 467 } 468 469 tcg_gen_ctpop_i64(dst, t0); 470} 471 472static bool trans_CNTLZDM(DisasContext *ctx, arg_X *a) 473{ 474 REQUIRE_64BIT(ctx); 475 REQUIRE_INSNS_FLAGS2(ctx, ISA310); 476#if defined(TARGET_PPC64) 477 do_cntzdm(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb], false); 478#else 479 qemu_build_not_reached(); 480#endif 481 return true; 482} 483 484static bool trans_CNTTZDM(DisasContext *ctx, arg_X *a) 485{ 486 REQUIRE_64BIT(ctx); 487 REQUIRE_INSNS_FLAGS2(ctx, ISA310); 488#if defined(TARGET_PPC64) 489 do_cntzdm(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb], true); 490#else 491 qemu_build_not_reached(); 492#endif 493 return true; 494} 495 496static bool trans_PDEPD(DisasContext *ctx, arg_X *a) 497{ 498 REQUIRE_64BIT(ctx); 499 REQUIRE_INSNS_FLAGS2(ctx, ISA310); 500#if defined(TARGET_PPC64) 501 gen_helper_PDEPD(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]); 502#else 503 qemu_build_not_reached(); 504#endif 505 return true; 506} 507 508static bool trans_PEXTD(DisasContext *ctx, arg_X *a) 509{ 510 REQUIRE_64BIT(ctx); 511 REQUIRE_INSNS_FLAGS2(ctx, ISA310); 512#if defined(TARGET_PPC64) 513 gen_helper_PEXTD(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]); 514#else 515 qemu_build_not_reached(); 516#endif 517 return true; 518} 519 520static bool trans_ADDG6S(DisasContext *ctx, arg_X *a) 521{ 522 const target_ulong carry_bits = (target_ulong)-1 / 0xf; 523 TCGv in1, in2, carryl, carryh, tmp; 524 TCGv zero = tcg_constant_tl(0); 525 526 REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206); 527 528 in1 = cpu_gpr[a->ra]; 529 in2 = cpu_gpr[a->rb]; 530 tmp = tcg_temp_new(); 531 carryl = tcg_temp_new(); 532 carryh = tcg_temp_new(); 533 534 /* Addition with carry. */ 535 tcg_gen_add2_tl(carryl, carryh, in1, zero, in2, zero); 536 /* Addition without carry. */ 537 tcg_gen_xor_tl(tmp, in1, in2); 538 /* Difference between the two is carry in to each bit. */ 539 tcg_gen_xor_tl(carryl, carryl, tmp); 540 541 /* 542 * The carry-out that we're looking for is the carry-in to 543 * the next nibble. Shift the double-word down one nibble, 544 * which puts all of the bits back into one word. 545 */ 546 tcg_gen_extract2_tl(carryl, carryl, carryh, 4); 547 548 /* Invert, isolate the carry bits, and produce 6's. */ 549 tcg_gen_andc_tl(carryl, tcg_constant_tl(carry_bits), carryl); 550 tcg_gen_muli_tl(cpu_gpr[a->rt], carryl, 6); 551 return true; 552} 553 554static bool trans_CDTBCD(DisasContext *ctx, arg_X_sa *a) 555{ 556 REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206); 557 gen_helper_CDTBCD(cpu_gpr[a->ra], cpu_gpr[a->rs]); 558 return true; 559} 560 561static bool trans_CBCDTD(DisasContext *ctx, arg_X_sa *a) 562{ 563 REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206); 564 gen_helper_CBCDTD(cpu_gpr[a->ra], cpu_gpr[a->rs]); 565 return true; 566} 567 568static bool do_hash(DisasContext *ctx, arg_X *a, bool priv, 569 void (*helper)(TCGv_ptr, TCGv, TCGv, TCGv)) 570{ 571 TCGv ea; 572 573 if (!(ctx->insns_flags2 & PPC2_ISA310)) { 574 /* if version is before v3.1, this operation is a nop */ 575 return true; 576 } 577 578 if (priv) { 579 /* if instruction is privileged but the context is in user space */ 580 REQUIRE_SV(ctx); 581 } 582 583 if (unlikely(a->ra == 0)) { 584 /* if RA=0, the instruction form is invalid */ 585 gen_invalid(ctx); 586 return true; 587 } 588 589 ea = do_ea_calc(ctx, a->ra, tcg_constant_tl(a->rt)); 590 helper(tcg_env, ea, cpu_gpr[a->ra], cpu_gpr[a->rb]); 591 return true; 592} 593 594TRANS(HASHST, do_hash, false, gen_helper_HASHST) 595TRANS(HASHCHK, do_hash, false, gen_helper_HASHCHK) 596TRANS(HASHSTP, do_hash, true, gen_helper_HASHSTP) 597TRANS(HASHCHKP, do_hash, true, gen_helper_HASHCHKP) 598