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