1a2b0a27dSPhilippe Mathieu-Daudé /*
2a2b0a27dSPhilippe Mathieu-Daudé * Toshiba TX79-specific instructions translation routines
3a2b0a27dSPhilippe Mathieu-Daudé *
4a2b0a27dSPhilippe Mathieu-Daudé * Copyright (c) 2018 Fredrik Noring
52d4ab117SPhilippe Mathieu-Daudé * Copyright (c) 2021 Philippe Mathieu-Daudé
6a2b0a27dSPhilippe Mathieu-Daudé *
7a2b0a27dSPhilippe Mathieu-Daudé * SPDX-License-Identifier: GPL-2.0-or-later
8a2b0a27dSPhilippe Mathieu-Daudé */
9a2b0a27dSPhilippe Mathieu-Daudé
10a2b0a27dSPhilippe Mathieu-Daudé #include "qemu/osdep.h"
11a2b0a27dSPhilippe Mathieu-Daudé #include "translate.h"
128cab4157SRichard Henderson #include "tcg/tcg-op-gvec.h"
13a2b0a27dSPhilippe Mathieu-Daudé
14a2b0a27dSPhilippe Mathieu-Daudé /* Include the auto-generated decoder. */
15a2b0a27dSPhilippe Mathieu-Daudé #include "decode-tx79.c.inc"
16a2b0a27dSPhilippe Mathieu-Daudé
17a2b0a27dSPhilippe Mathieu-Daudé /*
18a2b0a27dSPhilippe Mathieu-Daudé * Overview of the TX79-specific instruction set
19a2b0a27dSPhilippe Mathieu-Daudé * =============================================
20a2b0a27dSPhilippe Mathieu-Daudé *
21a2b0a27dSPhilippe Mathieu-Daudé * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
22a2b0a27dSPhilippe Mathieu-Daudé * are only used by the specific quadword (128-bit) LQ/SQ load/store
23a2b0a27dSPhilippe Mathieu-Daudé * instructions and certain multimedia instructions (MMIs). These MMIs
24a2b0a27dSPhilippe Mathieu-Daudé * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
25a2b0a27dSPhilippe Mathieu-Daudé * or sixteen 8-bit paths.
26a2b0a27dSPhilippe Mathieu-Daudé *
27a2b0a27dSPhilippe Mathieu-Daudé * Reference:
28a2b0a27dSPhilippe Mathieu-Daudé *
29a2b0a27dSPhilippe Mathieu-Daudé * The Toshiba TX System RISC TX79 Core Architecture manual,
30a2b0a27dSPhilippe Mathieu-Daudé * https://wiki.qemu.org/File:C790.pdf
31a2b0a27dSPhilippe Mathieu-Daudé */
32a2b0a27dSPhilippe Mathieu-Daudé
decode_ext_tx79(DisasContext * ctx,uint32_t insn)33a2b0a27dSPhilippe Mathieu-Daudé bool decode_ext_tx79(DisasContext *ctx, uint32_t insn)
34a2b0a27dSPhilippe Mathieu-Daudé {
35a2b0a27dSPhilippe Mathieu-Daudé if (TARGET_LONG_BITS == 64 && decode_tx79(ctx, insn)) {
36a2b0a27dSPhilippe Mathieu-Daudé return true;
37a2b0a27dSPhilippe Mathieu-Daudé }
38a2b0a27dSPhilippe Mathieu-Daudé return false;
39a2b0a27dSPhilippe Mathieu-Daudé }
40a2b0a27dSPhilippe Mathieu-Daudé
41a2b0a27dSPhilippe Mathieu-Daudé /*
42a2b0a27dSPhilippe Mathieu-Daudé * Three-Operand Multiply and Multiply-Add (4 instructions)
43a2b0a27dSPhilippe Mathieu-Daudé * --------------------------------------------------------
44a2b0a27dSPhilippe Mathieu-Daudé * MADD [rd,] rs, rt Multiply/Add
45a2b0a27dSPhilippe Mathieu-Daudé * MADDU [rd,] rs, rt Multiply/Add Unsigned
46a2b0a27dSPhilippe Mathieu-Daudé * MULT [rd,] rs, rt Multiply (3-operand)
47a2b0a27dSPhilippe Mathieu-Daudé * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
48a2b0a27dSPhilippe Mathieu-Daudé */
49a2b0a27dSPhilippe Mathieu-Daudé
50a2b0a27dSPhilippe Mathieu-Daudé /*
51a2b0a27dSPhilippe Mathieu-Daudé * Multiply Instructions for Pipeline 1 (10 instructions)
52a2b0a27dSPhilippe Mathieu-Daudé * ------------------------------------------------------
53a2b0a27dSPhilippe Mathieu-Daudé * MULT1 [rd,] rs, rt Multiply Pipeline 1
54a2b0a27dSPhilippe Mathieu-Daudé * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
55a2b0a27dSPhilippe Mathieu-Daudé * DIV1 rs, rt Divide Pipeline 1
56a2b0a27dSPhilippe Mathieu-Daudé * DIVU1 rs, rt Divide Unsigned Pipeline 1
57a2b0a27dSPhilippe Mathieu-Daudé * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
58a2b0a27dSPhilippe Mathieu-Daudé * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
59a2b0a27dSPhilippe Mathieu-Daudé * MFHI1 rd Move From HI1 Register
60a2b0a27dSPhilippe Mathieu-Daudé * MFLO1 rd Move From LO1 Register
61a2b0a27dSPhilippe Mathieu-Daudé * MTHI1 rs Move To HI1 Register
62a2b0a27dSPhilippe Mathieu-Daudé * MTLO1 rs Move To LO1 Register
63a2b0a27dSPhilippe Mathieu-Daudé */
64a2b0a27dSPhilippe Mathieu-Daudé
trans_MFHI1(DisasContext * ctx,arg_r * a)6534fe9fa3SPhilippe Mathieu-Daudé static bool trans_MFHI1(DisasContext *ctx, arg_r *a)
66a2b0a27dSPhilippe Mathieu-Daudé {
67a2b0a27dSPhilippe Mathieu-Daudé gen_store_gpr(cpu_HI[1], a->rd);
68a2b0a27dSPhilippe Mathieu-Daudé
69a2b0a27dSPhilippe Mathieu-Daudé return true;
70a2b0a27dSPhilippe Mathieu-Daudé }
71a2b0a27dSPhilippe Mathieu-Daudé
trans_MFLO1(DisasContext * ctx,arg_r * a)7234fe9fa3SPhilippe Mathieu-Daudé static bool trans_MFLO1(DisasContext *ctx, arg_r *a)
73a2b0a27dSPhilippe Mathieu-Daudé {
74a2b0a27dSPhilippe Mathieu-Daudé gen_store_gpr(cpu_LO[1], a->rd);
75a2b0a27dSPhilippe Mathieu-Daudé
76a2b0a27dSPhilippe Mathieu-Daudé return true;
77a2b0a27dSPhilippe Mathieu-Daudé }
78a2b0a27dSPhilippe Mathieu-Daudé
trans_MTHI1(DisasContext * ctx,arg_r * a)7934fe9fa3SPhilippe Mathieu-Daudé static bool trans_MTHI1(DisasContext *ctx, arg_r *a)
80a2b0a27dSPhilippe Mathieu-Daudé {
81a2b0a27dSPhilippe Mathieu-Daudé gen_load_gpr(cpu_HI[1], a->rs);
82a2b0a27dSPhilippe Mathieu-Daudé
83a2b0a27dSPhilippe Mathieu-Daudé return true;
84a2b0a27dSPhilippe Mathieu-Daudé }
85a2b0a27dSPhilippe Mathieu-Daudé
trans_MTLO1(DisasContext * ctx,arg_r * a)8634fe9fa3SPhilippe Mathieu-Daudé static bool trans_MTLO1(DisasContext *ctx, arg_r *a)
87a2b0a27dSPhilippe Mathieu-Daudé {
88a2b0a27dSPhilippe Mathieu-Daudé gen_load_gpr(cpu_LO[1], a->rs);
89a2b0a27dSPhilippe Mathieu-Daudé
90a2b0a27dSPhilippe Mathieu-Daudé return true;
91a2b0a27dSPhilippe Mathieu-Daudé }
92a2b0a27dSPhilippe Mathieu-Daudé
93a2b0a27dSPhilippe Mathieu-Daudé /*
94a2b0a27dSPhilippe Mathieu-Daudé * Arithmetic (19 instructions)
95a2b0a27dSPhilippe Mathieu-Daudé * ----------------------------
96a2b0a27dSPhilippe Mathieu-Daudé * PADDB rd, rs, rt Parallel Add Byte
97a2b0a27dSPhilippe Mathieu-Daudé * PSUBB rd, rs, rt Parallel Subtract Byte
98a2b0a27dSPhilippe Mathieu-Daudé * PADDH rd, rs, rt Parallel Add Halfword
99a2b0a27dSPhilippe Mathieu-Daudé * PSUBH rd, rs, rt Parallel Subtract Halfword
100a2b0a27dSPhilippe Mathieu-Daudé * PADDW rd, rs, rt Parallel Add Word
101a2b0a27dSPhilippe Mathieu-Daudé * PSUBW rd, rs, rt Parallel Subtract Word
102a2b0a27dSPhilippe Mathieu-Daudé * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
103a2b0a27dSPhilippe Mathieu-Daudé * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
104a2b0a27dSPhilippe Mathieu-Daudé * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
105a2b0a27dSPhilippe Mathieu-Daudé * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
106a2b0a27dSPhilippe Mathieu-Daudé * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
107a2b0a27dSPhilippe Mathieu-Daudé * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
108a2b0a27dSPhilippe Mathieu-Daudé * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
109a2b0a27dSPhilippe Mathieu-Daudé * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
110a2b0a27dSPhilippe Mathieu-Daudé * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
111a2b0a27dSPhilippe Mathieu-Daudé * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
112a2b0a27dSPhilippe Mathieu-Daudé * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
113a2b0a27dSPhilippe Mathieu-Daudé * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
114a2b0a27dSPhilippe Mathieu-Daudé * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
115a2b0a27dSPhilippe Mathieu-Daudé */
116a2b0a27dSPhilippe Mathieu-Daudé
trans_parallel_arith(DisasContext * ctx,arg_r * a,void (* gen_logic_i64)(TCGv_i64,TCGv_i64,TCGv_i64))11734fe9fa3SPhilippe Mathieu-Daudé static bool trans_parallel_arith(DisasContext *ctx, arg_r *a,
1182d4ab117SPhilippe Mathieu-Daudé void (*gen_logic_i64)(TCGv_i64, TCGv_i64, TCGv_i64))
1192d4ab117SPhilippe Mathieu-Daudé {
1202d4ab117SPhilippe Mathieu-Daudé TCGv_i64 ax, bx;
1212d4ab117SPhilippe Mathieu-Daudé
1222d4ab117SPhilippe Mathieu-Daudé if (a->rd == 0) {
1232d4ab117SPhilippe Mathieu-Daudé /* nop */
1242d4ab117SPhilippe Mathieu-Daudé return true;
1252d4ab117SPhilippe Mathieu-Daudé }
1262d4ab117SPhilippe Mathieu-Daudé
1272d4ab117SPhilippe Mathieu-Daudé ax = tcg_temp_new_i64();
1282d4ab117SPhilippe Mathieu-Daudé bx = tcg_temp_new_i64();
1292d4ab117SPhilippe Mathieu-Daudé
1302d4ab117SPhilippe Mathieu-Daudé /* Lower half */
1312d4ab117SPhilippe Mathieu-Daudé gen_load_gpr(ax, a->rs);
1322d4ab117SPhilippe Mathieu-Daudé gen_load_gpr(bx, a->rt);
1332d4ab117SPhilippe Mathieu-Daudé gen_logic_i64(cpu_gpr[a->rd], ax, bx);
1342d4ab117SPhilippe Mathieu-Daudé
1352d4ab117SPhilippe Mathieu-Daudé /* Upper half */
1362d4ab117SPhilippe Mathieu-Daudé gen_load_gpr_hi(ax, a->rs);
1372d4ab117SPhilippe Mathieu-Daudé gen_load_gpr_hi(bx, a->rt);
1382d4ab117SPhilippe Mathieu-Daudé gen_logic_i64(cpu_gpr_hi[a->rd], ax, bx);
1392d4ab117SPhilippe Mathieu-Daudé return true;
1402d4ab117SPhilippe Mathieu-Daudé }
1412d4ab117SPhilippe Mathieu-Daudé
142709324dcSPhilippe Mathieu-Daudé /* Parallel Subtract Byte */
trans_PSUBB(DisasContext * ctx,arg_r * a)14334fe9fa3SPhilippe Mathieu-Daudé static bool trans_PSUBB(DisasContext *ctx, arg_r *a)
144709324dcSPhilippe Mathieu-Daudé {
145709324dcSPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_vec_sub8_i64);
146709324dcSPhilippe Mathieu-Daudé }
147709324dcSPhilippe Mathieu-Daudé
148709324dcSPhilippe Mathieu-Daudé /* Parallel Subtract Halfword */
trans_PSUBH(DisasContext * ctx,arg_r * a)14934fe9fa3SPhilippe Mathieu-Daudé static bool trans_PSUBH(DisasContext *ctx, arg_r *a)
150709324dcSPhilippe Mathieu-Daudé {
151709324dcSPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_vec_sub16_i64);
152709324dcSPhilippe Mathieu-Daudé }
153709324dcSPhilippe Mathieu-Daudé
154709324dcSPhilippe Mathieu-Daudé /* Parallel Subtract Word */
trans_PSUBW(DisasContext * ctx,arg_r * a)15534fe9fa3SPhilippe Mathieu-Daudé static bool trans_PSUBW(DisasContext *ctx, arg_r *a)
156709324dcSPhilippe Mathieu-Daudé {
157709324dcSPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_vec_sub32_i64);
158709324dcSPhilippe Mathieu-Daudé }
159709324dcSPhilippe Mathieu-Daudé
160a2b0a27dSPhilippe Mathieu-Daudé /*
161a2b0a27dSPhilippe Mathieu-Daudé * Min/Max (4 instructions)
162a2b0a27dSPhilippe Mathieu-Daudé * ------------------------
163a2b0a27dSPhilippe Mathieu-Daudé * PMAXH rd, rs, rt Parallel Maximum Halfword
164a2b0a27dSPhilippe Mathieu-Daudé * PMINH rd, rs, rt Parallel Minimum Halfword
165a2b0a27dSPhilippe Mathieu-Daudé * PMAXW rd, rs, rt Parallel Maximum Word
166a2b0a27dSPhilippe Mathieu-Daudé * PMINW rd, rs, rt Parallel Minimum Word
167a2b0a27dSPhilippe Mathieu-Daudé */
168a2b0a27dSPhilippe Mathieu-Daudé
169a2b0a27dSPhilippe Mathieu-Daudé /*
170a2b0a27dSPhilippe Mathieu-Daudé * Absolute (2 instructions)
171a2b0a27dSPhilippe Mathieu-Daudé * -------------------------
172a2b0a27dSPhilippe Mathieu-Daudé * PABSH rd, rt Parallel Absolute Halfword
173a2b0a27dSPhilippe Mathieu-Daudé * PABSW rd, rt Parallel Absolute Word
174a2b0a27dSPhilippe Mathieu-Daudé */
175a2b0a27dSPhilippe Mathieu-Daudé
176a2b0a27dSPhilippe Mathieu-Daudé /*
177a2b0a27dSPhilippe Mathieu-Daudé * Logical (4 instructions)
178a2b0a27dSPhilippe Mathieu-Daudé * ------------------------
179a2b0a27dSPhilippe Mathieu-Daudé * PAND rd, rs, rt Parallel AND
180a2b0a27dSPhilippe Mathieu-Daudé * POR rd, rs, rt Parallel OR
181a2b0a27dSPhilippe Mathieu-Daudé * PXOR rd, rs, rt Parallel XOR
182a2b0a27dSPhilippe Mathieu-Daudé * PNOR rd, rs, rt Parallel NOR
183a2b0a27dSPhilippe Mathieu-Daudé */
184a2b0a27dSPhilippe Mathieu-Daudé
1852d4ab117SPhilippe Mathieu-Daudé /* Parallel And */
trans_PAND(DisasContext * ctx,arg_r * a)18634fe9fa3SPhilippe Mathieu-Daudé static bool trans_PAND(DisasContext *ctx, arg_r *a)
1872d4ab117SPhilippe Mathieu-Daudé {
1882d4ab117SPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_and_i64);
1892d4ab117SPhilippe Mathieu-Daudé }
1902d4ab117SPhilippe Mathieu-Daudé
1912d4ab117SPhilippe Mathieu-Daudé /* Parallel Or */
trans_POR(DisasContext * ctx,arg_r * a)19234fe9fa3SPhilippe Mathieu-Daudé static bool trans_POR(DisasContext *ctx, arg_r *a)
1932d4ab117SPhilippe Mathieu-Daudé {
1942d4ab117SPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_or_i64);
1952d4ab117SPhilippe Mathieu-Daudé }
1962d4ab117SPhilippe Mathieu-Daudé
1972d4ab117SPhilippe Mathieu-Daudé /* Parallel Exclusive Or */
trans_PXOR(DisasContext * ctx,arg_r * a)19834fe9fa3SPhilippe Mathieu-Daudé static bool trans_PXOR(DisasContext *ctx, arg_r *a)
1992d4ab117SPhilippe Mathieu-Daudé {
2002d4ab117SPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_xor_i64);
2012d4ab117SPhilippe Mathieu-Daudé }
2022d4ab117SPhilippe Mathieu-Daudé
2032d4ab117SPhilippe Mathieu-Daudé /* Parallel Not Or */
trans_PNOR(DisasContext * ctx,arg_r * a)20434fe9fa3SPhilippe Mathieu-Daudé static bool trans_PNOR(DisasContext *ctx, arg_r *a)
2052d4ab117SPhilippe Mathieu-Daudé {
2062d4ab117SPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_nor_i64);
2072d4ab117SPhilippe Mathieu-Daudé }
2082d4ab117SPhilippe Mathieu-Daudé
209a2b0a27dSPhilippe Mathieu-Daudé /*
210a2b0a27dSPhilippe Mathieu-Daudé * Shift (9 instructions)
211a2b0a27dSPhilippe Mathieu-Daudé * ----------------------
212a2b0a27dSPhilippe Mathieu-Daudé * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
213a2b0a27dSPhilippe Mathieu-Daudé * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
214a2b0a27dSPhilippe Mathieu-Daudé * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
215a2b0a27dSPhilippe Mathieu-Daudé * PSLLW rd, rt, sa Parallel Shift Left Logical Word
216a2b0a27dSPhilippe Mathieu-Daudé * PSRLW rd, rt, sa Parallel Shift Right Logical Word
217a2b0a27dSPhilippe Mathieu-Daudé * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
218a2b0a27dSPhilippe Mathieu-Daudé * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
219a2b0a27dSPhilippe Mathieu-Daudé * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
220a2b0a27dSPhilippe Mathieu-Daudé * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
221a2b0a27dSPhilippe Mathieu-Daudé */
222a2b0a27dSPhilippe Mathieu-Daudé
223a2b0a27dSPhilippe Mathieu-Daudé /*
224a2b0a27dSPhilippe Mathieu-Daudé * Compare (6 instructions)
225a2b0a27dSPhilippe Mathieu-Daudé * ------------------------
226a2b0a27dSPhilippe Mathieu-Daudé * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
227a2b0a27dSPhilippe Mathieu-Daudé * PCEQB rd, rs, rt Parallel Compare for Equal Byte
228a2b0a27dSPhilippe Mathieu-Daudé * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
229a2b0a27dSPhilippe Mathieu-Daudé * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
230a2b0a27dSPhilippe Mathieu-Daudé * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
231a2b0a27dSPhilippe Mathieu-Daudé * PCEQW rd, rs, rt Parallel Compare for Equal Word
232a2b0a27dSPhilippe Mathieu-Daudé */
233a2b0a27dSPhilippe Mathieu-Daudé
trans_parallel_compare(DisasContext * ctx,arg_r * a,TCGCond cond,unsigned wlen)23434fe9fa3SPhilippe Mathieu-Daudé static bool trans_parallel_compare(DisasContext *ctx, arg_r *a,
23582fbf9fcSPhilippe Mathieu-Daudé TCGCond cond, unsigned wlen)
23682fbf9fcSPhilippe Mathieu-Daudé {
23782fbf9fcSPhilippe Mathieu-Daudé TCGv_i64 c0, c1, ax, bx, t0, t1, t2;
23882fbf9fcSPhilippe Mathieu-Daudé
23982fbf9fcSPhilippe Mathieu-Daudé if (a->rd == 0) {
24082fbf9fcSPhilippe Mathieu-Daudé /* nop */
24182fbf9fcSPhilippe Mathieu-Daudé return true;
24282fbf9fcSPhilippe Mathieu-Daudé }
24382fbf9fcSPhilippe Mathieu-Daudé
244c29e79afSRichard Henderson c0 = tcg_constant_tl(0);
245c29e79afSRichard Henderson c1 = tcg_constant_tl(0xffffffff);
24682fbf9fcSPhilippe Mathieu-Daudé ax = tcg_temp_new_i64();
24782fbf9fcSPhilippe Mathieu-Daudé bx = tcg_temp_new_i64();
24882fbf9fcSPhilippe Mathieu-Daudé t0 = tcg_temp_new_i64();
24982fbf9fcSPhilippe Mathieu-Daudé t1 = tcg_temp_new_i64();
25082fbf9fcSPhilippe Mathieu-Daudé t2 = tcg_temp_new_i64();
25182fbf9fcSPhilippe Mathieu-Daudé
25282fbf9fcSPhilippe Mathieu-Daudé /* Lower half */
25382fbf9fcSPhilippe Mathieu-Daudé gen_load_gpr(ax, a->rs);
25482fbf9fcSPhilippe Mathieu-Daudé gen_load_gpr(bx, a->rt);
25582fbf9fcSPhilippe Mathieu-Daudé for (int i = 0; i < (64 / wlen); i++) {
25682fbf9fcSPhilippe Mathieu-Daudé tcg_gen_sextract_i64(t0, ax, wlen * i, wlen);
25782fbf9fcSPhilippe Mathieu-Daudé tcg_gen_sextract_i64(t1, bx, wlen * i, wlen);
25882fbf9fcSPhilippe Mathieu-Daudé tcg_gen_movcond_i64(cond, t2, t1, t0, c1, c0);
25982fbf9fcSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rd], t2, wlen * i, wlen);
26082fbf9fcSPhilippe Mathieu-Daudé }
26182fbf9fcSPhilippe Mathieu-Daudé /* Upper half */
26282fbf9fcSPhilippe Mathieu-Daudé gen_load_gpr_hi(ax, a->rs);
26382fbf9fcSPhilippe Mathieu-Daudé gen_load_gpr_hi(bx, a->rt);
26482fbf9fcSPhilippe Mathieu-Daudé for (int i = 0; i < (64 / wlen); i++) {
26582fbf9fcSPhilippe Mathieu-Daudé tcg_gen_sextract_i64(t0, ax, wlen * i, wlen);
26682fbf9fcSPhilippe Mathieu-Daudé tcg_gen_sextract_i64(t1, bx, wlen * i, wlen);
26782fbf9fcSPhilippe Mathieu-Daudé tcg_gen_movcond_i64(cond, t2, t1, t0, c1, c0);
26882fbf9fcSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], t2, wlen * i, wlen);
26982fbf9fcSPhilippe Mathieu-Daudé }
27082fbf9fcSPhilippe Mathieu-Daudé return true;
27182fbf9fcSPhilippe Mathieu-Daudé }
27282fbf9fcSPhilippe Mathieu-Daudé
2738bd42c00SPhilippe Mathieu-Daudé /* Parallel Compare for Greater Than Byte */
trans_PCGTB(DisasContext * ctx,arg_r * a)27434fe9fa3SPhilippe Mathieu-Daudé static bool trans_PCGTB(DisasContext *ctx, arg_r *a)
2758bd42c00SPhilippe Mathieu-Daudé {
2768bd42c00SPhilippe Mathieu-Daudé return trans_parallel_compare(ctx, a, TCG_COND_GE, 8);
2778bd42c00SPhilippe Mathieu-Daudé }
2788bd42c00SPhilippe Mathieu-Daudé
27982fbf9fcSPhilippe Mathieu-Daudé /* Parallel Compare for Equal Byte */
trans_PCEQB(DisasContext * ctx,arg_r * a)28034fe9fa3SPhilippe Mathieu-Daudé static bool trans_PCEQB(DisasContext *ctx, arg_r *a)
28182fbf9fcSPhilippe Mathieu-Daudé {
28282fbf9fcSPhilippe Mathieu-Daudé return trans_parallel_compare(ctx, a, TCG_COND_EQ, 8);
28382fbf9fcSPhilippe Mathieu-Daudé }
28482fbf9fcSPhilippe Mathieu-Daudé
2858bd42c00SPhilippe Mathieu-Daudé /* Parallel Compare for Greater Than Halfword */
trans_PCGTH(DisasContext * ctx,arg_r * a)28634fe9fa3SPhilippe Mathieu-Daudé static bool trans_PCGTH(DisasContext *ctx, arg_r *a)
2878bd42c00SPhilippe Mathieu-Daudé {
2888bd42c00SPhilippe Mathieu-Daudé return trans_parallel_compare(ctx, a, TCG_COND_GE, 16);
2898bd42c00SPhilippe Mathieu-Daudé }
2908bd42c00SPhilippe Mathieu-Daudé
29182fbf9fcSPhilippe Mathieu-Daudé /* Parallel Compare for Equal Halfword */
trans_PCEQH(DisasContext * ctx,arg_r * a)29234fe9fa3SPhilippe Mathieu-Daudé static bool trans_PCEQH(DisasContext *ctx, arg_r *a)
29382fbf9fcSPhilippe Mathieu-Daudé {
29482fbf9fcSPhilippe Mathieu-Daudé return trans_parallel_compare(ctx, a, TCG_COND_EQ, 16);
29582fbf9fcSPhilippe Mathieu-Daudé }
29682fbf9fcSPhilippe Mathieu-Daudé
2978bd42c00SPhilippe Mathieu-Daudé /* Parallel Compare for Greater Than Word */
trans_PCGTW(DisasContext * ctx,arg_r * a)29834fe9fa3SPhilippe Mathieu-Daudé static bool trans_PCGTW(DisasContext *ctx, arg_r *a)
2998bd42c00SPhilippe Mathieu-Daudé {
3008bd42c00SPhilippe Mathieu-Daudé return trans_parallel_compare(ctx, a, TCG_COND_GE, 32);
3018bd42c00SPhilippe Mathieu-Daudé }
3028bd42c00SPhilippe Mathieu-Daudé
30382fbf9fcSPhilippe Mathieu-Daudé /* Parallel Compare for Equal Word */
trans_PCEQW(DisasContext * ctx,arg_r * a)30434fe9fa3SPhilippe Mathieu-Daudé static bool trans_PCEQW(DisasContext *ctx, arg_r *a)
30582fbf9fcSPhilippe Mathieu-Daudé {
30682fbf9fcSPhilippe Mathieu-Daudé return trans_parallel_compare(ctx, a, TCG_COND_EQ, 32);
30782fbf9fcSPhilippe Mathieu-Daudé }
30882fbf9fcSPhilippe Mathieu-Daudé
309a2b0a27dSPhilippe Mathieu-Daudé /*
310a2b0a27dSPhilippe Mathieu-Daudé * LZC (1 instruction)
311a2b0a27dSPhilippe Mathieu-Daudé * -------------------
312a2b0a27dSPhilippe Mathieu-Daudé * PLZCW rd, rs Parallel Leading Zero or One Count Word
313a2b0a27dSPhilippe Mathieu-Daudé */
314a2b0a27dSPhilippe Mathieu-Daudé
315a2b0a27dSPhilippe Mathieu-Daudé /*
316a2b0a27dSPhilippe Mathieu-Daudé * Quadword Load and Store (2 instructions)
317a2b0a27dSPhilippe Mathieu-Daudé * ----------------------------------------
318a2b0a27dSPhilippe Mathieu-Daudé * LQ rt, offset(base) Load Quadword
319a2b0a27dSPhilippe Mathieu-Daudé * SQ rt, offset(base) Store Quadword
320a2b0a27dSPhilippe Mathieu-Daudé */
321a2b0a27dSPhilippe Mathieu-Daudé
trans_LQ(DisasContext * ctx,arg_i * a)32234fe9fa3SPhilippe Mathieu-Daudé static bool trans_LQ(DisasContext *ctx, arg_i *a)
323aaaa82a9SPhilippe Mathieu-Daudé {
324aaaa82a9SPhilippe Mathieu-Daudé TCGv_i64 t0;
325aaaa82a9SPhilippe Mathieu-Daudé TCGv addr;
326aaaa82a9SPhilippe Mathieu-Daudé
327aaaa82a9SPhilippe Mathieu-Daudé if (a->rt == 0) {
328aaaa82a9SPhilippe Mathieu-Daudé /* nop */
329aaaa82a9SPhilippe Mathieu-Daudé return true;
330aaaa82a9SPhilippe Mathieu-Daudé }
331aaaa82a9SPhilippe Mathieu-Daudé
332aaaa82a9SPhilippe Mathieu-Daudé t0 = tcg_temp_new_i64();
333aaaa82a9SPhilippe Mathieu-Daudé addr = tcg_temp_new();
334aaaa82a9SPhilippe Mathieu-Daudé
335aaaa82a9SPhilippe Mathieu-Daudé gen_base_offset_addr(ctx, addr, a->base, a->offset);
336aaaa82a9SPhilippe Mathieu-Daudé /*
337aaaa82a9SPhilippe Mathieu-Daudé * Clear least-significant four bits of the effective
338aaaa82a9SPhilippe Mathieu-Daudé * address, effectively creating an aligned address.
339aaaa82a9SPhilippe Mathieu-Daudé */
340aaaa82a9SPhilippe Mathieu-Daudé tcg_gen_andi_tl(addr, addr, ~0xf);
341aaaa82a9SPhilippe Mathieu-Daudé
342aaaa82a9SPhilippe Mathieu-Daudé /* Lower half */
343*2803e246SPhilippe Mathieu-Daudé tcg_gen_qemu_ld_i64(t0, addr, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
344aaaa82a9SPhilippe Mathieu-Daudé gen_store_gpr(t0, a->rt);
345aaaa82a9SPhilippe Mathieu-Daudé
346aaaa82a9SPhilippe Mathieu-Daudé /* Upper half */
347aaaa82a9SPhilippe Mathieu-Daudé tcg_gen_addi_i64(addr, addr, 8);
348*2803e246SPhilippe Mathieu-Daudé tcg_gen_qemu_ld_i64(t0, addr, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
349aaaa82a9SPhilippe Mathieu-Daudé gen_store_gpr_hi(t0, a->rt);
350aaaa82a9SPhilippe Mathieu-Daudé return true;
351aaaa82a9SPhilippe Mathieu-Daudé }
352aaaa82a9SPhilippe Mathieu-Daudé
trans_SQ(DisasContext * ctx,arg_i * a)35334fe9fa3SPhilippe Mathieu-Daudé static bool trans_SQ(DisasContext *ctx, arg_i *a)
35480ad6303SPhilippe Mathieu-Daudé {
35580ad6303SPhilippe Mathieu-Daudé TCGv_i64 t0 = tcg_temp_new_i64();
35680ad6303SPhilippe Mathieu-Daudé TCGv addr = tcg_temp_new();
35780ad6303SPhilippe Mathieu-Daudé
35880ad6303SPhilippe Mathieu-Daudé gen_base_offset_addr(ctx, addr, a->base, a->offset);
35980ad6303SPhilippe Mathieu-Daudé /*
36080ad6303SPhilippe Mathieu-Daudé * Clear least-significant four bits of the effective
36180ad6303SPhilippe Mathieu-Daudé * address, effectively creating an aligned address.
36280ad6303SPhilippe Mathieu-Daudé */
36380ad6303SPhilippe Mathieu-Daudé tcg_gen_andi_tl(addr, addr, ~0xf);
36480ad6303SPhilippe Mathieu-Daudé
36580ad6303SPhilippe Mathieu-Daudé /* Lower half */
36680ad6303SPhilippe Mathieu-Daudé gen_load_gpr(t0, a->rt);
367*2803e246SPhilippe Mathieu-Daudé tcg_gen_qemu_st_i64(t0, addr, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
36880ad6303SPhilippe Mathieu-Daudé
36980ad6303SPhilippe Mathieu-Daudé /* Upper half */
37080ad6303SPhilippe Mathieu-Daudé tcg_gen_addi_i64(addr, addr, 8);
37180ad6303SPhilippe Mathieu-Daudé gen_load_gpr_hi(t0, a->rt);
372*2803e246SPhilippe Mathieu-Daudé tcg_gen_qemu_st_i64(t0, addr, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
37380ad6303SPhilippe Mathieu-Daudé return true;
37480ad6303SPhilippe Mathieu-Daudé }
37580ad6303SPhilippe Mathieu-Daudé
376a2b0a27dSPhilippe Mathieu-Daudé /*
377a2b0a27dSPhilippe Mathieu-Daudé * Multiply and Divide (19 instructions)
378a2b0a27dSPhilippe Mathieu-Daudé * -------------------------------------
379a2b0a27dSPhilippe Mathieu-Daudé * PMULTW rd, rs, rt Parallel Multiply Word
380a2b0a27dSPhilippe Mathieu-Daudé * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
381a2b0a27dSPhilippe Mathieu-Daudé * PDIVW rs, rt Parallel Divide Word
382a2b0a27dSPhilippe Mathieu-Daudé * PDIVUW rs, rt Parallel Divide Unsigned Word
383a2b0a27dSPhilippe Mathieu-Daudé * PMADDW rd, rs, rt Parallel Multiply-Add Word
384a2b0a27dSPhilippe Mathieu-Daudé * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
385a2b0a27dSPhilippe Mathieu-Daudé * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
386a2b0a27dSPhilippe Mathieu-Daudé * PMULTH rd, rs, rt Parallel Multiply Halfword
387a2b0a27dSPhilippe Mathieu-Daudé * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
388a2b0a27dSPhilippe Mathieu-Daudé * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
389a2b0a27dSPhilippe Mathieu-Daudé * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
390a2b0a27dSPhilippe Mathieu-Daudé * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
391a2b0a27dSPhilippe Mathieu-Daudé * PDIVBW rs, rt Parallel Divide Broadcast Word
392a2b0a27dSPhilippe Mathieu-Daudé * PMFHI rd Parallel Move From HI Register
393a2b0a27dSPhilippe Mathieu-Daudé * PMFLO rd Parallel Move From LO Register
394a2b0a27dSPhilippe Mathieu-Daudé * PMTHI rs Parallel Move To HI Register
395a2b0a27dSPhilippe Mathieu-Daudé * PMTLO rs Parallel Move To LO Register
396a2b0a27dSPhilippe Mathieu-Daudé * PMFHL rd Parallel Move From HI/LO Register
397a2b0a27dSPhilippe Mathieu-Daudé * PMTHL rs Parallel Move To HI/LO Register
398a2b0a27dSPhilippe Mathieu-Daudé */
399a2b0a27dSPhilippe Mathieu-Daudé
400a2b0a27dSPhilippe Mathieu-Daudé /*
401a2b0a27dSPhilippe Mathieu-Daudé * Pack/Extend (11 instructions)
402a2b0a27dSPhilippe Mathieu-Daudé * -----------------------------
403a2b0a27dSPhilippe Mathieu-Daudé * PPAC5 rd, rt Parallel Pack to 5 bits
404a2b0a27dSPhilippe Mathieu-Daudé * PPACB rd, rs, rt Parallel Pack to Byte
405a2b0a27dSPhilippe Mathieu-Daudé * PPACH rd, rs, rt Parallel Pack to Halfword
406a2b0a27dSPhilippe Mathieu-Daudé * PPACW rd, rs, rt Parallel Pack to Word
407a2b0a27dSPhilippe Mathieu-Daudé * PEXT5 rd, rt Parallel Extend Upper from 5 bits
408a2b0a27dSPhilippe Mathieu-Daudé * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
409a2b0a27dSPhilippe Mathieu-Daudé * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
410a2b0a27dSPhilippe Mathieu-Daudé * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
411a2b0a27dSPhilippe Mathieu-Daudé * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
412a2b0a27dSPhilippe Mathieu-Daudé * PEXTUW rd, rs, rt Parallel Extend Upper from Word
413a2b0a27dSPhilippe Mathieu-Daudé * PEXTLW rd, rs, rt Parallel Extend Lower from Word
414a2b0a27dSPhilippe Mathieu-Daudé */
415a2b0a27dSPhilippe Mathieu-Daudé
41671c49f39SPhilippe Mathieu-Daudé /* Parallel Pack to Word */
trans_PPACW(DisasContext * ctx,arg_r * a)41734fe9fa3SPhilippe Mathieu-Daudé static bool trans_PPACW(DisasContext *ctx, arg_r *a)
41871c49f39SPhilippe Mathieu-Daudé {
41971c49f39SPhilippe Mathieu-Daudé TCGv_i64 a0, b0, t0;
42071c49f39SPhilippe Mathieu-Daudé
42171c49f39SPhilippe Mathieu-Daudé if (a->rd == 0) {
42271c49f39SPhilippe Mathieu-Daudé /* nop */
42371c49f39SPhilippe Mathieu-Daudé return true;
42471c49f39SPhilippe Mathieu-Daudé }
42571c49f39SPhilippe Mathieu-Daudé
42671c49f39SPhilippe Mathieu-Daudé a0 = tcg_temp_new_i64();
42771c49f39SPhilippe Mathieu-Daudé b0 = tcg_temp_new_i64();
42871c49f39SPhilippe Mathieu-Daudé t0 = tcg_temp_new_i64();
42971c49f39SPhilippe Mathieu-Daudé
43071c49f39SPhilippe Mathieu-Daudé gen_load_gpr(a0, a->rs);
43171c49f39SPhilippe Mathieu-Daudé gen_load_gpr(b0, a->rt);
43271c49f39SPhilippe Mathieu-Daudé
43371c49f39SPhilippe Mathieu-Daudé gen_load_gpr_hi(t0, a->rt); /* b1 */
43471c49f39SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd], b0, t0, 32, 32);
43571c49f39SPhilippe Mathieu-Daudé
43671c49f39SPhilippe Mathieu-Daudé gen_load_gpr_hi(t0, a->rs); /* a1 */
43771c49f39SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], a0, t0, 32, 32);
43871c49f39SPhilippe Mathieu-Daudé return true;
43971c49f39SPhilippe Mathieu-Daudé }
44071c49f39SPhilippe Mathieu-Daudé
gen_pextw(TCGv_i64 dl,TCGv_i64 dh,TCGv_i64 a,TCGv_i64 b)4410bc69372SPhilippe Mathieu-Daudé static void gen_pextw(TCGv_i64 dl, TCGv_i64 dh, TCGv_i64 a, TCGv_i64 b)
4420bc69372SPhilippe Mathieu-Daudé {
4430bc69372SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(dl, b, a, 32, 32);
4440bc69372SPhilippe Mathieu-Daudé tcg_gen_shri_i64(b, b, 32);
4450bc69372SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(dh, a, b, 0, 32);
4460bc69372SPhilippe Mathieu-Daudé }
4470bc69372SPhilippe Mathieu-Daudé
trans_PEXTLx(DisasContext * ctx,arg_r * a,unsigned wlen)44834fe9fa3SPhilippe Mathieu-Daudé static bool trans_PEXTLx(DisasContext *ctx, arg_r *a, unsigned wlen)
449a9ea77f2SPhilippe Mathieu-Daudé {
450a9ea77f2SPhilippe Mathieu-Daudé TCGv_i64 ax, bx;
451a9ea77f2SPhilippe Mathieu-Daudé
452a9ea77f2SPhilippe Mathieu-Daudé if (a->rd == 0) {
453a9ea77f2SPhilippe Mathieu-Daudé /* nop */
454a9ea77f2SPhilippe Mathieu-Daudé return true;
455a9ea77f2SPhilippe Mathieu-Daudé }
456a9ea77f2SPhilippe Mathieu-Daudé
457a9ea77f2SPhilippe Mathieu-Daudé ax = tcg_temp_new_i64();
458a9ea77f2SPhilippe Mathieu-Daudé bx = tcg_temp_new_i64();
459a9ea77f2SPhilippe Mathieu-Daudé
460a9ea77f2SPhilippe Mathieu-Daudé gen_load_gpr(ax, a->rs);
461a9ea77f2SPhilippe Mathieu-Daudé gen_load_gpr(bx, a->rt);
462a9ea77f2SPhilippe Mathieu-Daudé
463a9ea77f2SPhilippe Mathieu-Daudé /* Lower half */
464a9ea77f2SPhilippe Mathieu-Daudé for (int i = 0; i < 64 / (2 * wlen); i++) {
465a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd],
466a9ea77f2SPhilippe Mathieu-Daudé cpu_gpr[a->rd], bx, 2 * wlen * i, wlen);
467a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd],
468a9ea77f2SPhilippe Mathieu-Daudé cpu_gpr[a->rd], ax, 2 * wlen * i + wlen, wlen);
469a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_shri_i64(bx, bx, wlen);
470a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_shri_i64(ax, ax, wlen);
471a9ea77f2SPhilippe Mathieu-Daudé }
472a9ea77f2SPhilippe Mathieu-Daudé /* Upper half */
473a9ea77f2SPhilippe Mathieu-Daudé for (int i = 0; i < 64 / (2 * wlen); i++) {
474a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd],
475a9ea77f2SPhilippe Mathieu-Daudé cpu_gpr_hi[a->rd], bx, 2 * wlen * i, wlen);
476a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd],
477a9ea77f2SPhilippe Mathieu-Daudé cpu_gpr_hi[a->rd], ax, 2 * wlen * i + wlen, wlen);
478a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_shri_i64(bx, bx, wlen);
479a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_shri_i64(ax, ax, wlen);
480a9ea77f2SPhilippe Mathieu-Daudé }
481a9ea77f2SPhilippe Mathieu-Daudé return true;
482a9ea77f2SPhilippe Mathieu-Daudé }
483a9ea77f2SPhilippe Mathieu-Daudé
484a9ea77f2SPhilippe Mathieu-Daudé /* Parallel Extend Lower from Byte */
trans_PEXTLB(DisasContext * ctx,arg_r * a)48534fe9fa3SPhilippe Mathieu-Daudé static bool trans_PEXTLB(DisasContext *ctx, arg_r *a)
486a9ea77f2SPhilippe Mathieu-Daudé {
487a9ea77f2SPhilippe Mathieu-Daudé return trans_PEXTLx(ctx, a, 8);
488a9ea77f2SPhilippe Mathieu-Daudé }
489a9ea77f2SPhilippe Mathieu-Daudé
490a9ea77f2SPhilippe Mathieu-Daudé /* Parallel Extend Lower from Halfword */
trans_PEXTLH(DisasContext * ctx,arg_r * a)49134fe9fa3SPhilippe Mathieu-Daudé static bool trans_PEXTLH(DisasContext *ctx, arg_r *a)
492a9ea77f2SPhilippe Mathieu-Daudé {
493a9ea77f2SPhilippe Mathieu-Daudé return trans_PEXTLx(ctx, a, 16);
494a9ea77f2SPhilippe Mathieu-Daudé }
495a9ea77f2SPhilippe Mathieu-Daudé
496a9ea77f2SPhilippe Mathieu-Daudé /* Parallel Extend Lower from Word */
trans_PEXTLW(DisasContext * ctx,arg_r * a)49734fe9fa3SPhilippe Mathieu-Daudé static bool trans_PEXTLW(DisasContext *ctx, arg_r *a)
498a9ea77f2SPhilippe Mathieu-Daudé {
499a9ea77f2SPhilippe Mathieu-Daudé TCGv_i64 ax, bx;
500a9ea77f2SPhilippe Mathieu-Daudé
501a9ea77f2SPhilippe Mathieu-Daudé if (a->rd == 0) {
502a9ea77f2SPhilippe Mathieu-Daudé /* nop */
503a9ea77f2SPhilippe Mathieu-Daudé return true;
504a9ea77f2SPhilippe Mathieu-Daudé }
505a9ea77f2SPhilippe Mathieu-Daudé
506a9ea77f2SPhilippe Mathieu-Daudé ax = tcg_temp_new_i64();
507a9ea77f2SPhilippe Mathieu-Daudé bx = tcg_temp_new_i64();
508a9ea77f2SPhilippe Mathieu-Daudé
509a9ea77f2SPhilippe Mathieu-Daudé gen_load_gpr(ax, a->rs);
510a9ea77f2SPhilippe Mathieu-Daudé gen_load_gpr(bx, a->rt);
511a9ea77f2SPhilippe Mathieu-Daudé gen_pextw(cpu_gpr[a->rd], cpu_gpr_hi[a->rd], ax, bx);
512a9ea77f2SPhilippe Mathieu-Daudé return true;
513a9ea77f2SPhilippe Mathieu-Daudé }
514a9ea77f2SPhilippe Mathieu-Daudé
5150bc69372SPhilippe Mathieu-Daudé /* Parallel Extend Upper from Word */
trans_PEXTUW(DisasContext * ctx,arg_r * a)51634fe9fa3SPhilippe Mathieu-Daudé static bool trans_PEXTUW(DisasContext *ctx, arg_r *a)
5170bc69372SPhilippe Mathieu-Daudé {
5180bc69372SPhilippe Mathieu-Daudé TCGv_i64 ax, bx;
5190bc69372SPhilippe Mathieu-Daudé
5200bc69372SPhilippe Mathieu-Daudé if (a->rd == 0) {
5210bc69372SPhilippe Mathieu-Daudé /* nop */
5220bc69372SPhilippe Mathieu-Daudé return true;
5230bc69372SPhilippe Mathieu-Daudé }
5240bc69372SPhilippe Mathieu-Daudé
5250bc69372SPhilippe Mathieu-Daudé ax = tcg_temp_new_i64();
5260bc69372SPhilippe Mathieu-Daudé bx = tcg_temp_new_i64();
5270bc69372SPhilippe Mathieu-Daudé
5280bc69372SPhilippe Mathieu-Daudé gen_load_gpr_hi(ax, a->rs);
5290bc69372SPhilippe Mathieu-Daudé gen_load_gpr_hi(bx, a->rt);
5300bc69372SPhilippe Mathieu-Daudé gen_pextw(cpu_gpr[a->rd], cpu_gpr_hi[a->rd], ax, bx);
5310bc69372SPhilippe Mathieu-Daudé return true;
5320bc69372SPhilippe Mathieu-Daudé }
5330bc69372SPhilippe Mathieu-Daudé
534a2b0a27dSPhilippe Mathieu-Daudé /*
535a2b0a27dSPhilippe Mathieu-Daudé * Others (16 instructions)
536a2b0a27dSPhilippe Mathieu-Daudé * ------------------------
537a2b0a27dSPhilippe Mathieu-Daudé * PCPYH rd, rt Parallel Copy Halfword
538a2b0a27dSPhilippe Mathieu-Daudé * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
539a2b0a27dSPhilippe Mathieu-Daudé * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
540a2b0a27dSPhilippe Mathieu-Daudé * PREVH rd, rt Parallel Reverse Halfword
541a2b0a27dSPhilippe Mathieu-Daudé * PINTH rd, rs, rt Parallel Interleave Halfword
542a2b0a27dSPhilippe Mathieu-Daudé * PINTEH rd, rs, rt Parallel Interleave Even Halfword
543a2b0a27dSPhilippe Mathieu-Daudé * PEXEH rd, rt Parallel Exchange Even Halfword
544a2b0a27dSPhilippe Mathieu-Daudé * PEXCH rd, rt Parallel Exchange Center Halfword
545a2b0a27dSPhilippe Mathieu-Daudé * PEXEW rd, rt Parallel Exchange Even Word
546a2b0a27dSPhilippe Mathieu-Daudé * PEXCW rd, rt Parallel Exchange Center Word
547a2b0a27dSPhilippe Mathieu-Daudé * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
548a2b0a27dSPhilippe Mathieu-Daudé * MFSA rd Move from Shift Amount Register
549a2b0a27dSPhilippe Mathieu-Daudé * MTSA rs Move to Shift Amount Register
550a2b0a27dSPhilippe Mathieu-Daudé * MTSAB rs, immediate Move Byte Count to Shift Amount Register
551a2b0a27dSPhilippe Mathieu-Daudé * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
552a2b0a27dSPhilippe Mathieu-Daudé * PROT3W rd, rt Parallel Rotate 3 Words
553a2b0a27dSPhilippe Mathieu-Daudé */
554a2b0a27dSPhilippe Mathieu-Daudé
555a2b0a27dSPhilippe Mathieu-Daudé /* Parallel Copy Halfword */
trans_PCPYH(DisasContext * s,arg_r * a)55634fe9fa3SPhilippe Mathieu-Daudé static bool trans_PCPYH(DisasContext *s, arg_r *a)
557a2b0a27dSPhilippe Mathieu-Daudé {
558a2b0a27dSPhilippe Mathieu-Daudé if (a->rd == 0) {
559a2b0a27dSPhilippe Mathieu-Daudé /* nop */
560a2b0a27dSPhilippe Mathieu-Daudé return true;
561a2b0a27dSPhilippe Mathieu-Daudé }
562a2b0a27dSPhilippe Mathieu-Daudé
563a2b0a27dSPhilippe Mathieu-Daudé if (a->rt == 0) {
564a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr[a->rd], 0);
565a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
566a2b0a27dSPhilippe Mathieu-Daudé return true;
567a2b0a27dSPhilippe Mathieu-Daudé }
568a2b0a27dSPhilippe Mathieu-Daudé
569a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rt], cpu_gpr[a->rt], 16, 16);
570a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rd], cpu_gpr[a->rd], 32, 32);
571a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rt], cpu_gpr_hi[a->rt], 16, 16);
572a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], 32, 32);
573a2b0a27dSPhilippe Mathieu-Daudé
574a2b0a27dSPhilippe Mathieu-Daudé return true;
575a2b0a27dSPhilippe Mathieu-Daudé }
576a2b0a27dSPhilippe Mathieu-Daudé
577a2b0a27dSPhilippe Mathieu-Daudé /* Parallel Copy Lower Doubleword */
trans_PCPYLD(DisasContext * s,arg_r * a)57834fe9fa3SPhilippe Mathieu-Daudé static bool trans_PCPYLD(DisasContext *s, arg_r *a)
579a2b0a27dSPhilippe Mathieu-Daudé {
580a2b0a27dSPhilippe Mathieu-Daudé if (a->rd == 0) {
581a2b0a27dSPhilippe Mathieu-Daudé /* nop */
582a2b0a27dSPhilippe Mathieu-Daudé return true;
583a2b0a27dSPhilippe Mathieu-Daudé }
584a2b0a27dSPhilippe Mathieu-Daudé
585a2b0a27dSPhilippe Mathieu-Daudé if (a->rs == 0) {
586a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
587a2b0a27dSPhilippe Mathieu-Daudé } else {
588a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_mov_i64(cpu_gpr_hi[a->rd], cpu_gpr[a->rs]);
589a2b0a27dSPhilippe Mathieu-Daudé }
590a2b0a27dSPhilippe Mathieu-Daudé
591a2b0a27dSPhilippe Mathieu-Daudé if (a->rt == 0) {
592a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr[a->rd], 0);
593a2b0a27dSPhilippe Mathieu-Daudé } else if (a->rd != a->rt) {
594a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_mov_i64(cpu_gpr[a->rd], cpu_gpr[a->rt]);
595a2b0a27dSPhilippe Mathieu-Daudé }
596a2b0a27dSPhilippe Mathieu-Daudé
597a2b0a27dSPhilippe Mathieu-Daudé return true;
598a2b0a27dSPhilippe Mathieu-Daudé }
599a2b0a27dSPhilippe Mathieu-Daudé
600a2b0a27dSPhilippe Mathieu-Daudé /* Parallel Copy Upper Doubleword */
trans_PCPYUD(DisasContext * s,arg_r * a)60134fe9fa3SPhilippe Mathieu-Daudé static bool trans_PCPYUD(DisasContext *s, arg_r *a)
602a2b0a27dSPhilippe Mathieu-Daudé {
603a2b0a27dSPhilippe Mathieu-Daudé if (a->rd == 0) {
604a2b0a27dSPhilippe Mathieu-Daudé /* nop */
605a2b0a27dSPhilippe Mathieu-Daudé return true;
606a2b0a27dSPhilippe Mathieu-Daudé }
607a2b0a27dSPhilippe Mathieu-Daudé
608a2b0a27dSPhilippe Mathieu-Daudé gen_load_gpr_hi(cpu_gpr[a->rd], a->rs);
609a2b0a27dSPhilippe Mathieu-Daudé
610a2b0a27dSPhilippe Mathieu-Daudé if (a->rt == 0) {
611a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
612a2b0a27dSPhilippe Mathieu-Daudé } else if (a->rd != a->rt) {
613a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_mov_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rt]);
614a2b0a27dSPhilippe Mathieu-Daudé }
615a2b0a27dSPhilippe Mathieu-Daudé
616a2b0a27dSPhilippe Mathieu-Daudé return true;
617a2b0a27dSPhilippe Mathieu-Daudé }
618dce4808fSPhilippe Mathieu-Daudé
619dce4808fSPhilippe Mathieu-Daudé /* Parallel Rotate 3 Words Left */
trans_PROT3W(DisasContext * ctx,arg_r * a)62034fe9fa3SPhilippe Mathieu-Daudé static bool trans_PROT3W(DisasContext *ctx, arg_r *a)
621dce4808fSPhilippe Mathieu-Daudé {
622dce4808fSPhilippe Mathieu-Daudé TCGv_i64 ax;
623dce4808fSPhilippe Mathieu-Daudé
624dce4808fSPhilippe Mathieu-Daudé if (a->rd == 0) {
625dce4808fSPhilippe Mathieu-Daudé /* nop */
626dce4808fSPhilippe Mathieu-Daudé return true;
627dce4808fSPhilippe Mathieu-Daudé }
628dce4808fSPhilippe Mathieu-Daudé if (a->rt == 0) {
629dce4808fSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr[a->rd], 0);
630dce4808fSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
631dce4808fSPhilippe Mathieu-Daudé return true;
632dce4808fSPhilippe Mathieu-Daudé }
633dce4808fSPhilippe Mathieu-Daudé
634dce4808fSPhilippe Mathieu-Daudé ax = tcg_temp_new_i64();
635dce4808fSPhilippe Mathieu-Daudé
636dce4808fSPhilippe Mathieu-Daudé tcg_gen_mov_i64(ax, cpu_gpr_hi[a->rt]);
637dce4808fSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], ax, cpu_gpr[a->rt], 0, 32);
638dce4808fSPhilippe Mathieu-Daudé
639dce4808fSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rt], ax, 0, 32);
640dce4808fSPhilippe Mathieu-Daudé tcg_gen_rotri_i64(cpu_gpr[a->rd], cpu_gpr[a->rd], 32);
641dce4808fSPhilippe Mathieu-Daudé return true;
642dce4808fSPhilippe Mathieu-Daudé }
643