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é 67a2b0a27dSPhilippe Mathieu-Daudé static bool trans_MFHI1(DisasContext *ctx, arg_rtype *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é 74a2b0a27dSPhilippe Mathieu-Daudé static bool trans_MFLO1(DisasContext *ctx, arg_rtype *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é 81a2b0a27dSPhilippe Mathieu-Daudé static bool trans_MTHI1(DisasContext *ctx, arg_rtype *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é 88a2b0a27dSPhilippe Mathieu-Daudé static bool trans_MTLO1(DisasContext *ctx, arg_rtype *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é 1192d4ab117SPhilippe Mathieu-Daudé static bool trans_parallel_arith(DisasContext *ctx, arg_rtype *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é 1422d4ab117SPhilippe Mathieu-Daudé tcg_temp_free(bx); 1432d4ab117SPhilippe Mathieu-Daudé tcg_temp_free(ax); 1442d4ab117SPhilippe Mathieu-Daudé 1452d4ab117SPhilippe Mathieu-Daudé return true; 1462d4ab117SPhilippe Mathieu-Daudé } 1472d4ab117SPhilippe Mathieu-Daudé 148709324dcSPhilippe Mathieu-Daudé /* Parallel Subtract Byte */ 149709324dcSPhilippe Mathieu-Daudé static bool trans_PSUBB(DisasContext *ctx, arg_rtype *a) 150709324dcSPhilippe Mathieu-Daudé { 151709324dcSPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_vec_sub8_i64); 152709324dcSPhilippe Mathieu-Daudé } 153709324dcSPhilippe Mathieu-Daudé 154709324dcSPhilippe Mathieu-Daudé /* Parallel Subtract Halfword */ 155709324dcSPhilippe Mathieu-Daudé static bool trans_PSUBH(DisasContext *ctx, arg_rtype *a) 156709324dcSPhilippe Mathieu-Daudé { 157709324dcSPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_vec_sub16_i64); 158709324dcSPhilippe Mathieu-Daudé } 159709324dcSPhilippe Mathieu-Daudé 160709324dcSPhilippe Mathieu-Daudé /* Parallel Subtract Word */ 161709324dcSPhilippe Mathieu-Daudé static bool trans_PSUBW(DisasContext *ctx, arg_rtype *a) 162709324dcSPhilippe Mathieu-Daudé { 163709324dcSPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_vec_sub32_i64); 164709324dcSPhilippe Mathieu-Daudé } 165709324dcSPhilippe Mathieu-Daudé 166a2b0a27dSPhilippe Mathieu-Daudé /* 167a2b0a27dSPhilippe Mathieu-Daudé * Min/Max (4 instructions) 168a2b0a27dSPhilippe Mathieu-Daudé * ------------------------ 169a2b0a27dSPhilippe Mathieu-Daudé * PMAXH rd, rs, rt Parallel Maximum Halfword 170a2b0a27dSPhilippe Mathieu-Daudé * PMINH rd, rs, rt Parallel Minimum Halfword 171a2b0a27dSPhilippe Mathieu-Daudé * PMAXW rd, rs, rt Parallel Maximum Word 172a2b0a27dSPhilippe Mathieu-Daudé * PMINW rd, rs, rt Parallel Minimum Word 173a2b0a27dSPhilippe Mathieu-Daudé */ 174a2b0a27dSPhilippe Mathieu-Daudé 175a2b0a27dSPhilippe Mathieu-Daudé /* 176a2b0a27dSPhilippe Mathieu-Daudé * Absolute (2 instructions) 177a2b0a27dSPhilippe Mathieu-Daudé * ------------------------- 178a2b0a27dSPhilippe Mathieu-Daudé * PABSH rd, rt Parallel Absolute Halfword 179a2b0a27dSPhilippe Mathieu-Daudé * PABSW rd, rt Parallel Absolute Word 180a2b0a27dSPhilippe Mathieu-Daudé */ 181a2b0a27dSPhilippe Mathieu-Daudé 182a2b0a27dSPhilippe Mathieu-Daudé /* 183a2b0a27dSPhilippe Mathieu-Daudé * Logical (4 instructions) 184a2b0a27dSPhilippe Mathieu-Daudé * ------------------------ 185a2b0a27dSPhilippe Mathieu-Daudé * PAND rd, rs, rt Parallel AND 186a2b0a27dSPhilippe Mathieu-Daudé * POR rd, rs, rt Parallel OR 187a2b0a27dSPhilippe Mathieu-Daudé * PXOR rd, rs, rt Parallel XOR 188a2b0a27dSPhilippe Mathieu-Daudé * PNOR rd, rs, rt Parallel NOR 189a2b0a27dSPhilippe Mathieu-Daudé */ 190a2b0a27dSPhilippe Mathieu-Daudé 1912d4ab117SPhilippe Mathieu-Daudé /* Parallel And */ 1922d4ab117SPhilippe Mathieu-Daudé static bool trans_PAND(DisasContext *ctx, arg_rtype *a) 1932d4ab117SPhilippe Mathieu-Daudé { 1942d4ab117SPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_and_i64); 1952d4ab117SPhilippe Mathieu-Daudé } 1962d4ab117SPhilippe Mathieu-Daudé 1972d4ab117SPhilippe Mathieu-Daudé /* Parallel Or */ 1982d4ab117SPhilippe Mathieu-Daudé static bool trans_POR(DisasContext *ctx, arg_rtype *a) 1992d4ab117SPhilippe Mathieu-Daudé { 2002d4ab117SPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_or_i64); 2012d4ab117SPhilippe Mathieu-Daudé } 2022d4ab117SPhilippe Mathieu-Daudé 2032d4ab117SPhilippe Mathieu-Daudé /* Parallel Exclusive Or */ 2042d4ab117SPhilippe Mathieu-Daudé static bool trans_PXOR(DisasContext *ctx, arg_rtype *a) 2052d4ab117SPhilippe Mathieu-Daudé { 2062d4ab117SPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_xor_i64); 2072d4ab117SPhilippe Mathieu-Daudé } 2082d4ab117SPhilippe Mathieu-Daudé 2092d4ab117SPhilippe Mathieu-Daudé /* Parallel Not Or */ 2102d4ab117SPhilippe Mathieu-Daudé static bool trans_PNOR(DisasContext *ctx, arg_rtype *a) 2112d4ab117SPhilippe Mathieu-Daudé { 2122d4ab117SPhilippe Mathieu-Daudé return trans_parallel_arith(ctx, a, tcg_gen_nor_i64); 2132d4ab117SPhilippe Mathieu-Daudé } 2142d4ab117SPhilippe Mathieu-Daudé 215a2b0a27dSPhilippe Mathieu-Daudé /* 216a2b0a27dSPhilippe Mathieu-Daudé * Shift (9 instructions) 217a2b0a27dSPhilippe Mathieu-Daudé * ---------------------- 218a2b0a27dSPhilippe Mathieu-Daudé * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword 219a2b0a27dSPhilippe Mathieu-Daudé * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword 220a2b0a27dSPhilippe Mathieu-Daudé * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword 221a2b0a27dSPhilippe Mathieu-Daudé * PSLLW rd, rt, sa Parallel Shift Left Logical Word 222a2b0a27dSPhilippe Mathieu-Daudé * PSRLW rd, rt, sa Parallel Shift Right Logical Word 223a2b0a27dSPhilippe Mathieu-Daudé * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word 224a2b0a27dSPhilippe Mathieu-Daudé * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word 225a2b0a27dSPhilippe Mathieu-Daudé * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word 226a2b0a27dSPhilippe Mathieu-Daudé * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word 227a2b0a27dSPhilippe Mathieu-Daudé */ 228a2b0a27dSPhilippe Mathieu-Daudé 229a2b0a27dSPhilippe Mathieu-Daudé /* 230a2b0a27dSPhilippe Mathieu-Daudé * Compare (6 instructions) 231a2b0a27dSPhilippe Mathieu-Daudé * ------------------------ 232a2b0a27dSPhilippe Mathieu-Daudé * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte 233a2b0a27dSPhilippe Mathieu-Daudé * PCEQB rd, rs, rt Parallel Compare for Equal Byte 234a2b0a27dSPhilippe Mathieu-Daudé * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword 235a2b0a27dSPhilippe Mathieu-Daudé * PCEQH rd, rs, rt Parallel Compare for Equal Halfword 236a2b0a27dSPhilippe Mathieu-Daudé * PCGTW rd, rs, rt Parallel Compare for Greater Than Word 237a2b0a27dSPhilippe Mathieu-Daudé * PCEQW rd, rs, rt Parallel Compare for Equal Word 238a2b0a27dSPhilippe Mathieu-Daudé */ 239a2b0a27dSPhilippe Mathieu-Daudé 240a2b0a27dSPhilippe Mathieu-Daudé /* 241a2b0a27dSPhilippe Mathieu-Daudé * LZC (1 instruction) 242a2b0a27dSPhilippe Mathieu-Daudé * ------------------- 243a2b0a27dSPhilippe Mathieu-Daudé * PLZCW rd, rs Parallel Leading Zero or One Count Word 244a2b0a27dSPhilippe Mathieu-Daudé */ 245a2b0a27dSPhilippe Mathieu-Daudé 246a2b0a27dSPhilippe Mathieu-Daudé /* 247a2b0a27dSPhilippe Mathieu-Daudé * Quadword Load and Store (2 instructions) 248a2b0a27dSPhilippe Mathieu-Daudé * ---------------------------------------- 249a2b0a27dSPhilippe Mathieu-Daudé * LQ rt, offset(base) Load Quadword 250a2b0a27dSPhilippe Mathieu-Daudé * SQ rt, offset(base) Store Quadword 251a2b0a27dSPhilippe Mathieu-Daudé */ 252a2b0a27dSPhilippe Mathieu-Daudé 253a2b0a27dSPhilippe Mathieu-Daudé /* 254a2b0a27dSPhilippe Mathieu-Daudé * Multiply and Divide (19 instructions) 255a2b0a27dSPhilippe Mathieu-Daudé * ------------------------------------- 256a2b0a27dSPhilippe Mathieu-Daudé * PMULTW rd, rs, rt Parallel Multiply Word 257a2b0a27dSPhilippe Mathieu-Daudé * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word 258a2b0a27dSPhilippe Mathieu-Daudé * PDIVW rs, rt Parallel Divide Word 259a2b0a27dSPhilippe Mathieu-Daudé * PDIVUW rs, rt Parallel Divide Unsigned Word 260a2b0a27dSPhilippe Mathieu-Daudé * PMADDW rd, rs, rt Parallel Multiply-Add Word 261a2b0a27dSPhilippe Mathieu-Daudé * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word 262a2b0a27dSPhilippe Mathieu-Daudé * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word 263a2b0a27dSPhilippe Mathieu-Daudé * PMULTH rd, rs, rt Parallel Multiply Halfword 264a2b0a27dSPhilippe Mathieu-Daudé * PMADDH rd, rs, rt Parallel Multiply-Add Halfword 265a2b0a27dSPhilippe Mathieu-Daudé * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword 266a2b0a27dSPhilippe Mathieu-Daudé * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword 267a2b0a27dSPhilippe Mathieu-Daudé * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword 268a2b0a27dSPhilippe Mathieu-Daudé * PDIVBW rs, rt Parallel Divide Broadcast Word 269a2b0a27dSPhilippe Mathieu-Daudé * PMFHI rd Parallel Move From HI Register 270a2b0a27dSPhilippe Mathieu-Daudé * PMFLO rd Parallel Move From LO Register 271a2b0a27dSPhilippe Mathieu-Daudé * PMTHI rs Parallel Move To HI Register 272a2b0a27dSPhilippe Mathieu-Daudé * PMTLO rs Parallel Move To LO Register 273a2b0a27dSPhilippe Mathieu-Daudé * PMFHL rd Parallel Move From HI/LO Register 274a2b0a27dSPhilippe Mathieu-Daudé * PMTHL rs Parallel Move To HI/LO Register 275a2b0a27dSPhilippe Mathieu-Daudé */ 276a2b0a27dSPhilippe Mathieu-Daudé 277a2b0a27dSPhilippe Mathieu-Daudé /* 278a2b0a27dSPhilippe Mathieu-Daudé * Pack/Extend (11 instructions) 279a2b0a27dSPhilippe Mathieu-Daudé * ----------------------------- 280a2b0a27dSPhilippe Mathieu-Daudé * PPAC5 rd, rt Parallel Pack to 5 bits 281a2b0a27dSPhilippe Mathieu-Daudé * PPACB rd, rs, rt Parallel Pack to Byte 282a2b0a27dSPhilippe Mathieu-Daudé * PPACH rd, rs, rt Parallel Pack to Halfword 283a2b0a27dSPhilippe Mathieu-Daudé * PPACW rd, rs, rt Parallel Pack to Word 284a2b0a27dSPhilippe Mathieu-Daudé * PEXT5 rd, rt Parallel Extend Upper from 5 bits 285a2b0a27dSPhilippe Mathieu-Daudé * PEXTUB rd, rs, rt Parallel Extend Upper from Byte 286a2b0a27dSPhilippe Mathieu-Daudé * PEXTLB rd, rs, rt Parallel Extend Lower from Byte 287a2b0a27dSPhilippe Mathieu-Daudé * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword 288a2b0a27dSPhilippe Mathieu-Daudé * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword 289a2b0a27dSPhilippe Mathieu-Daudé * PEXTUW rd, rs, rt Parallel Extend Upper from Word 290a2b0a27dSPhilippe Mathieu-Daudé * PEXTLW rd, rs, rt Parallel Extend Lower from Word 291a2b0a27dSPhilippe Mathieu-Daudé */ 292a2b0a27dSPhilippe Mathieu-Daudé 2930bc69372SPhilippe Mathieu-Daudé static void gen_pextw(TCGv_i64 dl, TCGv_i64 dh, TCGv_i64 a, TCGv_i64 b) 2940bc69372SPhilippe Mathieu-Daudé { 2950bc69372SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(dl, b, a, 32, 32); 2960bc69372SPhilippe Mathieu-Daudé tcg_gen_shri_i64(b, b, 32); 2970bc69372SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(dh, a, b, 0, 32); 2980bc69372SPhilippe Mathieu-Daudé } 2990bc69372SPhilippe Mathieu-Daudé 300*a9ea77f2SPhilippe Mathieu-Daudé static bool trans_PEXTLx(DisasContext *ctx, arg_rtype *a, unsigned wlen) 301*a9ea77f2SPhilippe Mathieu-Daudé { 302*a9ea77f2SPhilippe Mathieu-Daudé TCGv_i64 ax, bx; 303*a9ea77f2SPhilippe Mathieu-Daudé 304*a9ea77f2SPhilippe Mathieu-Daudé if (a->rd == 0) { 305*a9ea77f2SPhilippe Mathieu-Daudé /* nop */ 306*a9ea77f2SPhilippe Mathieu-Daudé return true; 307*a9ea77f2SPhilippe Mathieu-Daudé } 308*a9ea77f2SPhilippe Mathieu-Daudé 309*a9ea77f2SPhilippe Mathieu-Daudé ax = tcg_temp_new_i64(); 310*a9ea77f2SPhilippe Mathieu-Daudé bx = tcg_temp_new_i64(); 311*a9ea77f2SPhilippe Mathieu-Daudé 312*a9ea77f2SPhilippe Mathieu-Daudé gen_load_gpr(ax, a->rs); 313*a9ea77f2SPhilippe Mathieu-Daudé gen_load_gpr(bx, a->rt); 314*a9ea77f2SPhilippe Mathieu-Daudé 315*a9ea77f2SPhilippe Mathieu-Daudé /* Lower half */ 316*a9ea77f2SPhilippe Mathieu-Daudé for (int i = 0; i < 64 / (2 * wlen); i++) { 317*a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd], 318*a9ea77f2SPhilippe Mathieu-Daudé cpu_gpr[a->rd], bx, 2 * wlen * i, wlen); 319*a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd], 320*a9ea77f2SPhilippe Mathieu-Daudé cpu_gpr[a->rd], ax, 2 * wlen * i + wlen, wlen); 321*a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_shri_i64(bx, bx, wlen); 322*a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_shri_i64(ax, ax, wlen); 323*a9ea77f2SPhilippe Mathieu-Daudé } 324*a9ea77f2SPhilippe Mathieu-Daudé /* Upper half */ 325*a9ea77f2SPhilippe Mathieu-Daudé for (int i = 0; i < 64 / (2 * wlen); i++) { 326*a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], 327*a9ea77f2SPhilippe Mathieu-Daudé cpu_gpr_hi[a->rd], bx, 2 * wlen * i, wlen); 328*a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], 329*a9ea77f2SPhilippe Mathieu-Daudé cpu_gpr_hi[a->rd], ax, 2 * wlen * i + wlen, wlen); 330*a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_shri_i64(bx, bx, wlen); 331*a9ea77f2SPhilippe Mathieu-Daudé tcg_gen_shri_i64(ax, ax, wlen); 332*a9ea77f2SPhilippe Mathieu-Daudé } 333*a9ea77f2SPhilippe Mathieu-Daudé 334*a9ea77f2SPhilippe Mathieu-Daudé tcg_temp_free(bx); 335*a9ea77f2SPhilippe Mathieu-Daudé tcg_temp_free(ax); 336*a9ea77f2SPhilippe Mathieu-Daudé 337*a9ea77f2SPhilippe Mathieu-Daudé return true; 338*a9ea77f2SPhilippe Mathieu-Daudé } 339*a9ea77f2SPhilippe Mathieu-Daudé 340*a9ea77f2SPhilippe Mathieu-Daudé /* Parallel Extend Lower from Byte */ 341*a9ea77f2SPhilippe Mathieu-Daudé static bool trans_PEXTLB(DisasContext *ctx, arg_rtype *a) 342*a9ea77f2SPhilippe Mathieu-Daudé { 343*a9ea77f2SPhilippe Mathieu-Daudé return trans_PEXTLx(ctx, a, 8); 344*a9ea77f2SPhilippe Mathieu-Daudé } 345*a9ea77f2SPhilippe Mathieu-Daudé 346*a9ea77f2SPhilippe Mathieu-Daudé /* Parallel Extend Lower from Halfword */ 347*a9ea77f2SPhilippe Mathieu-Daudé static bool trans_PEXTLH(DisasContext *ctx, arg_rtype *a) 348*a9ea77f2SPhilippe Mathieu-Daudé { 349*a9ea77f2SPhilippe Mathieu-Daudé return trans_PEXTLx(ctx, a, 16); 350*a9ea77f2SPhilippe Mathieu-Daudé } 351*a9ea77f2SPhilippe Mathieu-Daudé 352*a9ea77f2SPhilippe Mathieu-Daudé /* Parallel Extend Lower from Word */ 353*a9ea77f2SPhilippe Mathieu-Daudé static bool trans_PEXTLW(DisasContext *ctx, arg_rtype *a) 354*a9ea77f2SPhilippe Mathieu-Daudé { 355*a9ea77f2SPhilippe Mathieu-Daudé TCGv_i64 ax, bx; 356*a9ea77f2SPhilippe Mathieu-Daudé 357*a9ea77f2SPhilippe Mathieu-Daudé if (a->rd == 0) { 358*a9ea77f2SPhilippe Mathieu-Daudé /* nop */ 359*a9ea77f2SPhilippe Mathieu-Daudé return true; 360*a9ea77f2SPhilippe Mathieu-Daudé } 361*a9ea77f2SPhilippe Mathieu-Daudé 362*a9ea77f2SPhilippe Mathieu-Daudé ax = tcg_temp_new_i64(); 363*a9ea77f2SPhilippe Mathieu-Daudé bx = tcg_temp_new_i64(); 364*a9ea77f2SPhilippe Mathieu-Daudé 365*a9ea77f2SPhilippe Mathieu-Daudé gen_load_gpr(ax, a->rs); 366*a9ea77f2SPhilippe Mathieu-Daudé gen_load_gpr(bx, a->rt); 367*a9ea77f2SPhilippe Mathieu-Daudé gen_pextw(cpu_gpr[a->rd], cpu_gpr_hi[a->rd], ax, bx); 368*a9ea77f2SPhilippe Mathieu-Daudé 369*a9ea77f2SPhilippe Mathieu-Daudé tcg_temp_free(bx); 370*a9ea77f2SPhilippe Mathieu-Daudé tcg_temp_free(ax); 371*a9ea77f2SPhilippe Mathieu-Daudé 372*a9ea77f2SPhilippe Mathieu-Daudé return true; 373*a9ea77f2SPhilippe Mathieu-Daudé } 374*a9ea77f2SPhilippe Mathieu-Daudé 3750bc69372SPhilippe Mathieu-Daudé /* Parallel Extend Upper from Word */ 3760bc69372SPhilippe Mathieu-Daudé static bool trans_PEXTUW(DisasContext *ctx, arg_rtype *a) 3770bc69372SPhilippe Mathieu-Daudé { 3780bc69372SPhilippe Mathieu-Daudé TCGv_i64 ax, bx; 3790bc69372SPhilippe Mathieu-Daudé 3800bc69372SPhilippe Mathieu-Daudé if (a->rd == 0) { 3810bc69372SPhilippe Mathieu-Daudé /* nop */ 3820bc69372SPhilippe Mathieu-Daudé return true; 3830bc69372SPhilippe Mathieu-Daudé } 3840bc69372SPhilippe Mathieu-Daudé 3850bc69372SPhilippe Mathieu-Daudé ax = tcg_temp_new_i64(); 3860bc69372SPhilippe Mathieu-Daudé bx = tcg_temp_new_i64(); 3870bc69372SPhilippe Mathieu-Daudé 3880bc69372SPhilippe Mathieu-Daudé gen_load_gpr_hi(ax, a->rs); 3890bc69372SPhilippe Mathieu-Daudé gen_load_gpr_hi(bx, a->rt); 3900bc69372SPhilippe Mathieu-Daudé gen_pextw(cpu_gpr[a->rd], cpu_gpr_hi[a->rd], ax, bx); 3910bc69372SPhilippe Mathieu-Daudé 3920bc69372SPhilippe Mathieu-Daudé tcg_temp_free(bx); 3930bc69372SPhilippe Mathieu-Daudé tcg_temp_free(ax); 3940bc69372SPhilippe Mathieu-Daudé 3950bc69372SPhilippe Mathieu-Daudé return true; 3960bc69372SPhilippe Mathieu-Daudé } 3970bc69372SPhilippe Mathieu-Daudé 398a2b0a27dSPhilippe Mathieu-Daudé /* 399a2b0a27dSPhilippe Mathieu-Daudé * Others (16 instructions) 400a2b0a27dSPhilippe Mathieu-Daudé * ------------------------ 401a2b0a27dSPhilippe Mathieu-Daudé * PCPYH rd, rt Parallel Copy Halfword 402a2b0a27dSPhilippe Mathieu-Daudé * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword 403a2b0a27dSPhilippe Mathieu-Daudé * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword 404a2b0a27dSPhilippe Mathieu-Daudé * PREVH rd, rt Parallel Reverse Halfword 405a2b0a27dSPhilippe Mathieu-Daudé * PINTH rd, rs, rt Parallel Interleave Halfword 406a2b0a27dSPhilippe Mathieu-Daudé * PINTEH rd, rs, rt Parallel Interleave Even Halfword 407a2b0a27dSPhilippe Mathieu-Daudé * PEXEH rd, rt Parallel Exchange Even Halfword 408a2b0a27dSPhilippe Mathieu-Daudé * PEXCH rd, rt Parallel Exchange Center Halfword 409a2b0a27dSPhilippe Mathieu-Daudé * PEXEW rd, rt Parallel Exchange Even Word 410a2b0a27dSPhilippe Mathieu-Daudé * PEXCW rd, rt Parallel Exchange Center Word 411a2b0a27dSPhilippe Mathieu-Daudé * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable 412a2b0a27dSPhilippe Mathieu-Daudé * MFSA rd Move from Shift Amount Register 413a2b0a27dSPhilippe Mathieu-Daudé * MTSA rs Move to Shift Amount Register 414a2b0a27dSPhilippe Mathieu-Daudé * MTSAB rs, immediate Move Byte Count to Shift Amount Register 415a2b0a27dSPhilippe Mathieu-Daudé * MTSAH rs, immediate Move Halfword Count to Shift Amount Register 416a2b0a27dSPhilippe Mathieu-Daudé * PROT3W rd, rt Parallel Rotate 3 Words 417a2b0a27dSPhilippe Mathieu-Daudé */ 418a2b0a27dSPhilippe Mathieu-Daudé 419a2b0a27dSPhilippe Mathieu-Daudé /* Parallel Copy Halfword */ 420a2b0a27dSPhilippe Mathieu-Daudé static bool trans_PCPYH(DisasContext *s, arg_rtype *a) 421a2b0a27dSPhilippe Mathieu-Daudé { 422a2b0a27dSPhilippe Mathieu-Daudé if (a->rd == 0) { 423a2b0a27dSPhilippe Mathieu-Daudé /* nop */ 424a2b0a27dSPhilippe Mathieu-Daudé return true; 425a2b0a27dSPhilippe Mathieu-Daudé } 426a2b0a27dSPhilippe Mathieu-Daudé 427a2b0a27dSPhilippe Mathieu-Daudé if (a->rt == 0) { 428a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr[a->rd], 0); 429a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0); 430a2b0a27dSPhilippe Mathieu-Daudé return true; 431a2b0a27dSPhilippe Mathieu-Daudé } 432a2b0a27dSPhilippe Mathieu-Daudé 433a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rt], cpu_gpr[a->rt], 16, 16); 434a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rd], cpu_gpr[a->rd], 32, 32); 435a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rt], cpu_gpr_hi[a->rt], 16, 16); 436a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], 32, 32); 437a2b0a27dSPhilippe Mathieu-Daudé 438a2b0a27dSPhilippe Mathieu-Daudé return true; 439a2b0a27dSPhilippe Mathieu-Daudé } 440a2b0a27dSPhilippe Mathieu-Daudé 441a2b0a27dSPhilippe Mathieu-Daudé /* Parallel Copy Lower Doubleword */ 442a2b0a27dSPhilippe Mathieu-Daudé static bool trans_PCPYLD(DisasContext *s, arg_rtype *a) 443a2b0a27dSPhilippe Mathieu-Daudé { 444a2b0a27dSPhilippe Mathieu-Daudé if (a->rd == 0) { 445a2b0a27dSPhilippe Mathieu-Daudé /* nop */ 446a2b0a27dSPhilippe Mathieu-Daudé return true; 447a2b0a27dSPhilippe Mathieu-Daudé } 448a2b0a27dSPhilippe Mathieu-Daudé 449a2b0a27dSPhilippe Mathieu-Daudé if (a->rs == 0) { 450a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0); 451a2b0a27dSPhilippe Mathieu-Daudé } else { 452a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_mov_i64(cpu_gpr_hi[a->rd], cpu_gpr[a->rs]); 453a2b0a27dSPhilippe Mathieu-Daudé } 454a2b0a27dSPhilippe Mathieu-Daudé 455a2b0a27dSPhilippe Mathieu-Daudé if (a->rt == 0) { 456a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr[a->rd], 0); 457a2b0a27dSPhilippe Mathieu-Daudé } else if (a->rd != a->rt) { 458a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_mov_i64(cpu_gpr[a->rd], cpu_gpr[a->rt]); 459a2b0a27dSPhilippe Mathieu-Daudé } 460a2b0a27dSPhilippe Mathieu-Daudé 461a2b0a27dSPhilippe Mathieu-Daudé return true; 462a2b0a27dSPhilippe Mathieu-Daudé } 463a2b0a27dSPhilippe Mathieu-Daudé 464a2b0a27dSPhilippe Mathieu-Daudé /* Parallel Copy Upper Doubleword */ 465a2b0a27dSPhilippe Mathieu-Daudé static bool trans_PCPYUD(DisasContext *s, arg_rtype *a) 466a2b0a27dSPhilippe Mathieu-Daudé { 467a2b0a27dSPhilippe Mathieu-Daudé if (a->rd == 0) { 468a2b0a27dSPhilippe Mathieu-Daudé /* nop */ 469a2b0a27dSPhilippe Mathieu-Daudé return true; 470a2b0a27dSPhilippe Mathieu-Daudé } 471a2b0a27dSPhilippe Mathieu-Daudé 472a2b0a27dSPhilippe Mathieu-Daudé gen_load_gpr_hi(cpu_gpr[a->rd], a->rs); 473a2b0a27dSPhilippe Mathieu-Daudé 474a2b0a27dSPhilippe Mathieu-Daudé if (a->rt == 0) { 475a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0); 476a2b0a27dSPhilippe Mathieu-Daudé } else if (a->rd != a->rt) { 477a2b0a27dSPhilippe Mathieu-Daudé tcg_gen_mov_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rt]); 478a2b0a27dSPhilippe Mathieu-Daudé } 479a2b0a27dSPhilippe Mathieu-Daudé 480a2b0a27dSPhilippe Mathieu-Daudé return true; 481a2b0a27dSPhilippe Mathieu-Daudé } 482