1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "tcg/tcg-op.h"
12#include "tcg/tcg-op-gvec.h"
13#include "exec/helper-gen.h"
14#include "translate.h"
15
16
17#include "decode-tx79.c.inc"
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35bool decode_ext_tx79(DisasContext *ctx, uint32_t insn)
36{
37 if (TARGET_LONG_BITS == 64 && decode_tx79(ctx, insn)) {
38 return true;
39 }
40 return false;
41}
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67static bool trans_MFHI1(DisasContext *ctx, arg_r *a)
68{
69 gen_store_gpr(cpu_HI[1], a->rd);
70
71 return true;
72}
73
74static bool trans_MFLO1(DisasContext *ctx, arg_r *a)
75{
76 gen_store_gpr(cpu_LO[1], a->rd);
77
78 return true;
79}
80
81static bool trans_MTHI1(DisasContext *ctx, arg_r *a)
82{
83 gen_load_gpr(cpu_HI[1], a->rs);
84
85 return true;
86}
87
88static bool trans_MTLO1(DisasContext *ctx, arg_r *a)
89{
90 gen_load_gpr(cpu_LO[1], a->rs);
91
92 return true;
93}
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119static bool trans_parallel_arith(DisasContext *ctx, arg_r *a,
120 void (*gen_logic_i64)(TCGv_i64, TCGv_i64, TCGv_i64))
121{
122 TCGv_i64 ax, bx;
123
124 if (a->rd == 0) {
125
126 return true;
127 }
128
129 ax = tcg_temp_new_i64();
130 bx = tcg_temp_new_i64();
131
132
133 gen_load_gpr(ax, a->rs);
134 gen_load_gpr(bx, a->rt);
135 gen_logic_i64(cpu_gpr[a->rd], ax, bx);
136
137
138 gen_load_gpr_hi(ax, a->rs);
139 gen_load_gpr_hi(bx, a->rt);
140 gen_logic_i64(cpu_gpr_hi[a->rd], ax, bx);
141 return true;
142}
143
144
145static bool trans_PSUBB(DisasContext *ctx, arg_r *a)
146{
147 return trans_parallel_arith(ctx, a, tcg_gen_vec_sub8_i64);
148}
149
150
151static bool trans_PSUBH(DisasContext *ctx, arg_r *a)
152{
153 return trans_parallel_arith(ctx, a, tcg_gen_vec_sub16_i64);
154}
155
156
157static bool trans_PSUBW(DisasContext *ctx, arg_r *a)
158{
159 return trans_parallel_arith(ctx, a, tcg_gen_vec_sub32_i64);
160}
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188static bool trans_PAND(DisasContext *ctx, arg_r *a)
189{
190 return trans_parallel_arith(ctx, a, tcg_gen_and_i64);
191}
192
193
194static bool trans_POR(DisasContext *ctx, arg_r *a)
195{
196 return trans_parallel_arith(ctx, a, tcg_gen_or_i64);
197}
198
199
200static bool trans_PXOR(DisasContext *ctx, arg_r *a)
201{
202 return trans_parallel_arith(ctx, a, tcg_gen_xor_i64);
203}
204
205
206static bool trans_PNOR(DisasContext *ctx, arg_r *a)
207{
208 return trans_parallel_arith(ctx, a, tcg_gen_nor_i64);
209}
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236static bool trans_parallel_compare(DisasContext *ctx, arg_r *a,
237 TCGCond cond, unsigned wlen)
238{
239 TCGv_i64 c0, c1, ax, bx, t0, t1, t2;
240
241 if (a->rd == 0) {
242
243 return true;
244 }
245
246 c0 = tcg_constant_tl(0);
247 c1 = tcg_constant_tl(0xffffffff);
248 ax = tcg_temp_new_i64();
249 bx = tcg_temp_new_i64();
250 t0 = tcg_temp_new_i64();
251 t1 = tcg_temp_new_i64();
252 t2 = tcg_temp_new_i64();
253
254
255 gen_load_gpr(ax, a->rs);
256 gen_load_gpr(bx, a->rt);
257 for (int i = 0; i < (64 / wlen); i++) {
258 tcg_gen_sextract_i64(t0, ax, wlen * i, wlen);
259 tcg_gen_sextract_i64(t1, bx, wlen * i, wlen);
260 tcg_gen_movcond_i64(cond, t2, t1, t0, c1, c0);
261 tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rd], t2, wlen * i, wlen);
262 }
263
264 gen_load_gpr_hi(ax, a->rs);
265 gen_load_gpr_hi(bx, a->rt);
266 for (int i = 0; i < (64 / wlen); i++) {
267 tcg_gen_sextract_i64(t0, ax, wlen * i, wlen);
268 tcg_gen_sextract_i64(t1, bx, wlen * i, wlen);
269 tcg_gen_movcond_i64(cond, t2, t1, t0, c1, c0);
270 tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], t2, wlen * i, wlen);
271 }
272 return true;
273}
274
275
276static bool trans_PCGTB(DisasContext *ctx, arg_r *a)
277{
278 return trans_parallel_compare(ctx, a, TCG_COND_GE, 8);
279}
280
281
282static bool trans_PCEQB(DisasContext *ctx, arg_r *a)
283{
284 return trans_parallel_compare(ctx, a, TCG_COND_EQ, 8);
285}
286
287
288static bool trans_PCGTH(DisasContext *ctx, arg_r *a)
289{
290 return trans_parallel_compare(ctx, a, TCG_COND_GE, 16);
291}
292
293
294static bool trans_PCEQH(DisasContext *ctx, arg_r *a)
295{
296 return trans_parallel_compare(ctx, a, TCG_COND_EQ, 16);
297}
298
299
300static bool trans_PCGTW(DisasContext *ctx, arg_r *a)
301{
302 return trans_parallel_compare(ctx, a, TCG_COND_GE, 32);
303}
304
305
306static bool trans_PCEQW(DisasContext *ctx, arg_r *a)
307{
308 return trans_parallel_compare(ctx, a, TCG_COND_EQ, 32);
309}
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324static bool trans_LQ(DisasContext *ctx, arg_i *a)
325{
326 TCGv_i64 t0;
327 TCGv addr;
328
329 if (a->rt == 0) {
330
331 return true;
332 }
333
334 t0 = tcg_temp_new_i64();
335 addr = tcg_temp_new();
336
337 gen_base_offset_addr(ctx, addr, a->base, a->offset);
338
339
340
341
342 tcg_gen_andi_tl(addr, addr, ~0xf);
343
344
345 tcg_gen_qemu_ld_i64(t0, addr, ctx->mem_idx, MO_TEUQ);
346 gen_store_gpr(t0, a->rt);
347
348
349 tcg_gen_addi_i64(addr, addr, 8);
350 tcg_gen_qemu_ld_i64(t0, addr, ctx->mem_idx, MO_TEUQ);
351 gen_store_gpr_hi(t0, a->rt);
352 return true;
353}
354
355static bool trans_SQ(DisasContext *ctx, arg_i *a)
356{
357 TCGv_i64 t0 = tcg_temp_new_i64();
358 TCGv addr = tcg_temp_new();
359
360 gen_base_offset_addr(ctx, addr, a->base, a->offset);
361
362
363
364
365 tcg_gen_andi_tl(addr, addr, ~0xf);
366
367
368 gen_load_gpr(t0, a->rt);
369 tcg_gen_qemu_st_i64(t0, addr, ctx->mem_idx, MO_TEUQ);
370
371
372 tcg_gen_addi_i64(addr, addr, 8);
373 gen_load_gpr_hi(t0, a->rt);
374 tcg_gen_qemu_st_i64(t0, addr, ctx->mem_idx, MO_TEUQ);
375 return true;
376}
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419static bool trans_PPACW(DisasContext *ctx, arg_r *a)
420{
421 TCGv_i64 a0, b0, t0;
422
423 if (a->rd == 0) {
424
425 return true;
426 }
427
428 a0 = tcg_temp_new_i64();
429 b0 = tcg_temp_new_i64();
430 t0 = tcg_temp_new_i64();
431
432 gen_load_gpr(a0, a->rs);
433 gen_load_gpr(b0, a->rt);
434
435 gen_load_gpr_hi(t0, a->rt);
436 tcg_gen_deposit_i64(cpu_gpr[a->rd], b0, t0, 32, 32);
437
438 gen_load_gpr_hi(t0, a->rs);
439 tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], a0, t0, 32, 32);
440 return true;
441}
442
443static void gen_pextw(TCGv_i64 dl, TCGv_i64 dh, TCGv_i64 a, TCGv_i64 b)
444{
445 tcg_gen_deposit_i64(dl, b, a, 32, 32);
446 tcg_gen_shri_i64(b, b, 32);
447 tcg_gen_deposit_i64(dh, a, b, 0, 32);
448}
449
450static bool trans_PEXTLx(DisasContext *ctx, arg_r *a, unsigned wlen)
451{
452 TCGv_i64 ax, bx;
453
454 if (a->rd == 0) {
455
456 return true;
457 }
458
459 ax = tcg_temp_new_i64();
460 bx = tcg_temp_new_i64();
461
462 gen_load_gpr(ax, a->rs);
463 gen_load_gpr(bx, a->rt);
464
465
466 for (int i = 0; i < 64 / (2 * wlen); i++) {
467 tcg_gen_deposit_i64(cpu_gpr[a->rd],
468 cpu_gpr[a->rd], bx, 2 * wlen * i, wlen);
469 tcg_gen_deposit_i64(cpu_gpr[a->rd],
470 cpu_gpr[a->rd], ax, 2 * wlen * i + wlen, wlen);
471 tcg_gen_shri_i64(bx, bx, wlen);
472 tcg_gen_shri_i64(ax, ax, wlen);
473 }
474
475 for (int i = 0; i < 64 / (2 * wlen); i++) {
476 tcg_gen_deposit_i64(cpu_gpr_hi[a->rd],
477 cpu_gpr_hi[a->rd], bx, 2 * wlen * i, wlen);
478 tcg_gen_deposit_i64(cpu_gpr_hi[a->rd],
479 cpu_gpr_hi[a->rd], ax, 2 * wlen * i + wlen, wlen);
480 tcg_gen_shri_i64(bx, bx, wlen);
481 tcg_gen_shri_i64(ax, ax, wlen);
482 }
483 return true;
484}
485
486
487static bool trans_PEXTLB(DisasContext *ctx, arg_r *a)
488{
489 return trans_PEXTLx(ctx, a, 8);
490}
491
492
493static bool trans_PEXTLH(DisasContext *ctx, arg_r *a)
494{
495 return trans_PEXTLx(ctx, a, 16);
496}
497
498
499static bool trans_PEXTLW(DisasContext *ctx, arg_r *a)
500{
501 TCGv_i64 ax, bx;
502
503 if (a->rd == 0) {
504
505 return true;
506 }
507
508 ax = tcg_temp_new_i64();
509 bx = tcg_temp_new_i64();
510
511 gen_load_gpr(ax, a->rs);
512 gen_load_gpr(bx, a->rt);
513 gen_pextw(cpu_gpr[a->rd], cpu_gpr_hi[a->rd], ax, bx);
514 return true;
515}
516
517
518static bool trans_PEXTUW(DisasContext *ctx, arg_r *a)
519{
520 TCGv_i64 ax, bx;
521
522 if (a->rd == 0) {
523
524 return true;
525 }
526
527 ax = tcg_temp_new_i64();
528 bx = tcg_temp_new_i64();
529
530 gen_load_gpr_hi(ax, a->rs);
531 gen_load_gpr_hi(bx, a->rt);
532 gen_pextw(cpu_gpr[a->rd], cpu_gpr_hi[a->rd], ax, bx);
533 return true;
534}
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558static bool trans_PCPYH(DisasContext *s, arg_r *a)
559{
560 if (a->rd == 0) {
561
562 return true;
563 }
564
565 if (a->rt == 0) {
566 tcg_gen_movi_i64(cpu_gpr[a->rd], 0);
567 tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
568 return true;
569 }
570
571 tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rt], cpu_gpr[a->rt], 16, 16);
572 tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rd], cpu_gpr[a->rd], 32, 32);
573 tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rt], cpu_gpr_hi[a->rt], 16, 16);
574 tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], 32, 32);
575
576 return true;
577}
578
579
580static bool trans_PCPYLD(DisasContext *s, arg_r *a)
581{
582 if (a->rd == 0) {
583
584 return true;
585 }
586
587 if (a->rs == 0) {
588 tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
589 } else {
590 tcg_gen_mov_i64(cpu_gpr_hi[a->rd], cpu_gpr[a->rs]);
591 }
592
593 if (a->rt == 0) {
594 tcg_gen_movi_i64(cpu_gpr[a->rd], 0);
595 } else if (a->rd != a->rt) {
596 tcg_gen_mov_i64(cpu_gpr[a->rd], cpu_gpr[a->rt]);
597 }
598
599 return true;
600}
601
602
603static bool trans_PCPYUD(DisasContext *s, arg_r *a)
604{
605 if (a->rd == 0) {
606
607 return true;
608 }
609
610 gen_load_gpr_hi(cpu_gpr[a->rd], a->rs);
611
612 if (a->rt == 0) {
613 tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
614 } else if (a->rd != a->rt) {
615 tcg_gen_mov_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rt]);
616 }
617
618 return true;
619}
620
621
622static bool trans_PROT3W(DisasContext *ctx, arg_r *a)
623{
624 TCGv_i64 ax;
625
626 if (a->rd == 0) {
627
628 return true;
629 }
630 if (a->rt == 0) {
631 tcg_gen_movi_i64(cpu_gpr[a->rd], 0);
632 tcg_gen_movi_i64(cpu_gpr_hi[a->rd], 0);
633 return true;
634 }
635
636 ax = tcg_temp_new_i64();
637
638 tcg_gen_mov_i64(ax, cpu_gpr_hi[a->rt]);
639 tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], ax, cpu_gpr[a->rt], 0, 32);
640
641 tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rt], ax, 0, 32);
642 tcg_gen_rotri_i64(cpu_gpr[a->rd], cpu_gpr[a->rd], 32);
643 return true;
644}
645