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