xref: /openbmc/qemu/target/ppc/translate/fixedpoint-impl.c.inc (revision a1faff873ab1b808126a110aa6b3bc6050baa0f1)
199082815SRichard Henderson/*
299082815SRichard Henderson * Power ISA decode for Fixed-Point Facility instructions
399082815SRichard Henderson *
499082815SRichard Henderson * Copyright (c) 2021 Instituto de Pesquisas Eldorado (eldorado.org.br)
599082815SRichard Henderson *
699082815SRichard Henderson * This library is free software; you can redistribute it and/or
799082815SRichard Henderson * modify it under the terms of the GNU Lesser General Public
899082815SRichard Henderson * License as published by the Free Software Foundation; either
999082815SRichard Henderson * version 2.1 of the License, or (at your option) any later version.
1099082815SRichard Henderson *
1199082815SRichard Henderson * This library is distributed in the hope that it will be useful,
1299082815SRichard Henderson * but WITHOUT ANY WARRANTY; without even the implied warranty of
1399082815SRichard Henderson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1499082815SRichard Henderson * Lesser General Public License for more details.
1599082815SRichard Henderson *
1699082815SRichard Henderson * You should have received a copy of the GNU Lesser General Public
1799082815SRichard Henderson * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1899082815SRichard Henderson */
195e560864SRichard Henderson
205e560864SRichard Henderson/*
21f2aabda8SRichard Henderson * Fixed-Point Load/Store Instructions
22f2aabda8SRichard Henderson */
23f2aabda8SRichard Henderson
24f2aabda8SRichard Hendersonstatic bool do_ldst(DisasContext *ctx, int rt, int ra, TCGv displ, bool update,
25f2aabda8SRichard Henderson                    bool store, MemOp mop)
26f2aabda8SRichard Henderson{
27f2aabda8SRichard Henderson    TCGv ea;
28f2aabda8SRichard Henderson
29f2aabda8SRichard Henderson    if (update && (ra == 0 || (!store && ra == rt))) {
30f2aabda8SRichard Henderson        gen_invalid(ctx);
31f2aabda8SRichard Henderson        return true;
32f2aabda8SRichard Henderson    }
33f2aabda8SRichard Henderson    gen_set_access_type(ctx, ACCESS_INT);
34f2aabda8SRichard Henderson
35eb63efd9SFernando Eckhardt Valle    ea = do_ea_calc(ctx, ra, displ);
36f2aabda8SRichard Henderson    mop ^= ctx->default_tcg_memop_mask;
37f2aabda8SRichard Henderson    if (store) {
38f2aabda8SRichard Henderson        tcg_gen_qemu_st_tl(cpu_gpr[rt], ea, ctx->mem_idx, mop);
39f2aabda8SRichard Henderson    } else {
40f2aabda8SRichard Henderson        tcg_gen_qemu_ld_tl(cpu_gpr[rt], ea, ctx->mem_idx, mop);
41f2aabda8SRichard Henderson    }
42f2aabda8SRichard Henderson    if (update) {
43f2aabda8SRichard Henderson        tcg_gen_mov_tl(cpu_gpr[ra], ea);
44f2aabda8SRichard Henderson    }
45f2aabda8SRichard Henderson    return true;
46f2aabda8SRichard Henderson}
47f2aabda8SRichard Henderson
48f2aabda8SRichard Hendersonstatic bool do_ldst_D(DisasContext *ctx, arg_D *a, bool update, bool store,
49f2aabda8SRichard Henderson                      MemOp mop)
50f2aabda8SRichard Henderson{
51f2aabda8SRichard Henderson    return do_ldst(ctx, a->rt, a->ra, tcg_constant_tl(a->si), update, store, mop);
52f2aabda8SRichard Henderson}
53f2aabda8SRichard Henderson
5400e03265SRichard Hendersonstatic bool do_ldst_PLS_D(DisasContext *ctx, arg_PLS_D *a, bool update,
5500e03265SRichard Henderson                          bool store, MemOp mop)
5600e03265SRichard Henderson{
5700e03265SRichard Henderson    arg_D d;
5800e03265SRichard Henderson    if (!resolve_PLS_D(ctx, &d, a)) {
5900e03265SRichard Henderson        return true;
6000e03265SRichard Henderson    }
6100e03265SRichard Henderson    return do_ldst_D(ctx, &d, update, store, mop);
6200e03265SRichard Henderson}
6300e03265SRichard Henderson
64f2aabda8SRichard Hendersonstatic bool do_ldst_X(DisasContext *ctx, arg_X *a, bool update,
65f2aabda8SRichard Henderson                      bool store, MemOp mop)
66f2aabda8SRichard Henderson{
67f2aabda8SRichard Henderson    return do_ldst(ctx, a->rt, a->ra, cpu_gpr[a->rb], update, store, mop);
68f2aabda8SRichard Henderson}
69f2aabda8SRichard Henderson
70e10271e1SMatheus Ferststatic bool do_ldst_quad(DisasContext *ctx, arg_D *a, bool store, bool prefixed)
71e10271e1SMatheus Ferst{
72e10271e1SMatheus Ferst#if defined(TARGET_PPC64)
73e10271e1SMatheus Ferst    TCGv ea;
7471820935SNicholas Piggin    TCGv_i64 lo, hi;
7557b38ffdSRichard Henderson    TCGv_i128 t16;
76e10271e1SMatheus Ferst
77e10271e1SMatheus Ferst    REQUIRE_INSNS_FLAGS(ctx, 64BX);
78e10271e1SMatheus Ferst
79e10271e1SMatheus Ferst    if (!prefixed && !(ctx->insns_flags2 & PPC2_LSQ_ISA207)) {
80e10271e1SMatheus Ferst        /* lq and stq were privileged prior to V. 2.07 */
81fc34e81aSMatheus Ferst        REQUIRE_SV(ctx);
82e10271e1SMatheus Ferst
83e10271e1SMatheus Ferst        if (ctx->le_mode) {
84e10271e1SMatheus Ferst            gen_align_no_le(ctx);
85e10271e1SMatheus Ferst            return true;
86e10271e1SMatheus Ferst        }
87e10271e1SMatheus Ferst    }
88e10271e1SMatheus Ferst
89e10271e1SMatheus Ferst    if (!store && unlikely(a->ra == a->rt)) {
90e10271e1SMatheus Ferst        gen_invalid(ctx);
91e10271e1SMatheus Ferst        return true;
92e10271e1SMatheus Ferst    }
93e10271e1SMatheus Ferst
94e10271e1SMatheus Ferst    gen_set_access_type(ctx, ACCESS_INT);
95e10271e1SMatheus Ferst    ea = do_ea_calc(ctx, a->ra, tcg_constant_tl(a->si));
96e10271e1SMatheus Ferst
9771820935SNicholas Piggin    if (ctx->le_mode && prefixed) {
9871820935SNicholas Piggin        lo = cpu_gpr[a->rt];
9971820935SNicholas Piggin        hi = cpu_gpr[a->rt + 1];
100e10271e1SMatheus Ferst    } else {
10171820935SNicholas Piggin        lo = cpu_gpr[a->rt + 1];
10271820935SNicholas Piggin        hi = cpu_gpr[a->rt];
103e10271e1SMatheus Ferst    }
10457b38ffdSRichard Henderson    t16 = tcg_temp_new_i128();
105e10271e1SMatheus Ferst
106e10271e1SMatheus Ferst    if (store) {
10771820935SNicholas Piggin        tcg_gen_concat_i64_i128(t16, lo, hi);
10857b38ffdSRichard Henderson        tcg_gen_qemu_st_i128(t16, ea, ctx->mem_idx, DEF_MEMOP(MO_128));
109e10271e1SMatheus Ferst    } else {
11057b38ffdSRichard Henderson        tcg_gen_qemu_ld_i128(t16, ea, ctx->mem_idx, DEF_MEMOP(MO_128));
11171820935SNicholas Piggin        tcg_gen_extr_i128_i64(lo, hi, t16);
112e10271e1SMatheus Ferst    }
113e10271e1SMatheus Ferst#else
114e10271e1SMatheus Ferst    qemu_build_not_reached();
115e10271e1SMatheus Ferst#endif
116e10271e1SMatheus Ferst
117e10271e1SMatheus Ferst    return true;
118e10271e1SMatheus Ferst}
119e10271e1SMatheus Ferst
12049de0648SMatheus Ferststatic bool do_ldst_quad_PLS_D(DisasContext *ctx, arg_PLS_D *a, bool store)
12149de0648SMatheus Ferst{
12249de0648SMatheus Ferst    arg_D d;
12349de0648SMatheus Ferst    if (!resolve_PLS_D(ctx, &d, a)) {
12449de0648SMatheus Ferst        return true;
12549de0648SMatheus Ferst    }
12649de0648SMatheus Ferst
12749de0648SMatheus Ferst    return do_ldst_quad(ctx, &d, store, true);
12849de0648SMatheus Ferst}
12949de0648SMatheus Ferst
130f2aabda8SRichard Henderson/* Load Byte and Zero */
131f2aabda8SRichard HendersonTRANS(LBZ, do_ldst_D, false, false, MO_UB)
132f2aabda8SRichard HendersonTRANS(LBZX, do_ldst_X, false, false, MO_UB)
133f2aabda8SRichard HendersonTRANS(LBZU, do_ldst_D, true, false, MO_UB)
134f2aabda8SRichard HendersonTRANS(LBZUX, do_ldst_X, true, false, MO_UB)
13500e03265SRichard HendersonTRANS(PLBZ, do_ldst_PLS_D, false, false, MO_UB)
136f2aabda8SRichard Henderson
137f2aabda8SRichard Henderson/* Load Halfword and Zero */
138f2aabda8SRichard HendersonTRANS(LHZ, do_ldst_D, false, false, MO_UW)
139f2aabda8SRichard HendersonTRANS(LHZX, do_ldst_X, false, false, MO_UW)
140f2aabda8SRichard HendersonTRANS(LHZU, do_ldst_D, true, false, MO_UW)
141f2aabda8SRichard HendersonTRANS(LHZUX, do_ldst_X, true, false, MO_UW)
14200e03265SRichard HendersonTRANS(PLHZ, do_ldst_PLS_D, false, false, MO_UW)
143f2aabda8SRichard Henderson
144f2aabda8SRichard Henderson/* Load Halfword Algebraic */
145f2aabda8SRichard HendersonTRANS(LHA, do_ldst_D, false, false, MO_SW)
146f2aabda8SRichard HendersonTRANS(LHAX, do_ldst_X, false, false, MO_SW)
147f2aabda8SRichard HendersonTRANS(LHAU, do_ldst_D, true, false, MO_SW)
148f2aabda8SRichard HendersonTRANS(LHAXU, do_ldst_X, true, false, MO_SW)
14900e03265SRichard HendersonTRANS(PLHA, do_ldst_PLS_D, false, false, MO_SW)
150f2aabda8SRichard Henderson
151f2aabda8SRichard Henderson/* Load Word and Zero */
152f2aabda8SRichard HendersonTRANS(LWZ, do_ldst_D, false, false, MO_UL)
153f2aabda8SRichard HendersonTRANS(LWZX, do_ldst_X, false, false, MO_UL)
154f2aabda8SRichard HendersonTRANS(LWZU, do_ldst_D, true, false, MO_UL)
155f2aabda8SRichard HendersonTRANS(LWZUX, do_ldst_X, true, false, MO_UL)
15600e03265SRichard HendersonTRANS(PLWZ, do_ldst_PLS_D, false, false, MO_UL)
157f2aabda8SRichard Henderson
158f2aabda8SRichard Henderson/* Load Word Algebraic */
159f2aabda8SRichard HendersonTRANS64(LWA, do_ldst_D, false, false, MO_SL)
160f2aabda8SRichard HendersonTRANS64(LWAX, do_ldst_X, false, false, MO_SL)
161f2aabda8SRichard HendersonTRANS64(LWAUX, do_ldst_X, true, false, MO_SL)
16200e03265SRichard HendersonTRANS64(PLWA, do_ldst_PLS_D, false, false, MO_SL)
163f2aabda8SRichard Henderson
164f2aabda8SRichard Henderson/* Load Doubleword */
165fc313c64SFrédéric PétrotTRANS64(LD, do_ldst_D, false, false, MO_UQ)
166fc313c64SFrédéric PétrotTRANS64(LDX, do_ldst_X, false, false, MO_UQ)
167fc313c64SFrédéric PétrotTRANS64(LDU, do_ldst_D, true, false, MO_UQ)
168fc313c64SFrédéric PétrotTRANS64(LDUX, do_ldst_X, true, false, MO_UQ)
169fc313c64SFrédéric PétrotTRANS64(PLD, do_ldst_PLS_D, false, false, MO_UQ)
170f2aabda8SRichard Henderson
171e10271e1SMatheus Ferst/* Load Quadword */
172e10271e1SMatheus FerstTRANS64(LQ, do_ldst_quad, false, false);
17349de0648SMatheus FerstTRANS64(PLQ, do_ldst_quad_PLS_D, false);
174e10271e1SMatheus Ferst
175e8f4c8d6SRichard Henderson/* Store Byte */
176e8f4c8d6SRichard HendersonTRANS(STB, do_ldst_D, false, true, MO_UB)
177e8f4c8d6SRichard HendersonTRANS(STBX, do_ldst_X, false, true, MO_UB)
178e8f4c8d6SRichard HendersonTRANS(STBU, do_ldst_D, true, true, MO_UB)
179e8f4c8d6SRichard HendersonTRANS(STBUX, do_ldst_X, true, true, MO_UB)
180b0f7bebcSRichard HendersonTRANS(PSTB, do_ldst_PLS_D, false, true, MO_UB)
181e8f4c8d6SRichard Henderson
182e8f4c8d6SRichard Henderson/* Store Halfword */
183e8f4c8d6SRichard HendersonTRANS(STH, do_ldst_D, false, true, MO_UW)
184e8f4c8d6SRichard HendersonTRANS(STHX, do_ldst_X, false, true, MO_UW)
185e8f4c8d6SRichard HendersonTRANS(STHU, do_ldst_D, true, true, MO_UW)
186e8f4c8d6SRichard HendersonTRANS(STHUX, do_ldst_X, true, true, MO_UW)
187b0f7bebcSRichard HendersonTRANS(PSTH, do_ldst_PLS_D, false, true, MO_UW)
188e8f4c8d6SRichard Henderson
189e8f4c8d6SRichard Henderson/* Store Word */
190e8f4c8d6SRichard HendersonTRANS(STW, do_ldst_D, false, true, MO_UL)
191e8f4c8d6SRichard HendersonTRANS(STWX, do_ldst_X, false, true, MO_UL)
192e8f4c8d6SRichard HendersonTRANS(STWU, do_ldst_D, true, true, MO_UL)
193e8f4c8d6SRichard HendersonTRANS(STWUX, do_ldst_X, true, true, MO_UL)
194b0f7bebcSRichard HendersonTRANS(PSTW, do_ldst_PLS_D, false, true, MO_UL)
195e8f4c8d6SRichard Henderson
196e8f4c8d6SRichard Henderson/* Store Doubleword */
197fc313c64SFrédéric PétrotTRANS64(STD, do_ldst_D, false, true, MO_UQ)
198fc313c64SFrédéric PétrotTRANS64(STDX, do_ldst_X, false, true, MO_UQ)
199fc313c64SFrédéric PétrotTRANS64(STDU, do_ldst_D, true, true, MO_UQ)
200fc313c64SFrédéric PétrotTRANS64(STDUX, do_ldst_X, true, true, MO_UQ)
201fc313c64SFrédéric PétrotTRANS64(PSTD, do_ldst_PLS_D, false, true, MO_UQ)
202e8f4c8d6SRichard Henderson
203e10271e1SMatheus Ferst/* Store Quadword */
204e10271e1SMatheus FerstTRANS64(STQ, do_ldst_quad, true, false);
20549de0648SMatheus FerstTRANS64(PSTQ, do_ldst_quad_PLS_D, true);
206e10271e1SMatheus Ferst
207f2aabda8SRichard Henderson/*
2088f0a4b6aSMatheus Ferst * Fixed-Point Compare Instructions
2098f0a4b6aSMatheus Ferst */
2108f0a4b6aSMatheus Ferst
2118f0a4b6aSMatheus Ferststatic bool do_cmp_X(DisasContext *ctx, arg_X_bfl *a, bool s)
2128f0a4b6aSMatheus Ferst{
2132d1154bdSMatheus Ferst    if ((ctx->insns_flags & PPC_64B) == 0) {
2142d1154bdSMatheus Ferst        /*
2152d1154bdSMatheus Ferst         * For 32-bit implementations, The Programming Environments Manual says
2162d1154bdSMatheus Ferst         * that "the L field must be cleared, otherwise the instruction form is
2172d1154bdSMatheus Ferst         * invalid." It seems, however, that most 32-bit CPUs ignore invalid
2182d1154bdSMatheus Ferst         * forms (e.g., section "Instruction Formats" of the 405 and 440
2192d1154bdSMatheus Ferst         * manuals, "Integer Compare Instructions" of the 601 manual), with the
2202d1154bdSMatheus Ferst         * notable exception of the e500 and e500mc, where L=1 was reported to
2212d1154bdSMatheus Ferst         * cause an exception.
2222d1154bdSMatheus Ferst         */
2238f0a4b6aSMatheus Ferst        if (a->l) {
2242d1154bdSMatheus Ferst            if ((ctx->insns_flags2 & PPC2_BOOKE206)) {
2252d1154bdSMatheus Ferst                /*
2262d1154bdSMatheus Ferst                 * For 32-bit Book E v2.06 implementations (i.e. e500/e500mc),
2272d1154bdSMatheus Ferst                 * generate an illegal instruction exception.
2282d1154bdSMatheus Ferst                 */
2292d1154bdSMatheus Ferst                return false;
2302d1154bdSMatheus Ferst            } else {
2312d1154bdSMatheus Ferst                qemu_log_mask(LOG_GUEST_ERROR,
2322d1154bdSMatheus Ferst                        "Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n",
2332d1154bdSMatheus Ferst                        s ? "" : "L", ctx->cia);
2342d1154bdSMatheus Ferst            }
2352d1154bdSMatheus Ferst        }
2362d1154bdSMatheus Ferst        gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
2372d1154bdSMatheus Ferst        return true;
2382d1154bdSMatheus Ferst    }
2392d1154bdSMatheus Ferst
2402d1154bdSMatheus Ferst    /* For 64-bit implementations, deal with bit L accordingly. */
2412d1154bdSMatheus Ferst    if (a->l) {
2428f0a4b6aSMatheus Ferst        gen_op_cmp(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
2438f0a4b6aSMatheus Ferst    } else {
2448f0a4b6aSMatheus Ferst        gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
2458f0a4b6aSMatheus Ferst    }
2468f0a4b6aSMatheus Ferst    return true;
2478f0a4b6aSMatheus Ferst}
2488f0a4b6aSMatheus Ferst
2498f0a4b6aSMatheus Ferststatic bool do_cmp_D(DisasContext *ctx, arg_D_bf *a, bool s)
2508f0a4b6aSMatheus Ferst{
2512d1154bdSMatheus Ferst    if ((ctx->insns_flags & PPC_64B) == 0) {
2522d1154bdSMatheus Ferst        /*
2532d1154bdSMatheus Ferst         * For 32-bit implementations, The Programming Environments Manual says
2542d1154bdSMatheus Ferst         * that "the L field must be cleared, otherwise the instruction form is
2552d1154bdSMatheus Ferst         * invalid." It seems, however, that most 32-bit CPUs ignore invalid
2562d1154bdSMatheus Ferst         * forms (e.g., section "Instruction Formats" of the 405 and 440
2572d1154bdSMatheus Ferst         * manuals, "Integer Compare Instructions" of the 601 manual), with the
2582d1154bdSMatheus Ferst         * notable exception of the e500 and e500mc, where L=1 was reported to
2592d1154bdSMatheus Ferst         * cause an exception.
2602d1154bdSMatheus Ferst         */
2618f0a4b6aSMatheus Ferst        if (a->l) {
2622d1154bdSMatheus Ferst            if ((ctx->insns_flags2 & PPC2_BOOKE206)) {
2632d1154bdSMatheus Ferst                /*
2642d1154bdSMatheus Ferst                 * For 32-bit Book E v2.06 implementations (i.e. e500/e500mc),
2652d1154bdSMatheus Ferst                 * generate an illegal instruction exception.
2662d1154bdSMatheus Ferst                 */
2672d1154bdSMatheus Ferst                return false;
2682d1154bdSMatheus Ferst            } else {
2692d1154bdSMatheus Ferst                qemu_log_mask(LOG_GUEST_ERROR,
2702d1154bdSMatheus Ferst                        "Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n",
2712d1154bdSMatheus Ferst                        s ? "I" : "LI", ctx->cia);
2722d1154bdSMatheus Ferst            }
2732d1154bdSMatheus Ferst        }
2742d1154bdSMatheus Ferst        gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
2752d1154bdSMatheus Ferst        return true;
2762d1154bdSMatheus Ferst    }
2772d1154bdSMatheus Ferst
2782d1154bdSMatheus Ferst    /* For 64-bit implementations, deal with bit L accordingly. */
2792d1154bdSMatheus Ferst    if (a->l) {
2808f0a4b6aSMatheus Ferst        gen_op_cmp(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
2818f0a4b6aSMatheus Ferst    } else {
2828f0a4b6aSMatheus Ferst        gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
2838f0a4b6aSMatheus Ferst    }
2848f0a4b6aSMatheus Ferst    return true;
2858f0a4b6aSMatheus Ferst}
2868f0a4b6aSMatheus Ferst
2878f0a4b6aSMatheus FerstTRANS(CMP, do_cmp_X, true);
2888f0a4b6aSMatheus FerstTRANS(CMPL, do_cmp_X, false);
2898f0a4b6aSMatheus FerstTRANS(CMPI, do_cmp_D, true);
2908f0a4b6aSMatheus FerstTRANS(CMPLI, do_cmp_D, false);
2918f0a4b6aSMatheus Ferst
2928f0a4b6aSMatheus Ferst/*
293f2aabda8SRichard Henderson * Fixed-Point Arithmetic Instructions
294f2aabda8SRichard Henderson */
295f2aabda8SRichard Henderson
2965e560864SRichard Hendersonstatic bool trans_ADDI(DisasContext *ctx, arg_D *a)
2975e560864SRichard Henderson{
2985e560864SRichard Henderson    if (a->ra) {
2995e560864SRichard Henderson        tcg_gen_addi_tl(cpu_gpr[a->rt], cpu_gpr[a->ra], a->si);
3005e560864SRichard Henderson    } else {
3015e560864SRichard Henderson        tcg_gen_movi_tl(cpu_gpr[a->rt], a->si);
3025e560864SRichard Henderson    }
3035e560864SRichard Henderson    return true;
3045e560864SRichard Henderson}
3055e560864SRichard Henderson
3065e560864SRichard Hendersonstatic bool trans_PADDI(DisasContext *ctx, arg_PLS_D *a)
3075e560864SRichard Henderson{
3085e560864SRichard Henderson    arg_D d;
3095e560864SRichard Henderson    if (!resolve_PLS_D(ctx, &d, a)) {
3105e560864SRichard Henderson        return true;
3115e560864SRichard Henderson    }
3125e560864SRichard Henderson    return trans_ADDI(ctx, &d);
3135e560864SRichard Henderson}
3145e560864SRichard Henderson
3155e560864SRichard Hendersonstatic bool trans_ADDIS(DisasContext *ctx, arg_D *a)
3165e560864SRichard Henderson{
3175e560864SRichard Henderson    a->si <<= 16;
3185e560864SRichard Henderson    return trans_ADDI(ctx, a);
3195e560864SRichard Henderson}
3200a11bb7aSRichard Henderson
321e7a5d578SMatheus Ferststatic bool trans_ADDPCIS(DisasContext *ctx, arg_DX *a)
322e7a5d578SMatheus Ferst{
323e7a5d578SMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
324e7a5d578SMatheus Ferst    tcg_gen_movi_tl(cpu_gpr[a->rt], ctx->base.pc_next + (a->d << 16));
325e7a5d578SMatheus Ferst    return true;
326e7a5d578SMatheus Ferst}
327e7a5d578SMatheus Ferst
328a9bd40d9SChinmay Rathstatic bool trans_ADDEX(DisasContext *ctx, arg_X *a)
329a9bd40d9SChinmay Rath{
330a9bd40d9SChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
331a9bd40d9SChinmay Rath    gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
332a9bd40d9SChinmay Rath                     cpu_ov, cpu_ov32, true, true, false, false);
333a9bd40d9SChinmay Rath    return true;
334a9bd40d9SChinmay Rath}
335a9bd40d9SChinmay Rath
336a9bd40d9SChinmay Rathstatic bool do_add_D(DisasContext *ctx, arg_D *a, bool add_ca, bool compute_ca,
337a9bd40d9SChinmay Rath                     bool compute_ov, bool compute_rc0)
338a9bd40d9SChinmay Rath{
339a9bd40d9SChinmay Rath    gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra],
340a9bd40d9SChinmay Rath                     tcg_constant_tl(a->si), cpu_ca, cpu_ca32,
341a9bd40d9SChinmay Rath                     add_ca, compute_ca, compute_ov, compute_rc0);
342a9bd40d9SChinmay Rath    return true;
343a9bd40d9SChinmay Rath}
344a9bd40d9SChinmay Rath
345a9bd40d9SChinmay Rathstatic bool do_add_XO(DisasContext *ctx, arg_XO *a, bool add_ca,
346a9bd40d9SChinmay Rath                      bool compute_ca)
347a9bd40d9SChinmay Rath{
348a9bd40d9SChinmay Rath    gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
349a9bd40d9SChinmay Rath                     cpu_ca, cpu_ca32, add_ca, compute_ca, a->oe, a->rc);
350a9bd40d9SChinmay Rath    return true;
351a9bd40d9SChinmay Rath}
352a9bd40d9SChinmay Rath
353a9bd40d9SChinmay Rathstatic bool do_add_const_XO(DisasContext *ctx, arg_XO_ta *a, TCGv const_val,
354a9bd40d9SChinmay Rath                            bool add_ca, bool compute_ca)
355a9bd40d9SChinmay Rath{
356a9bd40d9SChinmay Rath    gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], const_val,
357a9bd40d9SChinmay Rath                     cpu_ca, cpu_ca32, add_ca, compute_ca, a->oe, a->rc);
358a9bd40d9SChinmay Rath    return true;
359a9bd40d9SChinmay Rath}
360a9bd40d9SChinmay Rath
361a9bd40d9SChinmay RathTRANS(ADD, do_add_XO, false, false);
362a9bd40d9SChinmay RathTRANS(ADDC, do_add_XO, false, true);
363a9bd40d9SChinmay RathTRANS(ADDE, do_add_XO, true, true);
364a9bd40d9SChinmay RathTRANS(ADDME, do_add_const_XO, tcg_constant_tl(-1LL), true, true);
365a9bd40d9SChinmay RathTRANS(ADDZE, do_add_const_XO, tcg_constant_tl(0), true, true);
366a9bd40d9SChinmay RathTRANS(ADDIC, do_add_D, false, true, false, false);
367a9bd40d9SChinmay RathTRANS(ADDIC_, do_add_D, false, true, false, true);
368a9bd40d9SChinmay Rath
369a9bd40d9SChinmay Rathstatic bool trans_SUBFIC(DisasContext *ctx, arg_D *a)
370a9bd40d9SChinmay Rath{
371a9bd40d9SChinmay Rath    gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra],
372a9bd40d9SChinmay Rath                      tcg_constant_tl(a->si), false, true, false, false);
373a9bd40d9SChinmay Rath    return true;
374a9bd40d9SChinmay Rath}
375a9bd40d9SChinmay Rath
376a9bd40d9SChinmay Rathstatic bool do_subf_XO(DisasContext *ctx, arg_XO *a, bool add_ca,
377a9bd40d9SChinmay Rath                       bool compute_ca)
378a9bd40d9SChinmay Rath{
379a9bd40d9SChinmay Rath    gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
380a9bd40d9SChinmay Rath                      add_ca, compute_ca, a->oe, a->rc);
381a9bd40d9SChinmay Rath    return true;
382a9bd40d9SChinmay Rath}
383a9bd40d9SChinmay Rath
384a9bd40d9SChinmay Rathstatic bool do_subf_const_XO(DisasContext *ctx, arg_XO_ta *a, TCGv const_val,
385a9bd40d9SChinmay Rath                             bool add_ca, bool compute_ca)
386a9bd40d9SChinmay Rath{
387a9bd40d9SChinmay Rath    gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], const_val,
388a9bd40d9SChinmay Rath                      add_ca, compute_ca, a->oe, a->rc);
389a9bd40d9SChinmay Rath    return true;
390a9bd40d9SChinmay Rath}
391a9bd40d9SChinmay Rath
392a9bd40d9SChinmay RathTRANS(SUBF, do_subf_XO, false, false)
393a9bd40d9SChinmay RathTRANS(SUBFC, do_subf_XO, false, true)
394a9bd40d9SChinmay RathTRANS(SUBFE, do_subf_XO, true, true)
395a9bd40d9SChinmay RathTRANS(SUBFME, do_subf_const_XO, tcg_constant_tl(-1LL), true, true)
396a9bd40d9SChinmay RathTRANS(SUBFZE, do_subf_const_XO, tcg_constant_tl(0), true, true)
397a9bd40d9SChinmay Rath
398*a1faff87SChinmay Rathstatic bool trans_MULLI(DisasContext *ctx, arg_MULLI *a)
399*a1faff87SChinmay Rath{
400*a1faff87SChinmay Rath    tcg_gen_muli_tl(cpu_gpr[a->rt], cpu_gpr[a->ra], a->si);
401*a1faff87SChinmay Rath    return true;
402*a1faff87SChinmay Rath}
403*a1faff87SChinmay Rath
404*a1faff87SChinmay Rathstatic bool trans_MULLW(DisasContext *ctx, arg_MULLW *a)
405*a1faff87SChinmay Rath{
406*a1faff87SChinmay Rath    TCGv t0 = tcg_temp_new();
407*a1faff87SChinmay Rath    TCGv t1 = tcg_temp_new();
408*a1faff87SChinmay Rath
409*a1faff87SChinmay Rath    tcg_gen_ext32s_tl(t0, cpu_gpr[a->ra]);
410*a1faff87SChinmay Rath    tcg_gen_ext32s_tl(t1, cpu_gpr[a->rb]);
411*a1faff87SChinmay Rath    tcg_gen_mul_tl(cpu_gpr[a->rt], t0, t1);
412*a1faff87SChinmay Rath    if (unlikely(a->rc)) {
413*a1faff87SChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
414*a1faff87SChinmay Rath    }
415*a1faff87SChinmay Rath    return true;
416*a1faff87SChinmay Rath}
417*a1faff87SChinmay Rath
418*a1faff87SChinmay Rathstatic bool trans_MULLWO(DisasContext *ctx, arg_MULLWO *a)
419*a1faff87SChinmay Rath{
420*a1faff87SChinmay Rath    TCGv t0 = tcg_temp_new();
421*a1faff87SChinmay Rath    TCGv t1 = tcg_temp_new();
422*a1faff87SChinmay Rath
423*a1faff87SChinmay Rath#if defined(TARGET_PPC64)
424*a1faff87SChinmay Rath    tcg_gen_ext32s_i64(t0, cpu_gpr[a->ra]);
425*a1faff87SChinmay Rath    tcg_gen_ext32s_i64(t1, cpu_gpr[a->rb]);
426*a1faff87SChinmay Rath    tcg_gen_mul_i64(cpu_gpr[a->rt], t0, t1);
427*a1faff87SChinmay Rath    tcg_gen_sextract_i64(t0, cpu_gpr[a->rt], 31, 1);
428*a1faff87SChinmay Rath    tcg_gen_sari_i64(t1, cpu_gpr[a->rt], 32);
429*a1faff87SChinmay Rath#else
430*a1faff87SChinmay Rath    tcg_gen_muls2_i32(cpu_gpr[a->rt], t1, cpu_gpr[a->ra], cpu_gpr[a->rb]);
431*a1faff87SChinmay Rath    tcg_gen_sari_i32(t0, cpu_gpr[a->rt], 31);
432*a1faff87SChinmay Rath#endif
433*a1faff87SChinmay Rath    tcg_gen_setcond_tl(TCG_COND_NE, cpu_ov, t0, t1);
434*a1faff87SChinmay Rath    if (is_isa300(ctx)) {
435*a1faff87SChinmay Rath        tcg_gen_mov_tl(cpu_ov32, cpu_ov);
436*a1faff87SChinmay Rath    }
437*a1faff87SChinmay Rath    tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
438*a1faff87SChinmay Rath
439*a1faff87SChinmay Rath    if (unlikely(a->rc)) {
440*a1faff87SChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
441*a1faff87SChinmay Rath    }
442*a1faff87SChinmay Rath    return true;
443*a1faff87SChinmay Rath}
444*a1faff87SChinmay Rath
445*a1faff87SChinmay Rathstatic bool do_mulhw(DisasContext *ctx, arg_XO_tab_rc *a,
446*a1faff87SChinmay Rath                     void (*helper)(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1,
447*a1faff87SChinmay Rath                                    TCGv_i32 arg2))
448*a1faff87SChinmay Rath{
449*a1faff87SChinmay Rath    TCGv_i32 t0 = tcg_temp_new_i32();
450*a1faff87SChinmay Rath    TCGv_i32 t1 = tcg_temp_new_i32();
451*a1faff87SChinmay Rath    tcg_gen_trunc_tl_i32(t0, cpu_gpr[a->ra]);
452*a1faff87SChinmay Rath    tcg_gen_trunc_tl_i32(t1, cpu_gpr[a->rb]);
453*a1faff87SChinmay Rath    helper(t0, t1, t0, t1);
454*a1faff87SChinmay Rath    tcg_gen_extu_i32_tl(cpu_gpr[a->rt], t1);
455*a1faff87SChinmay Rath    if (unlikely(a->rc)) {
456*a1faff87SChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
457*a1faff87SChinmay Rath    }
458*a1faff87SChinmay Rath    return true;
459*a1faff87SChinmay Rath}
460*a1faff87SChinmay Rath
461*a1faff87SChinmay RathTRANS(MULHW, do_mulhw, tcg_gen_muls2_i32)
462*a1faff87SChinmay RathTRANS(MULHWU, do_mulhw, tcg_gen_mulu2_i32)
463*a1faff87SChinmay Rath
4640a11bb7aSRichard Hendersonstatic bool trans_INVALID(DisasContext *ctx, arg_INVALID *a)
4650a11bb7aSRichard Henderson{
4660a11bb7aSRichard Henderson    gen_invalid(ctx);
4670a11bb7aSRichard Henderson    return true;
4680a11bb7aSRichard Henderson}
4690a11bb7aSRichard Henderson
4700a11bb7aSRichard Hendersonstatic bool trans_PNOP(DisasContext *ctx, arg_PNOP *a)
4710a11bb7aSRichard Henderson{
4720a11bb7aSRichard Henderson    return true;
4730a11bb7aSRichard Henderson}
4749a14365eSMatheus Ferst
4759a14365eSMatheus Ferststatic bool do_set_bool_cond(DisasContext *ctx, arg_X_bi *a, bool neg, bool rev)
4769a14365eSMatheus Ferst{
4779a14365eSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
4789a14365eSMatheus Ferst    uint32_t mask = 0x08 >> (a->bi & 0x03);
4799a14365eSMatheus Ferst    TCGCond cond = rev ? TCG_COND_EQ : TCG_COND_NE;
4809a14365eSMatheus Ferst    TCGv temp = tcg_temp_new();
481253d110dSRichard Henderson    TCGv zero = tcg_constant_tl(0);
4829a14365eSMatheus Ferst
4839a14365eSMatheus Ferst    tcg_gen_extu_i32_tl(temp, cpu_crf[a->bi >> 2]);
4849a14365eSMatheus Ferst    tcg_gen_andi_tl(temp, temp, mask);
4859a14365eSMatheus Ferst    if (neg) {
486253d110dSRichard Henderson        tcg_gen_negsetcond_tl(cond, cpu_gpr[a->rt], temp, zero);
487253d110dSRichard Henderson    } else {
488253d110dSRichard Henderson        tcg_gen_setcond_tl(cond, cpu_gpr[a->rt], temp, zero);
4899a14365eSMatheus Ferst    }
4909a14365eSMatheus Ferst    return true;
4919a14365eSMatheus Ferst}
4929a14365eSMatheus Ferst
4939a14365eSMatheus FerstTRANS(SETBC, do_set_bool_cond, false, false)
4949a14365eSMatheus FerstTRANS(SETBCR, do_set_bool_cond, false, true)
4959a14365eSMatheus FerstTRANS(SETNBC, do_set_bool_cond, true, false)
4969a14365eSMatheus FerstTRANS(SETNBCR, do_set_bool_cond, true, true)
49789ccd7dcSMatheus Ferst
49889ccd7dcSMatheus Ferststatic bool trans_CFUGED(DisasContext *ctx, arg_X *a)
49989ccd7dcSMatheus Ferst{
50089ccd7dcSMatheus Ferst    REQUIRE_64BIT(ctx);
50189ccd7dcSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
50289ccd7dcSMatheus Ferst#if defined(TARGET_PPC64)
5036e0bbc40SMatheus Ferst    gen_helper_CFUGED(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
50489ccd7dcSMatheus Ferst#else
50589ccd7dcSMatheus Ferst    qemu_build_not_reached();
50689ccd7dcSMatheus Ferst#endif
50789ccd7dcSMatheus Ferst    return true;
50889ccd7dcSMatheus Ferst}
50982be6e02SLuis Pires
510a2c975e1SMatheus Ferststatic void do_cntzdm(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 mask, int64_t trail)
51182be6e02SLuis Pires{
512ab1e25adSMatheus Ferst    TCGv_i64 t0, t1;
51382be6e02SLuis Pires
514ab1e25adSMatheus Ferst    t0 = tcg_temp_new_i64();
515ab1e25adSMatheus Ferst    t1 = tcg_temp_new_i64();
51682be6e02SLuis Pires
517ab1e25adSMatheus Ferst    tcg_gen_and_i64(t0, src, mask);
518f356b3baSLuis Pires    if (trail) {
519ab1e25adSMatheus Ferst        tcg_gen_ctzi_i64(t0, t0, -1);
520f356b3baSLuis Pires    } else {
521ab1e25adSMatheus Ferst        tcg_gen_clzi_i64(t0, t0, -1);
522f356b3baSLuis Pires    }
52382be6e02SLuis Pires
524ab1e25adSMatheus Ferst    tcg_gen_setcondi_i64(TCG_COND_NE, t1, t0, -1);
525ab1e25adSMatheus Ferst    tcg_gen_andi_i64(t0, t0, 63);
526ab1e25adSMatheus Ferst    tcg_gen_xori_i64(t0, t0, 63);
527f356b3baSLuis Pires    if (trail) {
528ab1e25adSMatheus Ferst        tcg_gen_shl_i64(t0, mask, t0);
529ab1e25adSMatheus Ferst        tcg_gen_shl_i64(t0, t0, t1);
530f356b3baSLuis Pires    } else {
531ab1e25adSMatheus Ferst        tcg_gen_shr_i64(t0, mask, t0);
532ab1e25adSMatheus Ferst        tcg_gen_shr_i64(t0, t0, t1);
533f356b3baSLuis Pires    }
53482be6e02SLuis Pires
535ab1e25adSMatheus Ferst    tcg_gen_ctpop_i64(dst, t0);
53682be6e02SLuis Pires}
53782be6e02SLuis Pires
53882be6e02SLuis Piresstatic bool trans_CNTLZDM(DisasContext *ctx, arg_X *a)
53982be6e02SLuis Pires{
54082be6e02SLuis Pires    REQUIRE_64BIT(ctx);
54182be6e02SLuis Pires    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
54282be6e02SLuis Pires#if defined(TARGET_PPC64)
543f356b3baSLuis Pires    do_cntzdm(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb], false);
544f356b3baSLuis Pires#else
545f356b3baSLuis Pires    qemu_build_not_reached();
546f356b3baSLuis Pires#endif
547f356b3baSLuis Pires    return true;
548f356b3baSLuis Pires}
549f356b3baSLuis Pires
550f356b3baSLuis Piresstatic bool trans_CNTTZDM(DisasContext *ctx, arg_X *a)
551f356b3baSLuis Pires{
552f356b3baSLuis Pires    REQUIRE_64BIT(ctx);
553f356b3baSLuis Pires    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
554f356b3baSLuis Pires#if defined(TARGET_PPC64)
555f356b3baSLuis Pires    do_cntzdm(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb], true);
55682be6e02SLuis Pires#else
55782be6e02SLuis Pires    qemu_build_not_reached();
55882be6e02SLuis Pires#endif
55982be6e02SLuis Pires    return true;
56082be6e02SLuis Pires}
56121ba6e58SMatheus Ferst
56221ba6e58SMatheus Ferststatic bool trans_PDEPD(DisasContext *ctx, arg_X *a)
56321ba6e58SMatheus Ferst{
56421ba6e58SMatheus Ferst    REQUIRE_64BIT(ctx);
56521ba6e58SMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
56621ba6e58SMatheus Ferst#if defined(TARGET_PPC64)
56721ba6e58SMatheus Ferst    gen_helper_PDEPD(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
56821ba6e58SMatheus Ferst#else
56921ba6e58SMatheus Ferst    qemu_build_not_reached();
57021ba6e58SMatheus Ferst#endif
57121ba6e58SMatheus Ferst    return true;
57221ba6e58SMatheus Ferst}
5738bdb7606SMatheus Ferst
5748bdb7606SMatheus Ferststatic bool trans_PEXTD(DisasContext *ctx, arg_X *a)
5758bdb7606SMatheus Ferst{
5768bdb7606SMatheus Ferst    REQUIRE_64BIT(ctx);
5778bdb7606SMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
5788bdb7606SMatheus Ferst#if defined(TARGET_PPC64)
5798bdb7606SMatheus Ferst    gen_helper_PEXTD(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
5808bdb7606SMatheus Ferst#else
5818bdb7606SMatheus Ferst    qemu_build_not_reached();
5828bdb7606SMatheus Ferst#endif
5838bdb7606SMatheus Ferst    return true;
5848bdb7606SMatheus Ferst}
5856addef4dSMatheus Ferst
5866addef4dSMatheus Ferststatic bool trans_ADDG6S(DisasContext *ctx, arg_X *a)
5876addef4dSMatheus Ferst{
5884fe0e9dbSRichard Henderson    const target_ulong carry_bits = (target_ulong)-1 / 0xf;
5894fe0e9dbSRichard Henderson    TCGv in1, in2, carryl, carryh, tmp;
5904fe0e9dbSRichard Henderson    TCGv zero = tcg_constant_tl(0);
5916addef4dSMatheus Ferst
5926addef4dSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206);
5936addef4dSMatheus Ferst
5944fe0e9dbSRichard Henderson    in1 = cpu_gpr[a->ra];
5954fe0e9dbSRichard Henderson    in2 = cpu_gpr[a->rb];
5964fe0e9dbSRichard Henderson    tmp = tcg_temp_new();
5974fe0e9dbSRichard Henderson    carryl = tcg_temp_new();
5984fe0e9dbSRichard Henderson    carryh = tcg_temp_new();
5996addef4dSMatheus Ferst
6004fe0e9dbSRichard Henderson    /* Addition with carry. */
6014fe0e9dbSRichard Henderson    tcg_gen_add2_tl(carryl, carryh, in1, zero, in2, zero);
6024fe0e9dbSRichard Henderson    /* Addition without carry. */
6034fe0e9dbSRichard Henderson    tcg_gen_xor_tl(tmp, in1, in2);
6044fe0e9dbSRichard Henderson    /* Difference between the two is carry in to each bit. */
6054fe0e9dbSRichard Henderson    tcg_gen_xor_tl(carryl, carryl, tmp);
6066addef4dSMatheus Ferst
6074fe0e9dbSRichard Henderson    /*
6084fe0e9dbSRichard Henderson     * The carry-out that we're looking for is the carry-in to
6094fe0e9dbSRichard Henderson     * the next nibble.  Shift the double-word down one nibble,
6104fe0e9dbSRichard Henderson     * which puts all of the bits back into one word.
6114fe0e9dbSRichard Henderson     */
6124fe0e9dbSRichard Henderson    tcg_gen_extract2_tl(carryl, carryl, carryh, 4);
6136addef4dSMatheus Ferst
6144fe0e9dbSRichard Henderson    /* Invert, isolate the carry bits, and produce 6's. */
6154fe0e9dbSRichard Henderson    tcg_gen_andc_tl(carryl, tcg_constant_tl(carry_bits), carryl);
6164fe0e9dbSRichard Henderson    tcg_gen_muli_tl(cpu_gpr[a->rt], carryl, 6);
6176addef4dSMatheus Ferst    return true;
6186addef4dSMatheus Ferst}
61938d3690bSMatheus Ferst
6206b924d4aSMatheus Ferststatic bool trans_CDTBCD(DisasContext *ctx, arg_X_sa *a)
6216b924d4aSMatheus Ferst{
6226b924d4aSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206);
6236b924d4aSMatheus Ferst    gen_helper_CDTBCD(cpu_gpr[a->ra], cpu_gpr[a->rs]);
6246b924d4aSMatheus Ferst    return true;
6256b924d4aSMatheus Ferst}
6266b924d4aSMatheus Ferst
62738d3690bSMatheus Ferststatic bool trans_CBCDTD(DisasContext *ctx, arg_X_sa *a)
62838d3690bSMatheus Ferst{
62938d3690bSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206);
63038d3690bSMatheus Ferst    gen_helper_CBCDTD(cpu_gpr[a->ra], cpu_gpr[a->rs]);
63138d3690bSMatheus Ferst    return true;
63238d3690bSMatheus Ferst}
633670f1da3SVíctor Colombo
634670f1da3SVíctor Colombostatic bool do_hash(DisasContext *ctx, arg_X *a, bool priv,
635670f1da3SVíctor Colombo    void (*helper)(TCGv_ptr, TCGv, TCGv, TCGv))
636670f1da3SVíctor Colombo{
637670f1da3SVíctor Colombo    TCGv ea;
638670f1da3SVíctor Colombo
639670f1da3SVíctor Colombo    if (!(ctx->insns_flags2 & PPC2_ISA310)) {
640670f1da3SVíctor Colombo        /* if version is before v3.1, this operation is a nop */
641670f1da3SVíctor Colombo        return true;
642670f1da3SVíctor Colombo    }
643670f1da3SVíctor Colombo
644670f1da3SVíctor Colombo    if (priv) {
645670f1da3SVíctor Colombo        /* if instruction is privileged but the context is in user space */
646670f1da3SVíctor Colombo        REQUIRE_SV(ctx);
647670f1da3SVíctor Colombo    }
648670f1da3SVíctor Colombo
649670f1da3SVíctor Colombo    if (unlikely(a->ra == 0)) {
650670f1da3SVíctor Colombo        /* if RA=0, the instruction form is invalid */
651670f1da3SVíctor Colombo        gen_invalid(ctx);
652670f1da3SVíctor Colombo        return true;
653670f1da3SVíctor Colombo    }
654670f1da3SVíctor Colombo
655670f1da3SVíctor Colombo    ea = do_ea_calc(ctx, a->ra, tcg_constant_tl(a->rt));
656ad75a51eSRichard Henderson    helper(tcg_env, ea, cpu_gpr[a->ra], cpu_gpr[a->rb]);
657670f1da3SVíctor Colombo    return true;
658670f1da3SVíctor Colombo}
659670f1da3SVíctor Colombo
660670f1da3SVíctor ColomboTRANS(HASHST, do_hash, false, gen_helper_HASHST)
661670f1da3SVíctor ColomboTRANS(HASHCHK, do_hash, false, gen_helper_HASHCHK)
66253ae2aebSVíctor ColomboTRANS(HASHSTP, do_hash, true, gen_helper_HASHSTP)
66353ae2aebSVíctor ColomboTRANS(HASHCHKP, do_hash, true, gen_helper_HASHCHKP)
664