xref: /qemu/target/mips/tcg/tx79_translate.c (revision d0fb9657)
1 /*
2  * Toshiba TX79-specific instructions translation routines
3  *
4  *  Copyright (c) 2018 Fredrik Noring
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "qemu/osdep.h"
10 #include "tcg/tcg-op.h"
11 #include "exec/helper-gen.h"
12 #include "translate.h"
13 
14 /* Include the auto-generated decoder.  */
15 #include "decode-tx79.c.inc"
16 
17 /*
18  *     Overview of the TX79-specific instruction set
19  *     =============================================
20  *
21  * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
22  * are only used by the specific quadword (128-bit) LQ/SQ load/store
23  * instructions and certain multimedia instructions (MMIs). These MMIs
24  * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
25  * or sixteen 8-bit paths.
26  *
27  * Reference:
28  *
29  * The Toshiba TX System RISC TX79 Core Architecture manual,
30  * https://wiki.qemu.org/File:C790.pdf
31  */
32 
33 bool decode_ext_tx79(DisasContext *ctx, uint32_t insn)
34 {
35     if (TARGET_LONG_BITS == 64 && decode_tx79(ctx, insn)) {
36         return true;
37     }
38     return false;
39 }
40 
41 /*
42  *     Three-Operand Multiply and Multiply-Add (4 instructions)
43  *     --------------------------------------------------------
44  * MADD    [rd,] rs, rt      Multiply/Add
45  * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
46  * MULT    [rd,] rs, rt      Multiply (3-operand)
47  * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
48  */
49 
50 /*
51  *     Multiply Instructions for Pipeline 1 (10 instructions)
52  *     ------------------------------------------------------
53  * MULT1   [rd,] rs, rt      Multiply Pipeline 1
54  * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
55  * DIV1    rs, rt            Divide Pipeline 1
56  * DIVU1   rs, rt            Divide Unsigned Pipeline 1
57  * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
58  * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
59  * MFHI1   rd                Move From HI1 Register
60  * MFLO1   rd                Move From LO1 Register
61  * MTHI1   rs                Move To HI1 Register
62  * MTLO1   rs                Move To LO1 Register
63  */
64 
65 static bool trans_MFHI1(DisasContext *ctx, arg_rtype *a)
66 {
67     gen_store_gpr(cpu_HI[1], a->rd);
68 
69     return true;
70 }
71 
72 static bool trans_MFLO1(DisasContext *ctx, arg_rtype *a)
73 {
74     gen_store_gpr(cpu_LO[1], a->rd);
75 
76     return true;
77 }
78 
79 static bool trans_MTHI1(DisasContext *ctx, arg_rtype *a)
80 {
81     gen_load_gpr(cpu_HI[1], a->rs);
82 
83     return true;
84 }
85 
86 static bool trans_MTLO1(DisasContext *ctx, arg_rtype *a)
87 {
88     gen_load_gpr(cpu_LO[1], a->rs);
89 
90     return true;
91 }
92 
93 /*
94  *     Arithmetic (19 instructions)
95  *     ----------------------------
96  * PADDB   rd, rs, rt        Parallel Add Byte
97  * PSUBB   rd, rs, rt        Parallel Subtract Byte
98  * PADDH   rd, rs, rt        Parallel Add Halfword
99  * PSUBH   rd, rs, rt        Parallel Subtract Halfword
100  * PADDW   rd, rs, rt        Parallel Add Word
101  * PSUBW   rd, rs, rt        Parallel Subtract Word
102  * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
103  * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
104  * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
105  * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
106  * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
107  * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
108  * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
109  * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
110  * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
111  * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
112  * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
113  * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
114  * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
115  */
116 
117 /*
118  *     Min/Max (4 instructions)
119  *     ------------------------
120  * PMAXH   rd, rs, rt        Parallel Maximum Halfword
121  * PMINH   rd, rs, rt        Parallel Minimum Halfword
122  * PMAXW   rd, rs, rt        Parallel Maximum Word
123  * PMINW   rd, rs, rt        Parallel Minimum Word
124  */
125 
126 /*
127  *     Absolute (2 instructions)
128  *     -------------------------
129  * PABSH   rd, rt            Parallel Absolute Halfword
130  * PABSW   rd, rt            Parallel Absolute Word
131  */
132 
133 /*
134  *     Logical (4 instructions)
135  *     ------------------------
136  * PAND    rd, rs, rt        Parallel AND
137  * POR     rd, rs, rt        Parallel OR
138  * PXOR    rd, rs, rt        Parallel XOR
139  * PNOR    rd, rs, rt        Parallel NOR
140  */
141 
142 /*
143  *     Shift (9 instructions)
144  *     ----------------------
145  * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
146  * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
147  * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
148  * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
149  * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
150  * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
151  * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
152  * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
153  * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
154  */
155 
156 /*
157  *     Compare (6 instructions)
158  *     ------------------------
159  * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
160  * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
161  * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
162  * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
163  * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
164  * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
165  */
166 
167 /*
168  *     LZC (1 instruction)
169  *     -------------------
170  * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
171  */
172 
173 /*
174  *     Quadword Load and Store (2 instructions)
175  *     ----------------------------------------
176  * LQ      rt, offset(base)  Load Quadword
177  * SQ      rt, offset(base)  Store Quadword
178  */
179 
180 /*
181  *     Multiply and Divide (19 instructions)
182  *     -------------------------------------
183  * PMULTW  rd, rs, rt        Parallel Multiply Word
184  * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
185  * PDIVW   rs, rt            Parallel Divide Word
186  * PDIVUW  rs, rt            Parallel Divide Unsigned Word
187  * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
188  * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
189  * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
190  * PMULTH  rd, rs, rt        Parallel Multiply Halfword
191  * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
192  * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
193  * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
194  * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
195  * PDIVBW  rs, rt            Parallel Divide Broadcast Word
196  * PMFHI   rd                Parallel Move From HI Register
197  * PMFLO   rd                Parallel Move From LO Register
198  * PMTHI   rs                Parallel Move To HI Register
199  * PMTLO   rs                Parallel Move To LO Register
200  * PMFHL   rd                Parallel Move From HI/LO Register
201  * PMTHL   rs                Parallel Move To HI/LO Register
202  */
203 
204 /*
205  *     Pack/Extend (11 instructions)
206  *     -----------------------------
207  * PPAC5   rd, rt            Parallel Pack to 5 bits
208  * PPACB   rd, rs, rt        Parallel Pack to Byte
209  * PPACH   rd, rs, rt        Parallel Pack to Halfword
210  * PPACW   rd, rs, rt        Parallel Pack to Word
211  * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
212  * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
213  * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
214  * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
215  * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
216  * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
217  * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
218  */
219 
220 /*
221  *     Others (16 instructions)
222  *     ------------------------
223  * PCPYH   rd, rt            Parallel Copy Halfword
224  * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
225  * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
226  * PREVH   rd, rt            Parallel Reverse Halfword
227  * PINTH   rd, rs, rt        Parallel Interleave Halfword
228  * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
229  * PEXEH   rd, rt            Parallel Exchange Even Halfword
230  * PEXCH   rd, rt            Parallel Exchange Center Halfword
231  * PEXEW   rd, rt            Parallel Exchange Even Word
232  * PEXCW   rd, rt            Parallel Exchange Center Word
233  * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
234  * MFSA    rd                Move from Shift Amount Register
235  * MTSA    rs                Move to Shift Amount Register
236  * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
237  * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
238  * PROT3W  rd, rt            Parallel Rotate 3 Words
239  */
240 
241 /* Parallel Copy Halfword */
242 static bool trans_PCPYH(DisasContext *s, arg_rtype *a)
243 {
244     if (a->rd == 0) {
245         /* nop */
246         return true;
247     }
248 
249     if (a->rt == 0) {
250         tcg_gen_movi_i64(cpu_gpr[a->rd], 0);
251         tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
252         return true;
253     }
254 
255     tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rt], cpu_gpr[a->rt], 16, 16);
256     tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rd], cpu_gpr[a->rd], 32, 32);
257     tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rt], cpu_gpr_hi[a->rt], 16, 16);
258     tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], 32, 32);
259 
260     return true;
261 }
262 
263 /* Parallel Copy Lower Doubleword */
264 static bool trans_PCPYLD(DisasContext *s, arg_rtype *a)
265 {
266     if (a->rd == 0) {
267         /* nop */
268         return true;
269     }
270 
271     if (a->rs == 0) {
272         tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
273     } else {
274         tcg_gen_mov_i64(cpu_gpr_hi[a->rd], cpu_gpr[a->rs]);
275     }
276 
277     if (a->rt == 0) {
278         tcg_gen_movi_i64(cpu_gpr[a->rd], 0);
279     } else if (a->rd != a->rt) {
280         tcg_gen_mov_i64(cpu_gpr[a->rd], cpu_gpr[a->rt]);
281     }
282 
283     return true;
284 }
285 
286 /* Parallel Copy Upper Doubleword */
287 static bool trans_PCPYUD(DisasContext *s, arg_rtype *a)
288 {
289     if (a->rd == 0) {
290         /* nop */
291         return true;
292     }
293 
294     gen_load_gpr_hi(cpu_gpr[a->rd], a->rs);
295 
296     if (a->rt == 0) {
297         tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
298     } else if (a->rd != a->rt) {
299         tcg_gen_mov_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rt]);
300     }
301 
302     return true;
303 }
304