xref: /openbmc/qemu/target/ppc/translate/fixedpoint-impl.c.inc (revision ffdd099a782556b9ead26551a6f1d070a595306d)
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
292ae556c6aSChinmay Rathstatic bool trans_CMPRB(DisasContext *ctx, arg_CMPRB *a)
293ae556c6aSChinmay Rath{
294ae556c6aSChinmay Rath    TCGv_i32 src1 = tcg_temp_new_i32();
295ae556c6aSChinmay Rath    TCGv_i32 src2 = tcg_temp_new_i32();
296ae556c6aSChinmay Rath    TCGv_i32 src2lo = tcg_temp_new_i32();
297ae556c6aSChinmay Rath    TCGv_i32 src2hi = tcg_temp_new_i32();
298ae556c6aSChinmay Rath    TCGv_i32 crf = cpu_crf[a->bf];
299ae556c6aSChinmay Rath
300ae556c6aSChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
301ae556c6aSChinmay Rath    tcg_gen_trunc_tl_i32(src1, cpu_gpr[a->ra]);
302ae556c6aSChinmay Rath    tcg_gen_trunc_tl_i32(src2, cpu_gpr[a->rb]);
303ae556c6aSChinmay Rath
304ae556c6aSChinmay Rath    tcg_gen_andi_i32(src1, src1, 0xFF);
305ae556c6aSChinmay Rath    tcg_gen_ext8u_i32(src2lo, src2);
306ae556c6aSChinmay Rath    tcg_gen_extract_i32(src2hi, src2, 8, 8);
307ae556c6aSChinmay Rath
308ae556c6aSChinmay Rath    tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
309ae556c6aSChinmay Rath    tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
310ae556c6aSChinmay Rath    tcg_gen_and_i32(crf, src2lo, src2hi);
311ae556c6aSChinmay Rath
312ae556c6aSChinmay Rath    if (a->l) {
313ae556c6aSChinmay Rath        tcg_gen_extract_i32(src2lo, src2, 16, 8);
314ae556c6aSChinmay Rath        tcg_gen_extract_i32(src2hi, src2, 24, 8);
315ae556c6aSChinmay Rath        tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
316ae556c6aSChinmay Rath        tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
317ae556c6aSChinmay Rath        tcg_gen_and_i32(src2lo, src2lo, src2hi);
318ae556c6aSChinmay Rath        tcg_gen_or_i32(crf, crf, src2lo);
319ae556c6aSChinmay Rath    }
320ae556c6aSChinmay Rath    tcg_gen_shli_i32(crf, crf, CRF_GT_BIT);
321ae556c6aSChinmay Rath    return true;
322ae556c6aSChinmay Rath}
323ae556c6aSChinmay Rath
324ae556c6aSChinmay Rathstatic bool trans_CMPEQB(DisasContext *ctx, arg_CMPEQB *a)
325ae556c6aSChinmay Rath{
326ae556c6aSChinmay Rath    REQUIRE_64BIT(ctx);
327ae556c6aSChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
328ae556c6aSChinmay Rath#if defined(TARGET_PPC64)
329ae556c6aSChinmay Rath    gen_helper_CMPEQB(cpu_crf[a->bf], cpu_gpr[a->ra], cpu_gpr[a->rb]);
330ae556c6aSChinmay Rath#else
331ae556c6aSChinmay Rath    qemu_build_not_reached();
332ae556c6aSChinmay Rath#endif
333ae556c6aSChinmay Rath    return true;
334ae556c6aSChinmay Rath}
335ae556c6aSChinmay Rath
3368f0a4b6aSMatheus Ferst/*
337f2aabda8SRichard Henderson * Fixed-Point Arithmetic Instructions
338f2aabda8SRichard Henderson */
339f2aabda8SRichard Henderson
3405e560864SRichard Hendersonstatic bool trans_ADDI(DisasContext *ctx, arg_D *a)
3415e560864SRichard Henderson{
3425e560864SRichard Henderson    if (a->ra) {
3435e560864SRichard Henderson        tcg_gen_addi_tl(cpu_gpr[a->rt], cpu_gpr[a->ra], a->si);
3445e560864SRichard Henderson    } else {
3455e560864SRichard Henderson        tcg_gen_movi_tl(cpu_gpr[a->rt], a->si);
3465e560864SRichard Henderson    }
3475e560864SRichard Henderson    return true;
3485e560864SRichard Henderson}
3495e560864SRichard Henderson
3505e560864SRichard Hendersonstatic bool trans_PADDI(DisasContext *ctx, arg_PLS_D *a)
3515e560864SRichard Henderson{
3525e560864SRichard Henderson    arg_D d;
3535e560864SRichard Henderson    if (!resolve_PLS_D(ctx, &d, a)) {
3545e560864SRichard Henderson        return true;
3555e560864SRichard Henderson    }
3565e560864SRichard Henderson    return trans_ADDI(ctx, &d);
3575e560864SRichard Henderson}
3585e560864SRichard Henderson
3595e560864SRichard Hendersonstatic bool trans_ADDIS(DisasContext *ctx, arg_D *a)
3605e560864SRichard Henderson{
3615e560864SRichard Henderson    a->si <<= 16;
3625e560864SRichard Henderson    return trans_ADDI(ctx, a);
3635e560864SRichard Henderson}
3640a11bb7aSRichard Henderson
365e7a5d578SMatheus Ferststatic bool trans_ADDPCIS(DisasContext *ctx, arg_DX *a)
366e7a5d578SMatheus Ferst{
367e7a5d578SMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
368e7a5d578SMatheus Ferst    tcg_gen_movi_tl(cpu_gpr[a->rt], ctx->base.pc_next + (a->d << 16));
369e7a5d578SMatheus Ferst    return true;
370e7a5d578SMatheus Ferst}
371e7a5d578SMatheus Ferst
372a9bd40d9SChinmay Rathstatic bool trans_ADDEX(DisasContext *ctx, arg_X *a)
373a9bd40d9SChinmay Rath{
374a9bd40d9SChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
375a9bd40d9SChinmay Rath    gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
376a9bd40d9SChinmay Rath                     cpu_ov, cpu_ov32, true, true, false, false);
377a9bd40d9SChinmay Rath    return true;
378a9bd40d9SChinmay Rath}
379a9bd40d9SChinmay Rath
380a9bd40d9SChinmay Rathstatic bool do_add_D(DisasContext *ctx, arg_D *a, bool add_ca, bool compute_ca,
381a9bd40d9SChinmay Rath                     bool compute_ov, bool compute_rc0)
382a9bd40d9SChinmay Rath{
383a9bd40d9SChinmay Rath    gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra],
384a9bd40d9SChinmay Rath                     tcg_constant_tl(a->si), cpu_ca, cpu_ca32,
385a9bd40d9SChinmay Rath                     add_ca, compute_ca, compute_ov, compute_rc0);
386a9bd40d9SChinmay Rath    return true;
387a9bd40d9SChinmay Rath}
388a9bd40d9SChinmay Rath
389a9bd40d9SChinmay Rathstatic bool do_add_XO(DisasContext *ctx, arg_XO *a, bool add_ca,
390a9bd40d9SChinmay Rath                      bool compute_ca)
391a9bd40d9SChinmay Rath{
392a9bd40d9SChinmay Rath    gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
393a9bd40d9SChinmay Rath                     cpu_ca, cpu_ca32, add_ca, compute_ca, a->oe, a->rc);
394a9bd40d9SChinmay Rath    return true;
395a9bd40d9SChinmay Rath}
396a9bd40d9SChinmay Rath
397a9bd40d9SChinmay Rathstatic bool do_add_const_XO(DisasContext *ctx, arg_XO_ta *a, TCGv const_val,
398a9bd40d9SChinmay Rath                            bool add_ca, bool compute_ca)
399a9bd40d9SChinmay Rath{
400a9bd40d9SChinmay Rath    gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], const_val,
401a9bd40d9SChinmay Rath                     cpu_ca, cpu_ca32, add_ca, compute_ca, a->oe, a->rc);
402a9bd40d9SChinmay Rath    return true;
403a9bd40d9SChinmay Rath}
404a9bd40d9SChinmay Rath
405a9bd40d9SChinmay RathTRANS(ADD, do_add_XO, false, false);
406a9bd40d9SChinmay RathTRANS(ADDC, do_add_XO, false, true);
407a9bd40d9SChinmay RathTRANS(ADDE, do_add_XO, true, true);
408a9bd40d9SChinmay RathTRANS(ADDME, do_add_const_XO, tcg_constant_tl(-1LL), true, true);
409a9bd40d9SChinmay RathTRANS(ADDZE, do_add_const_XO, tcg_constant_tl(0), true, true);
410a9bd40d9SChinmay RathTRANS(ADDIC, do_add_D, false, true, false, false);
411a9bd40d9SChinmay RathTRANS(ADDIC_, do_add_D, false, true, false, true);
412a9bd40d9SChinmay Rath
413a9bd40d9SChinmay Rathstatic bool trans_SUBFIC(DisasContext *ctx, arg_D *a)
414a9bd40d9SChinmay Rath{
415a9bd40d9SChinmay Rath    gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra],
416a9bd40d9SChinmay Rath                      tcg_constant_tl(a->si), false, true, false, false);
417a9bd40d9SChinmay Rath    return true;
418a9bd40d9SChinmay Rath}
419a9bd40d9SChinmay Rath
420a9bd40d9SChinmay Rathstatic bool do_subf_XO(DisasContext *ctx, arg_XO *a, bool add_ca,
421a9bd40d9SChinmay Rath                       bool compute_ca)
422a9bd40d9SChinmay Rath{
423a9bd40d9SChinmay Rath    gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
424a9bd40d9SChinmay Rath                      add_ca, compute_ca, a->oe, a->rc);
425a9bd40d9SChinmay Rath    return true;
426a9bd40d9SChinmay Rath}
427a9bd40d9SChinmay Rath
428a9bd40d9SChinmay Rathstatic bool do_subf_const_XO(DisasContext *ctx, arg_XO_ta *a, TCGv const_val,
429a9bd40d9SChinmay Rath                             bool add_ca, bool compute_ca)
430a9bd40d9SChinmay Rath{
431a9bd40d9SChinmay Rath    gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], const_val,
432a9bd40d9SChinmay Rath                      add_ca, compute_ca, a->oe, a->rc);
433a9bd40d9SChinmay Rath    return true;
434a9bd40d9SChinmay Rath}
435a9bd40d9SChinmay Rath
436a9bd40d9SChinmay RathTRANS(SUBF, do_subf_XO, false, false)
437a9bd40d9SChinmay RathTRANS(SUBFC, do_subf_XO, false, true)
438a9bd40d9SChinmay RathTRANS(SUBFE, do_subf_XO, true, true)
439a9bd40d9SChinmay RathTRANS(SUBFME, do_subf_const_XO, tcg_constant_tl(-1LL), true, true)
440a9bd40d9SChinmay RathTRANS(SUBFZE, do_subf_const_XO, tcg_constant_tl(0), true, true)
441a9bd40d9SChinmay Rath
442a1faff87SChinmay Rathstatic bool trans_MULLI(DisasContext *ctx, arg_MULLI *a)
443a1faff87SChinmay Rath{
444a1faff87SChinmay Rath    tcg_gen_muli_tl(cpu_gpr[a->rt], cpu_gpr[a->ra], a->si);
445a1faff87SChinmay Rath    return true;
446a1faff87SChinmay Rath}
447a1faff87SChinmay Rath
448a1faff87SChinmay Rathstatic bool trans_MULLW(DisasContext *ctx, arg_MULLW *a)
449a1faff87SChinmay Rath{
450a1faff87SChinmay Rath    TCGv t0 = tcg_temp_new();
451a1faff87SChinmay Rath    TCGv t1 = tcg_temp_new();
452a1faff87SChinmay Rath
453a1faff87SChinmay Rath    tcg_gen_ext32s_tl(t0, cpu_gpr[a->ra]);
454a1faff87SChinmay Rath    tcg_gen_ext32s_tl(t1, cpu_gpr[a->rb]);
455a1faff87SChinmay Rath    tcg_gen_mul_tl(cpu_gpr[a->rt], t0, t1);
456a1faff87SChinmay Rath    if (unlikely(a->rc)) {
457a1faff87SChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
458a1faff87SChinmay Rath    }
459a1faff87SChinmay Rath    return true;
460a1faff87SChinmay Rath}
461a1faff87SChinmay Rath
462a1faff87SChinmay Rathstatic bool trans_MULLWO(DisasContext *ctx, arg_MULLWO *a)
463a1faff87SChinmay Rath{
464a1faff87SChinmay Rath    TCGv t0 = tcg_temp_new();
465a1faff87SChinmay Rath    TCGv t1 = tcg_temp_new();
466a1faff87SChinmay Rath
467a1faff87SChinmay Rath#if defined(TARGET_PPC64)
468a1faff87SChinmay Rath    tcg_gen_ext32s_i64(t0, cpu_gpr[a->ra]);
469a1faff87SChinmay Rath    tcg_gen_ext32s_i64(t1, cpu_gpr[a->rb]);
470a1faff87SChinmay Rath    tcg_gen_mul_i64(cpu_gpr[a->rt], t0, t1);
471a1faff87SChinmay Rath    tcg_gen_sextract_i64(t0, cpu_gpr[a->rt], 31, 1);
472a1faff87SChinmay Rath    tcg_gen_sari_i64(t1, cpu_gpr[a->rt], 32);
473a1faff87SChinmay Rath#else
474a1faff87SChinmay Rath    tcg_gen_muls2_i32(cpu_gpr[a->rt], t1, cpu_gpr[a->ra], cpu_gpr[a->rb]);
475a1faff87SChinmay Rath    tcg_gen_sari_i32(t0, cpu_gpr[a->rt], 31);
476a1faff87SChinmay Rath#endif
477a1faff87SChinmay Rath    tcg_gen_setcond_tl(TCG_COND_NE, cpu_ov, t0, t1);
478a1faff87SChinmay Rath    if (is_isa300(ctx)) {
479a1faff87SChinmay Rath        tcg_gen_mov_tl(cpu_ov32, cpu_ov);
480a1faff87SChinmay Rath    }
481a1faff87SChinmay Rath    tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
482a1faff87SChinmay Rath
483a1faff87SChinmay Rath    if (unlikely(a->rc)) {
484a1faff87SChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
485a1faff87SChinmay Rath    }
486a1faff87SChinmay Rath    return true;
487a1faff87SChinmay Rath}
488a1faff87SChinmay Rath
489a1faff87SChinmay Rathstatic bool do_mulhw(DisasContext *ctx, arg_XO_tab_rc *a,
490a1faff87SChinmay Rath                     void (*helper)(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1,
491a1faff87SChinmay Rath                                    TCGv_i32 arg2))
492a1faff87SChinmay Rath{
493a1faff87SChinmay Rath    TCGv_i32 t0 = tcg_temp_new_i32();
494a1faff87SChinmay Rath    TCGv_i32 t1 = tcg_temp_new_i32();
495a1faff87SChinmay Rath    tcg_gen_trunc_tl_i32(t0, cpu_gpr[a->ra]);
496a1faff87SChinmay Rath    tcg_gen_trunc_tl_i32(t1, cpu_gpr[a->rb]);
497a1faff87SChinmay Rath    helper(t0, t1, t0, t1);
498a1faff87SChinmay Rath    tcg_gen_extu_i32_tl(cpu_gpr[a->rt], t1);
499a1faff87SChinmay Rath    if (unlikely(a->rc)) {
500a1faff87SChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
501a1faff87SChinmay Rath    }
502a1faff87SChinmay Rath    return true;
503a1faff87SChinmay Rath}
504a1faff87SChinmay Rath
505a1faff87SChinmay RathTRANS(MULHW, do_mulhw, tcg_gen_muls2_i32)
506a1faff87SChinmay RathTRANS(MULHWU, do_mulhw, tcg_gen_mulu2_i32)
507a1faff87SChinmay Rath
5082871921dSChinmay Rathstatic bool do_divw(DisasContext *ctx, arg_XO *a, int sign)
5092871921dSChinmay Rath{
5102871921dSChinmay Rath    gen_op_arith_divw(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
5112871921dSChinmay Rath                      sign, a->oe, a->rc);
5122871921dSChinmay Rath    return true;
5132871921dSChinmay Rath}
5142871921dSChinmay Rath
515f424bc10SChinmay Rathstatic bool do_dive(DisasContext *ctx, arg_XO *a,
5162871921dSChinmay Rath                     void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv, TCGv_i32))
5172871921dSChinmay Rath{
5182871921dSChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, DIVE_ISA206);
5192871921dSChinmay Rath    helper(cpu_gpr[a->rt], tcg_env, cpu_gpr[a->ra], cpu_gpr[a->rb],
5202871921dSChinmay Rath           tcg_constant_i32(a->oe));
5212871921dSChinmay Rath    if (unlikely(a->rc)) {
5222871921dSChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
5232871921dSChinmay Rath    }
5242871921dSChinmay Rath    return true;
5252871921dSChinmay Rath}
5262871921dSChinmay Rath
5272871921dSChinmay RathTRANS(DIVW, do_divw, 1);
5282871921dSChinmay RathTRANS(DIVWU, do_divw, 0);
529f424bc10SChinmay RathTRANS(DIVWE, do_dive, gen_helper_DIVWE);
530f424bc10SChinmay RathTRANS(DIVWEU, do_dive, gen_helper_DIVWEU);
5312871921dSChinmay Rath
532a81b5c18SChinmay Rathstatic bool do_modw(DisasContext *ctx, arg_X *a, bool sign)
533a81b5c18SChinmay Rath{
534a81b5c18SChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
535a81b5c18SChinmay Rath    gen_op_arith_modw(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
536a81b5c18SChinmay Rath                      sign);
537a81b5c18SChinmay Rath    return true;
538a81b5c18SChinmay Rath}
539a81b5c18SChinmay Rath
540a81b5c18SChinmay RathTRANS(MODUW, do_modw, false);
541a81b5c18SChinmay RathTRANS(MODSW, do_modw, true);
542a81b5c18SChinmay Rath
543a81b5c18SChinmay Rathstatic bool trans_NEG(DisasContext *ctx, arg_NEG *a)
544a81b5c18SChinmay Rath{
545a81b5c18SChinmay Rath    if (a->oe) {
546a81b5c18SChinmay Rath        TCGv zero = tcg_constant_tl(0);
547a81b5c18SChinmay Rath        gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], zero,
548a81b5c18SChinmay Rath                          false, false, true, a->rc);
549a81b5c18SChinmay Rath    } else {
550a81b5c18SChinmay Rath        tcg_gen_neg_tl(cpu_gpr[a->rt], cpu_gpr[a->ra]);
551a81b5c18SChinmay Rath        if (unlikely(a->rc)) {
552a81b5c18SChinmay Rath            gen_set_Rc0(ctx, cpu_gpr[a->rt]);
553a81b5c18SChinmay Rath        }
554a81b5c18SChinmay Rath    }
555a81b5c18SChinmay Rath    return true;
556a81b5c18SChinmay Rath}
557a81b5c18SChinmay Rath
558a81b5c18SChinmay Rathstatic bool trans_DARN(DisasContext *ctx, arg_DARN *a)
559a81b5c18SChinmay Rath{
560a81b5c18SChinmay Rath    REQUIRE_64BIT(ctx);
561a81b5c18SChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
562a81b5c18SChinmay Rath#if defined(TARGET_PPC64)
563a81b5c18SChinmay Rath    if (a->l > 2) {
564a81b5c18SChinmay Rath        tcg_gen_movi_i64(cpu_gpr[a->rt], -1);
565a81b5c18SChinmay Rath    } else {
566a81b5c18SChinmay Rath        translator_io_start(&ctx->base);
567a81b5c18SChinmay Rath        if (a->l == 0) {
568a81b5c18SChinmay Rath            gen_helper_DARN32(cpu_gpr[a->rt]);
569a81b5c18SChinmay Rath        } else {
570a81b5c18SChinmay Rath            /* Return 64-bit random for both CRN and RRN */
571a81b5c18SChinmay Rath            gen_helper_DARN64(cpu_gpr[a->rt]);
572a81b5c18SChinmay Rath        }
573a81b5c18SChinmay Rath    }
574a81b5c18SChinmay Rath#else
575a81b5c18SChinmay Rath    qemu_build_not_reached();
576a81b5c18SChinmay Rath#endif
577a81b5c18SChinmay Rath    return true;
578a81b5c18SChinmay Rath}
579a81b5c18SChinmay Rath
580703e88f7SChinmay Rathstatic bool trans_MULLD(DisasContext *ctx, arg_MULLD *a)
581703e88f7SChinmay Rath{
582703e88f7SChinmay Rath    REQUIRE_64BIT(ctx);
583703e88f7SChinmay Rath#if defined(TARGET_PPC64)
584703e88f7SChinmay Rath    tcg_gen_mul_tl(cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb]);
585703e88f7SChinmay Rath    if (unlikely(a->rc)) {
586703e88f7SChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
587703e88f7SChinmay Rath    }
588703e88f7SChinmay Rath#else
589703e88f7SChinmay Rath    qemu_build_not_reached();
590703e88f7SChinmay Rath#endif
591703e88f7SChinmay Rath    return true;
592703e88f7SChinmay Rath}
593703e88f7SChinmay Rath
594703e88f7SChinmay Rathstatic bool trans_MULLDO(DisasContext *ctx, arg_MULLD *a)
595703e88f7SChinmay Rath{
596703e88f7SChinmay Rath    REQUIRE_64BIT(ctx);
597703e88f7SChinmay Rath#if defined(TARGET_PPC64)
598703e88f7SChinmay Rath    TCGv_i64 t0 = tcg_temp_new_i64();
599703e88f7SChinmay Rath    TCGv_i64 t1 = tcg_temp_new_i64();
600703e88f7SChinmay Rath
601703e88f7SChinmay Rath    tcg_gen_muls2_i64(t0, t1, cpu_gpr[a->ra], cpu_gpr[a->rb]);
602703e88f7SChinmay Rath    tcg_gen_mov_i64(cpu_gpr[a->rt], t0);
603703e88f7SChinmay Rath
604703e88f7SChinmay Rath    tcg_gen_sari_i64(t0, t0, 63);
605703e88f7SChinmay Rath    tcg_gen_setcond_i64(TCG_COND_NE, cpu_ov, t0, t1);
606703e88f7SChinmay Rath    if (is_isa300(ctx)) {
607703e88f7SChinmay Rath        tcg_gen_mov_tl(cpu_ov32, cpu_ov);
608703e88f7SChinmay Rath    }
609703e88f7SChinmay Rath    tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
610703e88f7SChinmay Rath
611703e88f7SChinmay Rath    if (unlikely(a->rc)) {
612703e88f7SChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
613703e88f7SChinmay Rath    }
614703e88f7SChinmay Rath#else
615703e88f7SChinmay Rath    qemu_build_not_reached();
616703e88f7SChinmay Rath#endif
617703e88f7SChinmay Rath    return true;
618703e88f7SChinmay Rath}
619703e88f7SChinmay Rath
620703e88f7SChinmay Rathstatic bool do_mulhd(DisasContext *ctx, arg_XO_tab_rc *a,
621703e88f7SChinmay Rath                     void (*helper)(TCGv, TCGv, TCGv, TCGv))
622703e88f7SChinmay Rath{
623703e88f7SChinmay Rath    TCGv lo = tcg_temp_new();
624703e88f7SChinmay Rath    helper(lo, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb]);
625703e88f7SChinmay Rath    if (unlikely(a->rc)) {
626703e88f7SChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
627703e88f7SChinmay Rath    }
628703e88f7SChinmay Rath    return true;
629703e88f7SChinmay Rath}
630703e88f7SChinmay Rath
631703e88f7SChinmay RathTRANS64(MULHD, do_mulhd, tcg_gen_muls2_tl);
632703e88f7SChinmay RathTRANS64(MULHDU, do_mulhd, tcg_gen_mulu2_tl);
633703e88f7SChinmay Rath
634703e88f7SChinmay Rathstatic bool trans_MADDLD(DisasContext *ctx, arg_MADDLD *a)
635703e88f7SChinmay Rath{
636703e88f7SChinmay Rath    REQUIRE_64BIT(ctx);
637703e88f7SChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
638703e88f7SChinmay Rath#if defined(TARGET_PPC64)
639703e88f7SChinmay Rath    TCGv_i64 t1 = tcg_temp_new_i64();
640703e88f7SChinmay Rath
641703e88f7SChinmay Rath    tcg_gen_mul_i64(t1, cpu_gpr[a->vra], cpu_gpr[a->vrb]);
642703e88f7SChinmay Rath    tcg_gen_add_i64(cpu_gpr[a->vrt], t1, cpu_gpr[a->rc]);
643703e88f7SChinmay Rath#else
644703e88f7SChinmay Rath    qemu_build_not_reached();
645703e88f7SChinmay Rath#endif
646703e88f7SChinmay Rath    return true;
647703e88f7SChinmay Rath}
648703e88f7SChinmay Rath
649703e88f7SChinmay Rathstatic bool trans_MADDHD(DisasContext *ctx, arg_MADDHD *a)
650703e88f7SChinmay Rath{
651703e88f7SChinmay Rath    REQUIRE_64BIT(ctx);
652703e88f7SChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
653703e88f7SChinmay Rath#if defined(TARGET_PPC64)
654703e88f7SChinmay Rath    TCGv_i64 lo = tcg_temp_new_i64();
655703e88f7SChinmay Rath    TCGv_i64 hi = tcg_temp_new_i64();
656703e88f7SChinmay Rath    TCGv_i64 t1 = tcg_temp_new_i64();
657703e88f7SChinmay Rath
658703e88f7SChinmay Rath    tcg_gen_muls2_i64(lo, hi, cpu_gpr[a->vra], cpu_gpr[a->vrb]);
659703e88f7SChinmay Rath    tcg_gen_sari_i64(t1, cpu_gpr[a->rc], 63);
660703e88f7SChinmay Rath    tcg_gen_add2_i64(t1, cpu_gpr[a->vrt], lo, hi, cpu_gpr[a->rc], t1);
661703e88f7SChinmay Rath#else
662703e88f7SChinmay Rath    qemu_build_not_reached();
663703e88f7SChinmay Rath#endif
664703e88f7SChinmay Rath    return true;
665703e88f7SChinmay Rath}
666703e88f7SChinmay Rath
667703e88f7SChinmay Rathstatic bool trans_MADDHDU(DisasContext *ctx, arg_MADDHDU *a)
668703e88f7SChinmay Rath{
669703e88f7SChinmay Rath    REQUIRE_64BIT(ctx);
670703e88f7SChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
671703e88f7SChinmay Rath#if defined(TARGET_PPC64)
672703e88f7SChinmay Rath    TCGv_i64 lo = tcg_temp_new_i64();
673703e88f7SChinmay Rath    TCGv_i64 hi = tcg_temp_new_i64();
674703e88f7SChinmay Rath    TCGv_i64 t1 = tcg_temp_new_i64();
675703e88f7SChinmay Rath
676703e88f7SChinmay Rath    tcg_gen_mulu2_i64(lo, hi, cpu_gpr[a->vra], cpu_gpr[a->vrb]);
677703e88f7SChinmay Rath    tcg_gen_add2_i64(t1, cpu_gpr[a->vrt], lo, hi, cpu_gpr[a->rc],
678703e88f7SChinmay Rath                     tcg_constant_i64(0));
679703e88f7SChinmay Rath#else
680703e88f7SChinmay Rath    qemu_build_not_reached();
681703e88f7SChinmay Rath#endif
682703e88f7SChinmay Rath    return true;
683703e88f7SChinmay Rath}
684703e88f7SChinmay Rath
685f424bc10SChinmay Rathstatic bool do_divd(DisasContext *ctx, arg_XO *a, bool sign)
686f424bc10SChinmay Rath{
687f424bc10SChinmay Rath    REQUIRE_64BIT(ctx);
688f424bc10SChinmay Rath#if defined(TARGET_PPC64)
689f424bc10SChinmay Rath    gen_op_arith_divd(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
690f424bc10SChinmay Rath                      sign, a->oe, a->rc);
691f424bc10SChinmay Rath#else
692f424bc10SChinmay Rath    qemu_build_not_reached();
693f424bc10SChinmay Rath#endif
694f424bc10SChinmay Rath    return true;
695f424bc10SChinmay Rath}
696f424bc10SChinmay Rath
697f424bc10SChinmay Rathstatic bool do_modd(DisasContext *ctx, arg_X *a, bool sign)
698f424bc10SChinmay Rath{
699f424bc10SChinmay Rath    REQUIRE_64BIT(ctx);
700f424bc10SChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
701f424bc10SChinmay Rath#if defined(TARGET_PPC64)
702f424bc10SChinmay Rath    gen_op_arith_modd(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
703f424bc10SChinmay Rath                      sign);
704f424bc10SChinmay Rath#else
705f424bc10SChinmay Rath    qemu_build_not_reached();
706f424bc10SChinmay Rath#endif
707f424bc10SChinmay Rath    return true;
708f424bc10SChinmay Rath}
709f424bc10SChinmay Rath
710f424bc10SChinmay RathTRANS64(DIVD, do_divd, true);
711f424bc10SChinmay RathTRANS64(DIVDU, do_divd, false);
712f424bc10SChinmay Rath
713f424bc10SChinmay Rathstatic bool trans_DIVDE(DisasContext *ctx, arg_DIVDE *a)
714f424bc10SChinmay Rath{
715f424bc10SChinmay Rath    REQUIRE_64BIT(ctx);
716f424bc10SChinmay Rath#if defined(TARGET_PPC64)
717f424bc10SChinmay Rath    return do_dive(ctx, a, gen_helper_DIVDE);
718f424bc10SChinmay Rath#else
719f424bc10SChinmay Rath    qemu_build_not_reached();
720f424bc10SChinmay Rath#endif
721f424bc10SChinmay Rath}
722f424bc10SChinmay Rath
723f424bc10SChinmay Rathstatic bool trans_DIVDEU(DisasContext *ctx, arg_DIVDEU *a)
724f424bc10SChinmay Rath{
725f424bc10SChinmay Rath    REQUIRE_64BIT(ctx);
726f424bc10SChinmay Rath#if defined(TARGET_PPC64)
727f424bc10SChinmay Rath    return do_dive(ctx, a, gen_helper_DIVDEU);
728f424bc10SChinmay Rath#else
729f424bc10SChinmay Rath    qemu_build_not_reached();
730f424bc10SChinmay Rath#endif
731f424bc10SChinmay Rath    return true;
732f424bc10SChinmay Rath}
733f424bc10SChinmay Rath
734f424bc10SChinmay RathTRANS64(MODSD, do_modd, true);
735f424bc10SChinmay RathTRANS64(MODUD, do_modd, false);
736f424bc10SChinmay Rath
737ae556c6aSChinmay Rath/*
738ae556c6aSChinmay Rath * Fixed-Point Select Instructions
739ae556c6aSChinmay Rath */
740ae556c6aSChinmay Rath
741ae556c6aSChinmay Rathstatic bool trans_ISEL(DisasContext *ctx, arg_ISEL *a)
742ae556c6aSChinmay Rath{
743ae556c6aSChinmay Rath    REQUIRE_INSNS_FLAGS(ctx, ISEL);
744ae556c6aSChinmay Rath    uint32_t bi = a->bc;
745ae556c6aSChinmay Rath    uint32_t mask = 0x08 >> (bi & 0x03);
746ae556c6aSChinmay Rath    TCGv t0 = tcg_temp_new();
747ae556c6aSChinmay Rath    TCGv zr;
748ae556c6aSChinmay Rath
749ae556c6aSChinmay Rath    tcg_gen_extu_i32_tl(t0, cpu_crf[bi >> 2]);
750ae556c6aSChinmay Rath    tcg_gen_andi_tl(t0, t0, mask);
751ae556c6aSChinmay Rath
752ae556c6aSChinmay Rath    zr = tcg_constant_tl(0);
753ae556c6aSChinmay Rath    tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[a->rt], t0, zr,
754ae556c6aSChinmay Rath                       a->ra ? cpu_gpr[a->ra] : zr,
755ae556c6aSChinmay Rath                       cpu_gpr[a->rb]);
756ae556c6aSChinmay Rath    return true;
757ae556c6aSChinmay Rath}
758ae556c6aSChinmay Rath
759ae556c6aSChinmay Rath/*
760ae556c6aSChinmay Rath * Fixed-Point Trap Instructions
761ae556c6aSChinmay Rath */
762ae556c6aSChinmay Rath
763ae556c6aSChinmay Rathstatic bool trans_TW(DisasContext *ctx, arg_TW *a)
764ae556c6aSChinmay Rath{
765ae556c6aSChinmay Rath    TCGv_i32 t0;
766ae556c6aSChinmay Rath
767ae556c6aSChinmay Rath    if (check_unconditional_trap(ctx, a->rt)) {
768ae556c6aSChinmay Rath        return true;
769ae556c6aSChinmay Rath    }
770ae556c6aSChinmay Rath    t0 = tcg_constant_i32(a->rt);
771ae556c6aSChinmay Rath    gen_helper_TW(tcg_env, cpu_gpr[a->ra], cpu_gpr[a->rb], t0);
772ae556c6aSChinmay Rath    return true;
773ae556c6aSChinmay Rath}
774ae556c6aSChinmay Rath
775ae556c6aSChinmay Rathstatic bool trans_TWI(DisasContext *ctx, arg_TWI *a)
776ae556c6aSChinmay Rath{
777ae556c6aSChinmay Rath    TCGv t0;
778ae556c6aSChinmay Rath    TCGv_i32 t1;
779ae556c6aSChinmay Rath
780ae556c6aSChinmay Rath    if (check_unconditional_trap(ctx, a->rt)) {
781ae556c6aSChinmay Rath        return true;
782ae556c6aSChinmay Rath    }
783ae556c6aSChinmay Rath    t0 = tcg_constant_tl(a->si);
784ae556c6aSChinmay Rath    t1 = tcg_constant_i32(a->rt);
785ae556c6aSChinmay Rath    gen_helper_TW(tcg_env, cpu_gpr[a->ra], t0, t1);
786ae556c6aSChinmay Rath    return true;
787ae556c6aSChinmay Rath}
788ae556c6aSChinmay Rath
789ae556c6aSChinmay Rathstatic bool trans_TD(DisasContext *ctx, arg_TD *a)
790ae556c6aSChinmay Rath{
791ae556c6aSChinmay Rath    REQUIRE_64BIT(ctx);
792ae556c6aSChinmay Rath#if defined(TARGET_PPC64)
793ae556c6aSChinmay Rath    TCGv_i32 t0;
794ae556c6aSChinmay Rath
795ae556c6aSChinmay Rath    if (check_unconditional_trap(ctx, a->rt)) {
796ae556c6aSChinmay Rath        return true;
797ae556c6aSChinmay Rath    }
798ae556c6aSChinmay Rath    t0 = tcg_constant_i32(a->rt);
799ae556c6aSChinmay Rath    gen_helper_TD(tcg_env, cpu_gpr[a->ra], cpu_gpr[a->rb], t0);
800ae556c6aSChinmay Rath#else
801ae556c6aSChinmay Rath    qemu_build_not_reached();
802ae556c6aSChinmay Rath#endif
803ae556c6aSChinmay Rath    return true;
804ae556c6aSChinmay Rath}
805ae556c6aSChinmay Rath
806ae556c6aSChinmay Rathstatic bool trans_TDI(DisasContext *ctx, arg_TDI *a)
807ae556c6aSChinmay Rath{
808ae556c6aSChinmay Rath    REQUIRE_64BIT(ctx);
809ae556c6aSChinmay Rath#if defined(TARGET_PPC64)
810ae556c6aSChinmay Rath    TCGv t0;
811ae556c6aSChinmay Rath    TCGv_i32 t1;
812ae556c6aSChinmay Rath
813ae556c6aSChinmay Rath    if (check_unconditional_trap(ctx, a->rt)) {
814ae556c6aSChinmay Rath        return true;
815ae556c6aSChinmay Rath    }
816ae556c6aSChinmay Rath    t0 = tcg_constant_tl(a->si);
817ae556c6aSChinmay Rath    t1 = tcg_constant_i32(a->rt);
818ae556c6aSChinmay Rath    gen_helper_TD(tcg_env, cpu_gpr[a->ra], t0, t1);
819ae556c6aSChinmay Rath#else
820ae556c6aSChinmay Rath    qemu_build_not_reached();
821ae556c6aSChinmay Rath#endif
822ae556c6aSChinmay Rath    return true;
823ae556c6aSChinmay Rath}
824ae556c6aSChinmay Rath
8250a11bb7aSRichard Hendersonstatic bool trans_INVALID(DisasContext *ctx, arg_INVALID *a)
8260a11bb7aSRichard Henderson{
8270a11bb7aSRichard Henderson    gen_invalid(ctx);
8280a11bb7aSRichard Henderson    return true;
8290a11bb7aSRichard Henderson}
8300a11bb7aSRichard Henderson
8310a11bb7aSRichard Hendersonstatic bool trans_PNOP(DisasContext *ctx, arg_PNOP *a)
8320a11bb7aSRichard Henderson{
8330a11bb7aSRichard Henderson    return true;
8340a11bb7aSRichard Henderson}
8359a14365eSMatheus Ferst
8369a14365eSMatheus Ferststatic bool do_set_bool_cond(DisasContext *ctx, arg_X_bi *a, bool neg, bool rev)
8379a14365eSMatheus Ferst{
8389a14365eSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
8399a14365eSMatheus Ferst    uint32_t mask = 0x08 >> (a->bi & 0x03);
8409a14365eSMatheus Ferst    TCGCond cond = rev ? TCG_COND_EQ : TCG_COND_NE;
8419a14365eSMatheus Ferst    TCGv temp = tcg_temp_new();
842253d110dSRichard Henderson    TCGv zero = tcg_constant_tl(0);
8439a14365eSMatheus Ferst
8449a14365eSMatheus Ferst    tcg_gen_extu_i32_tl(temp, cpu_crf[a->bi >> 2]);
8459a14365eSMatheus Ferst    tcg_gen_andi_tl(temp, temp, mask);
8469a14365eSMatheus Ferst    if (neg) {
847253d110dSRichard Henderson        tcg_gen_negsetcond_tl(cond, cpu_gpr[a->rt], temp, zero);
848253d110dSRichard Henderson    } else {
849253d110dSRichard Henderson        tcg_gen_setcond_tl(cond, cpu_gpr[a->rt], temp, zero);
8509a14365eSMatheus Ferst    }
8519a14365eSMatheus Ferst    return true;
8529a14365eSMatheus Ferst}
8539a14365eSMatheus Ferst
8549a14365eSMatheus FerstTRANS(SETBC, do_set_bool_cond, false, false)
8559a14365eSMatheus FerstTRANS(SETBCR, do_set_bool_cond, false, true)
8569a14365eSMatheus FerstTRANS(SETNBC, do_set_bool_cond, true, false)
8579a14365eSMatheus FerstTRANS(SETNBCR, do_set_bool_cond, true, true)
85889ccd7dcSMatheus Ferst
859*948e257cSChinmay Rath/*
860*948e257cSChinmay Rath * Fixed-Point Logical Instructions
861*948e257cSChinmay Rath */
862*948e257cSChinmay Rath
863*948e257cSChinmay Rathstatic bool do_addi_(DisasContext *ctx, arg_D_ui *a, bool shift)
864*948e257cSChinmay Rath{
865*948e257cSChinmay Rath    tcg_gen_andi_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], shift ? a->ui << 16 : a->ui);
866*948e257cSChinmay Rath    gen_set_Rc0(ctx, cpu_gpr[a->ra]);
867*948e257cSChinmay Rath    return true;
868*948e257cSChinmay Rath}
869*948e257cSChinmay Rath
870*948e257cSChinmay Rathstatic bool do_ori(DisasContext *ctx, arg_D_ui *a, bool shift)
871*948e257cSChinmay Rath{
872*948e257cSChinmay Rath    if (a->rt == a->ra && a->ui == 0) {
873*948e257cSChinmay Rath        /* NOP */
874*948e257cSChinmay Rath        return true;
875*948e257cSChinmay Rath    }
876*948e257cSChinmay Rath    tcg_gen_ori_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], shift ? a->ui << 16 : a->ui);
877*948e257cSChinmay Rath    return true;
878*948e257cSChinmay Rath}
879*948e257cSChinmay Rath
880*948e257cSChinmay Rathstatic bool do_xori(DisasContext *ctx, arg_D_ui *a, bool shift)
881*948e257cSChinmay Rath{
882*948e257cSChinmay Rath    if (a->rt == a->ra && a->ui == 0) {
883*948e257cSChinmay Rath        /* NOP */
884*948e257cSChinmay Rath        return true;
885*948e257cSChinmay Rath    }
886*948e257cSChinmay Rath    tcg_gen_xori_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], shift ? a->ui << 16 : a->ui);
887*948e257cSChinmay Rath    return true;
888*948e257cSChinmay Rath}
889*948e257cSChinmay Rath
890*948e257cSChinmay Rathstatic bool do_logical1(DisasContext *ctx, arg_X_sa_rc *a,
891*948e257cSChinmay Rath                        void (*helper)(TCGv, TCGv))
892*948e257cSChinmay Rath{
893*948e257cSChinmay Rath    helper(cpu_gpr[a->ra], cpu_gpr[a->rs]);
894*948e257cSChinmay Rath    if (unlikely(a->rc)) {
895*948e257cSChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->ra]);
896*948e257cSChinmay Rath    }
897*948e257cSChinmay Rath    return true;
898*948e257cSChinmay Rath}
899*948e257cSChinmay Rath
900*948e257cSChinmay Rathstatic bool do_logical2(DisasContext *ctx, arg_X_rc *a,
901*948e257cSChinmay Rath                        void (*helper)(TCGv, TCGv, TCGv))
902*948e257cSChinmay Rath{
903*948e257cSChinmay Rath    helper(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
904*948e257cSChinmay Rath    if (unlikely(a->rc)) {
905*948e257cSChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->ra]);
906*948e257cSChinmay Rath    }
907*948e257cSChinmay Rath    return true;
908*948e257cSChinmay Rath}
909*948e257cSChinmay Rath
910*948e257cSChinmay Rathstatic bool trans_OR(DisasContext *ctx, arg_OR *a)
911*948e257cSChinmay Rath{
912*948e257cSChinmay Rath    /* Optimisation for mr. ri case */
913*948e257cSChinmay Rath    if (a->rt != a->ra || a->rt != a->rb) {
914*948e257cSChinmay Rath        if (a->rt != a->rb) {
915*948e257cSChinmay Rath            tcg_gen_or_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
916*948e257cSChinmay Rath        } else {
917*948e257cSChinmay Rath            tcg_gen_mov_tl(cpu_gpr[a->ra], cpu_gpr[a->rt]);
918*948e257cSChinmay Rath        }
919*948e257cSChinmay Rath        if (unlikely(a->rc)) {
920*948e257cSChinmay Rath            gen_set_Rc0(ctx, cpu_gpr[a->ra]);
921*948e257cSChinmay Rath        }
922*948e257cSChinmay Rath    } else if (unlikely(a->rc)) {
923*948e257cSChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->rt]);
924*948e257cSChinmay Rath#if defined(TARGET_PPC64)
925*948e257cSChinmay Rath    } else if (a->rt != 0) { /* 0 is nop */
926*948e257cSChinmay Rath        int prio = 0;
927*948e257cSChinmay Rath
928*948e257cSChinmay Rath        switch (a->rt) {
929*948e257cSChinmay Rath        case 1:
930*948e257cSChinmay Rath            /* Set process priority to low */
931*948e257cSChinmay Rath            prio = 2;
932*948e257cSChinmay Rath            break;
933*948e257cSChinmay Rath        case 6:
934*948e257cSChinmay Rath            /* Set process priority to medium-low */
935*948e257cSChinmay Rath            prio = 3;
936*948e257cSChinmay Rath            break;
937*948e257cSChinmay Rath        case 2:
938*948e257cSChinmay Rath            /* Set process priority to normal */
939*948e257cSChinmay Rath            prio = 4;
940*948e257cSChinmay Rath            break;
941*948e257cSChinmay Rath#if !defined(CONFIG_USER_ONLY)
942*948e257cSChinmay Rath        case 31:
943*948e257cSChinmay Rath            if (!ctx->pr) {
944*948e257cSChinmay Rath                /* Set process priority to very low */
945*948e257cSChinmay Rath                prio = 1;
946*948e257cSChinmay Rath            }
947*948e257cSChinmay Rath            break;
948*948e257cSChinmay Rath        case 5:
949*948e257cSChinmay Rath            if (!ctx->pr) {
950*948e257cSChinmay Rath                /* Set process priority to medium-hight */
951*948e257cSChinmay Rath                prio = 5;
952*948e257cSChinmay Rath            }
953*948e257cSChinmay Rath            break;
954*948e257cSChinmay Rath        case 3:
955*948e257cSChinmay Rath            if (!ctx->pr) {
956*948e257cSChinmay Rath                /* Set process priority to high */
957*948e257cSChinmay Rath                prio = 6;
958*948e257cSChinmay Rath            }
959*948e257cSChinmay Rath            break;
960*948e257cSChinmay Rath        case 7:
961*948e257cSChinmay Rath            if (ctx->hv && !ctx->pr) {
962*948e257cSChinmay Rath                /* Set process priority to very high */
963*948e257cSChinmay Rath                prio = 7;
964*948e257cSChinmay Rath            }
965*948e257cSChinmay Rath            break;
966*948e257cSChinmay Rath#endif
967*948e257cSChinmay Rath        default:
968*948e257cSChinmay Rath            break;
969*948e257cSChinmay Rath        }
970*948e257cSChinmay Rath        if (prio) {
971*948e257cSChinmay Rath            TCGv t0 = tcg_temp_new();
972*948e257cSChinmay Rath            gen_load_spr(t0, SPR_PPR);
973*948e257cSChinmay Rath            tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
974*948e257cSChinmay Rath            tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
975*948e257cSChinmay Rath            gen_store_spr(SPR_PPR, t0);
976*948e257cSChinmay Rath        }
977*948e257cSChinmay Rath#if !defined(CONFIG_USER_ONLY)
978*948e257cSChinmay Rath        /*
979*948e257cSChinmay Rath         * Pause out of TCG otherwise spin loops with smt_low eat too
980*948e257cSChinmay Rath         * much CPU and the kernel hangs.  This applies to all
981*948e257cSChinmay Rath         * encodings other than no-op, e.g., miso(rs=26), yield(27),
982*948e257cSChinmay Rath         * mdoio(29), mdoom(30), and all currently undefined.
983*948e257cSChinmay Rath         */
984*948e257cSChinmay Rath        gen_pause(ctx);
985*948e257cSChinmay Rath#endif
986*948e257cSChinmay Rath#endif
987*948e257cSChinmay Rath    }
988*948e257cSChinmay Rath
989*948e257cSChinmay Rath    return true;
990*948e257cSChinmay Rath}
991*948e257cSChinmay Rath
992*948e257cSChinmay Rathstatic bool trans_XOR(DisasContext *ctx, arg_XOR *a)
993*948e257cSChinmay Rath{
994*948e257cSChinmay Rath    /* Optimisation for "set to zero" case */
995*948e257cSChinmay Rath    if (a->rt != a->rb) {
996*948e257cSChinmay Rath        tcg_gen_xor_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
997*948e257cSChinmay Rath    } else {
998*948e257cSChinmay Rath        tcg_gen_movi_tl(cpu_gpr[a->ra], 0);
999*948e257cSChinmay Rath    }
1000*948e257cSChinmay Rath    if (unlikely(a->rc)) {
1001*948e257cSChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->ra]);
1002*948e257cSChinmay Rath    }
1003*948e257cSChinmay Rath    return true;
1004*948e257cSChinmay Rath}
1005*948e257cSChinmay Rath
1006*948e257cSChinmay Rathstatic bool trans_CMPB(DisasContext *ctx, arg_CMPB *a)
1007*948e257cSChinmay Rath{
1008*948e257cSChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA205);
1009*948e257cSChinmay Rath    gen_helper_CMPB(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
1010*948e257cSChinmay Rath    return true;
1011*948e257cSChinmay Rath}
1012*948e257cSChinmay Rath
1013*948e257cSChinmay Rathstatic bool do_cntzw(DisasContext *ctx, arg_X_sa_rc *a,
1014*948e257cSChinmay Rath                    void (*helper)(TCGv_i32, TCGv_i32, uint32_t))
1015*948e257cSChinmay Rath{
1016*948e257cSChinmay Rath    TCGv_i32 t = tcg_temp_new_i32();
1017*948e257cSChinmay Rath
1018*948e257cSChinmay Rath    tcg_gen_trunc_tl_i32(t, cpu_gpr[a->rs]);
1019*948e257cSChinmay Rath    helper(t, t, 32);
1020*948e257cSChinmay Rath    tcg_gen_extu_i32_tl(cpu_gpr[a->ra], t);
1021*948e257cSChinmay Rath
1022*948e257cSChinmay Rath    if (unlikely(a->rc)) {
1023*948e257cSChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->ra]);
1024*948e257cSChinmay Rath    }
1025*948e257cSChinmay Rath    return true;
1026*948e257cSChinmay Rath}
1027*948e257cSChinmay Rath
1028*948e257cSChinmay Rath#if defined(TARGET_PPC64)
1029*948e257cSChinmay Rathstatic bool do_cntzd(DisasContext *ctx, arg_X_sa_rc *a,
1030*948e257cSChinmay Rath                    void (*helper)(TCGv_i64, TCGv_i64, uint64_t))
1031*948e257cSChinmay Rath{
1032*948e257cSChinmay Rath    helper(cpu_gpr[a->ra], cpu_gpr[a->rs], 64);
1033*948e257cSChinmay Rath    if (unlikely(a->rc)) {
1034*948e257cSChinmay Rath        gen_set_Rc0(ctx, cpu_gpr[a->ra]);
1035*948e257cSChinmay Rath    }
1036*948e257cSChinmay Rath    return true;
1037*948e257cSChinmay Rath}
1038*948e257cSChinmay Rath#endif
1039*948e257cSChinmay Rath
1040*948e257cSChinmay Rathstatic bool trans_CNTLZD(DisasContext *ctx, arg_CNTLZD *a)
1041*948e257cSChinmay Rath{
1042*948e257cSChinmay Rath    REQUIRE_64BIT(ctx);
1043*948e257cSChinmay Rath#if defined(TARGET_PPC64)
1044*948e257cSChinmay Rath    do_cntzd(ctx, a, tcg_gen_clzi_i64);
1045*948e257cSChinmay Rath#else
1046*948e257cSChinmay Rath    qemu_build_not_reached();
1047*948e257cSChinmay Rath#endif
1048*948e257cSChinmay Rath    return true;
1049*948e257cSChinmay Rath}
1050*948e257cSChinmay Rath
1051*948e257cSChinmay Rathstatic bool trans_CNTTZD(DisasContext *ctx, arg_CNTTZD *a)
1052*948e257cSChinmay Rath{
1053*948e257cSChinmay Rath    REQUIRE_64BIT(ctx);
1054*948e257cSChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA300);
1055*948e257cSChinmay Rath#if defined(TARGET_PPC64)
1056*948e257cSChinmay Rath    do_cntzd(ctx, a, tcg_gen_ctzi_i64);
1057*948e257cSChinmay Rath#else
1058*948e257cSChinmay Rath    qemu_build_not_reached();
1059*948e257cSChinmay Rath#endif
1060*948e257cSChinmay Rath    return true;
1061*948e257cSChinmay Rath}
1062*948e257cSChinmay Rath
1063*948e257cSChinmay Rathstatic bool trans_POPCNTB(DisasContext *ctx, arg_POPCNTB *a)
1064*948e257cSChinmay Rath{
1065*948e257cSChinmay Rath    REQUIRE_INSNS_FLAGS(ctx, POPCNTB);
1066*948e257cSChinmay Rath    gen_helper_POPCNTB(cpu_gpr[a->ra], cpu_gpr[a->rs]);
1067*948e257cSChinmay Rath    return true;
1068*948e257cSChinmay Rath}
1069*948e257cSChinmay Rath
1070*948e257cSChinmay Rathstatic bool trans_POPCNTW(DisasContext *ctx, arg_POPCNTW *a)
1071*948e257cSChinmay Rath{
1072*948e257cSChinmay Rath    REQUIRE_INSNS_FLAGS(ctx, POPCNTWD);
1073*948e257cSChinmay Rath#if defined(TARGET_PPC64)
1074*948e257cSChinmay Rath    gen_helper_POPCNTW(cpu_gpr[a->ra], cpu_gpr[a->rs]);
1075*948e257cSChinmay Rath#else
1076*948e257cSChinmay Rath    tcg_gen_ctpop_i32(cpu_gpr[a->ra], cpu_gpr[a->rs]);
1077*948e257cSChinmay Rath#endif
1078*948e257cSChinmay Rath    return true;
1079*948e257cSChinmay Rath}
1080*948e257cSChinmay Rath
1081*948e257cSChinmay Rathstatic bool trans_POPCNTD(DisasContext *ctx, arg_POPCNTD *a)
1082*948e257cSChinmay Rath{
1083*948e257cSChinmay Rath    REQUIRE_64BIT(ctx);
1084*948e257cSChinmay Rath    REQUIRE_INSNS_FLAGS(ctx, POPCNTWD);
1085*948e257cSChinmay Rath#if defined(TARGET_PPC64)
1086*948e257cSChinmay Rath    tcg_gen_ctpop_i64(cpu_gpr[a->ra], cpu_gpr[a->rs]);
1087*948e257cSChinmay Rath#else
1088*948e257cSChinmay Rath    qemu_build_not_reached();
1089*948e257cSChinmay Rath#endif
1090*948e257cSChinmay Rath    return true;
1091*948e257cSChinmay Rath}
1092*948e257cSChinmay Rath
1093*948e257cSChinmay Rathstatic bool trans_PRTYW(DisasContext *ctx, arg_PRTYW *a)
1094*948e257cSChinmay Rath{
1095*948e257cSChinmay Rath    TCGv ra = cpu_gpr[a->ra];
1096*948e257cSChinmay Rath    TCGv rs = cpu_gpr[a->rs];
1097*948e257cSChinmay Rath    TCGv t0 = tcg_temp_new();
1098*948e257cSChinmay Rath
1099*948e257cSChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA205);
1100*948e257cSChinmay Rath    tcg_gen_shri_tl(t0, rs, 16);
1101*948e257cSChinmay Rath    tcg_gen_xor_tl(ra, rs, t0);
1102*948e257cSChinmay Rath    tcg_gen_shri_tl(t0, ra, 8);
1103*948e257cSChinmay Rath    tcg_gen_xor_tl(ra, ra, t0);
1104*948e257cSChinmay Rath    tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
1105*948e257cSChinmay Rath    return true;
1106*948e257cSChinmay Rath}
1107*948e257cSChinmay Rath
1108*948e257cSChinmay Rathstatic bool trans_PRTYD(DisasContext *ctx, arg_PRTYD *a)
1109*948e257cSChinmay Rath{
1110*948e257cSChinmay Rath    TCGv ra = cpu_gpr[a->ra];
1111*948e257cSChinmay Rath    TCGv rs = cpu_gpr[a->rs];
1112*948e257cSChinmay Rath    TCGv t0 = tcg_temp_new();
1113*948e257cSChinmay Rath
1114*948e257cSChinmay Rath    REQUIRE_64BIT(ctx);
1115*948e257cSChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, ISA205);
1116*948e257cSChinmay Rath    tcg_gen_shri_tl(t0, rs, 32);
1117*948e257cSChinmay Rath    tcg_gen_xor_tl(ra, rs, t0);
1118*948e257cSChinmay Rath    tcg_gen_shri_tl(t0, ra, 16);
1119*948e257cSChinmay Rath    tcg_gen_xor_tl(ra, ra, t0);
1120*948e257cSChinmay Rath    tcg_gen_shri_tl(t0, ra, 8);
1121*948e257cSChinmay Rath    tcg_gen_xor_tl(ra, ra, t0);
1122*948e257cSChinmay Rath    tcg_gen_andi_tl(ra, ra, 1);
1123*948e257cSChinmay Rath    return true;
1124*948e257cSChinmay Rath}
1125*948e257cSChinmay Rath
1126*948e257cSChinmay Rathstatic bool trans_BPERMD(DisasContext *ctx, arg_BPERMD *a)
1127*948e257cSChinmay Rath{
1128*948e257cSChinmay Rath    REQUIRE_64BIT(ctx);
1129*948e257cSChinmay Rath    REQUIRE_INSNS_FLAGS2(ctx, PERM_ISA206);
1130*948e257cSChinmay Rath#if defined(TARGET_PPC64)
1131*948e257cSChinmay Rath    gen_helper_BPERMD(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
1132*948e257cSChinmay Rath#else
1133*948e257cSChinmay Rath    qemu_build_not_reached();
1134*948e257cSChinmay Rath#endif
1135*948e257cSChinmay Rath    return true;
1136*948e257cSChinmay Rath}
1137*948e257cSChinmay Rath
113889ccd7dcSMatheus Ferststatic bool trans_CFUGED(DisasContext *ctx, arg_X *a)
113989ccd7dcSMatheus Ferst{
114089ccd7dcSMatheus Ferst    REQUIRE_64BIT(ctx);
114189ccd7dcSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
114289ccd7dcSMatheus Ferst#if defined(TARGET_PPC64)
11436e0bbc40SMatheus Ferst    gen_helper_CFUGED(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
114489ccd7dcSMatheus Ferst#else
114589ccd7dcSMatheus Ferst    qemu_build_not_reached();
114689ccd7dcSMatheus Ferst#endif
114789ccd7dcSMatheus Ferst    return true;
114889ccd7dcSMatheus Ferst}
114982be6e02SLuis Pires
1150a2c975e1SMatheus Ferststatic void do_cntzdm(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 mask, int64_t trail)
115182be6e02SLuis Pires{
1152ab1e25adSMatheus Ferst    TCGv_i64 t0, t1;
115382be6e02SLuis Pires
1154ab1e25adSMatheus Ferst    t0 = tcg_temp_new_i64();
1155ab1e25adSMatheus Ferst    t1 = tcg_temp_new_i64();
115682be6e02SLuis Pires
1157ab1e25adSMatheus Ferst    tcg_gen_and_i64(t0, src, mask);
1158f356b3baSLuis Pires    if (trail) {
1159ab1e25adSMatheus Ferst        tcg_gen_ctzi_i64(t0, t0, -1);
1160f356b3baSLuis Pires    } else {
1161ab1e25adSMatheus Ferst        tcg_gen_clzi_i64(t0, t0, -1);
1162f356b3baSLuis Pires    }
116382be6e02SLuis Pires
1164ab1e25adSMatheus Ferst    tcg_gen_setcondi_i64(TCG_COND_NE, t1, t0, -1);
1165ab1e25adSMatheus Ferst    tcg_gen_andi_i64(t0, t0, 63);
1166ab1e25adSMatheus Ferst    tcg_gen_xori_i64(t0, t0, 63);
1167f356b3baSLuis Pires    if (trail) {
1168ab1e25adSMatheus Ferst        tcg_gen_shl_i64(t0, mask, t0);
1169ab1e25adSMatheus Ferst        tcg_gen_shl_i64(t0, t0, t1);
1170f356b3baSLuis Pires    } else {
1171ab1e25adSMatheus Ferst        tcg_gen_shr_i64(t0, mask, t0);
1172ab1e25adSMatheus Ferst        tcg_gen_shr_i64(t0, t0, t1);
1173f356b3baSLuis Pires    }
117482be6e02SLuis Pires
1175ab1e25adSMatheus Ferst    tcg_gen_ctpop_i64(dst, t0);
117682be6e02SLuis Pires}
117782be6e02SLuis Pires
117882be6e02SLuis Piresstatic bool trans_CNTLZDM(DisasContext *ctx, arg_X *a)
117982be6e02SLuis Pires{
118082be6e02SLuis Pires    REQUIRE_64BIT(ctx);
118182be6e02SLuis Pires    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
118282be6e02SLuis Pires#if defined(TARGET_PPC64)
1183f356b3baSLuis Pires    do_cntzdm(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb], false);
1184f356b3baSLuis Pires#else
1185f356b3baSLuis Pires    qemu_build_not_reached();
1186f356b3baSLuis Pires#endif
1187f356b3baSLuis Pires    return true;
1188f356b3baSLuis Pires}
1189f356b3baSLuis Pires
1190f356b3baSLuis Piresstatic bool trans_CNTTZDM(DisasContext *ctx, arg_X *a)
1191f356b3baSLuis Pires{
1192f356b3baSLuis Pires    REQUIRE_64BIT(ctx);
1193f356b3baSLuis Pires    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
1194f356b3baSLuis Pires#if defined(TARGET_PPC64)
1195f356b3baSLuis Pires    do_cntzdm(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb], true);
119682be6e02SLuis Pires#else
119782be6e02SLuis Pires    qemu_build_not_reached();
119882be6e02SLuis Pires#endif
119982be6e02SLuis Pires    return true;
120082be6e02SLuis Pires}
120121ba6e58SMatheus Ferst
120221ba6e58SMatheus Ferststatic bool trans_PDEPD(DisasContext *ctx, arg_X *a)
120321ba6e58SMatheus Ferst{
120421ba6e58SMatheus Ferst    REQUIRE_64BIT(ctx);
120521ba6e58SMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
120621ba6e58SMatheus Ferst#if defined(TARGET_PPC64)
120721ba6e58SMatheus Ferst    gen_helper_PDEPD(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
120821ba6e58SMatheus Ferst#else
120921ba6e58SMatheus Ferst    qemu_build_not_reached();
121021ba6e58SMatheus Ferst#endif
121121ba6e58SMatheus Ferst    return true;
121221ba6e58SMatheus Ferst}
12138bdb7606SMatheus Ferst
12148bdb7606SMatheus Ferststatic bool trans_PEXTD(DisasContext *ctx, arg_X *a)
12158bdb7606SMatheus Ferst{
12168bdb7606SMatheus Ferst    REQUIRE_64BIT(ctx);
12178bdb7606SMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
12188bdb7606SMatheus Ferst#if defined(TARGET_PPC64)
12198bdb7606SMatheus Ferst    gen_helper_PEXTD(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
12208bdb7606SMatheus Ferst#else
12218bdb7606SMatheus Ferst    qemu_build_not_reached();
12228bdb7606SMatheus Ferst#endif
12238bdb7606SMatheus Ferst    return true;
12248bdb7606SMatheus Ferst}
12256addef4dSMatheus Ferst
1226*948e257cSChinmay RathTRANS(ANDI_, do_addi_, false);
1227*948e257cSChinmay RathTRANS(ANDIS_, do_addi_, true);
1228*948e257cSChinmay RathTRANS(ORI, do_ori, false);
1229*948e257cSChinmay RathTRANS(ORIS, do_ori, true);
1230*948e257cSChinmay RathTRANS(XORI, do_xori, false);
1231*948e257cSChinmay RathTRANS(XORIS, do_xori, true);
1232*948e257cSChinmay Rath
1233*948e257cSChinmay RathTRANS(AND, do_logical2, tcg_gen_and_tl);
1234*948e257cSChinmay RathTRANS(ANDC, do_logical2, tcg_gen_andc_tl);
1235*948e257cSChinmay RathTRANS(NAND, do_logical2, tcg_gen_nand_tl);
1236*948e257cSChinmay RathTRANS(ORC, do_logical2, tcg_gen_orc_tl);
1237*948e257cSChinmay RathTRANS(NOR, do_logical2, tcg_gen_nor_tl);
1238*948e257cSChinmay RathTRANS(EQV, do_logical2, tcg_gen_eqv_tl);
1239*948e257cSChinmay RathTRANS(EXTSB, do_logical1, tcg_gen_ext8s_tl);
1240*948e257cSChinmay RathTRANS(EXTSH, do_logical1, tcg_gen_ext16s_tl);
1241*948e257cSChinmay Rath
1242*948e257cSChinmay RathTRANS(CNTLZW, do_cntzw, tcg_gen_clzi_i32);
1243*948e257cSChinmay RathTRANS_FLAGS2(ISA300, CNTTZW, do_cntzw, tcg_gen_ctzi_i32);
1244*948e257cSChinmay Rath
1245*948e257cSChinmay RathTRANS64(EXTSW, do_logical1, tcg_gen_ext32s_tl);
1246*948e257cSChinmay Rath
12476addef4dSMatheus Ferststatic bool trans_ADDG6S(DisasContext *ctx, arg_X *a)
12486addef4dSMatheus Ferst{
12494fe0e9dbSRichard Henderson    const target_ulong carry_bits = (target_ulong)-1 / 0xf;
12504fe0e9dbSRichard Henderson    TCGv in1, in2, carryl, carryh, tmp;
12514fe0e9dbSRichard Henderson    TCGv zero = tcg_constant_tl(0);
12526addef4dSMatheus Ferst
12536addef4dSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206);
12546addef4dSMatheus Ferst
12554fe0e9dbSRichard Henderson    in1 = cpu_gpr[a->ra];
12564fe0e9dbSRichard Henderson    in2 = cpu_gpr[a->rb];
12574fe0e9dbSRichard Henderson    tmp = tcg_temp_new();
12584fe0e9dbSRichard Henderson    carryl = tcg_temp_new();
12594fe0e9dbSRichard Henderson    carryh = tcg_temp_new();
12606addef4dSMatheus Ferst
12614fe0e9dbSRichard Henderson    /* Addition with carry. */
12624fe0e9dbSRichard Henderson    tcg_gen_add2_tl(carryl, carryh, in1, zero, in2, zero);
12634fe0e9dbSRichard Henderson    /* Addition without carry. */
12644fe0e9dbSRichard Henderson    tcg_gen_xor_tl(tmp, in1, in2);
12654fe0e9dbSRichard Henderson    /* Difference between the two is carry in to each bit. */
12664fe0e9dbSRichard Henderson    tcg_gen_xor_tl(carryl, carryl, tmp);
12676addef4dSMatheus Ferst
12684fe0e9dbSRichard Henderson    /*
12694fe0e9dbSRichard Henderson     * The carry-out that we're looking for is the carry-in to
12704fe0e9dbSRichard Henderson     * the next nibble.  Shift the double-word down one nibble,
12714fe0e9dbSRichard Henderson     * which puts all of the bits back into one word.
12724fe0e9dbSRichard Henderson     */
12734fe0e9dbSRichard Henderson    tcg_gen_extract2_tl(carryl, carryl, carryh, 4);
12746addef4dSMatheus Ferst
12754fe0e9dbSRichard Henderson    /* Invert, isolate the carry bits, and produce 6's. */
12764fe0e9dbSRichard Henderson    tcg_gen_andc_tl(carryl, tcg_constant_tl(carry_bits), carryl);
12774fe0e9dbSRichard Henderson    tcg_gen_muli_tl(cpu_gpr[a->rt], carryl, 6);
12786addef4dSMatheus Ferst    return true;
12796addef4dSMatheus Ferst}
128038d3690bSMatheus Ferst
12816b924d4aSMatheus Ferststatic bool trans_CDTBCD(DisasContext *ctx, arg_X_sa *a)
12826b924d4aSMatheus Ferst{
12836b924d4aSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206);
12846b924d4aSMatheus Ferst    gen_helper_CDTBCD(cpu_gpr[a->ra], cpu_gpr[a->rs]);
12856b924d4aSMatheus Ferst    return true;
12866b924d4aSMatheus Ferst}
12876b924d4aSMatheus Ferst
128838d3690bSMatheus Ferststatic bool trans_CBCDTD(DisasContext *ctx, arg_X_sa *a)
128938d3690bSMatheus Ferst{
129038d3690bSMatheus Ferst    REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206);
129138d3690bSMatheus Ferst    gen_helper_CBCDTD(cpu_gpr[a->ra], cpu_gpr[a->rs]);
129238d3690bSMatheus Ferst    return true;
129338d3690bSMatheus Ferst}
1294670f1da3SVíctor Colombo
1295670f1da3SVíctor Colombostatic bool do_hash(DisasContext *ctx, arg_X *a, bool priv,
1296670f1da3SVíctor Colombo    void (*helper)(TCGv_ptr, TCGv, TCGv, TCGv))
1297670f1da3SVíctor Colombo{
1298670f1da3SVíctor Colombo    TCGv ea;
1299670f1da3SVíctor Colombo
1300670f1da3SVíctor Colombo    if (!(ctx->insns_flags2 & PPC2_ISA310)) {
1301670f1da3SVíctor Colombo        /* if version is before v3.1, this operation is a nop */
1302670f1da3SVíctor Colombo        return true;
1303670f1da3SVíctor Colombo    }
1304670f1da3SVíctor Colombo
1305670f1da3SVíctor Colombo    if (priv) {
1306670f1da3SVíctor Colombo        /* if instruction is privileged but the context is in user space */
1307670f1da3SVíctor Colombo        REQUIRE_SV(ctx);
1308670f1da3SVíctor Colombo    }
1309670f1da3SVíctor Colombo
1310670f1da3SVíctor Colombo    if (unlikely(a->ra == 0)) {
1311670f1da3SVíctor Colombo        /* if RA=0, the instruction form is invalid */
1312670f1da3SVíctor Colombo        gen_invalid(ctx);
1313670f1da3SVíctor Colombo        return true;
1314670f1da3SVíctor Colombo    }
1315670f1da3SVíctor Colombo
1316670f1da3SVíctor Colombo    ea = do_ea_calc(ctx, a->ra, tcg_constant_tl(a->rt));
1317ad75a51eSRichard Henderson    helper(tcg_env, ea, cpu_gpr[a->ra], cpu_gpr[a->rb]);
1318670f1da3SVíctor Colombo    return true;
1319670f1da3SVíctor Colombo}
1320670f1da3SVíctor Colombo
1321670f1da3SVíctor ColomboTRANS(HASHST, do_hash, false, gen_helper_HASHST)
1322670f1da3SVíctor ColomboTRANS(HASHCHK, do_hash, false, gen_helper_HASHCHK)
132353ae2aebSVíctor ColomboTRANS(HASHSTP, do_hash, true, gen_helper_HASHSTP)
132453ae2aebSVíctor ColomboTRANS(HASHCHKP, do_hash, true, gen_helper_HASHCHKP)
1325